├── .github ├── dependabot.yml └── workflows │ ├── build.yml │ └── test.yml ├── .gitignore ├── .gitmodules ├── .idea └── gradle.xml ├── .run ├── Run Plugin.run.xml ├── Run Tests.run.xml └── Run Verifications.run.xml ├── CHANGELOG.md ├── LICENCE.md ├── README.md ├── build.gradle.kts ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── qodana.yml ├── settings.gradle.kts └── src └── main ├── kotlin ├── com │ └── github │ │ └── saundefined │ │ └── bitrix_idea │ │ ├── BitrixIdeaBundle.kt │ │ ├── actions │ │ ├── CreateGitignoreAction.kt │ │ ├── CreateModuleAction.kt │ │ ├── CreateSimpleComponentAction.kt │ │ └── CreateTemplateAction.kt │ │ ├── activity │ │ └── NotificationStartupActivity.kt │ │ ├── dialogs │ │ ├── CreateModuleDialogWrapper.kt │ │ ├── CreateSimpleComponentDialogWrapper.kt │ │ └── CreateTemplateDialogWrapper.kt │ │ ├── settings │ │ ├── AppSettingsState.kt │ │ └── ApplicationSettingsConfigurable.kt │ │ ├── templates │ │ ├── gitignore │ │ │ └── BitrixModuleFileTemplateGroupFactory.kt │ │ ├── module │ │ │ └── BitrixModuleFileTemplateGroupFactory.kt │ │ ├── simple_component │ │ │ └── BitrixSimpleComponentFileTemplateGroupFactory.kt │ │ └── template │ │ │ └── BitrixTemplateFileTemplateGroupFactory.kt │ │ └── validation │ │ ├── ComponentSimpleCodeVerifier.kt │ │ ├── ModuleCodeVerifier.kt │ │ ├── TemplateCodeVerifier.kt │ │ └── UrlVerifier.kt └── icons │ └── BitrixIdeaIcons.kt └── resources ├── META-INF ├── plugin.xml ├── pluginIcon.svg └── pluginIcon_dark.svg ├── fileTemplates └── j2ee │ ├── Bitrix Module .gitignore.ft │ ├── Bitrix Module .settings.php.ft │ ├── Bitrix Module default_option.php.ft │ ├── Bitrix Module include.php.ft │ ├── Bitrix Module install index.php.ft │ ├── Bitrix Module install version.php.ft │ ├── Bitrix Module language install index.php.ft │ ├── Bitrix Module options.php.ft │ ├── Bitrix Module prolog.php.ft │ ├── Bitrix Simple Component .description.php.ft │ ├── Bitrix Simple Component .parameters.php.ft │ ├── Bitrix Simple Component class.php.ft │ ├── Bitrix Simple Component language .description.php.ft │ ├── Bitrix Simple Component language .parameters.php.ft │ ├── Bitrix Simple Component language templates default template.php.ft │ ├── Bitrix Simple Component templates default template.php.ft │ ├── Bitrix Template .styles.php.ft │ ├── Bitrix Template description.php.ft │ ├── Bitrix Template footer.php.ft │ ├── Bitrix Template header.php.ft │ ├── Bitrix Template styles.css.ft │ └── Bitrix Template template_styles.css.ft ├── icons └── bitrix.svg └── messages └── BitrixIdeaBundle.properties /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Dependabot configuration: 2 | # https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates 3 | 4 | version: 2 5 | updates: 6 | # Maintain dependencies for Gradle dependencies 7 | - package-ecosystem: "gradle" 8 | directory: "/" 9 | target-branch: "next" 10 | schedule: 11 | interval: "daily" 12 | # Maintain dependencies for GitHub Actions 13 | - package-ecosystem: "github-actions" 14 | directory: "/" 15 | target-branch: "next" 16 | schedule: 17 | interval: "daily" 18 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | tags: 5 | - 'v*' 6 | 7 | concurrency: 8 | group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}" 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | build: 13 | name: Build 14 | runs-on: ubuntu-latest 15 | outputs: 16 | version: ${{ steps.properties.outputs.version }} 17 | changelog: ${{ steps.properties.outputs.changelog }} 18 | pluginVerifierHomeDir: ${{ steps.properties.outputs.pluginVerifierHomeDir }} 19 | steps: 20 | 21 | # Check out current repository 22 | - name: Fetch Sources 23 | uses: actions/checkout@v4 24 | with: 25 | submodules: 'true' 26 | token: ${{ secrets.FETCH_SUBMODULES_PAT }} 27 | 28 | - name: Remove .updates file 29 | run: | 30 | rm -f src/main/resources/bitrix-idea-library/.updates 31 | 32 | # Validate wrapper 33 | - name: Gradle Wrapper Validation 34 | uses: gradle/actions/wrapper-validation@v3 35 | 36 | # Setup Java environment for the next steps 37 | - name: Setup Java 38 | uses: actions/setup-java@v4 39 | with: 40 | distribution: zulu 41 | java-version: 17 42 | 43 | # Setup Java environment for the next steps 44 | - name: Setup Gradle 45 | uses: gradle/actions/setup-gradle@v4 46 | 47 | # Set environment variables 48 | - name: Export Properties 49 | id: properties 50 | shell: bash 51 | run: | 52 | PROPERTIES="$(./gradlew properties --console=plain -q)" 53 | VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')" 54 | CHANGELOG="$(./gradlew getChangelog --console=plain -q)" 55 | 56 | echo "version=$VERSION" >> $GITHUB_OUTPUT 57 | echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT 58 | 59 | echo "changelog<> $GITHUB_OUTPUT 60 | echo "$CHANGELOG" >> $GITHUB_OUTPUT 61 | echo "EOF" >> $GITHUB_OUTPUT 62 | 63 | # Build plugin 64 | - name: Build plugin 65 | run: ./gradlew buildPlugin 66 | 67 | # Prepare plugin archive content for creating artifact 68 | - name: Prepare Plugin Artifact 69 | id: artifact 70 | shell: bash 71 | run: | 72 | cd ${{ github.workspace }}/build/distributions 73 | FILENAME=`ls *.zip` 74 | unzip "$FILENAME" -d content 75 | 76 | echo "filename=${FILENAME:0:-4}" >> $GITHUB_OUTPUT 77 | 78 | # Store already-built plugin as an artifact for downloading 79 | - name: Upload artifact 80 | uses: actions/upload-artifact@v4 81 | with: 82 | name: ${{ steps.artifact.outputs.filename }} 83 | path: ./build/distributions/content/*/* 84 | 85 | # Run tests and upload a code coverage report 86 | test: 87 | name: Test 88 | needs: build 89 | runs-on: ubuntu-latest 90 | steps: 91 | # Free GitHub Actions Environment Disk Space 92 | - name: Maximize Build Space 93 | uses: jlumbroso/free-disk-space@main 94 | with: 95 | tool-cache: false 96 | large-packages: false 97 | 98 | # Check out current repository 99 | - name: Fetch Sources 100 | uses: actions/checkout@v4 101 | 102 | # Setup Java environment for the next steps 103 | - name: Setup Java 104 | uses: actions/setup-java@v4 105 | with: 106 | distribution: zulu 107 | java-version: 17 108 | 109 | # Setup Gradle 110 | - name: Setup Gradle 111 | uses: gradle/actions/setup-gradle@v4 112 | 113 | # Run tests 114 | - name: Run Tests 115 | run: ./gradlew check 116 | 117 | # Collect Tests Result of failed tests 118 | - name: Collect Tests Result 119 | if: ${{ failure() }} 120 | uses: actions/upload-artifact@v4 121 | with: 122 | name: tests-result 123 | path: ${{ github.workspace }}/build/reports/tests 124 | 125 | # Upload Kover report to CodeCov 126 | - name: Upload Code Coverage Report 127 | uses: codecov/codecov-action@v3 128 | with: 129 | files: ${{ github.workspace }}/build/reports/kover/report.xml 130 | 131 | # Run plugin structure verification along with IntelliJ Plugin Verifier 132 | verify: 133 | name: Verify plugin 134 | needs: build 135 | runs-on: ubuntu-latest 136 | steps: 137 | # Free GitHub Actions Environment Disk Space 138 | - name: Maximize Build Space 139 | uses: jlumbroso/free-disk-space@main 140 | with: 141 | tool-cache: false 142 | large-packages: false 143 | 144 | # Check out current repository 145 | - name: Fetch Sources 146 | uses: actions/checkout@v4 147 | 148 | # Setup Java environment for the next steps 149 | - name: Setup Java 150 | uses: actions/setup-java@v4 151 | with: 152 | distribution: zulu 153 | java-version: 17 154 | 155 | # Setup Gradle 156 | - name: Setup Gradle 157 | uses: gradle/actions/setup-gradle@v4 158 | 159 | # Cache Plugin Verifier IDEs 160 | - name: Setup Plugin Verifier IDEs Cache 161 | uses: actions/cache@v4 162 | with: 163 | path: ${{ needs.build.outputs.pluginVerifierHomeDir }}/ides 164 | key: plugin-verifier-${{ hashFiles('build/listProductsReleases.txt') }} 165 | 166 | # Run Verify Plugin task and IntelliJ Plugin Verifier tool 167 | - name: Run Plugin Verification tasks 168 | run: ./gradlew verifyPlugin -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }} 169 | 170 | # Collect Plugin Verifier Result 171 | - name: Collect Plugin Verifier Result 172 | if: ${{ always() }} 173 | uses: actions/upload-artifact@v4 174 | with: 175 | name: pluginVerifier-result 176 | path: ${{ github.workspace }}/build/reports/pluginVerifier 177 | 178 | # Prepare a draft release for GitHub Releases page for the manual verification 179 | # If accepted and published, release workflow would be triggered 180 | releaseDraft: 181 | name: Release Draft 182 | needs: build 183 | runs-on: ubuntu-latest 184 | permissions: 185 | contents: write 186 | steps: 187 | # Remove old release drafts by using the curl request for the available releases with draft flag 188 | - name: Remove Old Release Drafts 189 | env: 190 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 191 | run: | 192 | gh api repos/{owner}/{repo}/releases \ 193 | --jq '.[] | select(.draft == true) | .id' \ 194 | | xargs -I '{}' gh api -X DELETE repos/{owner}/{repo}/releases/{} 195 | 196 | # Create new release draft - which is not publicly visible and requires manual acceptance 197 | - name: Create Release Draft 198 | env: 199 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 200 | run: | 201 | gh release create "${{ needs.build.outputs.version }}"" \ 202 | --draft \ 203 | --title "${{ needs.build.outputs.version }}"" 204 | 205 | # Upload artifact as a release asset 206 | - name: Upload Release Asset 207 | env: 208 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 209 | run: gh release upload ${{ needs.build.outputs.version }}" ./build/distributions/* 210 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | build: 9 | name: Build 10 | runs-on: ubuntu-latest 11 | outputs: 12 | version: ${{ steps.properties.outputs.version }} 13 | changelog: ${{ steps.properties.outputs.changelog }} 14 | pluginVerifierHomeDir: ${{ steps.properties.outputs.pluginVerifierHomeDir }} 15 | steps: 16 | 17 | # Free GitHub Actions Environment Disk Space 18 | - name: Maximize Build Space 19 | uses: jlumbroso/free-disk-space@main 20 | with: 21 | tool-cache: false 22 | large-packages: false 23 | 24 | # Check out current repository 25 | - name: Fetch Sources 26 | uses: actions/checkout@v4 27 | with: 28 | submodules: 'true' 29 | token: ${{ secrets.FETCH_SUBMODULES_PAT }} 30 | 31 | - name: Remove .updates file 32 | run: | 33 | rm -f src/main/resources/bitrix-idea-library/.updates 34 | 35 | # Validate wrapper 36 | - name: Gradle Wrapper Validation 37 | uses: gradle/actions/wrapper-validation@v3 38 | 39 | # Setup Java environment for the next steps 40 | - name: Setup Java 41 | uses: actions/setup-java@v4 42 | with: 43 | distribution: zulu 44 | java-version: 17 45 | 46 | # Setup Java environment for the next steps 47 | - name: Setup Gradle 48 | uses: gradle/gradle-build-action@v2 49 | with: 50 | gradle-home-cache-cleanup: true 51 | 52 | # Set environment variables 53 | - name: Export Properties 54 | id: properties 55 | shell: bash 56 | run: | 57 | PROPERTIES="$(./gradlew properties --console=plain -q)" 58 | VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')" 59 | CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)" 60 | 61 | echo "version=$VERSION" >> $GITHUB_OUTPUT 62 | echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT 63 | 64 | echo "changelog<> $GITHUB_OUTPUT 65 | echo "$CHANGELOG" >> $GITHUB_OUTPUT 66 | echo "EOF" >> $GITHUB_OUTPUT 67 | 68 | # Build plugin 69 | - name: Build plugin 70 | run: ./gradlew buildPlugin 71 | 72 | # Prepare plugin archive content for creating artifact 73 | - name: Prepare Plugin Artifact 74 | id: artifact 75 | shell: bash 76 | run: | 77 | cd ${{ github.workspace }}/build/distributions 78 | FILENAME=`ls *.zip` 79 | unzip "$FILENAME" -d content 80 | 81 | echo "filename=${FILENAME:0:-4}" >> $GITHUB_OUTPUT 82 | 83 | # Store already-built plugin as an artifact for downloading 84 | - name: Upload artifact 85 | uses: actions/upload-artifact@v4 86 | with: 87 | name: ${{ steps.artifact.outputs.filename }} 88 | path: ./build/distributions/content/*/* 89 | 90 | # Run tests and upload a code coverage report 91 | test: 92 | name: Test 93 | needs: build 94 | runs-on: ubuntu-latest 95 | steps: 96 | 97 | # Free GitHub Actions Environment Disk Space 98 | - name: Maximize Build Space 99 | uses: jlumbroso/free-disk-space@main 100 | with: 101 | tool-cache: false 102 | large-packages: false 103 | 104 | # Check out current repository 105 | - name: Fetch Sources 106 | uses: actions/checkout@v4 107 | 108 | # Setup Java environment for the next steps 109 | - name: Setup Java 110 | uses: actions/setup-java@v4 111 | with: 112 | distribution: zulu 113 | java-version: 17 114 | 115 | # Setup Gradle 116 | - name: Setup Gradle 117 | uses: gradle/gradle-build-action@v2 118 | with: 119 | gradle-home-cache-cleanup: true 120 | 121 | # Run tests 122 | - name: Run Tests 123 | run: ./gradlew check 124 | 125 | # Collect Tests Result of failed tests 126 | - name: Collect Tests Result 127 | if: ${{ failure() }} 128 | uses: actions/upload-artifact@v4 129 | with: 130 | name: tests-result 131 | path: ${{ github.workspace }}/build/reports/tests 132 | 133 | # Upload Kover report to CodeCov 134 | - name: Upload Code Coverage Report 135 | uses: codecov/codecov-action@v5 136 | with: 137 | files: ${{ github.workspace }}/build/reports/kover/report.xml 138 | 139 | # Run plugin structure verification along with IntelliJ Plugin Verifier 140 | verify: 141 | name: Verify plugin 142 | needs: build 143 | runs-on: ubuntu-latest 144 | steps: 145 | 146 | # Check out current repository 147 | - name: Fetch Sources 148 | uses: actions/checkout@v4 149 | 150 | # Setup Java environment for the next steps 151 | - name: Setup Java 152 | uses: actions/setup-java@v4 153 | with: 154 | distribution: zulu 155 | java-version: 17 156 | 157 | # Setup Gradle 158 | - name: Setup Gradle 159 | uses: gradle/actions/setup-gradle@v4 160 | 161 | # Cache Plugin Verifier IDEs 162 | - name: Setup Plugin Verifier IDEs Cache 163 | uses: actions/cache@v4 164 | with: 165 | path: ${{ needs.build.outputs.pluginVerifierHomeDir }}/ides 166 | key: plugin-verifier-${{ hashFiles('build/listProductsReleases.txt') }} 167 | 168 | # Run Verify Plugin task and IntelliJ Plugin Verifier tool 169 | - name: Run Plugin Verification tasks 170 | run: ./gradlew verifyPlugin -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }} 171 | 172 | # Collect Plugin Verifier Result 173 | - name: Collect Plugin Verifier Result 174 | if: ${{ always() }} 175 | uses: actions/upload-artifact@v4 176 | with: 177 | name: pluginVerifier-result 178 | path: ${{ github.workspace }}/build/reports/pluginVerifier -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .idea 3 | .qodana 4 | build 5 | .intellijPlatform -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/main/resources/bitrix-idea-library"] 2 | path = src/main/resources/bitrix-idea-library 3 | url = https://github.com/qq-agency/bxApiDocs.git 4 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | -------------------------------------------------------------------------------- /.run/Run Plugin.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 17 | 19 | true 20 | true 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /.run/Run Tests.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 17 | 19 | true 20 | true 21 | false 22 | true 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /.run/Run Verifications.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 17 | 19 | true 20 | true 21 | false 22 | false 23 | 24 | 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## [Unreleased] 4 | 5 | 6 | ## [2025.1.0] 7 | 8 | ### Changed 9 | 10 | - Update IntelliJ Platform 2.1.0 11 | 12 | ## [2024.3.0] 13 | 14 | ### Changed 15 | 16 | - Updated Bitrix CMS core 17 | - Update IntelliJ Platform 1.14.1 18 | - Update IntelliJ Platform 1.14.2 19 | - Update IntelliJ Platform 2.0.0 20 | - Update IntelliJ Platform 2.0.1 21 | - Update IntelliJ Platform 2.0.2 22 | - Support for PhpStorm 2024.3 23 | 24 | ## [2024.2.0] 25 | 26 | ### Added 27 | 28 | - Creating Bitrix-related .gitignore file 29 | 30 | ### Changed 31 | 32 | - Updated Bitrix CMS core 33 | - Update IntelliJ Platform 1.13.0 34 | - Update IntelliJ Platform 1.14.0 35 | - Support for PhpStorm 2024.2 EAP 36 | - Fix icons 37 | 38 | ## [2024.1.0] 39 | 40 | ### Changed 41 | 42 | - Updated Bitrix CMS core 43 | - Support for PhpStorm 2024.1 EAP 44 | - Update IntelliJ Platform 1.12.0 45 | 46 | ## [2023.7.0] 47 | 48 | ### Changed 49 | 50 | - Updated Bitrix CMS core 51 | - Update IntelliJ Platform 1.11.3 52 | 53 | ## [2023.6.0] 54 | 55 | ### Changed 56 | 57 | - Update IntelliJ Platform 1.10.0 58 | - Update IntelliJ Platform 1.11.0 59 | - Update IntelliJ Platform 1.11.2 60 | - Updated Bitrix CMS core 61 | 62 | ## [2023.5.0] 63 | 64 | ### Added 65 | 66 | - Module creating form 67 | - Template creating form 68 | - Simple component creating form 69 | - Add Bitrix Idea settings 70 | - Add localizations table to settings and create entity forms 71 | 72 | ### Changed 73 | 74 | - Add "Don't show again" action to startup notification 75 | - Update IntelliJ Platform 1.8.0 76 | - Update IntelliJ Platform 1.9.0 77 | 78 | ## [2023.4.0] 79 | 80 | ### Changed 81 | 82 | - Updated Plugin Core 83 | - Updated Bitrix CMS core 84 | 85 | ## [2023.3.0] 86 | 87 | ### Changed 88 | 89 | - Updated Plugin Core 90 | - Updated Bitrix CMS core 91 | 92 | ## [2023.2.0] 93 | 94 | ### Changed 95 | 96 | - Updated Plugin Core 97 | - Updated Bitrix CMS core 98 | 99 | ## [2023.1.0] 100 | 101 | ### Changed 102 | 103 | - Updated Plugin Core 104 | - Updated Bitrix CMS core -------------------------------------------------------------------------------- /LICENCE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Sergey Panteleev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bitrix Idea 2 | 3 | [![Version](http://phpstorm.espend.de/badge/14703/version)](https://plugins.jetbrains.com/plugin/14703) 4 | [![Downloads](http://phpstorm.espend.de/badge/14703/downloads)](https://plugins.jetbrains.com/plugin/14703) 5 | [![Rating](https://img.shields.io/jetbrains/plugin/r/rating/14703-bitrix-idea?style=flat-square)](https://plugins.jetbrains.com/plugin/14703) 6 | ![Build](https://github.com/saundefined/bitrix-idea/actions/workflows/test.yml/badge.svg) 7 | [![License](https://img.shields.io/github/license/saundefined/bitrix-idea?style=flat-square)](https://plugins.jetbrains.com/plugin/14703) 8 | 9 | 10 | Plugin for [PhpStorm](https://www.jetbrains.com/phpstorm) to help 11 | the developer navigate the Bitrix CMS core source code. 12 | 13 | 14 | | Key | Value | 15 | |------------|--------------------------------------------------------| 16 | | Plugin url | https://plugins.jetbrains.com/plugin/14703-bitrix-idea | 17 | | Id | ru.panteleev.bitrix-idea | 18 | | Changelog | [CHANGELOG](CHANGELOG.md) | 19 | 20 | ## Support us 21 | 22 | [](https://sergeypanteleev.com/ad/bitrix-idea) 23 | 24 | ## Installation 25 | 26 | To install, go to Settings > Plugins and search for "Bitrix Idea". 27 | 28 | ## Supported IDEs 29 | 30 | The plugin can be installed on following IntelliJ-based: 31 | 32 | * PhpStorm 2024.2+ 33 | 34 | ## Release versions schema 35 | 36 | | Plugin version number | Since Version | Until Version | 37 | |-----------------------|---------------|---------------| 38 | | v2025.1.x | 2024.2 | 2025.2 | 39 | | v2024.3.x | 2024.1 | 2024.3 | 40 | | v2024.2.x | 2023.2 | 2024.2 | 41 | | v2024.1.x | 2023.1 | 2024.1 | 42 | | v2023.7.x | 2022.3 | 2023.3 | 43 | | v2023.6.x | 2022.3 | 2023.3 | 44 | | v2023.5.x | 2022.2 | 2023.2 | 45 | | v2023.4.x | 2022.2 | 2023.2 | 46 | | v2023.3.x | 2021.3 | 2023.2 | 47 | | v2023.2.x | 2021.3 | 2023.1 | 48 | | v2023.1.x | 2021.3 | 2023.1 | 49 | 50 | ## License 51 | 52 | The plugin is distributed under MIT. 53 | For full license terms, see [LICENCE](LICENCE.md). 54 | 55 | ## Screenshots 56 | 57 | ![bitrix_idea phpstorm](https://plugins.jetbrains.com/files/14703/screenshot_22644.png) -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.changelog.Changelog 2 | import org.jetbrains.changelog.markdownToHTML 3 | import org.jetbrains.intellij.platform.gradle.TestFrameworkType 4 | 5 | plugins { 6 | id("java") // Java support 7 | alias(libs.plugins.kotlin) // Kotlin support 8 | alias(libs.plugins.intelliJPlatform) // IntelliJ Platform Gradle Plugin 9 | alias(libs.plugins.changelog) // Gradle Changelog Plugin 10 | alias(libs.plugins.qodana) // Gradle Qodana Plugin 11 | alias(libs.plugins.kover) // Gradle Kover Plugin 12 | } 13 | 14 | group = providers.gradleProperty("pluginGroup").get() 15 | version = providers.gradleProperty("pluginVersion").get() 16 | 17 | // Set the JVM language level used to build the project. 18 | kotlin { 19 | jvmToolchain(21) 20 | } 21 | 22 | // Configure project's dependencies 23 | repositories { 24 | mavenCentral() 25 | 26 | // IntelliJ Platform Gradle Plugin Repositories Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-repositories-extension.html 27 | intellijPlatform { 28 | defaultRepositories() 29 | } 30 | } 31 | 32 | // Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog 33 | dependencies { 34 | testImplementation(libs.junit) 35 | testImplementation(libs.opentest4j) 36 | 37 | // IntelliJ Platform Gradle Plugin Dependencies Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html 38 | intellijPlatform { 39 | create(providers.gradleProperty("platformType"), providers.gradleProperty("platformVersion")) 40 | 41 | // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins. 42 | bundledPlugins(providers.gradleProperty("platformBundledPlugins").map { it.split(',') }) 43 | 44 | // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file for plugin from JetBrains Marketplace. 45 | plugins(providers.gradleProperty("platformPlugins").map { it.split(',') }) 46 | 47 | testFramework(TestFrameworkType.Platform) 48 | } 49 | } 50 | 51 | // Configure IntelliJ Platform Gradle Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-extension.html 52 | intellijPlatform { 53 | pluginConfiguration { 54 | name = providers.gradleProperty("pluginName") 55 | version = providers.gradleProperty("pluginVersion") 56 | 57 | // Extract the section from README.md and provide for the plugin's manifest 58 | description = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map { 59 | val start = "" 60 | val end = "" 61 | 62 | with(it.lines()) { 63 | if (!containsAll(listOf(start, end))) { 64 | throw GradleException("Plugin description section not found in README.md:\n$start ... $end") 65 | } 66 | subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML) 67 | } 68 | } 69 | 70 | val changelog = project.changelog // local variable for configuration cache compatibility 71 | // Get the latest available change notes from the changelog file 72 | changeNotes = providers.gradleProperty("pluginVersion").map { pluginVersion -> 73 | with(changelog) { 74 | renderItem( 75 | (getOrNull(pluginVersion) ?: getUnreleased()) 76 | .withHeader(false) 77 | .withEmptySections(false), 78 | Changelog.OutputType.HTML, 79 | ) 80 | } 81 | } 82 | 83 | ideaVersion { 84 | sinceBuild = providers.gradleProperty("pluginSinceBuild") 85 | untilBuild = providers.gradleProperty("pluginUntilBuild") 86 | } 87 | } 88 | 89 | pluginVerification { 90 | freeArgs = listOf("-mute", "TemplateWordInPluginName") 91 | } 92 | 93 | signing { 94 | certificateChain = providers.environmentVariable("CERTIFICATE_CHAIN") 95 | privateKey = providers.environmentVariable("PRIVATE_KEY") 96 | password = providers.environmentVariable("PRIVATE_KEY_PASSWORD") 97 | } 98 | 99 | publishing { 100 | token = providers.environmentVariable("PUBLISH_TOKEN") 101 | // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 102 | // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: 103 | // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel 104 | channels = providers.gradleProperty("pluginVersion") 105 | .map { listOf(it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" }) } 106 | } 107 | 108 | pluginVerification { 109 | ides { 110 | recommended() 111 | } 112 | } 113 | } 114 | 115 | // Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin 116 | changelog { 117 | groups.empty() 118 | repositoryUrl = providers.gradleProperty("pluginRepositoryUrl") 119 | } 120 | 121 | // Configure Gradle Kover Plugin - read more: https://github.com/Kotlin/kotlinx-kover#configuration 122 | kover { 123 | reports { 124 | total { 125 | xml { 126 | onCheck = true 127 | } 128 | } 129 | } 130 | } 131 | 132 | tasks { 133 | wrapper { 134 | gradleVersion = providers.gradleProperty("gradleVersion").get() 135 | } 136 | 137 | publishPlugin { 138 | dependsOn(patchChangelog) 139 | } 140 | } 141 | 142 | intellijPlatformTesting { 143 | runIde { 144 | register("runIdeForUiTests") { 145 | task { 146 | jvmArgumentProviders += CommandLineArgumentProvider { 147 | listOf( 148 | "-Drobot-server.port=8082", 149 | "-Dide.mac.message.dialogs.as.sheets=false", 150 | "-Djb.privacy.policy.text=", 151 | "-Djb.consents.confirmation.enabled=false", 152 | ) 153 | } 154 | } 155 | 156 | plugins { 157 | robotServerPlugin() 158 | } 159 | } 160 | } 161 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | pluginGroup = ru.panteleev.bitrix-idea 2 | pluginName = Bitrix Idea 3 | pluginRepositoryUrl = https://github.com/saundefined/bitrix-idea 4 | pluginVersion = 2025.1.0 5 | pluginSinceBuild = 242 6 | pluginUntilBuild = 252.* 7 | platformType = IC 8 | platformVersion = 2024.2.5 9 | platformPlugins = 10 | platformBundledPlugins = 11 | gradleVersion = 8.13 12 | kotlin.stdlib.default.dependency = false 13 | org.gradle.configuration-cache = true 14 | org.gradle.caching = true 15 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | # libraries 3 | junit = "4.13.2" 4 | opentest4j = "1.3.0" 5 | 6 | # plugins 7 | changelog = "2.2.1" 8 | intelliJPlatform = "2.5.0" 9 | kotlin = "2.1.20" 10 | kover = "0.9.1" 11 | qodana = "2024.3.4" 12 | 13 | [libraries] 14 | junit = { group = "junit", name = "junit", version.ref = "junit" } 15 | opentest4j = { group = "org.opentest4j", name = "opentest4j", version.ref = "opentest4j" } 16 | 17 | [plugins] 18 | changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } 19 | intelliJPlatform = { id = "org.jetbrains.intellij.platform", version.ref = "intelliJPlatform" } 20 | kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } 21 | kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } 22 | qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saundefined/bitrix-idea/a832d063960ae3a0cea0f148ee024329f08cdfb4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | if ! command -v java >/dev/null 2>&1 137 | then 138 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 139 | 140 | Please set the JAVA_HOME variable in your environment to match the 141 | location of your Java installation." 142 | fi 143 | fi 144 | 145 | # Increase the maximum file descriptors if we can. 146 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 147 | case $MAX_FD in #( 148 | max*) 149 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 150 | # shellcheck disable=SC2039,SC3045 151 | MAX_FD=$( ulimit -H -n ) || 152 | warn "Could not query maximum file descriptor limit" 153 | esac 154 | case $MAX_FD in #( 155 | '' | soft) :;; #( 156 | *) 157 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 158 | # shellcheck disable=SC2039,SC3045 159 | ulimit -n "$MAX_FD" || 160 | warn "Could not set maximum file descriptor limit to $MAX_FD" 161 | esac 162 | fi 163 | 164 | # Collect all arguments for the java command, stacking in reverse order: 165 | # * args from the command line 166 | # * the main class name 167 | # * -classpath 168 | # * -D...appname settings 169 | # * --module-path (only if needed) 170 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 171 | 172 | # For Cygwin or MSYS, switch paths to Windows format before running java 173 | if "$cygwin" || "$msys" ; then 174 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 175 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 176 | 177 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 178 | 179 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 180 | for arg do 181 | if 182 | case $arg in #( 183 | -*) false ;; # don't mess with options #( 184 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 185 | [ -e "$t" ] ;; #( 186 | *) false ;; 187 | esac 188 | then 189 | arg=$( cygpath --path --ignore --mixed "$arg" ) 190 | fi 191 | # Roll the args list around exactly as many times as the number of 192 | # args, so each arg winds up back in the position where it started, but 193 | # possibly modified. 194 | # 195 | # NB: a `for` loop captures its iteration list before it begins, so 196 | # changing the positional parameters here affects neither the number of 197 | # iterations, nor the values presented in `arg`. 198 | shift # remove old arg 199 | set -- "$@" "$arg" # push replacement arg 200 | done 201 | fi 202 | 203 | 204 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 205 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 206 | 207 | # Collect all arguments for the java command: 208 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 209 | # and any embedded shellness will be escaped. 210 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 211 | # treated as '${Hostname}' itself on the command line. 212 | 213 | set -- \ 214 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 215 | -classpath "$CLASSPATH" \ 216 | org.gradle.wrapper.GradleWrapperMain \ 217 | "$@" 218 | 219 | # Stop when "xargs" is not available. 220 | if ! command -v xargs >/dev/null 2>&1 221 | then 222 | die "xargs is not available" 223 | fi 224 | 225 | # Use "xargs" to parse quoted args. 226 | # 227 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 228 | # 229 | # In Bash we could simply go: 230 | # 231 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 232 | # set -- "${ARGS[@]}" "$@" 233 | # 234 | # but POSIX shell has neither arrays nor command substitution, so instead we 235 | # post-process each arg (as a line of input to sed) to backslash-escape any 236 | # character that might be a shell metacharacter, then use eval to reverse 237 | # that process (while maintaining the separation between arguments), and wrap 238 | # the whole thing up as a single "set" statement. 239 | # 240 | # This will of course break if any of these variables contains a newline or 241 | # an unmatched quote. 242 | # 243 | 244 | eval "set -- $( 245 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 246 | xargs -n1 | 247 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 248 | tr '\n' ' ' 249 | )" '"$@"' 250 | 251 | exec "$JAVACMD" "$@" 252 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /qodana.yml: -------------------------------------------------------------------------------- 1 | # Qodana configuration: 2 | # https://www.jetbrains.com/help/qodana/qodana-yaml.html 3 | 4 | version: 1.0 5 | linter: jetbrains/qodana-jvm-community:latest 6 | projectJDK: "17" 7 | profile: 8 | name: qodana.recommended 9 | exclude: 10 | - name: All 11 | paths: 12 | - .qodana 13 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" 3 | } 4 | 5 | rootProject.name = "bitrix-idea" -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/BitrixIdeaBundle.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea 2 | 3 | import com.intellij.DynamicBundle 4 | import org.jetbrains.annotations.NonNls 5 | import org.jetbrains.annotations.PropertyKey 6 | 7 | @NonNls 8 | private const val BUNDLE = "messages.BitrixIdeaBundle" 9 | 10 | object BitrixIdeaBundle : DynamicBundle(BUNDLE) { 11 | @Suppress("SpreadOperator") 12 | @JvmStatic 13 | fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) = 14 | getMessage(key, *params) 15 | 16 | @Suppress("SpreadOperator", "unused") 17 | @JvmStatic 18 | fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) = 19 | getLazyMessage(key, *params) 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/actions/CreateGitignoreAction.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.actions 2 | 3 | import com.intellij.ide.fileTemplates.FileTemplateManager 4 | import com.intellij.ide.fileTemplates.FileTemplateUtil 5 | import com.intellij.ide.util.DirectoryChooserUtil 6 | import com.intellij.openapi.actionSystem.ActionUpdateThread 7 | import com.intellij.openapi.actionSystem.AnAction 8 | import com.intellij.openapi.actionSystem.AnActionEvent 9 | import com.intellij.openapi.actionSystem.LangDataKeys 10 | import com.intellij.openapi.application.ApplicationManager 11 | import com.intellij.openapi.project.Project 12 | import org.jetbrains.annotations.NotNull 13 | 14 | class CreateGitignoreAction : AnAction() { 15 | override fun actionPerformed(@NotNull event: AnActionEvent) { 16 | val view = event.getData(LangDataKeys.IDE_VIEW) 17 | if (view === null) { 18 | return 19 | } 20 | 21 | val project: Project? = event.project 22 | if (project === null) { 23 | return 24 | } 25 | 26 | val directory = DirectoryChooserUtil.getOrChooseDirectory(view) 27 | if (directory === null) { 28 | return 29 | } 30 | 31 | val templateManager = FileTemplateManager.getInstance(project) 32 | 33 | ApplicationManager.getApplication().runWriteAction { 34 | try { 35 | val template = templateManager.getJ2eeTemplate("Bitrix Module .gitignore") 36 | FileTemplateUtil.createFromTemplate(template, ".gitignore", null, directory) 37 | } catch (e: Exception) { 38 | e.printStackTrace() 39 | } 40 | } 41 | } 42 | 43 | override fun getActionUpdateThread(): ActionUpdateThread { 44 | return ActionUpdateThread.EDT 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/actions/CreateModuleAction.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.actions 2 | 3 | import com.github.saundefined.bitrix_idea.dialogs.CreateModuleDialogWrapper 4 | import com.intellij.ide.util.DirectoryChooserUtil 5 | import com.intellij.openapi.actionSystem.ActionUpdateThread 6 | import com.intellij.openapi.actionSystem.AnAction 7 | import com.intellij.openapi.actionSystem.AnActionEvent 8 | import com.intellij.openapi.actionSystem.LangDataKeys 9 | import com.intellij.openapi.project.Project 10 | import org.jetbrains.annotations.NotNull 11 | 12 | class CreateModuleAction : AnAction() { 13 | override fun actionPerformed(@NotNull event: AnActionEvent) { 14 | val view = event.getData(LangDataKeys.IDE_VIEW) 15 | if (view === null) { 16 | return 17 | } 18 | 19 | val project: Project? = event.project 20 | if (project === null) { 21 | return 22 | } 23 | 24 | val directory = DirectoryChooserUtil.getOrChooseDirectory(view) 25 | if (directory === null) { 26 | return 27 | } 28 | 29 | 30 | val dialogWrapper = CreateModuleDialogWrapper() 31 | dialogWrapper.view = view 32 | dialogWrapper.project = project 33 | dialogWrapper.directory = directory 34 | dialogWrapper.showAndGet() 35 | } 36 | 37 | override fun getActionUpdateThread(): ActionUpdateThread { 38 | return ActionUpdateThread.EDT 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/actions/CreateSimpleComponentAction.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.actions 2 | 3 | import com.github.saundefined.bitrix_idea.dialogs.CreateSimpleComponentDialogWrapper 4 | import com.intellij.ide.util.DirectoryChooserUtil 5 | import com.intellij.openapi.actionSystem.ActionUpdateThread 6 | import com.intellij.openapi.actionSystem.AnAction 7 | import com.intellij.openapi.actionSystem.AnActionEvent 8 | import com.intellij.openapi.actionSystem.LangDataKeys 9 | import com.intellij.openapi.project.Project 10 | import org.jetbrains.annotations.NotNull 11 | 12 | 13 | class CreateSimpleComponentAction : AnAction() { 14 | override fun actionPerformed(@NotNull event: AnActionEvent) { 15 | val view = event.getData(LangDataKeys.IDE_VIEW) 16 | if (view === null) { 17 | return 18 | } 19 | 20 | val project: Project? = event.project 21 | if (project === null) { 22 | return 23 | } 24 | 25 | val directory = DirectoryChooserUtil.getOrChooseDirectory(view) 26 | if (directory === null) { 27 | return 28 | } 29 | 30 | val dialogWrapper = CreateSimpleComponentDialogWrapper() 31 | dialogWrapper.view = view 32 | dialogWrapper.project = project 33 | dialogWrapper.directory = directory 34 | dialogWrapper.showAndGet() 35 | } 36 | 37 | override fun getActionUpdateThread(): ActionUpdateThread { 38 | return ActionUpdateThread.EDT 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/actions/CreateTemplateAction.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.actions 2 | 3 | import com.github.saundefined.bitrix_idea.dialogs.CreateTemplateDialogWrapper 4 | import com.intellij.ide.util.DirectoryChooserUtil 5 | import com.intellij.openapi.actionSystem.ActionUpdateThread 6 | import com.intellij.openapi.actionSystem.AnAction 7 | import com.intellij.openapi.actionSystem.AnActionEvent 8 | import com.intellij.openapi.actionSystem.LangDataKeys 9 | import com.intellij.openapi.project.Project 10 | import org.jetbrains.annotations.NotNull 11 | 12 | class CreateTemplateAction : AnAction() { 13 | override fun actionPerformed(@NotNull event: AnActionEvent) { 14 | val view = event.getData(LangDataKeys.IDE_VIEW) 15 | if (view === null) { 16 | return 17 | } 18 | 19 | val project: Project? = event.project 20 | if (project === null) { 21 | return 22 | } 23 | 24 | val directory = DirectoryChooserUtil.getOrChooseDirectory(view) 25 | if (directory === null) { 26 | return 27 | } 28 | 29 | val dialogWrapper = CreateTemplateDialogWrapper() 30 | dialogWrapper.view = view 31 | dialogWrapper.project = project 32 | dialogWrapper.directory = directory 33 | dialogWrapper.showAndGet() 34 | } 35 | 36 | override fun getActionUpdateThread(): ActionUpdateThread { 37 | return ActionUpdateThread.EDT 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/activity/NotificationStartupActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.activity 2 | 3 | import com.github.saundefined.bitrix_idea.BitrixIdeaBundle.message 4 | import com.intellij.notification.* 5 | import com.intellij.openapi.actionSystem.AnActionEvent 6 | import com.intellij.openapi.application.ApplicationManager 7 | import com.intellij.openapi.project.Project 8 | import com.intellij.openapi.startup.StartupActivity 9 | import org.jetbrains.annotations.NotNull 10 | import java.awt.* 11 | import java.io.IOException 12 | import java.net.URI 13 | import java.net.URISyntaxException 14 | 15 | class NotificationStartupActivity : StartupActivity { 16 | 17 | @NotNull 18 | private val NOTIFICATION_GROUP = "Bitrix Idea Plugin" 19 | 20 | private val GITHUB_URL = "https://github.com/saundefined/bitrix-idea" 21 | 22 | override fun runActivity(project: Project) { 23 | val app = ApplicationManager.getApplication() 24 | app.invokeLater { 25 | val notification = 26 | Notification(NOTIFICATION_GROUP, message("startup.notification.title"), NotificationType.IDE_UPDATE) 27 | notification.addAction(object : 28 | NotificationAction(message("startup.notification.action")) { 29 | override fun actionPerformed(e: AnActionEvent, notification: Notification) { 30 | openUrl(GITHUB_URL) 31 | } 32 | }) 33 | 34 | notification.addAction(object : NotificationAction(message("startup.notification.dismiss")) { 35 | override fun actionPerformed(e: AnActionEvent, notification: Notification) { 36 | val notificationSettings = NotificationsConfiguration.getNotificationsConfiguration() 37 | notificationSettings.changeSettings( 38 | NOTIFICATION_GROUP, 39 | NotificationDisplayType.NONE, 40 | false, 41 | false 42 | ) 43 | notification.expire() 44 | } 45 | }) 46 | 47 | Notifications.Bus.notify(notification) 48 | } 49 | } 50 | 51 | private fun openUrl(url: String) { 52 | if (Desktop.isDesktopSupported()) { 53 | val desktop: Desktop = Desktop.getDesktop() 54 | if (desktop.isSupported(Desktop.Action.BROWSE)) { 55 | try { 56 | val uri = URI(url) 57 | desktop.browse(uri) 58 | } catch (ignored: URISyntaxException) { 59 | } catch (ignored: IOException) { 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/dialogs/CreateModuleDialogWrapper.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.dialogs 2 | 3 | import com.github.saundefined.bitrix_idea.BitrixIdeaBundle.message 4 | import com.github.saundefined.bitrix_idea.settings.AppSettingsState 5 | import com.github.saundefined.bitrix_idea.validation.ModuleCodeVerifier 6 | import com.github.saundefined.bitrix_idea.validation.UrlVerifier 7 | import com.intellij.ide.IdeView 8 | import com.intellij.ide.fileTemplates.FileTemplateManager 9 | import com.intellij.ide.fileTemplates.FileTemplateUtil 10 | import com.intellij.openapi.application.ApplicationManager 11 | import com.intellij.openapi.project.Project 12 | import com.intellij.openapi.ui.DialogWrapper 13 | import com.intellij.psi.PsiDirectory 14 | import com.intellij.ui.ScrollPaneFactory 15 | import com.intellij.ui.dsl.builder.* 16 | import com.intellij.ui.dsl.gridLayout.HorizontalAlign 17 | import com.intellij.ui.dsl.gridLayout.VerticalAlign 18 | import com.intellij.ui.table.JBTable 19 | import java.awt.* 20 | import java.util.* 21 | import javax.swing.* 22 | import javax.swing.table.DefaultTableModel 23 | import javax.swing.table.JTableHeader 24 | 25 | class CreateModuleDialogWrapper : DialogWrapper(true) { 26 | val settings: AppSettingsState 27 | get() = AppSettingsState().getInstance() 28 | 29 | var code: String = "" 30 | var name: String = "" 31 | var description: String = "" 32 | var vendor: String = "" 33 | var url: String = "" 34 | var languages: List = settings.languages 35 | 36 | lateinit var view: IdeView 37 | lateinit var project: Project 38 | lateinit var directory: PsiDirectory 39 | 40 | init { 41 | init() 42 | title = message("create.module.form.title") 43 | } 44 | 45 | override fun createCenterPanel(): JComponent { 46 | val tableModel = object : DefaultTableModel( 47 | languages.map { arrayOf(it) }.toTypedArray(), 48 | arrayOf(message("localization.table.column.name")) 49 | ) { 50 | override fun isCellEditable(row: Int, column: Int): Boolean { 51 | return false 52 | } 53 | } 54 | 55 | val table = JBTable(tableModel) 56 | .apply { 57 | tableHeader = JTableHeader(this.columnModel).apply { 58 | resizingAllowed = false 59 | reorderingAllowed = false 60 | } 61 | } 62 | 63 | val buttonDimension = Dimension(24, 24) 64 | 65 | val addButton = JButton("+").apply { 66 | preferredSize = buttonDimension 67 | minimumSize = buttonDimension 68 | maximumSize = buttonDimension 69 | 70 | addActionListener { 71 | val result = 72 | JOptionPane.showInputDialog( 73 | null, 74 | message("localization.add"), 75 | message("localization.add.title"), 76 | JOptionPane.QUESTION_MESSAGE, 77 | ) 78 | 79 | if (!result.isNullOrEmpty()) { 80 | tableModel.addRow(arrayOf(result)) 81 | languages = tableModel.dataVector.map { (it as Vector<*>)[0].toString() } 82 | } 83 | 84 | this@CreateModuleDialogWrapper.pack() 85 | } 86 | } 87 | 88 | val removeButton = JButton("-").apply { 89 | preferredSize = buttonDimension 90 | minimumSize = buttonDimension 91 | maximumSize = buttonDimension 92 | 93 | addActionListener { 94 | if (table.selectedRow != -1 && tableModel.rowCount > 1) { 95 | tableModel.removeRow(table.selectedRow) 96 | languages = tableModel.dataVector.map { (it as Vector<*>)[0].toString() } 97 | } 98 | 99 | this@CreateModuleDialogWrapper.pack() 100 | } 101 | } 102 | 103 | val btnPanel = JPanel().apply { 104 | layout = BoxLayout(this, BoxLayout.Y_AXIS) 105 | 106 | add(addButton) 107 | add(removeButton) 108 | } 109 | 110 | val wrapperPanel = JPanel(BorderLayout()) 111 | wrapperPanel.add(btnPanel, BorderLayout.LINE_END) 112 | wrapperPanel.add(ScrollPaneFactory.createScrollPane(table), BorderLayout.CENTER) 113 | 114 | return panel { 115 | row { 116 | label(message("create.module.code")) 117 | textField() 118 | .bindText(::code) 119 | .focused() 120 | .text(settings.vendorCode + ".") 121 | .align(AlignX.FILL) 122 | .validationOnApply { 123 | val value = it.text 124 | when { 125 | ModuleCodeVerifier().verify(value) 126 | .not() -> error(message("create.module.code.validation.fail")) 127 | 128 | else -> null 129 | } 130 | } 131 | 132 | label(message("create.module.name")) 133 | textField() 134 | .bindText(::name) 135 | .align(AlignX.FILL) 136 | .validationOnApply { 137 | val value = it.text 138 | when { 139 | value === null -> error(message("create.module.name.validation.fail")) 140 | else -> null 141 | } 142 | } 143 | }.layout(RowLayout.PARENT_GRID) 144 | 145 | row(message("create.module.description")) { 146 | textField() 147 | .bindText(::description) 148 | .align(AlignX.FILL) 149 | .validationOnApply { 150 | val value = it.text 151 | when { 152 | value === null -> error(message("create.module.description.validation.fail")) 153 | else -> null 154 | } 155 | } 156 | }.layout(RowLayout.PARENT_GRID) 157 | 158 | row { 159 | label(message("create.module.vendor")) 160 | textField() 161 | .bindText(::vendor) 162 | .text(settings.vendorName) 163 | .align(AlignX.FILL) 164 | .validationOnApply { 165 | val value = it.text 166 | when { 167 | value === null -> error(message("create.module.vendor.validation.fail")) 168 | else -> null 169 | } 170 | } 171 | 172 | label(message("create.module.url")) 173 | textField() 174 | .bindText(::url) 175 | .text(settings.vendorWebsite) 176 | .align(AlignX.FILL) 177 | .validationOnApply { 178 | val value = it.text 179 | when { 180 | UrlVerifier().verify(value) 181 | .not() -> error(message("create.module.url.validation.fail")) 182 | 183 | else -> null 184 | } 185 | } 186 | }.layout(RowLayout.PARENT_GRID) 187 | 188 | row { 189 | label(message("localization.table.row.name")) 190 | .align(AlignY.TOP) 191 | cell(wrapperPanel) 192 | .align(AlignX.FILL) 193 | } 194 | .layout(RowLayout.PARENT_GRID) 195 | } 196 | } 197 | 198 | override fun doOKAction() { 199 | super.applyFields() 200 | 201 | val templateManager = FileTemplateManager.getInstance(project) 202 | 203 | val properties: Properties = FileTemplateManager.getInstance(project).defaultProperties 204 | properties.setProperty("DEFAULT_MODULE_NAME", code) 205 | properties.setProperty("SNACK_CASED_MODULE_NAME", code.replace(".", "_")) 206 | properties.setProperty("UPPER_CASED_MODULE_NAME", code.replace(".", "_").uppercase(Locale.getDefault())) 207 | 208 | properties.setProperty("MODULE_NAME", name) 209 | properties.setProperty("MODULE_DESCRIPTION", description) 210 | properties.setProperty("PARTNER_NAME", vendor) 211 | properties.setProperty("PARTNER_URI", url) 212 | 213 | ApplicationManager.getApplication().runWriteAction { 214 | try { 215 | val moduleDirectory = directory.createSubdirectory(code) 216 | 217 | val rootFileNames = 218 | listOf("prolog.php", "options.php", "include.php", "default_option.php", ".settings.php") 219 | 220 | rootFileNames.forEach { fileName -> 221 | val template = templateManager.getJ2eeTemplate("Bitrix Module $fileName") 222 | FileTemplateUtil.createFromTemplate(template, fileName, properties, moduleDirectory) 223 | } 224 | 225 | val installDirectory = moduleDirectory.createSubdirectory("install") 226 | 227 | val installFileNames = listOf("index.php", "version.php") 228 | installFileNames.forEach { fileName -> 229 | val template = templateManager.getJ2eeTemplate("Bitrix Module install $fileName") 230 | FileTemplateUtil.createFromTemplate(template, fileName, properties, installDirectory) 231 | } 232 | 233 | val langDirectory = moduleDirectory.createSubdirectory("lang") 234 | languages.forEach { language -> 235 | val langInstallDirectory = langDirectory.createSubdirectory(language).createSubdirectory("install") 236 | installFileNames.filter { fileName -> fileName !== "version.php" }.forEach { fileName -> 237 | val template = templateManager.getJ2eeTemplate("Bitrix Module language install $fileName") 238 | FileTemplateUtil.createFromTemplate(template, fileName, properties, langInstallDirectory) 239 | } 240 | } 241 | } catch (e: Exception) { 242 | e.printStackTrace() 243 | } 244 | } 245 | 246 | super.doOKAction() 247 | } 248 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/dialogs/CreateSimpleComponentDialogWrapper.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.dialogs 2 | 3 | import com.github.saundefined.bitrix_idea.BitrixIdeaBundle.message 4 | import com.github.saundefined.bitrix_idea.settings.AppSettingsState 5 | import com.github.saundefined.bitrix_idea.validation.ComponentSimpleCodeVerifier 6 | import com.intellij.ide.IdeView 7 | import com.intellij.ide.fileTemplates.FileTemplateManager 8 | import com.intellij.ide.fileTemplates.FileTemplateUtil 9 | import com.intellij.openapi.application.ApplicationManager 10 | import com.intellij.openapi.project.Project 11 | import com.intellij.openapi.ui.DialogWrapper 12 | import com.intellij.psi.PsiDirectory 13 | import com.intellij.ui.ScrollPaneFactory 14 | import com.intellij.ui.dsl.builder.* 15 | import com.intellij.ui.dsl.gridLayout.HorizontalAlign 16 | import com.intellij.ui.dsl.gridLayout.VerticalAlign 17 | import com.intellij.ui.table.JBTable 18 | import java.awt.BorderLayout 19 | import java.awt.Dimension 20 | import java.util.* 21 | import javax.swing.* 22 | import javax.swing.table.DefaultTableModel 23 | import javax.swing.table.JTableHeader 24 | 25 | class CreateSimpleComponentDialogWrapper : DialogWrapper(true) { 26 | val settings: AppSettingsState 27 | get() = AppSettingsState().getInstance() 28 | 29 | var code: String = "" 30 | var name: String = "" 31 | var description: String = "" 32 | var languages: List = settings.languages 33 | 34 | lateinit var view: IdeView 35 | lateinit var project: Project 36 | lateinit var directory: PsiDirectory 37 | 38 | init { 39 | init() 40 | title = message("create.component.simple.form.title") 41 | } 42 | 43 | override fun createCenterPanel(): JComponent { 44 | val tableModel = object : DefaultTableModel( 45 | languages.map { arrayOf(it) }.toTypedArray(), 46 | arrayOf(message("localization.table.column.name")) 47 | ) { 48 | override fun isCellEditable(row: Int, column: Int): Boolean { 49 | return false 50 | } 51 | } 52 | 53 | val table = JBTable(tableModel) 54 | .apply { 55 | tableHeader = JTableHeader(this.columnModel).apply { 56 | resizingAllowed = false 57 | reorderingAllowed = false 58 | } 59 | } 60 | 61 | val buttonDimension = Dimension(24, 24) 62 | 63 | val addButton = JButton("+").apply { 64 | preferredSize = buttonDimension 65 | minimumSize = buttonDimension 66 | maximumSize = buttonDimension 67 | 68 | addActionListener { 69 | val result = 70 | JOptionPane.showInputDialog( 71 | null, 72 | message("localization.add"), 73 | message("localization.add.title"), 74 | JOptionPane.QUESTION_MESSAGE, 75 | ) 76 | 77 | if (!result.isNullOrEmpty()) { 78 | tableModel.addRow(arrayOf(result)) 79 | languages = tableModel.dataVector.map { (it as Vector<*>)[0].toString() } 80 | } 81 | 82 | this@CreateSimpleComponentDialogWrapper.pack() 83 | } 84 | } 85 | 86 | val removeButton = JButton("-").apply { 87 | preferredSize = buttonDimension 88 | minimumSize = buttonDimension 89 | maximumSize = buttonDimension 90 | 91 | addActionListener { 92 | if (table.selectedRow != -1 && tableModel.rowCount > 1) { 93 | tableModel.removeRow(table.selectedRow) 94 | languages = tableModel.dataVector.map { (it as Vector<*>)[0].toString() } 95 | } 96 | 97 | this@CreateSimpleComponentDialogWrapper.pack() 98 | } 99 | } 100 | 101 | val btnPanel = JPanel().apply { 102 | layout = BoxLayout(this, BoxLayout.Y_AXIS) 103 | 104 | add(addButton) 105 | add(removeButton) 106 | } 107 | 108 | val wrapperPanel = JPanel(BorderLayout()) 109 | wrapperPanel.add(btnPanel, BorderLayout.LINE_END) 110 | wrapperPanel.add(ScrollPaneFactory.createScrollPane(table), BorderLayout.CENTER) 111 | 112 | return panel { 113 | row { 114 | label(message("create.component.simple.code")) 115 | textField() 116 | .bindText(::code) 117 | .focused() 118 | .align(AlignX.FILL) 119 | .validationOnApply { 120 | val value = it.text 121 | when { 122 | ComponentSimpleCodeVerifier().verify(value) 123 | .not() -> error(message("create.component.simple.code.validation.fail")) 124 | 125 | else -> null 126 | } 127 | } 128 | 129 | label(message("create.component.simple.name")) 130 | textField() 131 | .bindText(::name) 132 | .align(AlignX.FILL) 133 | .validationOnApply { 134 | val value = it.text 135 | when { 136 | value === null -> error(message("create.component.simple.name.validation.fail")) 137 | else -> null 138 | } 139 | } 140 | 141 | }.layout(RowLayout.PARENT_GRID) 142 | 143 | row(message("create.component.simple.description")) { 144 | textField() 145 | .bindText(::description) 146 | .align(AlignX.FILL) 147 | .validationOnApply { 148 | val value = it.text 149 | when { 150 | value === null -> error(message("create.component.simple.description.validation.fail")) 151 | else -> null 152 | } 153 | } 154 | }.layout(RowLayout.PARENT_GRID) 155 | 156 | row { 157 | label(message("localization.table.row.name")) 158 | .align(AlignY.TOP) 159 | cell(wrapperPanel) 160 | .align(AlignX.FILL) 161 | } 162 | .layout(RowLayout.PARENT_GRID) 163 | } 164 | } 165 | 166 | override fun doOKAction() { 167 | super.applyFields() 168 | 169 | val templateManager = FileTemplateManager.getInstance(project) 170 | 171 | val properties: Properties = FileTemplateManager.getInstance(project).defaultProperties 172 | 173 | properties.setProperty("UPPERCASE_COMPONENT_NAME", code.replace(".", "_").uppercase(Locale.getDefault())) 174 | properties.setProperty( 175 | "CAMEL_COMPONENT_NAME", 176 | code.replace(".", "_").split("_").joinToString("") { it -> 177 | it.replaceFirstChar { 178 | if (it.isLowerCase()) it.titlecase( 179 | Locale.getDefault() 180 | ) else it.toString() 181 | } 182 | } 183 | ) 184 | properties.setProperty("COMPONENT_NAME", name) 185 | properties.setProperty("COMPONENT_DESCRIPTION", description) 186 | 187 | ApplicationManager.getApplication().runWriteAction { 188 | try { 189 | val componentDirectory = directory.createSubdirectory(code) 190 | 191 | val rootFileNames = listOf(".description.php", ".parameters.php", "class.php") 192 | rootFileNames.forEach { fileName -> 193 | val template = templateManager.getJ2eeTemplate("Bitrix Simple Component $fileName") 194 | FileTemplateUtil.createFromTemplate(template, fileName, properties, componentDirectory) 195 | } 196 | 197 | val templatesDirectory = componentDirectory.createSubdirectory("templates") 198 | val defaultTemplateDirectory = templatesDirectory.createSubdirectory(".default") 199 | 200 | val defaultTemplateDirectoryTemplate = 201 | templateManager.getJ2eeTemplate("Bitrix Simple Component templates default template.php") 202 | FileTemplateUtil.createFromTemplate( 203 | defaultTemplateDirectoryTemplate, 204 | "template.php", 205 | properties, 206 | defaultTemplateDirectory 207 | ) 208 | 209 | val langDirectory = componentDirectory.createSubdirectory("lang") 210 | languages.forEach { language -> 211 | val langInstallDirectory = langDirectory.createSubdirectory(language) 212 | rootFileNames 213 | .filter { fileName -> fileName !== "class.php" } 214 | .forEach { fileName -> 215 | val template = templateManager.getJ2eeTemplate("Bitrix Simple Component language $fileName") 216 | FileTemplateUtil.createFromTemplate(template, fileName, properties, langInstallDirectory) 217 | } 218 | 219 | val languageTemplatesDirectory = 220 | langInstallDirectory.createSubdirectory("templates") 221 | val languageDefaultTemplateDirectory = 222 | languageTemplatesDirectory.createSubdirectory(".default") 223 | 224 | val languageDefaultTemplateDirectoryTemplate = 225 | templateManager.getJ2eeTemplate("Bitrix Simple Component language templates default template.php") 226 | FileTemplateUtil.createFromTemplate( 227 | languageDefaultTemplateDirectoryTemplate, 228 | "template.php", 229 | properties, 230 | languageDefaultTemplateDirectory 231 | ) 232 | } 233 | 234 | } catch (e: Exception) { 235 | e.printStackTrace() 236 | } 237 | } 238 | 239 | super.doOKAction() 240 | } 241 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/dialogs/CreateTemplateDialogWrapper.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.dialogs 2 | 3 | import com.github.saundefined.bitrix_idea.BitrixIdeaBundle.message 4 | import com.github.saundefined.bitrix_idea.validation.TemplateCodeVerifier 5 | import com.intellij.ide.IdeView 6 | import com.intellij.ide.fileTemplates.FileTemplateManager 7 | import com.intellij.ide.fileTemplates.FileTemplateUtil 8 | import com.intellij.openapi.application.ApplicationManager 9 | import com.intellij.openapi.project.Project 10 | import com.intellij.openapi.ui.DialogWrapper 11 | import com.intellij.psi.PsiDirectory 12 | import com.intellij.ui.dsl.builder.AlignX 13 | import com.intellij.ui.dsl.builder.RowLayout 14 | import com.intellij.ui.dsl.builder.bindText 15 | import com.intellij.ui.dsl.builder.panel 16 | import com.intellij.ui.dsl.gridLayout.HorizontalAlign 17 | import java.util.* 18 | import javax.swing.JComponent 19 | 20 | class CreateTemplateDialogWrapper : DialogWrapper(true) { 21 | var code: String = "" 22 | var name: String = "" 23 | var description: String = "" 24 | 25 | lateinit var view: IdeView 26 | lateinit var project: Project 27 | lateinit var directory: PsiDirectory 28 | 29 | init { 30 | init() 31 | title = message("create.template.form.title") 32 | } 33 | 34 | override fun createCenterPanel(): JComponent { 35 | return panel { 36 | row { 37 | label(message("create.template.code")) 38 | textField() 39 | .bindText(::code) 40 | .focused() 41 | .align(AlignX.FILL) 42 | .validationOnApply { 43 | val value = it.text 44 | when { 45 | TemplateCodeVerifier().verify(value) 46 | .not() -> error(message("create.template.code.validation.fail")) 47 | 48 | else -> null 49 | } 50 | } 51 | 52 | label(message("create.template.name")) 53 | textField() 54 | .bindText(::name) 55 | .align(AlignX.FILL) 56 | .validationOnApply { 57 | val value = it.text 58 | when { 59 | value === null -> error(message("create.template.name.validation.fail")) 60 | else -> null 61 | } 62 | } 63 | }.layout(RowLayout.PARENT_GRID) 64 | 65 | row(message("create.template.description")) { 66 | textField() 67 | .bindText(::description) 68 | .align(AlignX.FILL) 69 | }.layout(RowLayout.PARENT_GRID) 70 | } 71 | } 72 | 73 | override fun doOKAction() { 74 | super.applyFields() 75 | 76 | val templateManager = FileTemplateManager.getInstance(project) 77 | 78 | val properties: Properties = FileTemplateManager.getInstance(project).defaultProperties 79 | properties.setProperty("TEMPLATE_NAME", name) 80 | properties.setProperty("TEMPLATE_DESCRIPTION", description) 81 | 82 | ApplicationManager.getApplication().runWriteAction { 83 | try { 84 | val templateDirectory = directory.createSubdirectory(code) 85 | 86 | val fileNames = listOf( 87 | ".styles.php", "description.php", "footer.php", "header.php", "styles.css", "template_styles.css" 88 | ) 89 | 90 | fileNames.forEach { fileName -> 91 | val template = templateManager.getJ2eeTemplate("Bitrix Template $fileName") 92 | FileTemplateUtil.createFromTemplate(template, fileName, properties, templateDirectory) 93 | } 94 | } catch (e: Exception) { 95 | e.printStackTrace() 96 | } 97 | } 98 | 99 | super.doOKAction() 100 | } 101 | 102 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/settings/AppSettingsState.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.settings 2 | 3 | import com.intellij.openapi.application.ApplicationManager 4 | import com.intellij.openapi.components.PersistentStateComponent 5 | import com.intellij.openapi.components.State 6 | import com.intellij.openapi.components.Storage 7 | import com.intellij.util.xmlb.XmlSerializerUtil 8 | import org.jetbrains.annotations.NotNull 9 | import org.jetbrains.annotations.Nullable 10 | 11 | 12 | @State( 13 | name = "com.github.saundefined.bitrix_idea.settings.AppSettingsState", 14 | storages = [Storage("TestBitrixIdeaSettingsPlugin.xml")] 15 | ) 16 | class AppSettingsState : PersistentStateComponent { 17 | var vendorCode: String = "" 18 | var vendorName: String = "" 19 | var vendorWebsite: String = "" 20 | var languages: List = listOf("ru") 21 | 22 | @Nullable 23 | override fun getState(): AppSettingsState { 24 | return this 25 | } 26 | 27 | override fun loadState(@NotNull state: AppSettingsState) { 28 | XmlSerializerUtil.copyBean(state, this) 29 | } 30 | 31 | fun getInstance(): AppSettingsState { 32 | return ApplicationManager.getApplication() 33 | .getService(AppSettingsState::class.java) 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/settings/ApplicationSettingsConfigurable.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.settings 2 | 3 | import com.github.saundefined.bitrix_idea.BitrixIdeaBundle.message 4 | import com.intellij.openapi.options.Configurable 5 | import com.intellij.openapi.ui.DialogPanel 6 | import com.intellij.ui.ScrollPaneFactory 7 | import com.intellij.ui.dsl.builder.* 8 | import com.intellij.ui.dsl.gridLayout.HorizontalAlign 9 | import com.intellij.ui.dsl.gridLayout.VerticalAlign 10 | import com.intellij.ui.table.JBTable 11 | import java.awt.BorderLayout 12 | import java.awt.Dimension 13 | import java.util.* 14 | import javax.swing.* 15 | import javax.swing.table.DefaultTableModel 16 | import javax.swing.table.JTableHeader 17 | 18 | class ApplicationSettingsConfigurable : Configurable { 19 | val settings: AppSettingsState 20 | get() = AppSettingsState().getInstance() 21 | 22 | lateinit var panel: DialogPanel 23 | 24 | override fun createComponent(): JComponent { 25 | val tableModel = object : DefaultTableModel( 26 | settings.languages.map { arrayOf(it) }.toTypedArray(), 27 | arrayOf(message("localization.table.column.name")) 28 | ) { 29 | override fun isCellEditable(row: Int, column: Int): Boolean { 30 | return false 31 | } 32 | } 33 | 34 | val table = JBTable(tableModel) 35 | .apply { 36 | tableHeader = JTableHeader(this.columnModel).apply { 37 | resizingAllowed = false 38 | reorderingAllowed = false 39 | } 40 | } 41 | 42 | val buttonDimension = Dimension(24, 24) 43 | 44 | val addButton = JButton("+").apply { 45 | preferredSize = buttonDimension 46 | minimumSize = buttonDimension 47 | maximumSize = buttonDimension 48 | 49 | addActionListener { 50 | val result = 51 | JOptionPane.showInputDialog( 52 | null, 53 | message("localization.add"), 54 | message("localization.add.title"), 55 | JOptionPane.QUESTION_MESSAGE, 56 | ) 57 | 58 | if (!result.isNullOrEmpty()) { 59 | tableModel.addRow(arrayOf(result)) 60 | settings.languages = tableModel.dataVector.map { (it as Vector<*>)[0].toString() } 61 | } 62 | } 63 | } 64 | 65 | val removeButton = JButton("-").apply { 66 | preferredSize = buttonDimension 67 | minimumSize = buttonDimension 68 | maximumSize = buttonDimension 69 | 70 | addActionListener { 71 | if (table.selectedRow != -1 && tableModel.rowCount > 1) { 72 | tableModel.removeRow(table.selectedRow) 73 | settings.languages = tableModel.dataVector.map { (it as Vector<*>)[0].toString() } 74 | } 75 | } 76 | } 77 | 78 | val btnPanel = JPanel().apply { 79 | layout = BoxLayout(this, BoxLayout.Y_AXIS) 80 | 81 | add(addButton) 82 | add(removeButton) 83 | } 84 | 85 | val wrapperPanel = JPanel(BorderLayout()) 86 | wrapperPanel.add(btnPanel, BorderLayout.LINE_END) 87 | wrapperPanel.add(ScrollPaneFactory.createScrollPane(table), BorderLayout.CENTER) 88 | 89 | panel = panel { 90 | collapsibleGroup(message("settings.vendor.group"), false) { 91 | row(message("settings.vendor.code")) { 92 | textField() 93 | .bindText(settings::vendorCode) 94 | .align(AlignX.FILL) 95 | }.layout(RowLayout.PARENT_GRID) 96 | 97 | row(message("settings.vendor.name")) { 98 | textField() 99 | .bindText(settings::vendorName) 100 | .align(AlignX.FILL) 101 | }.layout(RowLayout.PARENT_GRID) 102 | 103 | row(message("settings.vendor.website")) { 104 | textField() 105 | .bindText(settings::vendorWebsite) 106 | .align(AlignX.FILL) 107 | }.layout(RowLayout.PARENT_GRID) 108 | } 109 | .expanded = true 110 | 111 | collapsibleGroup(message("settings.localizations.group"), false) { 112 | row { 113 | label(message("localization.table.row.name")) 114 | .align(AlignY.TOP) 115 | cell(wrapperPanel) 116 | .align(AlignX.FILL) 117 | } 118 | .layout(RowLayout.PARENT_GRID) 119 | } 120 | } 121 | 122 | return panel 123 | } 124 | 125 | override fun isModified(): Boolean { 126 | return panel.isModified() 127 | } 128 | 129 | override fun apply() { 130 | return panel.apply() 131 | } 132 | 133 | override fun reset() { 134 | return panel.reset() 135 | } 136 | 137 | override fun getDisplayName(): String { 138 | return "Bitrix Idea" 139 | } 140 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/templates/gitignore/BitrixModuleFileTemplateGroupFactory.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.templates.gitignore 2 | 3 | import icons.BitrixIdeaIcons 4 | import com.intellij.ide.fileTemplates.FileTemplateDescriptor 5 | import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor 6 | import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory 7 | 8 | class BitrixModuleFileTemplateGroupFactory : FileTemplateGroupDescriptorFactory { 9 | override fun getFileTemplatesDescriptor(): FileTemplateGroupDescriptor { 10 | val group = FileTemplateGroupDescriptor("Bitrix Module", BitrixIdeaIcons.Bitrix) 11 | group.addTemplate(FileTemplateDescriptor(BITRIX_MODULE_GITIGNORE_TEMPLATE)) 12 | 13 | return group 14 | } 15 | 16 | companion object { 17 | const val BITRIX_MODULE_GITIGNORE_TEMPLATE = "Bitrix Module .gitignore" 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/templates/module/BitrixModuleFileTemplateGroupFactory.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.templates.module 2 | 3 | import icons.BitrixIdeaIcons 4 | import com.intellij.ide.fileTemplates.FileTemplateDescriptor 5 | import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor 6 | import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory 7 | 8 | class BitrixModuleFileTemplateGroupFactory : FileTemplateGroupDescriptorFactory { 9 | override fun getFileTemplatesDescriptor(): FileTemplateGroupDescriptor { 10 | val group = FileTemplateGroupDescriptor("Bitrix Module", BitrixIdeaIcons.Bitrix) 11 | group.addTemplate(FileTemplateDescriptor(BITRIX_MODULE_SETTINGS_TEMPLATE)) 12 | group.addTemplate(FileTemplateDescriptor(BITRIX_MODULE_DEFAULT_OPTION_TEMPLATE)) 13 | group.addTemplate(FileTemplateDescriptor(BITRIX_MODULE_INCLUDE_TEMPLATE)) 14 | group.addTemplate(FileTemplateDescriptor(BITRIX_MODULE_OPTIONS_TEMPLATE)) 15 | group.addTemplate(FileTemplateDescriptor(BITRIX_MODULE_PROLOG_TEMPLATE)) 16 | 17 | return group 18 | } 19 | 20 | companion object { 21 | const val BITRIX_MODULE_SETTINGS_TEMPLATE = "Bitrix Module .settings.php" 22 | const val BITRIX_MODULE_DEFAULT_OPTION_TEMPLATE = "Bitrix Module default_option.php" 23 | const val BITRIX_MODULE_INCLUDE_TEMPLATE = "Bitrix Module include.php" 24 | const val BITRIX_MODULE_OPTIONS_TEMPLATE = "Bitrix Module options.php" 25 | const val BITRIX_MODULE_PROLOG_TEMPLATE = "Bitrix Module prolog.php" 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/templates/simple_component/BitrixSimpleComponentFileTemplateGroupFactory.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.templates.simple_component 2 | 3 | import icons.BitrixIdeaIcons 4 | import com.intellij.ide.fileTemplates.FileTemplateDescriptor 5 | import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor 6 | import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory 7 | 8 | class BitrixSimpleComponentFileTemplateGroupFactory : FileTemplateGroupDescriptorFactory { 9 | override fun getFileTemplatesDescriptor(): FileTemplateGroupDescriptor { 10 | val group = FileTemplateGroupDescriptor("Bitrix Simple Component", BitrixIdeaIcons.Bitrix) 11 | group.addTemplate(FileTemplateDescriptor(BITRIX_SIMPLE_COMPONENT_CLASS_TEMPLATE)) 12 | group.addTemplate(FileTemplateDescriptor(BITRIX_SIMPLE_COMPONENT_PARAMETERS_TEMPLATE)) 13 | group.addTemplate(FileTemplateDescriptor(BITRIX_SIMPLE_COMPONENT_DESCRIPTION_TEMPLATE)) 14 | group.addTemplate(FileTemplateDescriptor(BITRIX_SIMPLE_COMPONENT_TEMPLATES_DEFAULT_TEMPLATE_TEMPLATE)) 15 | group.addTemplate(FileTemplateDescriptor(BITRIX_SIMPLE_COMPONENT_LANGUAGE__PARAMETERS_TEMPLATE)) 16 | group.addTemplate(FileTemplateDescriptor(BITRIX_SIMPLE_COMPONENT_LANGUAGE_DESCRIPTION_TEMPLATE)) 17 | group.addTemplate(FileTemplateDescriptor(BITRIX_SIMPLE_COMPONENT_LANGUAGE_TEMPLATES_DEFAULT_TEMPLATE_TEMPLATE)) 18 | 19 | return group 20 | } 21 | 22 | companion object { 23 | const val BITRIX_SIMPLE_COMPONENT_CLASS_TEMPLATE = "Bitrix Simple Component class.php" 24 | const val BITRIX_SIMPLE_COMPONENT_PARAMETERS_TEMPLATE = "Bitrix Simple Component .parameters.php" 25 | const val BITRIX_SIMPLE_COMPONENT_DESCRIPTION_TEMPLATE = "Bitrix Simple Component .description.php" 26 | const val BITRIX_SIMPLE_COMPONENT_TEMPLATES_DEFAULT_TEMPLATE_TEMPLATE = 27 | "Bitrix Simple Component templates default template.php" 28 | const val BITRIX_SIMPLE_COMPONENT_LANGUAGE__PARAMETERS_TEMPLATE = 29 | "Bitrix Simple Component language .parameters.php" 30 | const val BITRIX_SIMPLE_COMPONENT_LANGUAGE_DESCRIPTION_TEMPLATE = 31 | "Bitrix Simple Component language .description.php" 32 | const val BITRIX_SIMPLE_COMPONENT_LANGUAGE_TEMPLATES_DEFAULT_TEMPLATE_TEMPLATE = 33 | "Bitrix Simple Component language templates default template.php" 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/templates/template/BitrixTemplateFileTemplateGroupFactory.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.templates.template 2 | 3 | import icons.BitrixIdeaIcons 4 | import com.intellij.ide.fileTemplates.FileTemplateDescriptor 5 | import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor 6 | import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory 7 | 8 | class BitrixTemplateFileTemplateGroupFactory : FileTemplateGroupDescriptorFactory { 9 | override fun getFileTemplatesDescriptor(): FileTemplateGroupDescriptor { 10 | val group = FileTemplateGroupDescriptor("Bitrix Template", BitrixIdeaIcons.Bitrix) 11 | group.addTemplate(FileTemplateDescriptor(BITRIX_TEMPLATE_STYLES_TEMPLATE)) 12 | group.addTemplate(FileTemplateDescriptor(BITRIX_TEMPLATE_DESCRIPTION_TEMPLATE)) 13 | group.addTemplate(FileTemplateDescriptor(BITRIX_TEMPLATE_HEADER_TEMPLATE)) 14 | group.addTemplate(FileTemplateDescriptor(BITRIX_TEMPLATE_FOOTER_TEMPLATE)) 15 | group.addTemplate(FileTemplateDescriptor(BITRIX_TEMPLATE_STYLES_CSS_TEMPLATE)) 16 | group.addTemplate(FileTemplateDescriptor(BITRIX_TEMPLATE_TEMPLATE_STYLES_CSS_TEMPLATE)) 17 | 18 | return group 19 | } 20 | 21 | companion object { 22 | const val BITRIX_TEMPLATE_STYLES_TEMPLATE = "Bitrix Template .styles.php" 23 | const val BITRIX_TEMPLATE_DESCRIPTION_TEMPLATE = "Bitrix Template description.php" 24 | const val BITRIX_TEMPLATE_HEADER_TEMPLATE = "Bitrix Template header.php" 25 | const val BITRIX_TEMPLATE_FOOTER_TEMPLATE = "Bitrix Template footer.php" 26 | const val BITRIX_TEMPLATE_STYLES_CSS_TEMPLATE = "Bitrix Template styles.css" 27 | const val BITRIX_TEMPLATE_TEMPLATE_STYLES_CSS_TEMPLATE = "Bitrix Template template_styles.css" 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/validation/ComponentSimpleCodeVerifier.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.validation 2 | 3 | class ComponentSimpleCodeVerifier { 4 | fun verify(input: String): Boolean { 5 | return input.matches(Regex("^[a-zA-Z0-9_.]+[a-zA-Z0-9]+\$")) && input.isNotBlank() 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/validation/ModuleCodeVerifier.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.validation 2 | 3 | class ModuleCodeVerifier { 4 | fun verify(input: String): Boolean { 5 | return input.matches(Regex("^[a-zA-Z][a-zA-Z0-9_]*(\\.?[a-zA-Z0-9_]+)*$")) && input.isNotBlank() 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/validation/TemplateCodeVerifier.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.validation 2 | 3 | class TemplateCodeVerifier { 4 | fun verify(input: String): Boolean { 5 | return input.matches(Regex("^[a-zA-Z0-9_-]+$")) && input.isNotBlank() 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/github/saundefined/bitrix_idea/validation/UrlVerifier.kt: -------------------------------------------------------------------------------- 1 | package com.github.saundefined.bitrix_idea.validation 2 | 3 | class UrlVerifier { 4 | fun verify(input: String): Boolean { 5 | return input.matches(Regex("^https?://\\S*\$")) 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/icons/BitrixIdeaIcons.kt: -------------------------------------------------------------------------------- 1 | package icons 2 | 3 | import com.intellij.openapi.util.IconLoader.getIcon 4 | 5 | object BitrixIdeaIcons { 6 | @JvmField 7 | val Bitrix = getIcon("/icons/bitrix.svg", javaClass) 8 | 9 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | ru.panteleev.bitrix-idea 3 | Bitrix Idea 4 | sergey-panteleev 5 | 6 | com.intellij.modules.platform 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 17 | 19 | 21 | 22 | 23 | 28 | 29 | 30 | 31 | 32 | 38 | 39 | 45 | 46 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 70 | messages.BitrixIdeaBundle 71 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/pluginIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/pluginIcon_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Module .gitignore.ft: -------------------------------------------------------------------------------- 1 | .idea 2 | /bitrix/* 3 | /bitrix/*/* 4 | !/bitrix/composer.json 5 | !/bitrix/composer.lock 6 | !/bitrix/composer-bx.json 7 | upload/ 8 | !.gitignore 9 | /.htaccess 10 | /*.xml 11 | /*.txt 12 | /*.json 13 | /*.log 14 | /web.config -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Module .settings.php.ft: -------------------------------------------------------------------------------- 1 | MODULE_VERSION = ${DS}arModuleVersion['VERSION']; 25 | ${DS}this->MODULE_VERSION_DATE = ${DS}arModuleVersion['VERSION_DATE']; 26 | } 27 | 28 | ${DS}this->MODULE_NAME = Loc::getMessage('${UPPER_CASED_MODULE_NAME}_MODULE_NAME'); 29 | ${DS}this->MODULE_DESCRIPTION = Loc::getMessage('${UPPER_CASED_MODULE_NAME}_MODULE_DESCRIPTION'); 30 | ${DS}this->PARTNER_NAME = Loc::getMessage('${UPPER_CASED_MODULE_NAME}_PARTNER_NAME'); 31 | ${DS}this->PARTNER_URI = Loc::getMessage('${UPPER_CASED_MODULE_NAME}_PARTNER_URI'); 32 | } 33 | 34 | public function InstallFiles() 35 | { 36 | } 37 | 38 | public function InstallDB() 39 | { 40 | } 41 | 42 | public function InstallEvents() 43 | { 44 | } 45 | 46 | public function InstallTasks() 47 | { 48 | } 49 | 50 | public function UnInstallTasks() 51 | { 52 | } 53 | 54 | public function UnInstallEvents() 55 | { 56 | } 57 | 58 | public function UnInstallDB() 59 | { 60 | } 61 | 62 | public function UnInstallFiles() 63 | { 64 | } 65 | 66 | public function GetModuleRightList() 67 | { 68 | return [ 69 | 'reference_id' => ['D', 'R', 'W'], 70 | 'reference' => [ 71 | Loc::getMessage('${UPPER_CASED_MODULE_NAME}_MODULE_ACCESS_DENIED'), 72 | Loc::getMessage('${UPPER_CASED_MODULE_NAME}_MODULE_ACCESS_OPENED'), 73 | Loc::getMessage('${UPPER_CASED_MODULE_NAME}_MODULE_ACCESS_FULL'), 74 | ], 75 | ]; 76 | } 77 | 78 | public function DoInstall() 79 | { 80 | ${DS}this->InstallFiles(); 81 | ${DS}this->InstallDB(); 82 | ${DS}this->InstallEvents(); 83 | ${DS}this->InstallTasks(); 84 | 85 | ModuleManager::registerModule(${DS}this->MODULE_ID); 86 | 87 | return true; 88 | } 89 | 90 | public function DoUninstall() 91 | { 92 | ${DS}this->UnInstallTasks(); 93 | ${DS}this->UnInstallEvents(); 94 | ${DS}this->UnInstallDB(); 95 | ${DS}this->UnInstallFiles(); 96 | 97 | ModuleManager::unRegisterModule(${DS}this->MODULE_ID); 98 | } 99 | } -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Module install version.php.ft: -------------------------------------------------------------------------------- 1 | '1.0.0', 5 | 'VERSION_DATE' => '${YEAR}-${MONTH}-${DAY}' 6 | ]; -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Module language install index.php.ft: -------------------------------------------------------------------------------- 1 | Loc::getMessage('${UPPERCASE_COMPONENT_NAME}_COMPONENT_NAME'), 9 | 'DESCRIPTION' => Loc::getMessage('${UPPERCASE_COMPONENT_NAME}_COMPONENT_DESCRIPTION'), 10 | 'PATH' => [ 11 | 'ID' => 'content', 12 | 'CHILD' => [ 13 | 'ID' => 'vendor', 14 | 'NAME' => Loc::getMessage('${UPPERCASE_COMPONENT_NAME}_COMPONENT_VENDOR'), 15 | ] 16 | ], 17 | 'CACHE_PATH' => 'Y', 18 | 'COMPLEX' => 'N' 19 | ]; -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Simple Component .parameters.php.ft: -------------------------------------------------------------------------------- 1 | [ 9 | 'SETTINGS' => [ 10 | 'NAME' => Loc::getMessage('${UPPERCASE_COMPONENT_NAME}_GROUP_SETTINGS') 11 | ], 12 | ], 13 | 'PARAMETERS' => [ 14 | 'PARAMETER_1' => [ 15 | 'PARENT' => 'SETTINGS', 16 | 'NAME' => Loc::getMessage('${UPPERCASE_COMPONENT_NAME}_PARAMETERS_PARAMETER_1'), 17 | 'TYPE' => 'STRING', 18 | 'MULTIPLE' => 'N', 19 | 'DEFAULT' => Loc::getMessage('${UPPERCASE_COMPONENT_NAME}_PARAMETERS_PARAMETER_1_DEFAULT'), 20 | ], 21 | 'CACHE_TIME' => [], 22 | ] 23 | ]; -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Simple Component class.php.ft: -------------------------------------------------------------------------------- 1 | includeComponentTemplate(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Simple Component language .description.php.ft: -------------------------------------------------------------------------------- 1 | '${TEMPLATE_NAME}', 5 | 'DESCRIPTION' => '${TEMPLATE_DESCRIPTION}', 6 | 'SORT' => '', 7 | 'TYPE' => '', 8 | ]; -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Template footer.php.ft: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Template header.php.ft: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 12 | 13 | <?php ${DS}APPLICATION->ShowTitle(); ?> 14 | ShowHead() ?> 15 | 16 | 17 | ShowPanel(); ?> -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Template styles.css.ft: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saundefined/bitrix-idea/a832d063960ae3a0cea0f148ee024329f08cdfb4/src/main/resources/fileTemplates/j2ee/Bitrix Template styles.css.ft -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/j2ee/Bitrix Template template_styles.css.ft: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saundefined/bitrix-idea/a832d063960ae3a0cea0f148ee024329f08cdfb4/src/main/resources/fileTemplates/j2ee/Bitrix Template template_styles.css.ft -------------------------------------------------------------------------------- /src/main/resources/icons/bitrix.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/resources/messages/BitrixIdeaBundle.properties: -------------------------------------------------------------------------------- 1 | startup.notification.title=\u0415\u0441\u043B\u0438 \u0432\u0430\u043C \u043D\u0440\u0430\u0432\u0438\u0442\u0441\u044F Bitrix Idea, \u044F \u0431\u0443\u0434\u0443 \u043E\u0447\u0435\u043D\u044C \u043F\u0440\u0438\u0437\u043D\u0430\u0442\u0435\u043B\u0435\u043D, \u0435\u0441\u043B\u0438 \u0432\u044B \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u0437\u0432\u0435\u0437\u0434\u0443 \u043D\u0430 GitHub. 2 | startup.notification.action=\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u043D\u0430 GitHub 3 | startup.notification.dismiss=\u0411\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C 4 | create.module.form.title=\u0421\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u043C\u043E\u0434\u0443\u043B\u044F 5 | create.module.code=\u041A\u043E\u0434 \u043C\u043E\u0434\u0443\u043B\u044F: 6 | create.module.code.validation.fail=\u041A\u043E\u0434 \u043C\u043E\u0434\u0443\u043B\u044F \u0434\u043E\u043B\u0436\u0435\u043D \u0441\u043E\u0441\u0442\u043E\u044F\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0438\u0437 \u043B\u0430\u0442\u0438\u043D\u0441\u043A\u0438\u0445 \u0431\u0443\u043A\u0432, \u0446\u0438\u0444\u0440, \u0442\u043E\u0447\u043A\u0438 \u0438 \u043D\u0438\u0436\u043D\u0435\u0433\u043E \u043F\u043E\u0434\u0447\u0435\u0440\u043A\u0438\u0432\u0430\u043D\u0438\u044F \u0438 \u043D\u0435 \u043D\u0430\u0447\u0438\u043D\u0430\u0442\u044C\u0441\u044F \u0441 \u0446\u0438\u0444\u0440\u044B 7 | create.module.name=\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043C\u043E\u0434\u0443\u043B\u044F: 8 | create.module.name.validation.fail=\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043C\u043E\u0434\u0443\u043B\u044F 9 | create.module.description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435: 10 | create.module.description.validation.fail=\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u043C\u043E\u0434\u0443\u043B\u044F 11 | create.module.vendor=\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043F\u0430\u0440\u0442\u043D\u0451\u0440\u0430: 12 | create.module.vendor.validation.fail=\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043F\u0430\u0440\u0442\u043D\u0451\u0440\u0430 13 | create.module.url=\u0421\u0430\u0439\u0442 \u043F\u0430\u0440\u0442\u043D\u0451\u0440\u0430: 14 | create.module.url.validation.fail=\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 URL 15 | create.template.form.title=\u0421\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u0448\u0430\u0431\u043B\u043E\u043D\u0430 16 | create.template.code=\u041A\u043E\u0434 \u0448\u0430\u0431\u043B\u043E\u043D\u0430: 17 | create.template.code.validation.fail=\u041A\u043E\u0434 \u0448\u0430\u0431\u043B\u043E\u043D\u0430 \u0434\u043E\u043B\u0436\u0435\u043D \u0441\u043E\u0441\u0442\u043E\u044F\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0438\u0437 \u043B\u0430\u0442\u0438\u043D\u0441\u043A\u0438\u0445 \u0431\u0443\u043A\u0432, \u0446\u0438\u0444\u0440, \u043D\u0438\u0436\u043D\u0435\u0433\u043E \u043F\u043E\u0434\u0447\u0435\u0440\u043A\u0438\u0432\u0430\u043D\u0438\u044F \u0438 \u0434\u0435\u0444\u0438\u0441\u0430 18 | create.template.name=\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0448\u0430\u0431\u043B\u043E\u043D\u0430: 19 | create.template.name.validation.fail=\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0448\u0430\u0431\u043B\u043E\u043D\u0430 20 | create.template.description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435: 21 | create.component.simple.form.title=\u0421\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u043F\u0440\u043E\u0441\u0442\u043E\u0433\u043E \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 22 | create.component.simple.code=\u041A\u043E\u0434 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430: 23 | create.component.simple.code.validation.fail=\u041A\u043E\u0434 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 \u0434\u043E\u043B\u0436\u0435\u043D \u0441\u043E\u0441\u0442\u043E\u044F\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0438\u0437 \u043B\u0430\u0442\u0438\u043D\u0441\u043A\u0438\u0445 \u0431\u0443\u043A\u0432 \u0438 \u0442\u043E\u0447\u043A\u0438 24 | create.component.simple.name=\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u0442\u0430: 25 | create.component.simple.name.validation.fail=\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u0442\u0430 26 | create.component.simple.description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435: 27 | create.component.simple.description.validation.fail=\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 28 | settings.vendor.group=\u0414\u0430\u043D\u043D\u044B\u0435 \u043E \u043F\u0430\u0440\u0442\u043D\u0451\u0440\u0435 29 | settings.vendor.code=\u041A\u043E\u0434: 30 | settings.vendor.name=\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435: 31 | settings.vendor.website=\u0421\u0430\u0439\u0442: 32 | localization.add=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043B\u043E\u043A\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044E 33 | localization.add.title=\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043B\u043E\u043A\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 34 | settings.localizations.group=\u041B\u043E\u043A\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E 35 | localization.table.column.name=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u044F\u0437\u044B\u043A\u0438 36 | localization.table.row.name=\u041B\u043E\u043A\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F: --------------------------------------------------------------------------------