├── .codeclimate.yml ├── .editorconfig ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.md ├── PHPMD_custom.xml ├── Plugin.php ├── README.md ├── assets └── images │ ├── logo.svg │ └── toolbox-banner.png ├── classes ├── collection │ ├── CollectionStore.php │ ├── ElementCollection.php │ └── TestCollection.php ├── component │ ├── ComponentSubmitForm.php │ ├── ElementData.php │ ├── ElementPage.php │ └── SortingElementList.php ├── console │ ├── CommonCreateFile.php │ ├── CreateAll.php │ ├── CreateCollection.php │ ├── CreateComponentData.php │ ├── CreateComponentList.php │ ├── CreateComponentPage.php │ ├── CreateController.php │ ├── CreateEventModel.php │ ├── CreateExtendBackendMenuHandler.php │ ├── CreateExtendModelColumnsHandler.php │ ├── CreateExtendModelFieldsHandler.php │ ├── CreateItem.php │ ├── CreateMigration.php │ ├── CreateModel.php │ ├── CreateModelColumn.php │ ├── CreateModelField.php │ ├── CreatePlugin.php │ ├── CreateStore.php │ └── ToolBoxHelper.php ├── event │ ├── AbstractBackendColumnHandler.php │ ├── AbstractBackendFieldHandler.php │ ├── AbstractBackendMenuHandler.php │ ├── AbstractExtendRelationConfigHandler.php │ ├── AbstractModelRelationHandler.php │ └── ModelHandler.php ├── helper │ ├── AbstractImportModel.php │ ├── AbstractImportModelFromCSV.php │ ├── AbstractImportModelFromXML.php │ ├── ImportXMLNode.php │ ├── PageHelper.php │ ├── ParseXMLNode.php │ ├── PriceHelper.php │ ├── SendMailHelper.php │ ├── UserHelper.php │ └── users │ │ ├── AbstractUserHelper.php │ │ ├── BuddiesUserHelper.php │ │ └── RainLabUserHelper.php ├── item │ ├── ElementItem.php │ ├── ItemStorage.php │ ├── MainItem.php │ └── TestItem.php ├── parser │ ├── create │ │ ├── ActiveListStoreCreateFile.php │ │ ├── CollectionCreateFile.php │ │ ├── CommonCreateFile.php │ │ ├── ComponentDataCreateFile.php │ │ ├── ComponentListCreateFile.php │ │ ├── ComponentPageCreateFile.php │ │ ├── ControllerConfigImportExportCreateFile.php │ │ ├── ControllerConfigReorderCreateFile.php │ │ ├── ControllerConfirmFilterCreateFile.php │ │ ├── ControllerConfirmFormCreateFile.php │ │ ├── ControllerConfirmListCreateFile.php │ │ ├── ControllerCreateCreateFile.php │ │ ├── ControllerCreateFile.php │ │ ├── ControllerExportCreateFile.php │ │ ├── ControllerImportCreateFile.php │ │ ├── ControllerIndexCreateFile.php │ │ ├── ControllerListToolbarCreateFile.php │ │ ├── ControllerPreviewCreateFile.php │ │ ├── ControllerReorderCreateFile.php │ │ ├── ControllerUpdateCreateFile.php │ │ ├── EventModelCreateFile.php │ │ ├── ExtendBackendMenuHandlerCreateFile.php │ │ ├── ExtendModelColumnsHandlerCreateFile.php │ │ ├── ExtendModelFieldsHandlerCreateFile.php │ │ ├── ItemCreateFile.php │ │ ├── ListStoreCreateFile.php │ │ ├── MigrationCreateFile.php │ │ ├── ModelColumnCreateFile.php │ │ ├── ModelCreateFile.php │ │ ├── ModelFieldCreateFile.php │ │ ├── PluginLangCreateFile.php │ │ ├── PluginPHPCreateFile.php │ │ ├── PluginVersionCreateFile.php │ │ ├── PluginYAMLCreateFile.php │ │ ├── SortingListStoreCreateFile.php │ │ └── TopLevelListStoreCreateFile.php │ ├── templates │ │ ├── active_list_store.stub │ │ ├── collection.stub │ │ ├── columns.stub │ │ ├── component_data.stub │ │ ├── component_list.stub │ │ ├── component_page.stub │ │ ├── controller.stub │ │ ├── controller_config_filter.stub │ │ ├── controller_config_form.stub │ │ ├── controller_config_import_export.stub │ │ ├── controller_config_list.stub │ │ ├── controller_config_reorder.stub │ │ ├── controller_create.stub │ │ ├── controller_export.stub │ │ ├── controller_import.stub │ │ ├── controller_index.stub │ │ ├── controller_list_toolbar.stub │ │ ├── controller_preview.stub │ │ ├── controller_reorder.stub │ │ ├── controller_update.stub │ │ ├── event_model.stub │ │ ├── extend_backend_menu_handler.stub │ │ ├── extend_model_columns_handler.stub │ │ ├── extend_model_fields_handler.stub │ │ ├── fields.stub │ │ ├── item.stub │ │ ├── lang.stub │ │ ├── list_store.stub │ │ ├── migration.stub │ │ ├── model.stub │ │ ├── plugin_php.stub │ │ ├── plugin_yaml.stub │ │ ├── sorting_list_store.stub │ │ ├── sorting_top_level_list_store.stub │ │ └── version.stub │ └── update │ │ ├── CommonUpdateFile.php │ │ ├── PluginLangUpdateFile.php │ │ ├── PluginVersionYAMLUpdateFile.php │ │ └── PluginYAMLUpdateFile.php ├── queue │ └── ImportItemQueue.php ├── storage │ ├── AbstractUserStorage.php │ ├── CookieUserStorage.php │ ├── SessionUserStorage.php │ └── UserStorage.php └── store │ ├── AbstractListStore.php │ ├── AbstractStore.php │ ├── AbstractStoreWithParam.php │ ├── AbstractStoreWithTwoParam.php │ └── AbstractStoreWithoutParam.php ├── components └── Pagination.php ├── composer.json ├── crowdin.yml ├── lang ├── ar │ └── lang.php ├── be │ └── lang.php ├── bg │ └── lang.php ├── ca │ └── lang.php ├── cs │ └── lang.php ├── da │ └── lang.php ├── de │ └── lang.php ├── el │ └── lang.php ├── en │ └── lang.php ├── es │ └── lang.php ├── et │ └── lang.php ├── fa │ └── lang.php ├── fi │ └── lang.php ├── fr │ └── lang.php ├── hu │ └── lang.php ├── id │ └── lang.php ├── it │ └── lang.php ├── ja │ └── lang.php ├── kk │ └── lang.php ├── ko │ └── lang.php ├── ky │ └── lang.php ├── lt │ └── lang.php ├── lv │ └── lang.php ├── nb │ └── lang.php ├── nl │ └── lang.php ├── pl │ └── lang.php ├── pt │ └── lang.php ├── ro │ └── lang.php ├── ru │ └── lang.php ├── sk │ └── lang.php ├── sv │ └── lang.php ├── tr │ └── lang.php ├── uk │ └── lang.php ├── vi │ └── lang.php └── zh │ └── lang.php ├── models ├── CommonProperty.php ├── CommonSettings.php ├── Settings.php └── settings │ └── fields.yaml ├── phpunit.xml ├── plugin.yaml ├── tests ├── CommonTest.php └── unit │ ├── CollectionStoreTest.php │ ├── CollectionTest.php │ └── ItemTest.php ├── traits ├── console │ ├── LogoTrait.php │ └── UpdateLangFile.php ├── helpers │ ├── PriceHelperTrait.php │ ├── TraitCached.php │ ├── TraitComponentNotFoundResponse.php │ ├── TraitInitActiveLang.php │ └── TraitValidationHelper.php ├── models │ ├── MultisiteHelperTrait.php │ └── SetPropertyAttributeTrait.php ├── parse │ └── ParseByPatternTrait.php └── tests │ ├── TestModelHasImages.php │ ├── TestModelHasPreviewImage.php │ ├── TestModelValidationNameField.php │ └── TestModelValidationSlugField.php └── updates └── version.yaml /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | plugins: 3 | duplication: 4 | enabled: true 5 | config: 6 | languages: 7 | php: 8 | mass_threshold: 50 9 | fixme: 10 | enabled: true 11 | phpmd: 12 | enabled: true 13 | config: 14 | file_extensions: "php" 15 | rulesets: "controversial,design,unusedcode,PHPMD_custom.xml" 16 | phpcodesniffer: 17 | enabled: true 18 | config: 19 | standard: "Symfony2" 20 | sonar-php: 21 | enabled: true 22 | ratings: 23 | paths: 24 | - "**.php" 25 | exclude_patterns: 26 | - 'tests/' 27 | - 'traits/tests/' 28 | - 'vendor/' 29 | - 'lang/' 30 | - 'classes/item/TestItem.php' 31 | - 'classes/collection/TestCollection.php' -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Defining consistent coding styles between different editors and IDEs 2 | # Support info @ http://editorconfig.org/#download 3 | # editorconfig.org 4 | 5 | # Top-most EditorConfig file 6 | root = true 7 | 8 | # General settings 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | indent_style = space 15 | indent_size = 4 16 | 17 | # CSS settings 18 | [*.css] 19 | indent_size = 2 20 | 21 | # YAML settings 22 | [*.yml] 23 | indent_size = 2 24 | 25 | # Markdown settings 26 | [*.md] 27 | trim_trailing_whitespace = false 28 | 29 | # Resetting rules for third-party libraries 30 | # [{lib/**.js, lib/**.css}] 31 | # charset = unset 32 | # end_of_line = unset 33 | # trim_trailing_whitespace = unset 34 | # insert_final_newline = unset 35 | # indent_style = unset 36 | # indent_size = unset 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | Homestead.yaml 3 | /_ide_helper.php 4 | build.sh 5 | 6 | vendor 7 | composer.lock 8 | 9 | #site 10 | pdf/ 11 | _backup/ 12 | cgi-bin/ 13 | 14 | *.log 15 | *.bin 16 | *.komodoproject 17 | /.komodotools/ 18 | 19 | # PhpStorm 20 | .idea 21 | 22 | # Eclipse 23 | *.pydevproject 24 | .project 25 | .metadata 26 | bin/** 27 | tmp/** 28 | tmp/**/* 29 | *.tmp 30 | *.bak 31 | *.swp 32 | *~.nib 33 | local.properties 34 | .classpath 35 | .settings/ 36 | .loadpath 37 | .externalToolBuilders/ 38 | *.launch 39 | .cproject 40 | .buildpath 41 | 42 | # SublimeText 43 | /*.sublime-project 44 | *.sublime-workspace 45 | 46 | # NetBeans 47 | nbproject/ 48 | build/ 49 | nbbuild/ 50 | dist/ 51 | nbdist/ 52 | nbactions.xml 53 | nb-configuration.xml 54 | 55 | # Windows system files 56 | $RECYCLE.BIN/ 57 | Thumbs.db 58 | ehthumbs.db 59 | Desktop.ini 60 | 61 | # OSX system files 62 | .DS_store 63 | .AppleDouble 64 | .LSOverride 65 | Icon 66 | ._* 67 | .Spotlight-V100 68 | .Trashes 69 | 70 | # SVN/CVS 71 | .svn 72 | /CVS/* 73 | */CVS/* 74 | .cvsignore 75 | */.cvsignore 76 | 77 | # temporary files/folders 78 | 79 | tmp* 80 | ~* 81 | *.~* 82 | *.bak 83 | *.swp 84 | 85 | build/ 86 | png/ 87 | psd/ 88 | doc/ 89 | svg/ 90 | vendors/ 91 | pixelPerfect/ 92 | node_modules/ 93 | docs/ 94 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue with the owners of this repository before making a change. 4 | 5 | Please note we have a code of conduct, please follow it in all your interactions with the project. 6 | 7 | ## Pull Request Process 8 | 9 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a build. 10 | 2. Cover your code contribution with unit tests and ensure your Pull Request passes all the tests. 11 | 3. Open a Pull Request to a `develop` branch. 12 | 4. Add to the Pull Request details of changes to the interface, this includes new environment variables, exposed ports, useful file locations and container parameters. 13 | 5. You may merge the Pull Request in once you have the sign-off of two other developers, or if you do not have permission to do that, you may request the second reviewer to merge it for you. 14 | 15 | ## Code of Conduct 16 | 17 | ### Our Pledge 18 | 19 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 20 | 21 | ### Our Standards 22 | 23 | Examples of behavior that contributes to creating a positive environment include: 24 | 25 | * Using welcoming and inclusive language. 26 | * Being respectful of differing viewpoints and experiences. 27 | * Gracefully accepting constructive criticism. 28 | * Focusing on what is best for the community. 29 | * Showing empathy towards other community members. 30 | 31 | Examples of unacceptable behavior by participants include: 32 | 33 | * The use of sexualized language or imagery and unwelcome sexual attention or advances. 34 | * Trolling, insulting/derogatory comments, and personal or political attacks. 35 | * Public or private harassment. 36 | * Publishing others' private information, such as a physical or electronic address, without explicit permission. 37 | * Other conduct which could reasonably be considered inappropriate in a professional setting. 38 | 39 | ### Our Responsibilities 40 | 41 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 42 | 43 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 44 | 45 | ### Scope 46 | 47 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 48 | 49 | ### Enforcement 50 | 51 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [support@lovata.com](mailto:support@lovata.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 52 | 53 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 54 | 55 | ### Attribution 56 | 57 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 58 | 59 | [homepage]: http://contributor-covenant.org 60 | [version]: http://contributor-covenant.org/version/1/4/ 61 | -------------------------------------------------------------------------------- /PHPMD_custom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | Custom rules for checking project LOVATA Group 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Toolbox 2 | 3 | [![Build Status](https://travis-ci.org/lovata/oc-toolbox-plugin.svg?branch=master)](https://travis-ci.org/lovata/oc-toolbox-plugin) 4 | [![Dependency Status](https://www.versioneye.com/user/projects/59d504fc2de28c002c1882b5/badge.svg)](https://www.versioneye.com/user/projects/59d504fc2de28c002c1882b5) 5 | [![Coverage Status](https://coveralls.io/repos/github/lovata/oc-toolbox-plugin/badge.svg?branch=master)](https://coveralls.io/github/lovata/oc-toolbox-plugin?branch=master) 6 | [![Code Climate](https://codeclimate.com/github/lovata/oc-toolbox-plugin/badges/gpa.svg)](https://codeclimate.com/github/lovata/oc-toolbox-plugin) 7 | [![Crowdin](https://d322cqt584bo4o.cloudfront.net/toolbox-plugin-for-october-cms/localized.svg)](https://crowdin.com/project/toolbox-plugin-for-october-cms) 8 | [![SemVer 2.0.0](http://img.shields.io/SemVer/2.0.0.png)](http://semver.org/spec/v2.0.0.html) 9 | [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) 10 | 11 | ![Toolbox Banner](assets/images/toolbox-banner.png) 12 | 13 | Toolbox is a set of helpers for faster development for [October CMS](https://github.com/octobercms/october). It includes a universal component for rendering pagination navigation controls, a set of tools for caching of objects and lists. Also, it includes a list of most common language strings for using in third-party plugins: name, title, description etc. 14 | 15 | ## Features 16 | 17 | * Components 18 | * Pagination is used to get a list of pagination buttons and provides flexible settings. 19 | * Classes 20 | * `ElementCollection` provides a flexible tool for working with cached lists of model elements. 21 | * `ElementData` is an abstract class for components that returns object of `ElementItem` class for model. 22 | * `ElementItem` provides a flexible tool for single element data caching. 23 | * etc. 24 | 25 | [Read more…](https://github.com/lovata/oc-toolbox-plugin/wiki) 26 | 27 | ## Get involved 28 | 29 | If you're interested in the improvement of this project you can help in the following ways: 30 | * bug reporting and new feature requesting by creating issues on plugin [GitHub page](https://github.com/lovata/oc-toolbox-plugin/issues); 31 | * contribution to a project following these [instructions](https://github.com/lovata/oc-toolbox-plugin/blob/master/CONTRIBUTING.md); 32 | * localization to your language using [Crowdin](https://crowdin.com/project/toolbox-plugin-for-october-cms) service. 33 | 34 | ## License 35 | 36 | © 2017, [LOVATA Group, LLC](https://github.com/lovata) under [GNU GPL v3](https://opensource.org/licenses/GPL-3.0). 37 | 38 | Developed by [Andrey Kharanenka](https://github.com/kharanenka). 39 | -------------------------------------------------------------------------------- /assets/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | Toolbox 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /assets/images/toolbox-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oc-shopaholic/oc-toolbox-plugin/e365e044d7d43d13ee5ccc71ad431aa6fc3fdf14/assets/images/toolbox-banner.png -------------------------------------------------------------------------------- /classes/collection/CollectionStore.php: -------------------------------------------------------------------------------- 1 | arStore[$sKey] = $obCollection->copy(); 30 | } 31 | 32 | /** 33 | * Get saved element collection 34 | * @see \Lovata\Toolbox\Tests\Unit\CollectionTest::testSaveMethod() 35 | * @param string $sKey 36 | * @return ElementCollection 37 | */ 38 | public function saved($sKey) 39 | { 40 | if (empty($sKey) || empty($this->arStore) || !isset($this->arStore[$sKey])) { 41 | return null; 42 | } 43 | 44 | return $this->arStore[$sKey]->copy(); 45 | } 46 | 47 | /** 48 | * Remove stored collection from store 49 | * @param string $sKey 50 | */ 51 | public function clear($sKey) 52 | { 53 | if (empty($sKey) || empty($this->arStore) || !isset($this->arStore[$sKey])) { 54 | return; 55 | } 56 | 57 | unset($this->arStore[$sKey]); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /classes/collection/TestCollection.php: -------------------------------------------------------------------------------- 1 | makeItem($iElementID); 21 | 22 | return $obElementItem->toArray(); 23 | } 24 | 25 | /** 26 | * Ajax listener 27 | * @return string 28 | */ 29 | public function onGetJSONData() 30 | { 31 | $iElementID = Input::get('element_id'); 32 | $obElementItem = $this->makeItem($iElementID); 33 | 34 | return $obElementItem->toJSON(); 35 | } 36 | 37 | /** 38 | * Ajax listener 39 | * @deprecated 40 | * @return bool 41 | */ 42 | public function onAjaxRequest() 43 | { 44 | return true; 45 | } 46 | 47 | /** 48 | * Get element item 49 | * @param int $iElementID 50 | * @return \Lovata\Toolbox\Classes\Item\ElementItem 51 | */ 52 | public function get($iElementID) 53 | { 54 | $obElementItem = $this->makeItem($iElementID); 55 | 56 | return $obElementItem; 57 | } 58 | 59 | /** 60 | * Male new element item 61 | * @param int $iElementID 62 | * @return \Lovata\Toolbox\Classes\Item\ElementItem 63 | */ 64 | abstract protected function makeItem($iElementID); 65 | } 66 | -------------------------------------------------------------------------------- /classes/component/SortingElementList.php: -------------------------------------------------------------------------------- 1 | setActiveSorting(); 22 | parent::init(); 23 | } 24 | 25 | /** 26 | * Get active sorting 27 | * @return string 28 | */ 29 | public function getSorting() 30 | { 31 | return $this->sSorting; 32 | } 33 | 34 | /** 35 | * Set active sorting 36 | */ 37 | protected function setActiveSorting() 38 | { 39 | $this->sSorting = Input::get('sort'); 40 | if (empty($this->sSorting)) { 41 | $this->sSorting = $this->property('sorting'); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /classes/console/CreateAll.php: -------------------------------------------------------------------------------- 1 | setModel(); 25 | $this->setController(); 26 | $this->setFieldList(); 27 | $this->setSorting(); 28 | $this->setImportExportCSV(); 29 | $this->setAdditionList(self::CODE_COMMAND_PARENT); 30 | $this->callCommandList(); 31 | } 32 | 33 | /** 34 | * Call command list 35 | */ 36 | protected function callCommandList() 37 | { 38 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_MODEL]); 39 | 40 | if ($this->confirm($sMessage, true)) { 41 | $this->call('toolbox:create.model', ['data' => $this->arData]); 42 | } 43 | 44 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_CONTROLLER]); 45 | 46 | if ($this->confirm($sMessage, true)) { 47 | $this->call('toolbox:create.controller', ['data' => $this->arData]); 48 | } 49 | 50 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_ITEM]); 51 | 52 | if ($this->confirm($sMessage, true)) { 53 | $this->call('toolbox:create.item', ['data' => $this->arData]); 54 | } 55 | 56 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_STORE]); 57 | 58 | if ($this->confirm($sMessage, true)) { 59 | $this->call('toolbox:create.store', ['data' => $this->arData]); 60 | } 61 | 62 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_COLLECTION]); 63 | 64 | if ($this->confirm($sMessage, true)) { 65 | $this->call('toolbox:create.collection', ['data' => $this->arData]); 66 | } 67 | 68 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_COMPONENT_PAGE]); 69 | 70 | if ($this->confirm($sMessage, true)) { 71 | $this->call('toolbox:create.component.page', ['data' => $this->arData]); 72 | } 73 | 74 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_COMPONENT_DATA]); 75 | 76 | if ($this->confirm($sMessage, true)) { 77 | $this->call('toolbox:create.component.data', ['data' => $this->arData]); 78 | } 79 | 80 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_COMPONENT_LIST]); 81 | 82 | if ($this->confirm($sMessage, true)) { 83 | $this->call('toolbox:create.component.list', ['data' => $this->arData]); 84 | } 85 | 86 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_EVENT]); 87 | 88 | if ($this->confirm($sMessage, true)) { 89 | $this->call('toolbox:create.event.model', ['data' => $this->arData]); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /classes/console/CreateCollection.php: -------------------------------------------------------------------------------- 1 | setModel(); 25 | $this->setFieldList(null, [self::CODE_ACTIVE, self::CODE_DEFAULT]); 26 | $this->setSorting(); 27 | $this->createFile(CollectionCreateFile::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /classes/console/CreateComponentData.php: -------------------------------------------------------------------------------- 1 | [ 22 | '{{lower_model}}_data_name' => '{{studly_model}} Data', 23 | '{{lower_model}}_data_description' => 'Get {{lower_model}} by ID', 24 | ], 25 | ]; 26 | 27 | /** 28 | * Execute the console command. 29 | */ 30 | public function handle() 31 | { 32 | parent::handle(); 33 | 34 | $this->setModel(); 35 | $this->createFile(ComponentDataCreateFile::class); 36 | $this->updatePluginLang($this->arLangData); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /classes/console/CreateComponentList.php: -------------------------------------------------------------------------------- 1 | [ 22 | '{{lower_model}}_list_name' => '{{studly_model}} List', 23 | '{{lower_model}}_list_description' => 'Get {{lower_model}} list', 24 | ], 25 | ]; 26 | 27 | /** 28 | * Execute the console command. 29 | */ 30 | public function handle() 31 | { 32 | parent::handle(); 33 | 34 | $this->setModel(); 35 | $this->setSorting([self::CODE_NESTED_TREE, self::CODE_SORTABLE]); 36 | $this->createFile(ComponentListCreateFile::class); 37 | $this->updatePluginLang($this->arLangData); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /classes/console/CreateComponentPage.php: -------------------------------------------------------------------------------- 1 | [ 22 | '{{lower_model}}_page_name' => '{{studly_model}} Page', 23 | '{{lower_model}}_page_description' => 'Get {{lower_model}} page data', 24 | ], 25 | ]; 26 | 27 | /** 28 | * Execute the console command. 29 | */ 30 | public function handle() 31 | { 32 | parent::handle(); 33 | 34 | $this->setModel(); 35 | $this->setFieldList(null, [self::CODE_ACTIVE, self::CODE_VIEW_COUNT, self::CODE_DEFAULT]); 36 | $this->createFile(ComponentPageCreateFile::class); 37 | $this->updatePluginLang($this->arLangData); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /classes/console/CreateController.php: -------------------------------------------------------------------------------- 1 | [ 37 | '{{lower_controller}}' => '{{studly_model}} list', 38 | ], 39 | 'permission' => [ 40 | '{{lower_model}}' => 'Manage {{lower_model}}', 41 | ], 42 | '{{lower_model}}' => [ 43 | 'name' => '{{lower_model}}', 44 | 'list_title' => '{{studly_model}} list', 45 | ], 46 | ]; 47 | 48 | /** 49 | * Execute the console command. 50 | */ 51 | public function handle() 52 | { 53 | parent::handle(); 54 | 55 | $this->setModel(); 56 | $this->setController(); 57 | $this->setFieldList(null, [self::CODE_ACTIVE, self::CODE_DEFAULT]); 58 | $this->setImportExportCSV(); 59 | $this->setSorting([self::CODE_DEFAULT_SORTING]); 60 | $this->createAdditionalFile(); 61 | } 62 | 63 | /** 64 | * Create file list 65 | */ 66 | protected function createAdditionalFile() 67 | { 68 | $this->createFile(ControllerCreateFile::class); 69 | $this->createFile(ControllerListToolbarCreateFile::class); 70 | $this->createFile(ControllerConfirmFormCreateFile::class); 71 | $this->createFile(ControllerConfirmListCreateFile::class); 72 | $this->createFile(ControllerCreateCreateFile::class); 73 | $this->createFile(ControllerIndexCreateFile::class); 74 | $this->createFile(ControllerPreviewCreateFile::class); 75 | $this->createFile(ControllerUpdateCreateFile::class); 76 | $this->createFile(ControllerConfirmFilterCreateFile::class); 77 | 78 | if ($this->checkEnableList(self::CODE_IMPORT_SVG)) { 79 | $this->createFile(ControllerImportCreateFile::class); 80 | } 81 | 82 | if ($this->checkEnableList(self::CODE_EXPORT_SVG)) { 83 | $this->createFile(ControllerExportCreateFile::class); 84 | } 85 | 86 | if ($this->checkEnableList(self::CODE_EMPTY_IMPORT_EXPORT_SVG)) { 87 | $this->createFile(ControllerConfigImportExportCreateFile::class); 88 | } 89 | 90 | if ($this->checkEnableList(self::CODE_EMPTY_SORTABLE_NESTED_TREE)) { 91 | $this->createFile(ControllerReorderCreateFile::class); 92 | $this->createFile(ControllerConfigReorderCreateFile::class); 93 | } 94 | 95 | $this->updatePluginYAML(); 96 | $this->updatePluginLang($this->arLangData); 97 | } 98 | 99 | /** 100 | * Update plugin.yaml 101 | */ 102 | protected function updatePluginYAML() 103 | { 104 | $sMessage = Lang::get('lovata.toolbox::lang.message.add_side_menu'); 105 | if ($this->confirm($sMessage, true)) { 106 | $obUpdate = new PluginYAMLUpdateFile($this->arData); 107 | $obUpdate->update(); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /classes/console/CreateEventModel.php: -------------------------------------------------------------------------------- 1 | setAuthor(true); 25 | $this->setPlugin(true); 26 | $this->setModel(); 27 | $this->setFieldList(null, [self::CODE_ACTIVE, self::CODE_VIEW_COUNT, self::CODE_DEFAULT]); 28 | $this->setSorting(); 29 | $this->createFile(EventModelCreateFile::class); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /classes/console/CreateExtendBackendMenuHandler.php: -------------------------------------------------------------------------------- 1 | createFile(ExtendBackendMenuHandlerCreateFile::class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /classes/console/CreateExtendModelColumnsHandler.php: -------------------------------------------------------------------------------- 1 | setAuthor(true); 25 | $this->setPlugin(true); 26 | $this->setModel(); 27 | $this->setController(); 28 | $this->createFile(ExtendModelColumnsHandlerCreateFile::class); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /classes/console/CreateExtendModelFieldsHandler.php: -------------------------------------------------------------------------------- 1 | setAuthor(true); 25 | $this->setPlugin(true); 26 | $this->setModel(); 27 | $this->setController(); 28 | $this->createFile(ExtendModelFieldsHandlerCreateFile::class); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /classes/console/CreateItem.php: -------------------------------------------------------------------------------- 1 | setModel(); 25 | $this->setFieldList(); 26 | $this->setSorting([self::CODE_DEFAULT_SORTING]); 27 | $this->createFile(ItemCreateFile::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /classes/console/CreateMigration.php: -------------------------------------------------------------------------------- 1 | setController(); 27 | $this->setFieldList([self::CODE_PREVIEW_IMAGE, self::CODE_IMAGES, self::CODE_FILE]); 28 | $this->setSorting([self::CODE_DEFAULT_SORTING]); 29 | $this->createFile(MigrationCreateFile::class); 30 | $this->updatePluginVersionYAML(); 31 | } 32 | 33 | /** 34 | * Update version.yaml 35 | */ 36 | protected function updatePluginVersionYAML() 37 | { 38 | $sMessage = Lang::get('lovata.toolbox::lang.message.version_up'); 39 | $bConfirm = $this->confirm($sMessage, false); 40 | array_set($this->arData, 'addition.version_up', $bConfirm); 41 | $obUpdate = new PluginVersionYAMLUpdateFile($this->arData); 42 | $obUpdate->update(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /classes/console/CreateModel.php: -------------------------------------------------------------------------------- 1 | setModel(); 26 | $this->setController(); 27 | $this->setFieldList(); 28 | $this->setImportExportCSV(); 29 | $this->setSorting([self::CODE_DEFAULT_SORTING]); 30 | $this->setAdditionList(self::CODE_COMMAND_PARENT); 31 | $this->createFile(ModelCreateFile::class); 32 | $this->callCommandList(); 33 | } 34 | 35 | /** 36 | * Call command list 37 | */ 38 | protected function callCommandList() 39 | { 40 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_CREATION_MIGRATION]); 41 | 42 | if ($this->confirm($sMessage, true)) { 43 | $this->call('toolbox:create.migration.create', ['data' => $this->arData]); 44 | } 45 | 46 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_CREATION_MODEL_COLUMNS]); 47 | 48 | if ($this->confirm($sMessage, true)) { 49 | $this->call('toolbox:create.model.columns', ['data' => $this->arData]); 50 | } 51 | 52 | $sMessage = Lang::get('lovata.toolbox::lang.message.create', ['name' => self::CODE_CREATION_MODEL_FIELDS]); 53 | 54 | if ($this->confirm($sMessage, true)) { 55 | $this->call('toolbox:create.model.fields', ['data' => $this->arData]); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /classes/console/CreateModelColumn.php: -------------------------------------------------------------------------------- 1 | setModel(); 25 | $this->setFieldList([self::CODE_PREVIEW_IMAGE, self::CODE_IMAGES, self::CODE_FILE]); 26 | $this->setSorting([self::CODE_DEFAULT_SORTING, self::CODE_NESTED_TREE]); 27 | $this->createFile(ModelColumnCreateFile::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /classes/console/CreateModelField.php: -------------------------------------------------------------------------------- 1 | setModel(); 25 | $this->setFieldList(); 26 | $this->createFile(ModelFieldCreateFile::class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /classes/console/CreatePlugin.php: -------------------------------------------------------------------------------- 1 | initData(); 35 | $this->setLogo(); 36 | $this->setDeveloper(); 37 | 38 | if (!$this->checkAdditionList(self::CODE_AUTHOR) || !$this->checkAdditionList(self::CODE_PLUGIN)) { 39 | $this->setAuthor(); 40 | $this->setPlugin(); 41 | } 42 | 43 | if ($this->checkPluginExist()) { 44 | return; 45 | } 46 | 47 | $this->setLangList(); 48 | $this->createFile(PluginPHPCreateFile::class); 49 | $this->createFile(PluginYAMLCreateFile::class); 50 | $this->createFile(PluginVersionCreateFile::class); 51 | $this->createLangFile(); 52 | } 53 | 54 | /** 55 | * Check plugin exist 56 | * @return bool 57 | */ 58 | protected function checkPluginExist() 59 | { 60 | $bResult = true; 61 | $sAuthor = array_get($this->arData, 'replace.lower_author'); 62 | $sPlugin = array_get($this->arData, 'replace.lower_plugin'); 63 | 64 | if (empty($sAuthor) || empty($sPlugin)) { 65 | return $bResult; 66 | } 67 | 68 | $sPluginPHPPath = plugins_path($sAuthor.'/'.$sPlugin.'/Plugin.php'); 69 | $sPluginYAMLPath = plugins_path($sAuthor.'/'.$sPlugin.'/plugin.yaml'); 70 | 71 | if (!file_exists($sPluginPHPPath) && !file_exists($sPluginYAMLPath)) { 72 | $bResult = false; 73 | } 74 | 75 | return $bResult; 76 | } 77 | 78 | /** 79 | * Set lang list 80 | */ 81 | protected function setLangList() 82 | { 83 | if (empty($this->arLangList)) { 84 | return; 85 | } 86 | 87 | $sMessage = Lang::get('lovata.toolbox::lang.message.choice_lang_list'); 88 | 89 | $this->arLangList = $this->choice($sMessage, $this->arLangList, null, null, true); 90 | } 91 | 92 | /** 93 | * Create lang file 94 | */ 95 | protected function createLangFile() 96 | { 97 | if (empty($this->arLangList)) { 98 | return; 99 | } 100 | 101 | foreach ($this->arLangList as $sLang) { 102 | array_set($this->arData, 'replace.lang', $sLang); 103 | $this->createFile(PluginLangCreateFile::class); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /classes/console/CreateStore.php: -------------------------------------------------------------------------------- 1 | setAuthor(true); 28 | $this->setPlugin(true); 29 | $this->setModel(); 30 | $this->setFieldList(null, [self::CODE_ACTIVE, self::CODE_VIEW_COUNT, self::CODE_DEFAULT]); 31 | $this->setSorting(); 32 | $this->createFile(ListStoreCreateFile::class); 33 | 34 | if ($this->checkEnableList(self::CODE_ACTIVE)) { 35 | $this->createFile(ActiveListStoreCreateFile::class); 36 | } 37 | 38 | if ($this->checkEnableList(self::CODE_SORTABLE) || $this->checkEnableList(self::CODE_DEFAULT_SORTING)) { 39 | $this->createFile(SortingListStoreCreateFile::class); 40 | } 41 | 42 | if ($this->checkEnableList(self::CODE_NESTED_TREE)) { 43 | $this->createFile(TopLevelListStoreCreateFile::class); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /classes/event/AbstractBackendColumnHandler.php: -------------------------------------------------------------------------------- 1 | listen('backend.list.extendColumns', function ($obWidget) { 19 | 20 | $sControllerClass = $this->getControllerClass(); 21 | $sModelName = $this->getModelClass(); 22 | 23 | /** @var \Backend\Widgets\Lists $obWidget */ 24 | if (!$obWidget->getController() instanceof $sControllerClass) { 25 | return; 26 | } 27 | 28 | if (!$obWidget->model instanceof $sModelName) { 29 | return; 30 | } 31 | 32 | $this->extendColumns($obWidget); 33 | }, $this->iPriority); 34 | } 35 | 36 | /** 37 | * Extend backend columns 38 | * @param \Backend\Widgets\Lists $obWidget 39 | */ 40 | abstract protected function extendColumns($obWidget); 41 | 42 | /** 43 | * Get model class name 44 | * @return string 45 | */ 46 | abstract protected function getModelClass() : string; 47 | 48 | /** 49 | * Get controller class name 50 | * @return string 51 | */ 52 | abstract protected function getControllerClass() : string; 53 | } 54 | -------------------------------------------------------------------------------- /classes/event/AbstractBackendFieldHandler.php: -------------------------------------------------------------------------------- 1 | listen('backend.form.extendFields', function ($obWidget) { 19 | 20 | $sControllerClass = $this->getControllerClass(); 21 | $sModelName = $this->getModelClass(); 22 | 23 | /** @var \Backend\Widgets\Form $obWidget */ 24 | if (!$obWidget->getController() instanceof $sControllerClass || $obWidget->isNested || empty($obWidget->context)) { 25 | return; 26 | } 27 | 28 | if (!$obWidget->model instanceof $sModelName) { 29 | return; 30 | } 31 | 32 | $this->extendFields($obWidget); 33 | }, $this->iPriority); 34 | } 35 | 36 | /** 37 | * Extend backend fields 38 | * @param \Backend\Widgets\Form $obWidget 39 | */ 40 | abstract protected function extendFields($obWidget); 41 | 42 | /** 43 | * Get model class name 44 | * @return string 45 | */ 46 | abstract protected function getModelClass() : string; 47 | 48 | /** 49 | * Get controller class name 50 | * @return string 51 | */ 52 | abstract protected function getControllerClass() : string; 53 | } 54 | -------------------------------------------------------------------------------- /classes/event/AbstractBackendMenuHandler.php: -------------------------------------------------------------------------------- 1 | listen('backend.menu.extendItems', function ($obManager) { 19 | $this->addMenuItems($obManager); 20 | }, $this->iPriority); 21 | } 22 | 23 | /** 24 | * Add menu items 25 | * @param \Backend\Classes\NavigationManager $obManager 26 | */ 27 | abstract protected function addMenuItems($obManager); 28 | } 29 | -------------------------------------------------------------------------------- /classes/event/AbstractExtendRelationConfigHandler.php: -------------------------------------------------------------------------------- 1 | getControllerClass(); 16 | $sControllerClass::extend(function ($obController) { 17 | /** @var \Backend\Classes\Controller $obController */ 18 | $this->extendConfig($obController); 19 | }); 20 | } 21 | 22 | /** 23 | * Extend controller 24 | * @param \Backend\Classes\Controller $obController 25 | */ 26 | protected function extendConfig($obController) 27 | { 28 | if (empty($obController->implement)) { 29 | $obController->implement = []; 30 | } 31 | 32 | //Extend controller 33 | if (!in_array('Backend.Behaviors.RelationController', $obController->implement) && !in_array('Backend\Behaviors\RelationController', $obController->implement)) { 34 | $obController->implement[] = 'Backend.Behaviors.RelationController'; 35 | } 36 | 37 | if (!isset($obController->relationConfig)) { 38 | $obController->addDynamicProperty('relationConfig'); 39 | } 40 | 41 | $obController->relationConfig = $obController->mergeConfig( 42 | $obController->relationConfig, 43 | $this->getConfigPath() 44 | ); 45 | } 46 | 47 | /** 48 | * Get controller class name 49 | * @return string 50 | */ 51 | abstract protected function getControllerClass() : string; 52 | 53 | /** 54 | * Get path to config file 55 | * @return string 56 | */ 57 | abstract protected function getConfigPath() : string; 58 | } 59 | -------------------------------------------------------------------------------- /classes/event/AbstractModelRelationHandler.php: -------------------------------------------------------------------------------- 1 | getModelClass(); 21 | 22 | $sModelClass::extend(function ($obModel) { 23 | if (class_exists('System')) { 24 | $sAfterAttach = 'model.relation.attach'; 25 | $sAfterDetach = 'model.relation.detach'; 26 | }else { 27 | $sAfterAttach = 'model.relation.afterAttach'; 28 | $sAfterDetach = 'model.relation.afterDetach'; 29 | } 30 | 31 | /** @var \Model $obModel */ 32 | $obModel->bindEvent($sAfterAttach, function ($sRelationName, $arAttachedIDList, $arInsertData) use ($obModel, $sAfterAttach) { 33 | if (!$this->checkRelationName($sRelationName)) { 34 | return; 35 | } 36 | 37 | $this->sRelationName = $sRelationName; 38 | $this->afterAttach($obModel, $arAttachedIDList, $arInsertData); 39 | }, $this->iPriority); 40 | 41 | $obModel->bindEvent($sAfterDetach, function ($sRelationName, $arAttachedIDList) use ($obModel, $sAfterDetach) { 42 | if (!$this->checkRelationName($sRelationName)) { 43 | return; 44 | } 45 | if (is_null($arAttachedIDList)) { 46 | $arAttachedIDList = $obModel->$sRelationName()->newPivotQuery()->lists($obModel->$sRelationName()->getRelatedPivotKeyName()); 47 | } 48 | 49 | $this->sRelationName = $sRelationName; 50 | $this->afterDetach($obModel, $arAttachedIDList); 51 | }, $this->iPriority); 52 | }); 53 | } 54 | 55 | /** 56 | * After attach event handler 57 | * @param \Model $obModel 58 | * @param array $arAttachedIDList 59 | * @param array $arInsertData 60 | */ 61 | protected function afterAttach($obModel, $arAttachedIDList, $arInsertData) 62 | { 63 | } 64 | 65 | /** 66 | * After detach event handler 67 | * @param \Model $obModel 68 | * @param array $arAttachedIDList 69 | */ 70 | protected function afterDetach($obModel, $arAttachedIDList) 71 | { 72 | } 73 | 74 | /** 75 | * Check relation name 76 | * @param string $sRelationName 77 | * @return bool 78 | */ 79 | protected function checkRelationName($sRelationName) : bool 80 | { 81 | $sCheckedRelationName = $this->getRelationName(); 82 | if (empty($sCheckedRelationName)) { 83 | return true; 84 | } 85 | 86 | if (is_array($sCheckedRelationName) && in_array($sRelationName, $sCheckedRelationName)) { 87 | return true; 88 | } 89 | 90 | $bResult = $sRelationName == $sCheckedRelationName; 91 | 92 | return $bResult; 93 | } 94 | 95 | /** 96 | * Get model class name 97 | * @return string 98 | */ 99 | abstract protected function getModelClass() : string; 100 | 101 | /** 102 | * Get relation name 103 | * @return string|array 104 | */ 105 | abstract protected function getRelationName(); 106 | } 107 | -------------------------------------------------------------------------------- /classes/helper/ImportXMLNode.php: -------------------------------------------------------------------------------- 1 | registerXPathNamespace($sPrefix, $sNamespace); 28 | 29 | // Split string to array to add prefix. If there is no separator, array_walk will work anyway. 30 | $arPaths = explode('/', $sPath); 31 | array_walk($arPaths, function (&$sSection) use ($sPrefix) { 32 | $sSection = sprintf("%s:%s", $sPrefix, $sSection); 33 | }); 34 | 35 | $sPath = implode('/', $arPaths); 36 | } 37 | 38 | $arResult = $this->xpath($sPath); 39 | 40 | return $arResult; 41 | } 42 | 43 | /** 44 | * @param \SimpleXMLElement $obNode 45 | * @param string $sFieldPath 46 | * @param string|null $sPrefix 47 | * @param string|null $sNamespace 48 | * @return string|null|array 49 | */ 50 | public function getValueByPath($sFieldPath, $sPrefix = null, $sNamespace = null) 51 | { 52 | if (empty($sFieldPath)) { 53 | return null; 54 | } 55 | 56 | $arValueNodeList = $this->findListByPath($sFieldPath, $sPrefix, $sNamespace); 57 | if (empty($arValueNodeList)) { 58 | return null; 59 | } 60 | 61 | $arResult = []; 62 | foreach ($arValueNodeList as $obValueNode) { 63 | $arResult[] = (string) $obValueNode; 64 | } 65 | 66 | if (count($arResult) == 1) { 67 | return array_shift($arResult); 68 | } elseif (empty($arResult)) { 69 | return null; 70 | } 71 | 72 | return $arResult; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /classes/helper/ParseXMLNode.php: -------------------------------------------------------------------------------- 1 | obElementNode = $obNode; 29 | $this->arImportSettings = $arSettings; 30 | $this->sPrefix = $sPrefix; 31 | $this->sNamespace = $sNamespace; 32 | 33 | $this->parse(); 34 | } 35 | 36 | /** 37 | * @return ImportXMLNode 38 | */ 39 | public function getNode() 40 | { 41 | return $this->obElementNode; 42 | } 43 | 44 | /** 45 | * Get node data 46 | * @return array 47 | */ 48 | public function get() 49 | { 50 | return $this->arImportData; 51 | } 52 | 53 | protected function parse() 54 | { 55 | if (empty($this->arImportSettings)) { 56 | return; 57 | } 58 | 59 | foreach ($this->arImportSettings as $arFieldData) { 60 | $sFieldName = array_get($arFieldData, 'field'); 61 | $sFieldPath = array_get($arFieldData, 'path_to_field'); 62 | if (empty($sFieldName) || empty($sFieldPath)) { 63 | continue; 64 | } 65 | 66 | $sMethodName = 'parse'.studly_case($sFieldName).'Attribute'; 67 | if (method_exists(static::class, $sMethodName)) { 68 | $sValue = $this->$sMethodName($sFieldPath, $this->sPrefix, $this->sNamespace); 69 | } else { 70 | $sValue = $this->obElementNode->getValueByPath($sFieldPath, $this->sPrefix, $this->sNamespace); 71 | } 72 | 73 | if ($sValue === null) { 74 | continue; 75 | } 76 | 77 | $sCurrentValue = array_get($this->arImportData, $sFieldName); 78 | if (!empty($sCurrentValue) && !is_array($sCurrentValue)) { 79 | $sCurrentValue = [$sCurrentValue]; 80 | } 81 | 82 | if (is_array($sCurrentValue) && is_array($sValue)) { 83 | $sCurrentValue = array_merge($sCurrentValue, $sValue); 84 | $sCurrentValue = array_filter($sCurrentValue); 85 | $sCurrentValue = array_unique($sCurrentValue); 86 | } elseif (is_array($sCurrentValue) && !is_array($sValue)) { 87 | $sCurrentValue[] = $sValue; 88 | $sCurrentValue = array_filter($sCurrentValue); 89 | $sCurrentValue = array_unique($sCurrentValue); 90 | } else { 91 | $sCurrentValue = $sValue; 92 | } 93 | 94 | array_set($this->arImportData, $sFieldName, $sCurrentValue); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /classes/helper/PriceHelper.php: -------------------------------------------------------------------------------- 1 | iDecimal, $obThis->sDecPoint, $obThis->sThousandsSep); 36 | } 37 | 38 | /** 39 | * Convert price string to float value 40 | * @param string $sValue 41 | * @return float 42 | */ 43 | public static function toFloat($sValue) 44 | { 45 | $sValue = str_replace(',', '.', $sValue); 46 | $fPrice = (float) preg_replace("/[^0-9\.]/", "", $sValue); 47 | 48 | return $fPrice; 49 | } 50 | 51 | /** 52 | * Round float price value 53 | * @param float $fPrice 54 | * 55 | * @return float 56 | */ 57 | public static function round($fPrice) 58 | { 59 | return round($fPrice, 2); 60 | } 61 | 62 | /** 63 | * PriceHelper constructor. 64 | */ 65 | protected function init() 66 | { 67 | //Get options from settings 68 | $iDecimalValue = (int) Settings::getValue('decimals'); 69 | if ($iDecimalValue >= 0) { 70 | $this->iDecimal = $iDecimalValue; 71 | } 72 | 73 | $sDecPointValue = Settings::getValue('dec_point'); 74 | switch ($sDecPointValue) { 75 | case 'comma': 76 | $this->sDecPoint = ','; 77 | break; 78 | default: 79 | $this->sDecPoint = '.'; 80 | } 81 | 82 | $sThousandsSepValue = Settings::getValue('thousands_sep'); 83 | switch ($sThousandsSepValue) { 84 | case 'space': 85 | $this->sThousandsSep = ' '; 86 | break; 87 | default: 88 | $this->sThousandsSep = ''; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /classes/helper/UserHelper.php: -------------------------------------------------------------------------------- 1 | obHelper)) { 31 | return null; 32 | } 33 | 34 | $sAuthFacadeClass = $this->obHelper->getAuthFacade(); 35 | 36 | return $sAuthFacadeClass::getUser(); 37 | } 38 | 39 | /** 40 | * Get user ID 41 | * @return int|null 42 | */ 43 | public function getUserID() 44 | { 45 | $obUser = $this->getUser(); 46 | if (empty($obUser)) { 47 | return null; 48 | } 49 | 50 | return $obUser->id; 51 | } 52 | 53 | /** 54 | * Create new user 55 | * @param array $arUserData 56 | * @param bool $bActivate 57 | * @return \Lovata\Buddies\Models\User|\RainLab\User\Models\User|null 58 | */ 59 | public function register($arUserData, $bActivate = false) 60 | { 61 | if (empty($this->obHelper)) { 62 | return null; 63 | } 64 | 65 | $sAuthFacadeClass = $this->obHelper->getAuthFacade(); 66 | 67 | return $sAuthFacadeClass::register($arUserData, $bActivate); 68 | } 69 | 70 | /** 71 | * Find user by email 72 | * @param string $sEmail 73 | * 74 | * @return \Lovata\Buddies\Models\User|\RainLab\User\Models\User|null 75 | */ 76 | public function findUserByEmail($sEmail) 77 | { 78 | if (empty($sEmail) || empty($this->obHelper)) { 79 | return null; 80 | } 81 | 82 | return $this->obHelper->findUserByEmail($sEmail); 83 | } 84 | 85 | /** 86 | * Get user model class name 87 | * @return string 88 | */ 89 | public function getUserModel() 90 | { 91 | if (empty($this->obHelper)) { 92 | return null; 93 | } 94 | 95 | return $this->obHelper->getUserModel(); 96 | } 97 | 98 | /** 99 | * Get user controller class name 100 | * @return string 101 | */ 102 | public function getUserController() 103 | { 104 | if (empty($this->obHelper)) { 105 | return null; 106 | } 107 | 108 | return $this->obHelper->getUserController(); 109 | } 110 | 111 | /** 112 | * Get auth facade class name 113 | * @return string 114 | */ 115 | public function getAuthFacade() 116 | { 117 | if (empty($this->obHelper)) { 118 | return null; 119 | } 120 | 121 | return $this->obHelper->getAuthFacade(); 122 | } 123 | 124 | /** 125 | * Get active plugin name 126 | * @return string 127 | */ 128 | public function getPluginName() 129 | { 130 | return $this->sPluginName; 131 | } 132 | 133 | /** 134 | * Init data 135 | */ 136 | protected function init() 137 | { 138 | $obPluginManager = PluginManager::instance(); 139 | if ($obPluginManager->exists('Lovata.Buddies')) { 140 | $this->obHelper = app(BuddiesUserHelper::class); 141 | $this->sPluginName = 'Lovata.Buddies'; 142 | } elseif ($obPluginManager->exists('RainLab.User')) { 143 | $this->obHelper = app(RainLabUserHelper::class); 144 | $this->sPluginName = 'RainLab.User'; 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /classes/helper/users/AbstractUserHelper.php: -------------------------------------------------------------------------------- 1 | first(); 23 | } 24 | 25 | /** 26 | * Get user model class name 27 | * @return string 28 | */ 29 | public function getUserModel() 30 | { 31 | return \Lovata\Buddies\Models\User::class; 32 | } 33 | 34 | /** 35 | * Get user controller class name 36 | * @return string 37 | */ 38 | public function getUserController() 39 | { 40 | return \Lovata\Buddies\Controllers\Users::class; 41 | } 42 | 43 | /** 44 | * Get auth facade class name 45 | * @return string 46 | */ 47 | public function getAuthFacade() 48 | { 49 | return \Lovata\Buddies\Facades\AuthHelper::class; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /classes/helper/users/RainLabUserHelper.php: -------------------------------------------------------------------------------- 1 | isEmpty()) { 38 | return; 39 | } 40 | 41 | $sKey = self::getKey($sClassName, $iElementID); 42 | self::$arItemStore[$sKey] = clone $obItem; 43 | } 44 | 45 | /** 46 | * Clear item object in storage 47 | * @param string $sClassName 48 | * @param int $iElementID 49 | */ 50 | public static function clear($sClassName, $iElementID) 51 | { 52 | $sKey = self::getKey($sClassName, $iElementID); 53 | if (!isset(self::$arItemStore[$sKey])) { 54 | return; 55 | } 56 | 57 | unset(self::$arItemStore[$sKey]); 58 | } 59 | 60 | /** 61 | * Get store key for item object 62 | * @param string $sClassName 63 | * @param int $iElementID 64 | * @return string 65 | */ 66 | protected static function getKey($sClassName, $iElementID) 67 | { 68 | return $sClassName.'|'.$iElementID; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /classes/item/TestItem.php: -------------------------------------------------------------------------------- 1 | [ 27 | 'class' => self::class, 28 | 'field' => 'test_id', 29 | ], 30 | 'test_null' => null, 31 | 'test_class' => [ 32 | 'class_fail' => self::class, 33 | 'field' => 'test_id', 34 | ], 35 | 'test_field' => [ 36 | 'class' => self::class, 37 | 'field_fail' => 'test_id', 38 | ], 39 | 'test_exist' => [ 40 | 'class' => self::class.'Test', 41 | 'field' => 'test_id', 42 | ], 43 | 'test_list' => [ 44 | 'class' => TestCollection::class, 45 | 'field' => 'test_list_id', 46 | ], 47 | 'test_empty_list' => [ 48 | 'class' => TestCollection::class, 49 | 'field' => 'test_empty_list_id', 50 | ], 51 | ]; 52 | 53 | /** 54 | * Set element object 55 | */ 56 | protected function setElementObject() 57 | { 58 | $obElement = new Model(); 59 | $obElement->id = $this->iElementID; 60 | 61 | $this->obElement = $obElement; 62 | } 63 | 64 | /** 65 | * Set brand data from model object 66 | * 67 | * @return array 68 | */ 69 | protected function getElementData() 70 | { 71 | $arResult = [ 72 | 'id' => $this->obElement->id, 73 | 'test_id' => $this->obElement->id + 1, 74 | 'test_list_id' => [$this->obElement->id, $this->obElement->id + 1], 75 | ]; 76 | 77 | return $arResult; 78 | } 79 | 80 | /** 81 | * Add title 82 | */ 83 | protected function addTitle() 84 | { 85 | $this->setAttribute('title', 'title'.$this->obElement->id); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /classes/parser/create/ActiveListStoreCreateFile.php: -------------------------------------------------------------------------------- 1 | arReplaceList = array_get($arData, 'replace'); 46 | $this->arEnableList = array_get($arData, 'enable'); 47 | $this->arDisableList = array_get($arData, 'disable'); 48 | 49 | if (empty($this->arReplaceList) || empty($this->sFolderPath) || empty($this->sFile) || empty($this->sTemplatePath)) { 50 | $this->bCreate = false; 51 | 52 | return; 53 | } 54 | 55 | $this->sFolderPath = plugins_path().$this->parseByName($this->arReplaceList, $this->sFolderPath); 56 | $this->sFile = $this->parseByName($this->arReplaceList, $this->sFile); 57 | $this->sFilePath = $this->sFolderPath.$this->sFile; 58 | $this->obFile = new Filesystem(); 59 | 60 | if (!$this->obFile->exists($this->sFolderPath)) { 61 | $this->obFile->makeDirectory($this->sFolderPath, 0777, true, true); 62 | } 63 | 64 | $this->sContent = $this->obFile->get(plugins_path().$this->sTemplatePath); 65 | 66 | if (!$this->obFile->exists($this->sFilePath)) { 67 | $this->bForce = true; 68 | } 69 | } 70 | 71 | /** 72 | * Create file 73 | * @param bool $bForce 74 | * @return null|string 75 | */ 76 | public function create($bForce = false) 77 | { 78 | if (!$this->bForce && !$bForce || !$this->bCreate) { 79 | return $this->sFilePath; 80 | } 81 | 82 | if (!empty($this->arDisableList)) { 83 | $this->sContent = $this->parseByWrapper($this->arDisableList, $this->sContent); 84 | } 85 | 86 | if (!empty($this->arEnableList)) { 87 | $this->sContent = $this->parseByNameWrapper($this->arEnableList, $this->sContent); 88 | } 89 | 90 | if (!empty($this->arReplaceList)) { 91 | $this->sContent = $this->parseByName($this->arReplaceList, $this->sContent); 92 | } 93 | 94 | if ($bForce || $this->bForce) { 95 | $this->obFile->put($this->sFilePath, $this->sContent); 96 | } 97 | 98 | return null; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /classes/parser/create/ComponentDataCreateFile.php: -------------------------------------------------------------------------------- 1 | pluck('id')->all(); 22 | 23 | return $arElementIDList; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /classes/parser/templates/collection.stub: -------------------------------------------------------------------------------- 1 | active->get(); 23 | 24 | return $this->intersect($arResultIDList); 25 | } 26 | [[active]][[sortable]] 27 | /** 28 | * Sort list 29 | * @return $this 30 | */ 31 | public function sort() 32 | { 33 | $arResultIDList = {{studly_model}}ListStore::instance()->sorting->get(); 34 | 35 | return $this->applySorting($arResultIDList); 36 | } 37 | [[sortable]][[default_sorting]] 38 | /** 39 | * Sort list by 40 | * @param string $sSorting 41 | * @return $this 42 | */ 43 | public function sort($sSorting) 44 | { 45 | $arResultIDList = {{studly_model}}ListStore::instance()->sorting->get($sSorting); 46 | 47 | return $this->applySorting($arResultIDList); 48 | } 49 | [[default_sorting]][[nested_tree]] 50 | /** 51 | * Sort list 52 | * @return $this 53 | */ 54 | public function tree() 55 | { 56 | $arResultIDList = {{studly_model}}ListStore::instance()->top_level->get(); 57 | 58 | return $this->applySorting($arResultIDList); 59 | } 60 | [[nested_tree]][[code]] 61 | /** 62 | * Get item by code 63 | * @param string $sCode 64 | * @return {{studly_model}}Item 65 | */ 66 | public function getByCode($sCode) 67 | { 68 | if ($this->isEmpty() || empty($sCode)) { 69 | return {{studly_model}}Item::make(null); 70 | } 71 | 72 | $ar{{studly_model}}List = $this->all(); 73 | 74 | /** @var {{studly_model}}Item $ob{{studly_model}}Item */ 75 | foreach ($ar{{studly_model}}List as $ob{{studly_model}}Item) { 76 | if ($ob{{studly_model}}Item->code == $sCode) { 77 | return $ob{{studly_model}}Item; 78 | } 79 | } 80 | 81 | return {{studly_model}}Item::make(null); 82 | } 83 | [[code]]} 84 | -------------------------------------------------------------------------------- /classes/parser/templates/columns.stub: -------------------------------------------------------------------------------- 1 | columns: 2 | [[name]] name: 3 | label: 'lovata.toolbox::lang.field.name' 4 | type: text 5 | searchable: true 6 | sortable: true 7 | [[name]][[active]] active: 8 | label: 'lovata.toolbox::lang.field.active' 9 | type: switch 10 | searchable: false 11 | sortable: true 12 | [[active]][[code]] code: 13 | label: 'lovata.toolbox::lang.field.code' 14 | type: text 15 | searchable: true 16 | sortable: true 17 | [[code]][[external_id]] external_id: 18 | label: 'lovata.toolbox::lang.field.external_id' 19 | type: text 20 | searchable: true 21 | sortable: true 22 | [[external_id]][[sortable]] sort_order: 23 | label: 'lovata.toolbox::lang.field.sort_order' 24 | type: text 25 | searchable: false 26 | sortable: true 27 | [[sortable]][[view_count]] view_count: 28 | label: 'lovata.toolbox::lang.field.view_count' 29 | type: number 30 | searchable: false 31 | sortable: true 32 | [[view_count]] id: 33 | label: 'lovata.toolbox::lang.field.id' 34 | type: number 35 | searchable: true 36 | sortable: true 37 | width: 100px 38 | created_at: 39 | label: 'lovata.toolbox::lang.field.created_at' 40 | type: timetense 41 | sortable: true 42 | invisible: true 43 | updated_at: 44 | label: 'lovata.toolbox::lang.field.updated_at' 45 | type: timetense 46 | sortable: true 47 | invisible: true 48 | -------------------------------------------------------------------------------- /classes/parser/templates/component_data.stub: -------------------------------------------------------------------------------- 1 | '{{lower_author}}.{{lower_plugin}}::lang.component.{{lower_model}}_data_name', 21 | 'description' => '{{lower_author}}.{{lower_plugin}}::lang.component.{{lower_model}}_data_description', 22 | ]; 23 | } 24 | 25 | /** 26 | * Make new element item 27 | * @param int $iElementID 28 | * @return {{studly_model}}Item 29 | */ 30 | protected function makeItem($iElementID) 31 | { 32 | return {{studly_model}}Item::make($iElementID); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /classes/parser/templates/component_list.stub: -------------------------------------------------------------------------------- 1 | '{{lower_author}}.{{lower_plugin}}::lang.component.{{lower_model}}_list_name', 21 | 'description' => '{{lower_author}}.{{lower_plugin}}::lang.component.{{lower_model}}_list_description', 22 | ]; 23 | } 24 | 25 | /** 26 | * Make element collection 27 | * @param array $arElementIDList 28 | * @return {{studly_model}}Collection 29 | */ 30 | public function make($arElementIDList = null) 31 | { 32 | return {{studly_model}}Collection::make($arElementIDList); 33 | } 34 | 35 | /** 36 | * Method for ajax request with empty response 37 | * @return bool 38 | */ 39 | public function onAjaxRequest() 40 | { 41 | return true; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /classes/parser/templates/component_page.stub: -------------------------------------------------------------------------------- 1 | '{{lower_author}}.{{lower_plugin}}::lang.component.{{lower_model}}_page_name', 22 | 'description' => '{{lower_author}}.{{lower_plugin}}::lang.component.{{lower_model}}_page_description', 23 | ]; 24 | } 25 | 26 | /** 27 | * Get element object 28 | * @param string $sElementSlug 29 | * @return {{studly_model}} 30 | */ 31 | protected function getElementObject($sElementSlug) 32 | { 33 | if (empty($sElementSlug)) { 34 | return null; 35 | } 36 | 37 | $obElement = {{studly_model}}::[[active]]active()->[[active]]getBySlug($sElementSlug)->first(); 38 | 39 | [[view_count]] if(!empty($obElement)) { 40 | $obElement->view_count++; 41 | $obElement->save(); 42 | } 43 | 44 | [[view_count]] return $obElement; 45 | } 46 | 47 | /** 48 | * Make new element item 49 | * @param int $iElementID 50 | * @param {{studly_model}} $obElement 51 | * @return {{studly_model}}Item 52 | */ 53 | protected function makeItem($iElementID, $obElement) 54 | { 55 | return {{studly_model}}Item::make($iElementID, $obElement); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /classes/parser/templates/controller.stub: -------------------------------------------------------------------------------- 1 | true 7 | - active = true 8 | [[active]] created_at: 9 | label: 'lovata.toolbox::lang.field.created_at' 10 | type: daterange 11 | conditions: created_at >= ':after' AND created_at <= ':before' 12 | updated_at: 13 | label: 'lovata.toolbox::lang.field.updated_at' 14 | type: daterange 15 | conditions: updated_at >= ':after' AND updated_at <= ':before' 16 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_config_form.stub: -------------------------------------------------------------------------------- 1 | # Record name 2 | name: '{{lower_author}}.{{lower_plugin}}::lang.{{lower_model}}.name' 3 | 4 | # Model Form Field configuration 5 | form: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/fields.yaml 6 | 7 | # Model Class name 8 | modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} 9 | 10 | # Default redirect location 11 | defaultRedirect: {{lower_author}}/{{lower_plugin}}/{{lower_controller}} 12 | 13 | # Create page 14 | create: 15 | title: 'backend::lang.form.create_title' 16 | redirect: {{lower_author}}/{{lower_plugin}}/{{lower_controller}}/update/:id 17 | redirectClose: {{lower_author}}/{{lower_plugin}}/{{lower_controller}} 18 | flashSave: 'lovata.toolbox::lang.message.create_success' 19 | 20 | # Update page 21 | update: 22 | title: 'backend::lang.form.update_title' 23 | redirect: {{lower_author}}/{{lower_plugin}}/{{lower_controller}} 24 | redirectClose: {{lower_author}}/{{lower_plugin}}/{{lower_controller}} 25 | flashSave: 'lovata.toolbox::lang.message.update_success' 26 | flashDelete: 'lovata.toolbox::lang.message.delete_success' 27 | [[import_svg]] 28 | # Import page 29 | import: 30 | title: 'backend::lang.form.update_title' 31 | redirect: {{lower_author}}/{{lower_plugin}}/{{lower_controller}}/import 32 | redirectClose: {{lower_author}}/{{lower_plugin}}/emails 33 | [[import_svg]][[export_svg]] 34 | # Export page 35 | export: 36 | title: 'backend::lang.form.update_title' 37 | redirect: {{lower_author}}/{{lower_plugin}}/emails/export 38 | redirectClose: {{lower_author}}/{{lower_plugin}}/{{lower_controller}} 39 | [[export_svg]] 40 | # Preview page 41 | preview: { } 42 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_config_import_export.stub: -------------------------------------------------------------------------------- 1 | [[import_svg]]import: 2 | title: '{{lower_author}}.toolbox::lang.button.import_from_csv' 3 | list: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/columns.yaml 4 | # form: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/fields.yaml 5 | # form: 6 | # fields: 7 | modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} 8 | redirect: {{lower_author}}/{{lower_plugin}}/{{lower_controller}} 9 | [[import_svg]][[export_svg]]export: 10 | title: '{{lower_author}}.toolbox::lang.button.export_in_csv' 11 | list: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/columns.yaml 12 | # form: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/fields.yaml 13 | # form: 14 | # fields: 15 | fileName: export.csv 16 | modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} 17 | redirect: {{lower_author}}/{{lower_plugin}}/{{lower_controller}} 18 | [[export_svg]] -------------------------------------------------------------------------------- /classes/parser/templates/controller_config_list.stub: -------------------------------------------------------------------------------- 1 | # Model List Column configuration 2 | list: $/{{lower_author}}/{{lower_plugin}}/models/{{lower_model}}/columns.yaml 3 | 4 | # Model Class name 5 | modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} 6 | 7 | # List Title 8 | title: '{{lower_author}}.{{lower_plugin}}::lang.{{lower_model}}.list_title' 9 | 10 | # Link URL for each record 11 | recordUrl: {{lower_author}}/{{lower_plugin}}/{{lower_controller}}/update/:id 12 | 13 | # Message to display if the list is empty 14 | noRecordsMessage: backend::lang.list.no_records 15 | 16 | # Records to display per page 17 | recordsPerPage: 20 18 | 19 | # Display page numbers with pagination, disable to improve performance 20 | showPageNumbers: true 21 | 22 | # Displays the list column set up button 23 | showSetup: true 24 | 25 | # Displays the sorting link on each column 26 | showSorting: true 27 | 28 | # Default sorting column 29 | # defaultSort: 30 | # column: created_at 31 | # direction: desc 32 | 33 | # Display checkboxes next to each record 34 | showCheckboxes: true 35 | 36 | # Toolbar widget configuration 37 | toolbar: 38 | # Partial for toolbar buttons 39 | buttons: list_toolbar 40 | 41 | # Search widget configuration 42 | search: 43 | prompt: backend::lang.list.search_prompt 44 | 45 | # Display filter list 46 | filter: _config_filter.yaml 47 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_config_reorder.stub: -------------------------------------------------------------------------------- 1 | title: 'backend::lang.reorder.default_title' 2 | modelClass: {{studly_author}}\{{studly_plugin}}\Models\{{studly_model}} 3 | nameFrom: name 4 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_create.stub: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | fatalError): ?> 12 | 'layout']) ?> 13 |
14 | formRender() ?> 15 |
16 |
17 |
18 | 26 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 | 44 | 45 |

fatalError) ?>

46 |

47 | 48 | 49 | 50 |

51 | 52 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_export.stub: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 'layout']) ?> 12 |
13 | exportRender() ?> 14 |
15 |
16 | 24 |
25 | 26 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_import.stub: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 'layout']) ?> 12 |
13 | importRender() ?> 14 |
15 |
16 | 24 |
25 | 26 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_index.stub: -------------------------------------------------------------------------------- 1 | listRender() ?> 2 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_list_toolbar.stub: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 18 | [[import_svg]] 19 | 20 | 21 | [[import_svg]][[export_svg]] 22 | 23 | 24 | [[export_svg]][[empty_sortable_nested_tree]] 25 | 26 | 27 | [[empty_sortable_nested_tree]]
28 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_preview.stub: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | fatalError): ?> 12 |
13 | formRenderPreview() ?> 14 |
15 | 16 |

fatalError) ?>

17 |

18 | 19 | 20 | 21 |

22 | 23 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_reorder.stub: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | reorderRender() ?> 8 | -------------------------------------------------------------------------------- /classes/parser/templates/controller_update.stub: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | fatalError): ?> 12 | 'layout']) ?> 13 |
14 | formRender() ?> 15 |
16 |
17 |
18 | 27 | 36 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
50 |
51 | 52 | 53 |

fatalError) ?>

54 |

55 | 56 | 57 | 58 |

59 | 60 | -------------------------------------------------------------------------------- /classes/parser/templates/extend_backend_menu_handler.stub: -------------------------------------------------------------------------------- 1 | removeSideMenuItem('Lovata.Shopaholic', 'shopaholic-menu-main', 'shopaholic-menu-products'); 23 | // $obManager->addSideMenuItem('Lovata.Shopaholic', 'shopaholic-menu-main', 'shopaholic-menu-products', $this->dataMenuProduct()); 24 | } 25 | 26 | // /** 27 | // * Data menu product 28 | // * @return array 29 | // */ 30 | // protected function dataMenuProduct() 31 | // { 32 | // return [ 33 | // 'label' => 'lovata.shopaholic::lang.menu.products', 34 | // 'url' => Backend::url('lovata/shopaholic/products'), 35 | // 'icon' => 'icon-smile-o', 36 | // 'permissions' => ['shopaholic-menu-products'], 37 | // 'order' => 1000, 38 | // ]; 39 | // } 40 | } 41 | -------------------------------------------------------------------------------- /classes/parser/templates/extend_model_columns_handler.stub: -------------------------------------------------------------------------------- 1 | removeColumn($obWidget); 21 | $this->addColumn($obWidget); 22 | } 23 | 24 | /** 25 | * Remove columns model 26 | * @param \Backend\Widgets\Lists $obWidget 27 | */ 28 | protected function removeColumn($obWidget) 29 | { 30 | $obWidget->removeColumn(''); 31 | } 32 | 33 | /** 34 | * Add columns model 35 | * @param \Backend\Widgets\Lists $obWidget 36 | */ 37 | protected function addColumn($obWidget) 38 | { 39 | $obWidget->addColumns([]); 40 | } 41 | 42 | /** 43 | * Get model class name 44 | * @return string 45 | */ 46 | protected function getModelClass() : string 47 | { 48 | return {{studly_model}}::class; 49 | } 50 | 51 | /** 52 | * Get controller class name 53 | * @return string 54 | */ 55 | protected function getControllerClass() : string 56 | { 57 | return {{studly_controller}}::class; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /classes/parser/templates/extend_model_fields_handler.stub: -------------------------------------------------------------------------------- 1 | removeField($obWidget); 21 | $this->addField($obWidget); 22 | } 23 | 24 | /** 25 | * Remove fields model 26 | * @param \Backend\Widgets\Form $obWidget 27 | */ 28 | protected function removeField($obWidget) 29 | { 30 | $obWidget->removeField(''); 31 | } 32 | 33 | /** 34 | * Add fields model 35 | * @param \Backend\Widgets\Form $obWidget 36 | */ 37 | protected function addField($obWidget) 38 | { 39 | $obWidget->addTabFields([]); 40 | } 41 | 42 | /** 43 | * Get model class name 44 | * @return string 45 | */ 46 | protected function getModelClass() : string 47 | { 48 | return {{studly_model}}::class; 49 | } 50 | 51 | /** 52 | * Get controller class name 53 | * @return string 54 | */ 55 | protected function getControllerClass() : string 56 | { 57 | return {{studly_controller}}::class; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /classes/parser/templates/fields.stub: -------------------------------------------------------------------------------- 1 | fields: 2 | [[active]] active: 3 | label: 'lovata.toolbox::lang.field.active' 4 | span: full 5 | default: 0 6 | type: switch 7 | [[active]][[name]] name: 8 | label: 'lovata.toolbox::lang.field.name' 9 | span: auto 10 | required: 1 11 | type: text 12 | placeholder: 'lovata.toolbox::lang.field.name' 13 | [[name]][[slug]] slug: 14 | label: 'lovata.toolbox::lang.field.slug' 15 | span: auto 16 | required: 1 17 | placeholder: 'lovata.toolbox::lang.field.slug' 18 | preset: 19 | field: name 20 | type: slug 21 | type: text 22 | [[slug]]tabs: 23 | fields: 24 | [[code]] code: 25 | label: 'lovata.toolbox::lang.field.code' 26 | span: left 27 | type: text 28 | placeholder: 'lovata.toolbox::lang.field.code' 29 | tab: 'lovata.toolbox::lang.tab.settings' 30 | [[code]][[external_id]] external_id: 31 | label: 'lovata.toolbox::lang.field.external_id' 32 | span: left 33 | type: text 34 | placeholder: 'lovata.toolbox::lang.field.external_id' 35 | tab: 'lovata.toolbox::lang.tab.settings' 36 | [[external_id]][[preview_text]] preview_text: 37 | label: 'lovata.toolbox::lang.field.preview_text' 38 | size: large 39 | span: full 40 | type: textarea 41 | placeholder: 'lovata.toolbox::lang.field.preview_text' 42 | tab: 'lovata.toolbox::lang.tab.description' 43 | [[preview_text]][[description]] description: 44 | label: 'lovata.toolbox::lang.field.description' 45 | size: giant 46 | span: full 47 | type: richeditor 48 | tab: 'lovata.toolbox::lang.tab.description' 49 | [[description]][[preview_image]] preview_image: 50 | label: 'lovata.toolbox::lang.field.preview_image' 51 | mode: image 52 | useCaption: true 53 | thumbOptions: 54 | mode: crop 55 | extension: auto 56 | span: left 57 | type: fileupload 58 | tab: 'lovata.toolbox::lang.tab.images' 59 | [[preview_image]][[images]] images: 60 | label: 'lovata.toolbox::lang.field.images' 61 | mode: image 62 | useCaption: true 63 | thumbOptions: 64 | mode: crop 65 | extension: auto 66 | span: left 67 | type: fileupload 68 | tab: 'lovata.toolbox::lang.tab.images' 69 | [[images]][[file]] file: 70 | label: 'lovata.toolbox::lang.field.file' 71 | type: fileupload 72 | span: left 73 | required: 0 74 | mode: file 75 | tab: 'lovata.toolbox::lang.tab.files'[[file]] 76 | -------------------------------------------------------------------------------- /classes/parser/templates/item.stub: -------------------------------------------------------------------------------- 1 | [ 48 | 'class' => {{studly_model}}Item::class, 49 | 'field' => 'parent_id', 50 | ], 51 | 'children' => [ 52 | 'class' => {{studly_model}}Collection::class, 53 | 'field' => 'children_id_list', 54 | ], 55 | ]; 56 | [[nested_tree]] 57 | /** 58 | * Returns URL of a brand page. 59 | * @param string $sPageCode 60 | * @return string 61 | */ 62 | public function getPageUrl($sPageCode = '{{lower_model}}') 63 | { 64 | //Get URL params 65 | $arParamList = $this->getPageParamList($sPageCode); 66 | 67 | //Generate page URL 68 | $sURL = CmsPage::url($sPageCode, $arParamList); 69 | 70 | return $sURL; 71 | } 72 | 73 | /** 74 | * Get URL param list by page code 75 | * @param string $sPageCode 76 | * @return array 77 | */ 78 | public function getPageParamList($sPageCode) : array 79 | { 80 | $arPageParamList = []; 81 | 82 | //Get URL params for page 83 | $arParamList = PageHelper::instance()->getUrlParamList($sPageCode, '{{studly_model}}Page'); 84 | if (!empty($arParamList)) { 85 | $sPageParam = array_shift($arParamList); 86 | $arPageParamList[$sPageParam] = $this->slug; 87 | } 88 | 89 | return $arPageParamList; 90 | } 91 | [[nested_tree]] 92 | /** 93 | * Set element data from model object 94 | * @return array 95 | */ 96 | protected function getElementData() 97 | { 98 | $arResult = [ 99 | 'nest_depth' => $this->obElement->getDepth(), 100 | ]; 101 | 102 | $arResult['children_id_list'] = $this->obElement->children() 103 | ->active() 104 | ->orderBy('nest_left', 'asc') 105 | ->pluck('id')->all(); 106 | 107 | return $arResult; 108 | } 109 | [[nested_tree]]} 110 | -------------------------------------------------------------------------------- /classes/parser/templates/lang.stub: -------------------------------------------------------------------------------- 1 | [ 3 | 'name' => '{{studly_plugin}}', 4 | 'description' => '', 5 | ], 6 | 'field' => [], 7 | 'menu' => [ 8 | 'main' => '{{studly_plugin}}', 9 | // 'products' => 'Products', 10 | ], 11 | 'tab' => [ 12 | 'permissions' => '{{studly_plugin}}', 13 | ], 14 | 'comment' => [], 15 | 'message' => [], 16 | 'button' => [], 17 | 'component' => [ 18 | // 'product_list_name' => 'Product List', 19 | // 'product_list_description' => '', 20 | ], 21 | 'permission' => [ 22 | // 'product' => 'Manage products', 23 | ], 24 | // 'product' => [ 25 | // 'name' => 'product', 26 | // 'list_title' => 'Product list', 27 | // ], 28 | ]; 29 | -------------------------------------------------------------------------------- /classes/parser/templates/list_store.stub: -------------------------------------------------------------------------------- 1 | addToStoreList('active', ActiveListStore::class); 33 | [[active]][[default_sorting]] $this->addToStoreList('sorting', SortingListStore::class); 34 | [[default_sorting]][[sortable]] $this->addToStoreList('sorting', SortingListStore::class); 35 | [[sortable]][[nested_tree]] $this->addToStoreList('top_level', TopLevelListStore::class); 36 | [[nested_tree]] } 37 | } 38 | -------------------------------------------------------------------------------- /classes/parser/templates/migration.stub: -------------------------------------------------------------------------------- 1 | engine = 'InnoDB'; 28 | $obTable->increments('id')->unsigned(); 29 | [[empty_fields]][[active]] $obTable->boolean('active')->default(0); 30 | [[active]][[name]] $obTable->string('name')->index(); 31 | [[name]][[slug]] $obTable->string('slug')->unique()->index(); 32 | [[slug]][[code]] $obTable->string('code')->nullable()->index(); 33 | [[code]][[external_id]] $obTable->string('external_id')->nullable()->index(); 34 | [[external_id]][[preview_text]] $obTable->text('preview_text')->nullable(); 35 | [[preview_text]][[description]] $obTable->text('description')->nullable(); 36 | [[description]][[view_count]] $obTable->integer('view_count')->nullable()->default(0); 37 | [[view_count]][[empty_fields]][[nested_tree]] $obTable->integer('parent_id')->nullable()->unsigned(); 38 | $obTable->integer('nest_left')->nullable()->unsigned(); 39 | $obTable->integer('nest_right')->nullable()->unsigned(); 40 | $obTable->integer('nest_depth')->nullable()->unsigned(); 41 | [[nested_tree]][[sortable]] $obTable->integer('sort_order')->nullable()->default(0); 42 | [[sortable]] $obTable->timestamps(); 43 | }); 44 | } 45 | 46 | /** 47 | * Rollback migration 48 | */ 49 | public function down() 50 | { 51 | Schema::dropIfExists(self::TABLE); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /classes/parser/templates/plugin_php.stub: -------------------------------------------------------------------------------- 1 | pluck('id')->all(); 23 | 24 | return $arElementIDList; 25 | } 26 | [[sortable]][[default_sorting]] 27 | /** 28 | * Get ID list from database 29 | * @return array 30 | */ 31 | protected function getIDListFromDB() : array 32 | { 33 | switch ($this->sValue) { 34 | case {{studly_model}}ListStore::SORT_CREATED_AT_ASC: 35 | $arElementIDList = $this->getByPublishASC(); 36 | break; 37 | case {{studly_model}}ListStore::SORT_CREATED_AT_DESC: 38 | $arElementIDList = $this->getByPublishDESC(); 39 | break; 40 | [[view_count]] case {{studly_model}}ListStore::SORT_VIEW_COUNT_ASC: 41 | $arElementIDList = $this->getByViewsASC(); 42 | break; 43 | case {{studly_model}}ListStore::SORT_VIEW_COUNT_DESC: 44 | $arElementIDList = $this->getByViewsDESC(); 45 | break; 46 | [[view_count]] default: 47 | $arElementIDList = $this->getDefaultList(); 48 | break; 49 | } 50 | 51 | return $arElementIDList; 52 | } 53 | 54 | /** 55 | * Get default list 56 | * @return array 57 | */ 58 | protected function getDefaultList() : array 59 | { 60 | $arElementIDList = (array) {{studly_model}}::pluck('id')->all(); 61 | 62 | return $arElementIDList; 63 | } 64 | 65 | /** 66 | * Get sorting ID list by published (ASC) 67 | * @return array 68 | */ 69 | protected function getByPublishASC() : array 70 | { 71 | $arElementIDList = (array) {{studly_model}}::orderBy('created_at', 'asc')->pluck('id')->all(); 72 | 73 | return $arElementIDList; 74 | } 75 | 76 | /** 77 | * Get sorting ID list by published (DESC) 78 | * @return array 79 | */ 80 | protected function getByPublishDESC() : array 81 | { 82 | $arElementIDList = (array) {{studly_model}}::orderBy('created_at', 'desc')->pluck('id')->all(); 83 | 84 | return $arElementIDList; 85 | } 86 | [[view_count]] 87 | /** 88 | * Get sorting ID list by views (ASC) 89 | * @return array 90 | */ 91 | protected function getByViewsASC() : array 92 | { 93 | $arElementIDList = (array) {{studly_model}}::orderBy('view_count', 'asc')->pluck('id')->all(); 94 | 95 | return $arElementIDList; 96 | } 97 | 98 | /** 99 | * Get sorting ID list by views (DESC) 100 | * @return array 101 | */ 102 | protected function getByViewsDESC() : array 103 | { 104 | $arElementIDList = (array) {{studly_model}}::orderBy('view_count', 'desc')->pluck('id')->all(); 105 | 106 | return $arElementIDList; 107 | } 108 | [[view_count]][[default_sorting]]} 109 | -------------------------------------------------------------------------------- /classes/parser/templates/sorting_top_level_list_store.stub: -------------------------------------------------------------------------------- 1 | orderBy('nest_left', 'asc') 23 | ->pluck('id')->all(); 24 | 25 | return $arElementIDList; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /classes/parser/templates/version.stub: -------------------------------------------------------------------------------- 1 | 1.0.0: 2 | - 'Init plugin' 3 | -------------------------------------------------------------------------------- /classes/parser/update/CommonUpdateFile.php: -------------------------------------------------------------------------------- 1 | arData = $arData; 35 | $arReplace = array_get($this->arData, 'replace'); 36 | $sClassCreateFile = $this->classCreateFile(); 37 | 38 | if (empty($this->arData) || empty($arReplace) || empty($this->sFilePath) || empty($sClassCreateFile)) { 39 | $this->bUpdate = false; 40 | 41 | return; 42 | } 43 | 44 | $this->obFile = new Filesystem(); 45 | $this->sFilePath = plugins_path($this->sFilePath); 46 | $this->sFilePath = $this->parseByName($arReplace, $this->sFilePath); 47 | 48 | if (!$this->obFile->exists($this->sFilePath)) { 49 | $obFile = new $sClassCreateFile($this->arData); 50 | $obFile->create(true); 51 | } 52 | } 53 | 54 | /** 55 | * Class create file 56 | * @return string 57 | */ 58 | protected function classCreateFile() 59 | { 60 | return ''; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /classes/parser/update/PluginLangUpdateFile.php: -------------------------------------------------------------------------------- 1 | arData, 'replace'); 22 | 23 | if (empty($arData) || !is_array($arData) || empty($arReplaceList) || !$this->bUpdate) { 24 | return; 25 | } 26 | 27 | $arLangData = $this->getLangData(); 28 | 29 | foreach ($arData as $sKeyLang => $arValueLang) { 30 | if (!is_array($arValueLang)) { 31 | continue; 32 | } 33 | 34 | $sKeyLang = $this->parseByName($arReplaceList, $sKeyLang); 35 | 36 | foreach ($arValueLang as $sKeyParam => $sValueParam) { 37 | $sKeyParam = $this->parseByName($arReplaceList, $sKeyParam); 38 | $sValueParam = $this->parseByName($arReplaceList, $sValueParam); 39 | 40 | $arCheck = array_get($arLangData, $sKeyLang.'.'.$sKeyParam); 41 | 42 | if (empty($arCheck)) { 43 | array_set($arLangData, $sKeyLang.'.'.$sKeyParam, $sValueParam); 44 | } 45 | } 46 | } 47 | 48 | $this->sContent = $this->arrayToStringFile($arLangData); 49 | $this->save(); 50 | } 51 | 52 | 53 | /** 54 | * Class create file 55 | * @return string 56 | */ 57 | protected function classCreateFile() 58 | { 59 | return PluginLangCreateFile::class; 60 | } 61 | 62 | /** 63 | * Get lang data 64 | * @return array|mixed 65 | */ 66 | protected function getLangData() 67 | { 68 | if (!isset($this->sFilePath) || empty($this->sFilePath)) { 69 | return []; 70 | } 71 | 72 | return require $this->sFilePath; 73 | } 74 | 75 | /** 76 | * Save lang.php 77 | */ 78 | protected function save() 79 | { 80 | if (!isset($this->sContent) || empty($this->sContent)) { 81 | return; 82 | } 83 | 84 | $this->obFile->put($this->sFilePath, $this->sContent); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /classes/queue/ImportItemQueue.php: -------------------------------------------------------------------------------- 1 | import($sImportClass, $arImportData); 24 | 25 | $obJob->delete(); 26 | } 27 | 28 | /** 29 | * Import item 30 | * @param string $sImportClass 31 | * @param array $arImportData 32 | * @throws \Throwable 33 | */ 34 | protected function import($sImportClass, $arImportData) 35 | { 36 | if (empty($sImportClass) || empty($arImportData) || !class_exists($sImportClass)) { 37 | return; 38 | } 39 | 40 | /** @var \Lovata\Toolbox\Classes\Helper\AbstractImportModel $obImport */ 41 | $obImport = new $sImportClass(); 42 | if ($obImport instanceof AbstractImportModelFromCSV) { 43 | $obImport->import($arImportData, false); 44 | } elseif($obImport instanceof AbstractImportModelFromXML) { 45 | $obImport->importRow($arImportData, false); 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /classes/storage/AbstractUserStorage.php: -------------------------------------------------------------------------------- 1 | get($sKey); 45 | if (empty($arValueList) || !is_array($arValueList)) { 46 | $arValueList = []; 47 | } 48 | 49 | return $arValueList; 50 | } 51 | 52 | /** 53 | * Add value to list 54 | * @param string $sKey 55 | * @param string $sValue 56 | */ 57 | public function addToList($sKey, $sValue) 58 | { 59 | if (empty($sKey) || empty($sValue)) { 60 | return; 61 | } 62 | 63 | //Get value from storage 64 | $arValueList = $this->getList($sKey); 65 | 66 | array_unshift($arValueList, $sValue); 67 | $arValueList = array_unique($arValueList); 68 | 69 | $this->put($sKey, $arValueList); 70 | } 71 | 72 | /** 73 | * Remove value from list 74 | * @param string $sKey 75 | * @param string $sValue 76 | */ 77 | public function removeFromList($sKey, $sValue) 78 | { 79 | if (empty($sKey) || empty($sValue)) { 80 | return; 81 | } 82 | 83 | //Get value from storage 84 | $arValueList = $this->getList($sKey); 85 | 86 | $iPosition = array_search($sValue, $arValueList); 87 | if ($iPosition === false) { 88 | return; 89 | } 90 | 91 | unset($arValueList[$iPosition]); 92 | $arValueList = array_values($arValueList); 93 | 94 | $this->put($sKey, $arValueList); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /classes/storage/CookieUserStorage.php: -------------------------------------------------------------------------------- 1 | iMinutePeriod); 47 | } 48 | 49 | /** 50 | * Clear value in storage 51 | * @param string $sKey 52 | */ 53 | public function clear($sKey) 54 | { 55 | if (empty($sKey)) { 56 | return; 57 | } 58 | 59 | Cookie::forget($sKey); 60 | } 61 | 62 | /** 63 | * Set minute period 64 | * @param int $iPeriod 65 | */ 66 | public function setMinutePeriod($iPeriod) 67 | { 68 | $this->iMinutePeriod = (int) $iPeriod; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /classes/storage/SessionUserStorage.php: -------------------------------------------------------------------------------- 1 | arStoreList[$sFieldName])) { 24 | return $this->arStoreList[$sFieldName]; 25 | } 26 | 27 | return null; 28 | } 29 | 30 | /** 31 | * Add store class to list and get store object 32 | * @param string $sFieldName 33 | * @param string $sClassName 34 | */ 35 | protected function addToStoreList($sFieldName, $sClassName) 36 | { 37 | if (empty($sFieldName) || empty($sClassName) || !class_exists($sClassName)) { 38 | return; 39 | } 40 | 41 | $this->arStoreList[$sFieldName] = $sClassName::instance(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /classes/store/AbstractStore.php: -------------------------------------------------------------------------------- 1 | getIDListFromCache(); 36 | if (!empty($arElementIDList) && is_array($arElementIDList)) { 37 | return $arElementIDList; 38 | } 39 | 40 | $arElementIDList = $this->getIDListFromDB(); 41 | $this->saveIDList($arElementIDList); 42 | 43 | return $arElementIDList; 44 | } 45 | 46 | /** 47 | * Get element ID list from array 48 | * @return array|null 49 | */ 50 | protected function getIDListFromCache() : array 51 | { 52 | $arCacheTags = $this->getCacheTagList(); 53 | $sCacheKey = $this->getCacheKey(); 54 | 55 | $arElementIDList = (array) CCache::get($arCacheTags, $sCacheKey); 56 | 57 | return $arElementIDList; 58 | } 59 | 60 | /** 61 | * Save element ID list in cache 62 | * @param array $arElementIDList 63 | */ 64 | protected function saveIDList($arElementIDList) 65 | { 66 | $arCacheTags = $this->getCacheTagList(); 67 | $sCacheKey = $this->getCacheKey(); 68 | 69 | //Set cache data 70 | CCache::forever($arCacheTags, $sCacheKey, $arElementIDList); 71 | } 72 | 73 | /** 74 | * Clear element ID list in cache 75 | */ 76 | protected function clearIDList() 77 | { 78 | $arCacheTags = $this->getCacheTagList(); 79 | $sCacheKey = $this->getCacheKey(); 80 | 81 | CCache::clear($arCacheTags, $sCacheKey); 82 | } 83 | 84 | /** 85 | * Get array with cache tags 86 | * @return array 87 | */ 88 | protected function getCacheTagList() 89 | { 90 | return [static::class]; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /classes/store/AbstractStoreWithParam.php: -------------------------------------------------------------------------------- 1 | sValue = $sFilterValue; 28 | if (array_key_exists($this->getCacheKey(), $this->arCachedList) && is_array($this->arCachedList[$this->getCacheKey()])) { 29 | return $this->arCachedList[$this->getCacheKey()]; 30 | } 31 | 32 | $arElementIDList = $this->getIDList(); 33 | $this->arCachedList[$this->getCacheKey()] = $arElementIDList; 34 | 35 | return $arElementIDList; 36 | } 37 | 38 | /** 39 | * Get element ID list from database, without cache 40 | * @param mixed $sFilterValue 41 | * @return array|null 42 | */ 43 | public function getNoCache($sFilterValue) : array 44 | { 45 | if (empty($sFilterValue) && $sFilterValue !== 0 && $sFilterValue !== '0') { 46 | return []; 47 | } 48 | 49 | $this->sValue = $sFilterValue; 50 | $arElementIDList = $this->getIDListFromDB(); 51 | 52 | return $arElementIDList; 53 | } 54 | 55 | /** 56 | * Clear element ID list 57 | * @param mixed $sFilterValue 58 | */ 59 | public function clear($sFilterValue) 60 | { 61 | if (empty($sFilterValue) && $sFilterValue !== 0 && $sFilterValue !== '0') { 62 | return; 63 | } 64 | 65 | $this->sValue = $sFilterValue; 66 | 67 | $this->clearIDList(); 68 | 69 | if (array_key_exists($this->getCacheKey(), $this->arCachedList)) { 70 | unset($this->arCachedList[$this->getCacheKey()]); 71 | } 72 | } 73 | 74 | /** 75 | * Get cache key 76 | * @return string 77 | */ 78 | protected function getCacheKey() : string 79 | { 80 | return $this->sValue; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /classes/store/AbstractStoreWithTwoParam.php: -------------------------------------------------------------------------------- 1 | sValue = $sFilterValue; 32 | $this->sAdditionParam = $sAdditionalParam; 33 | if (array_key_exists($this->getCacheKey(), $this->arCachedList) && is_array($this->arCachedList[$this->getCacheKey()])) { 34 | return $this->arCachedList[$this->getCacheKey()]; 35 | } 36 | 37 | $arElementIDList = $this->getIDList(); 38 | $this->arCachedList[$this->getCacheKey()] = $arElementIDList; 39 | 40 | return $arElementIDList; 41 | } 42 | 43 | /** 44 | * Get element ID list from database, without cache 45 | * @param mixed $sFilterValue 46 | * @param mixed $sAdditionalParam 47 | * @return array|null 48 | */ 49 | public function getNoCache($sFilterValue, $sAdditionalParam = null) : array 50 | { 51 | if (empty($sFilterValue) && $sFilterValue !== 0 && $sFilterValue !== '0') { 52 | return []; 53 | } 54 | 55 | $this->sValue = $sFilterValue; 56 | $this->sAdditionParam = $sAdditionalParam; 57 | 58 | $arElementIDList = $this->getIDListFromDB(); 59 | 60 | return $arElementIDList; 61 | } 62 | 63 | /** 64 | * Clear element ID list 65 | * @param mixed $sFilterValue 66 | * @param mixed $sAdditionalParam 67 | */ 68 | public function clear($sFilterValue, $sAdditionalParam = null) 69 | { 70 | if (empty($sFilterValue) && $sFilterValue !== 0 && $sFilterValue !== '0') { 71 | return; 72 | } 73 | 74 | $this->sValue = $sFilterValue; 75 | $this->sAdditionParam = $sAdditionalParam; 76 | 77 | $this->clearIDList(); 78 | 79 | if (array_key_exists($this->getCacheKey(), $this->arCachedList)) { 80 | unset($this->arCachedList[$this->getCacheKey()]); 81 | } 82 | } 83 | 84 | /** 85 | * Get cache key 86 | * @return string 87 | */ 88 | protected function getCacheKey() : string 89 | { 90 | return $this->sValue.'_'.$this->sAdditionParam; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /classes/store/AbstractStoreWithoutParam.php: -------------------------------------------------------------------------------- 1 | arCachedList !== null && is_array($this->arCachedList)) { 20 | return $this->arCachedList; 21 | } 22 | 23 | $arElementIDList = $this->getIDList(); 24 | $this->arCachedList = $arElementIDList; 25 | 26 | return $arElementIDList; 27 | } 28 | 29 | /** 30 | * Get element ID list from database, without cache 31 | * @return array|null 32 | */ 33 | public function getNoCache() : array 34 | { 35 | $arElementIDList = $this->getIDListFromDB(); 36 | 37 | return $arElementIDList; 38 | } 39 | 40 | /** 41 | * Clear element ID list 42 | */ 43 | public function clear() 44 | { 45 | $this->clearIDList(); 46 | $this->arCachedList = null; 47 | } 48 | 49 | /** 50 | * Get cache key 51 | * @return string 52 | */ 53 | protected function getCacheKey() : string 54 | { 55 | return static::class; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lovata/toolbox-plugin", 3 | "type": "october-plugin", 4 | "description": "Toolbox plugin for October CMS", 5 | "license": "GPL-3.0-only", 6 | "require": { 7 | "kharanenka/php-result-store": "2.*", 8 | "kharanenka/laravel-scope-active": "1.0.*", 9 | "kharanenka/oc-pagination": "1.0.*", 10 | "kharanenka/laravel-cache-helper": "^1.0.4", 11 | "kharanenka/laravel-scope-category-belongs-to": "1.0.*", 12 | "kharanenka/laravel-scope-code": "1.0.*", 13 | "kharanenka/laravel-scope-date": "1.0.*", 14 | "kharanenka/laravel-scope-external-id": "1.0.*", 15 | "kharanenka/laravel-scope-name": "1.0.*", 16 | "kharanenka/laravel-scope-slug": "1.0.*", 17 | "kharanenka/laravel-scope-user-belongs-to": "1.0.*", 18 | "kharanenka/oc-data-file-model": "1.*", 19 | "kharanenka/laravel-scope-moderation": "1.0.*", 20 | "kharanenka/laravel-scope-hidden": "1.0.*", 21 | "kharanenka/laravel-scope-type": "1.0.*", 22 | "october/rain": ">=3.1", 23 | "composer/installers": "~1.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | files: 2 | - source: /lang/en/*php 3 | translation: /lang/%two_letters_code%/%original_file_name% 4 | -------------------------------------------------------------------------------- /models/CommonSettings.php: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/unit 16 | 17 | 18 | 19 |          20 |             ./classes/collection/CollectionStore.php 21 |             ./classes/collection/ElementCollection.php 22 |             ./classes/item/ElementItem.php 23 |             ./classes/item/MainItem.php 24 |          25 |      26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /plugin.yaml: -------------------------------------------------------------------------------- 1 | plugin: 2 | name: 'lovata.toolbox::lang.plugin.name' 3 | description: 'lovata.toolbox::lang.plugin.description' 4 | author: Lovata 5 | icon: oc-icon-star 6 | homepage: 'https://github.com/lovata/oc-toolbox-plugin' 7 | permissions: 8 | toolbox-menu-settings: 9 | tab: 'lovata.toolbox::lang.tab.permissions' 10 | label: 'lovata.toolbox::lang.permission.settings' 11 | order: 100 -------------------------------------------------------------------------------- /tests/CommonTest.php: -------------------------------------------------------------------------------- 1 | getPlugins()); 27 | foreach ($arPluginList as $sPluginKey) { 28 | if(!preg_match('%^lovata.*%i', $sPluginKey)) { 29 | continue; 30 | } 31 | 32 | $obManager->refreshPlugin($sPluginKey); 33 | } 34 | 35 | $obManager->bootAll(true); 36 | $obManager->registerAll(true); 37 | } 38 | 39 | public function tearDown(): void 40 | { 41 | parent::tearDown(); 42 | 43 | // Get the plugin manager 44 | $obManager = PluginManager::instance(); 45 | 46 | // Ensure that plugins are registered again for the next test 47 | $obManager->unregisterAll(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/unit/CollectionStoreTest.php: -------------------------------------------------------------------------------- 1 | saved('test')); 27 | 28 | CollectionStore::instance()->save('', $obList); 29 | self::assertEquals(null, CollectionStore::instance()->saved('')); 30 | 31 | CollectionStore::instance()->save('test', $obList); 32 | 33 | $obList->merge([2]); 34 | $obSavedList = CollectionStore::instance()->saved('test'); 35 | 36 | self::assertEquals([1], $obSavedList->getIDList()); 37 | 38 | $obSavedList->clear(); 39 | 40 | self::assertEquals([1,2], $obList->getIDList()); 41 | } 42 | } -------------------------------------------------------------------------------- /tests/unit/ItemTest.php: -------------------------------------------------------------------------------- 1 | id, 'Error in "make" item method'); 26 | self::assertEquals(false, empty($obItem->id), 'Error in "__isset" item method'); 27 | 28 | $obItem = TestItem::makeNoCache(1); 29 | self::assertEquals(1, $obItem->id, 'Error in "makeNoCache" item method'); 30 | 31 | $arItemData = [ 32 | 'id' => 1, 33 | 'test_id' => 2, 34 | 'title' => 'title1', 35 | 'test_list_id' => [1,2], 36 | ]; 37 | 38 | self::assertEquals($arItemData, $obItem->toArray(), 'Error in "toArray" item method'); 39 | 40 | self::assertInstanceOf(\Model::class, $obItem->getObject(), 'Error in "getObject" item method'); 41 | } 42 | 43 | /** 44 | * Test item relations 45 | */ 46 | public function testItemRelations() 47 | { 48 | $sMessage = 'Error in relation methods'; 49 | $obItem = TestItem::make(1); 50 | 51 | $obRelationItem = $obItem->test; 52 | self::assertInstanceOf(TestItem::class, $obRelationItem, $sMessage); 53 | self::assertEquals(2, $obRelationItem->id, $sMessage); 54 | 55 | $obRelationItem = $obItem->test; 56 | self::assertInstanceOf(TestItem::class, $obRelationItem, $sMessage); 57 | self::assertEquals(2, $obRelationItem->id, $sMessage); 58 | 59 | $obRelationItem = $obItem->test_null; 60 | self::assertEquals(null, $obRelationItem, $sMessage); 61 | 62 | $obRelationItem = $obItem->test_class; 63 | self::assertEquals(null, $obRelationItem, $sMessage); 64 | 65 | $obRelationItem = $obItem->test_field; 66 | self::assertEquals(null, $obRelationItem, $sMessage); 67 | 68 | $obRelationItem = $obItem->test_exist; 69 | self::assertEquals(null, $obRelationItem, $sMessage); 70 | 71 | /** @var TestCollection $obRelationList */ 72 | $obRelationList = $obItem->test_list; 73 | self::assertInstanceOf(TestCollection::class, $obRelationList, $sMessage); 74 | self::assertEquals(2, $obRelationList->count(), $sMessage); 75 | 76 | /** @var TestCollection $obRelationList */ 77 | $obRelationList = $obItem->test_empty_list; 78 | self::assertInstanceOf(TestCollection::class, $obRelationList, $sMessage); 79 | self::assertEquals(0, $obRelationList->count(), $sMessage); 80 | self::assertEquals([], $obRelationList->getIDList(), $sMessage); 81 | } 82 | } -------------------------------------------------------------------------------- /traits/console/LogoTrait.php: -------------------------------------------------------------------------------- 1 | ███──████──████──█────████───████──██─██', 13 | '─█───█──█──█──█──█────█──██──█──█───███', 14 | '─█───█──█──█──█──█────████───█──█────█', 15 | '─█───█──█──█──█──█────█──██──█──█───███', 16 | '─█───████──████──███──████───████──██─██', 17 | ]; 18 | /** @var array */ 19 | protected $arLogoLovata = [ 20 | '█──────████───█───█───████──███████──████', 21 | '█──────█──█───█───█───█──█─────█─────█──█', 22 | '█──────█──█───█───█───████─────█─────████', 23 | '█──────█──█────███────█──█─────█─────█──█', 24 | '█████──████─────█─────█──█─────█─────█──█', 25 | ]; 26 | 27 | /** 28 | * Write logo toolbox 29 | */ 30 | protected function logoToolBox() 31 | { 32 | $this->output->newLine(1); 33 | $this->output->writeln($this->arLogoLovata); 34 | $this->output->newLine(1); 35 | $this->output->writeln($this->arLogoToolBox); 36 | $this->output->newLine(1); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /traits/console/UpdateLangFile.php: -------------------------------------------------------------------------------- 1 | arData) || empty($this->arData)) { 19 | return []; 20 | } 21 | 22 | $sLowerAuthor = array_get($this->arData, 'replace.'.self::PREFIX_LOWER.self::CODE_AUTHOR); 23 | $sLowerPlugin = array_get($this->arData, 'replace.'.self::PREFIX_LOWER.self::CODE_PLUGIN); 24 | 25 | $sFolderPath = plugins_path($sLowerAuthor.'/'.$sLowerPlugin.'/lang'); 26 | 27 | if (empty($sLowerAuthor) || empty($sLowerPlugin) || !file_exists($sFolderPath)) { 28 | return []; 29 | } 30 | 31 | $arLangList = scandir($sFolderPath); 32 | array_shift($arLangList); 33 | array_shift($arLangList); 34 | 35 | return $arLangList; 36 | } 37 | 38 | /** 39 | * Update lang file 40 | * @param array $arLangData 41 | */ 42 | protected function updatePluginLang($arLangData) 43 | { 44 | if (empty($arLangData)) { 45 | return; 46 | } 47 | 48 | foreach ($this->getLangList() as $sLang) { 49 | array_set($this->arData, 'replace.lang', $sLang); 50 | 51 | $obUpdate = new PluginLangUpdateFile($this->arData); 52 | $obUpdate->update($arLangData); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /traits/helpers/TraitCached.php: -------------------------------------------------------------------------------- 1 | cached) || !is_array($this->cached)) { 23 | $this->cached = []; 24 | } 25 | 26 | if (is_string($arFieldList)) { 27 | $arFieldList = [$arFieldList]; 28 | } 29 | 30 | $this->cached = array_merge($this->cached, $arFieldList); 31 | $this->cached = array_unique($this->cached); 32 | } 33 | 34 | /** 35 | * Get cached field list 36 | * @return array 37 | */ 38 | public function getCachedField(): array 39 | { 40 | if (empty($this->cached) || !is_array($this->cached)) { 41 | $this->cached = []; 42 | } 43 | 44 | return $this->cached; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /traits/helpers/TraitComponentNotFoundResponse.php: -------------------------------------------------------------------------------- 1 | [ 24 | 'title' => 'lovata.toolbox::lang.component.property_slug', 25 | 'type' => 'string', 26 | 'default' => '{{ :slug }}', 27 | ], 28 | 'slug_required' => [ 29 | 'title' => 'lovata.toolbox::lang.component.property_slug_required', 30 | 'type' => 'checkbox', 31 | 'default' => 1, 32 | ], 33 | ]; 34 | 35 | if ($this->bNeedSmartURLCheck) { 36 | $arResult['smart_url_check'] = [ 37 | 'title' => 'lovata.toolbox::lang.component.property_url_check', 38 | 'type' => 'checkbox', 39 | 'default' => 0, 40 | ]; 41 | } 42 | 43 | return $arResult; 44 | } 45 | 46 | /** 47 | * Get error response for 404 page 48 | * @throws AjaxException 49 | * @return \Illuminate\Http\Response 50 | */ 51 | public function getErrorResponse() 52 | { 53 | if (Request::ajax()) { 54 | throw new AjaxException('Element not found'); 55 | } 56 | 57 | return Response::make($this->controller->run('404')->getContent(), 404); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /traits/helpers/TraitInitActiveLang.php: -------------------------------------------------------------------------------- 1 | hasPlugin('RainLab.Translate')) { 30 | return self::$arActiveLangList; 31 | } 32 | 33 | if (class_exists('RainLab\Translate\Classes\Locale')) { 34 | $arEnabledLAngList = \RainLab\Translate\Classes\Locale::listEnabled(); 35 | self::$arActiveLangList = array_keys((array) $arEnabledLAngList); 36 | } else { 37 | self::$arActiveLangList = \RainLab\Translate\Models\Locale::isEnabled()->pluck('code')->all(); 38 | } 39 | 40 | if (empty(self::$arActiveLangList)) { 41 | return self::$arActiveLangList; 42 | } 43 | 44 | //Remove default lang from list 45 | foreach (self::$arActiveLangList as $iKey => $sLangCode) { 46 | if ($sLangCode == self::$sDefaultLang) { 47 | unset(self::$arActiveLangList[$iKey]); 48 | break; 49 | } 50 | } 51 | 52 | return self::$arActiveLangList; 53 | } 54 | 55 | /** 56 | * Get and save active lang from Translate plugin 57 | */ 58 | protected function initActiveLang() 59 | { 60 | if (self::$bLangInit || !PluginManager::instance()->hasPlugin('RainLab.Translate')) { 61 | return; 62 | } 63 | 64 | self::$bLangInit = true; 65 | $obTranslate = \RainLab\Translate\Classes\Translator::instance(); 66 | 67 | self::$sDefaultLang = $obTranslate->getDefaultLocale(); 68 | 69 | $sActiveLangCode = $obTranslate->getLocale(); 70 | if (empty($sActiveLangCode) || $obTranslate->getDefaultLocale() == $sActiveLangCode) { 71 | return; 72 | } 73 | 74 | self::$sActiveLang = $sActiveLangCode; 75 | } 76 | 77 | /** 78 | * Add suffix with active lang code 79 | * @param string $sValue 80 | * @param string $sSeparator 81 | * 82 | * @return string 83 | */ 84 | protected function addActiveLangSuffix($sValue, $sSeparator = '_') 85 | { 86 | if (empty(self::$sActiveLang)) { 87 | return $sValue; 88 | } 89 | 90 | return $sValue.$sSeparator.self::$sActiveLang; 91 | } 92 | 93 | /** 94 | * Add prefix with active lang code 95 | * @param string $sValue 96 | * @param string $sSeparator 97 | * 98 | * @return string 99 | */ 100 | protected function addActiveLangPrefix($sValue, $sSeparator = '_') 101 | { 102 | if (empty(self::$sActiveLang)) { 103 | return $sValue; 104 | } 105 | 106 | return self::$sActiveLang.$sSeparator.$sValue; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /traits/helpers/TraitValidationHelper.php: -------------------------------------------------------------------------------- 1 | getFields()); 19 | 20 | Result::setFalse(['field' => array_shift($arFiledList)]) 21 | ->setMessage($obException->getMessage()) 22 | ->setCode($obException->getCode()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /traits/models/MultisiteHelperTrait.php: -------------------------------------------------------------------------------- 1 | isEmpty()) { 26 | return []; 27 | } 28 | 29 | return $obSiteList->pluck('name', 'id')->toArray(); 30 | } 31 | 32 | /** 33 | * @param array|null $arValue 34 | * @return void 35 | * @throws \Exception 36 | */ 37 | protected function setSiteListAttribute($arValue) 38 | { 39 | $arValue = empty($arValue) ? [] : $arValue; 40 | $this->site()->sync($arValue); 41 | } 42 | 43 | /** 44 | * @return array 45 | */ 46 | protected function getSiteListAttribute(): array 47 | { 48 | return $this->site->pluck('id')->toArray(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /traits/models/SetPropertyAttributeTrait.php: -------------------------------------------------------------------------------- 1 | fromJson($arValue); 19 | } 20 | 21 | if (empty($arValue) || !is_array($arValue)) { 22 | return; 23 | } 24 | 25 | $arPropertyList = $this->property; 26 | if (empty($arPropertyList)) { 27 | $arPropertyList = []; 28 | } 29 | 30 | foreach ($arValue as $sKey => $sValue) { 31 | $arPropertyList[$sKey] = $sValue; 32 | } 33 | 34 | $this->attributes['property'] = $this->asJson($arPropertyList); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /traits/parse/ParseByPatternTrait.php: -------------------------------------------------------------------------------- 1 | $sName) { 23 | $sPattern = $this->namePattern($sKey); 24 | $sContent = str_replace($sPattern, $sName, $sContent); 25 | } 26 | 27 | return $sContent; 28 | } 29 | 30 | /** 31 | * Parse content by name wrapper 32 | * @param array $arNameList 33 | * @param string $sContent 34 | * @return string 35 | */ 36 | public function parseByNameWrapper($arNameList, $sContent) 37 | { 38 | if (empty($arNameList) || !is_array($arNameList) || empty($sContent)) { 39 | return ''; 40 | } 41 | 42 | foreach ($arNameList as $sName) { 43 | $sPattern = $this->nameWrapperPattern($sName); 44 | $sContent = preg_replace($sPattern, '', $sContent); 45 | } 46 | 47 | return $sContent; 48 | } 49 | 50 | /** 51 | * Parse content by wrapper 52 | * @param array $arNameList 53 | * @param string $sContent 54 | * @return string 55 | */ 56 | public function parseByWrapper($arNameList, $sContent) 57 | { 58 | if (empty($arNameList) || !is_array($arNameList) || empty($sContent)) { 59 | return ''; 60 | } 61 | 62 | foreach ($arNameList as $sName) { 63 | $sPattern = $this->wrapperPattern($sName); 64 | $sContent = preg_replace($sPattern, '', $sContent); 65 | } 66 | 67 | return $sContent; 68 | } 69 | 70 | /** 71 | * Name pattern. Example: {{key}} 72 | * @param string $sKey 73 | * @return string 74 | */ 75 | public function namePattern($sKey) 76 | { 77 | return '{{'.$sKey.'}}'; 78 | } 79 | 80 | /** 81 | * Name wrapper pattern. Example: [[key]] 82 | * @param string $sKey 83 | * @return string 84 | */ 85 | public function nameWrapperPattern($sKey) 86 | { 87 | return '/\[\['.$sKey.'\]\]/'; 88 | } 89 | 90 | /** 91 | * Wrapper pattern. Example: [[key]]...[[key]] 92 | * @param string $sKey 93 | * @return string 94 | */ 95 | public function wrapperPattern($sKey) 96 | { 97 | return "[\[\[".$sKey."\]\][A-Za-z0-9\t\n\r\f\v\x20-\x7E]+?\[\[".$sKey."\]\]]"; 98 | } 99 | 100 | /** 101 | * Parse array to string file 102 | * @param array $arData 103 | * @return string 104 | */ 105 | public function arrayToStringFile($arData) 106 | { 107 | if (empty($arData) || !is_array($arData)) { 108 | return ''; 109 | } 110 | 111 | $sContent = var_export($arData, true); 112 | $sContent = preg_replace("/(\\n[ ]+array[ , \\n]+\(\\n)/", "[\n", $sContent); 113 | $sContent = preg_replace("/(array[ , \\n]+\(\\n)/", "[\n", $sContent); 114 | $sContent = preg_replace("/\)\,/", "],", $sContent); 115 | $sContent = preg_replace("/\)$/", "];", $sContent); 116 | $sContent = 'sModelClass.' model has not correct images config'; 18 | 19 | /** @var \Model $obModel */ 20 | $obModel = new $this->sModelClass(); 21 | self::assertNotEmpty($obModel->attachMany, $sErrorMessage); 22 | self::assertArrayHasKey('images', $obModel->attachMany, $sErrorMessage); 23 | self::assertEquals('System\Models\File', $obModel->attachMany['images'], $sErrorMessage); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /traits/tests/TestModelHasPreviewImage.php: -------------------------------------------------------------------------------- 1 | sModelClass.' model has not correct preview image config'; 18 | 19 | /** @var \Model $obModel */ 20 | $obModel = new $this->sModelClass(); 21 | self::assertNotEmpty($obModel->attachOne, $sErrorMessage); 22 | self::assertArrayHasKey('preview_image', $obModel->attachOne, $sErrorMessage); 23 | self::assertEquals('System\Models\File', $obModel->attachOne['preview_image'], $sErrorMessage); 24 | } 25 | } -------------------------------------------------------------------------------- /traits/tests/TestModelValidationNameField.php: -------------------------------------------------------------------------------- 1 | sModelClass(); 20 | 21 | //Get validation rules array and check it 22 | $arValidationRules = $obModel->rules; 23 | self::assertNotEmpty($arValidationRules, $this->sModelClass.' model has empty validation rules array'); 24 | 25 | //Check rules for "name" field 26 | self::assertArrayHasKey('name', $arValidationRules, $this->sModelClass.' model not has validation rules for field "name"'); 27 | self::assertNotEmpty($arValidationRules['name'], $this->sModelClass.' model not has validation rules for field "name"'); 28 | 29 | $arValidationCondition = explode('|', $arValidationRules['name']); 30 | self::assertContains('required', $arValidationCondition,$this->sModelClass.' model not has validation rule "required" for field "name"'); 31 | } 32 | } -------------------------------------------------------------------------------- /traits/tests/TestModelValidationSlugField.php: -------------------------------------------------------------------------------- 1 | sModelClass(); 20 | 21 | //Get validation rules array and check it 22 | $arValidationRules = $obModel->rules; 23 | self::assertNotEmpty($arValidationRules, $this->sModelClass.' model has empty validation rules array'); 24 | 25 | //Check rules for "slug" field 26 | self::assertArrayHasKey('slug', $arValidationRules, $this->sModelClass.' model not has validation rules for field "slug"'); 27 | self::assertNotEmpty($arValidationRules['slug'], $this->sModelClass.' model not has validation rules for field "slug"'); 28 | 29 | $arValidationCondition = explode('|', $arValidationRules['slug']); 30 | self::assertContains('required', $arValidationCondition,$this->sModelClass.' model not has validation rule "required" for field "slug"'); 31 | self::assertContains('unique:'.$obModel->table, $arValidationCondition,$this->sModelClass.' model not has validation rule "unique" for field "slug"'); 32 | } 33 | } --------------------------------------------------------------------------------