├── glpi_network.png ├── locales ├── cs_CZ.mo ├── en_GB.mo ├── es_EC.mo ├── fi_FI.mo ├── fr_FR.mo ├── hr_HR.mo ├── it_IT.mo ├── pt_PT.mo ├── tr_TR.mo ├── sccm.pot ├── en_GB.po ├── fi_FI.po ├── it_IT.po ├── cs_CZ.po ├── pt_PT.po ├── es_EC.po ├── tr_TR.po ├── hr_HR.po └── fr_FR.po ├── screenshots ├── sccm.png ├── schema.png ├── auto_task.png ├── Config_SCCM.png ├── maxresdefault.jpg └── iconmonstr-database-10-icon-128.png ├── .gitignore ├── .tx └── config ├── .github ├── workflows │ ├── release.yml │ ├── locales-update-source.yml │ ├── locales-sync.yml │ ├── auto-tag-new-version.yml │ ├── label-commenter.yml │ ├── init-script.sh │ ├── continuous-integration.yml │ └── close_stale_issue.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ └── bug_report.yml ├── dependabot.yml ├── pull_request_template.md └── label-commenter-config.yml ├── phpstan.neon ├── .twig_cs.dist.php ├── composer.json ├── .php-cs-fixer.php ├── CHANGELOG.md ├── psalm.xml ├── SECURITY.md ├── tools └── HEADER ├── inc ├── menu.class.php ├── sccmdb.class.php ├── config.class.php ├── sccmxml.class.php └── sccm.class.php ├── front └── config.form.php ├── rector.php ├── README.md ├── hook.php ├── setup.php ├── templates └── config.html.twig ├── sccm.xml ├── composer.lock └── LICENSE.md /glpi_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/glpi_network.png -------------------------------------------------------------------------------- /locales/cs_CZ.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/cs_CZ.mo -------------------------------------------------------------------------------- /locales/en_GB.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/en_GB.mo -------------------------------------------------------------------------------- /locales/es_EC.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/es_EC.mo -------------------------------------------------------------------------------- /locales/fi_FI.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/fi_FI.mo -------------------------------------------------------------------------------- /locales/fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/fr_FR.mo -------------------------------------------------------------------------------- /locales/hr_HR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/hr_HR.mo -------------------------------------------------------------------------------- /locales/it_IT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/it_IT.mo -------------------------------------------------------------------------------- /locales/pt_PT.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/pt_PT.mo -------------------------------------------------------------------------------- /locales/tr_TR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/locales/tr_TR.mo -------------------------------------------------------------------------------- /screenshots/sccm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/screenshots/sccm.png -------------------------------------------------------------------------------- /screenshots/schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/screenshots/schema.png -------------------------------------------------------------------------------- /screenshots/auto_task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/screenshots/auto_task.png -------------------------------------------------------------------------------- /screenshots/Config_SCCM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/screenshots/Config_SCCM.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .settings/ 2 | .buildpath 3 | .project 4 | dist/ 5 | vendor/ 6 | .gh_token 7 | *.min.* 8 | var/ 9 | -------------------------------------------------------------------------------- /screenshots/maxresdefault.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/screenshots/maxresdefault.jpg -------------------------------------------------------------------------------- /screenshots/iconmonstr-database-10-icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pluginsGLPI/sccm/HEAD/screenshots/iconmonstr-database-10-icon-128.png -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [o:teclib:p:glpi-project-plugin-sccm:r:sccm-pot] 5 | file_filter = locales/.po 6 | source_file = locales/sccm.pot 7 | source_lang = en 8 | type = PO 9 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Publish release" 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | publish-release: 10 | permissions: 11 | contents: "write" 12 | name: "Publish release" 13 | uses: "glpi-project/plugin-release-workflows/.github/workflows/publish-release.yml@v1" 14 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | parallel: 3 | maximumNumberOfProcesses: 2 4 | level: 5 5 | bootstrapFiles: 6 | - ../../stubs/glpi_constants.php 7 | - ../../vendor/autoload.php 8 | paths: 9 | - front 10 | - inc 11 | - hook.php 12 | - setup.php 13 | scanDirectories: 14 | - ../../inc 15 | - ../../src 16 | -------------------------------------------------------------------------------- /.github/workflows/locales-update-source.yml: -------------------------------------------------------------------------------- 1 | name: "Update locales sources" 2 | 3 | on: 4 | push: 5 | branches: 6 | - "main" 7 | 8 | jobs: 9 | push-on-transifex: 10 | name: "Push locales sources" 11 | uses: "glpi-project/plugin-translation-workflows/.github/workflows/transifex-push-sources.yml@v1" 12 | secrets: 13 | transifex-token: "${{ secrets.TRANSIFEX_TOKEN }}" 14 | -------------------------------------------------------------------------------- /.github/workflows/locales-sync.yml: -------------------------------------------------------------------------------- 1 | name: "Synchronize locales" 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * 1-5" 6 | workflow_dispatch: 7 | 8 | jobs: 9 | sync-with-transifex: 10 | name: "Sync with transifex" 11 | uses: "glpi-project/plugin-translation-workflows/.github/workflows/transifex-sync.yml@v1" 12 | secrets: 13 | github-token: "${{ secrets.LOCALES_SYNC_TOKEN }}" 14 | transifex-token: "${{ secrets.TRANSIFEX_TOKEN }}" 15 | -------------------------------------------------------------------------------- /.twig_cs.dist.php: -------------------------------------------------------------------------------- 1 | in(__DIR__ . '/templates') 11 | ->name('*.html.twig') 12 | ->ignoreVCSIgnored(true); 13 | 14 | return Config::create() 15 | ->setFinder($finder) 16 | ->setRuleSet(GlpiTwigRuleset::class) 17 | ; 18 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": ">=8.2" 4 | }, 5 | "require-dev": { 6 | "glpi-project/tools": "^0.8.3" 7 | }, 8 | "config": { 9 | "optimize-autoloader": true, 10 | "platform": { 11 | "php": "8.2.99" 12 | }, 13 | "sort-packages": true 14 | }, 15 | "autoload-dev": { 16 | "psr-4": { 17 | "Glpi\\Tools\\": "../../tools/src/" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.github/workflows/auto-tag-new-version.yml: -------------------------------------------------------------------------------- 1 | name: "Automatically tag new version" 2 | 3 | on: 4 | push: 5 | branches: 6 | - "main" 7 | - "**/bugfixes" 8 | paths: 9 | - "setup.php" 10 | 11 | jobs: 12 | auto-tag-new-version: 13 | name: "Automatically tag new version" 14 | uses: "glpi-project/plugin-release-workflows/.github/workflows/auto-tag-new-version.yml@v1" 15 | secrets: 16 | github-token: "${{ secrets.AUTOTAG_TOKEN }}" 17 | -------------------------------------------------------------------------------- /.github/workflows/label-commenter.yml: -------------------------------------------------------------------------------- 1 | name: "Label commenter" 2 | 3 | on: 4 | issues: 5 | types: 6 | - "labeled" 7 | - "unlabeled" 8 | 9 | jobs: 10 | comment: 11 | permissions: 12 | contents: "read" 13 | issues: "write" 14 | runs-on: "ubuntu-latest" 15 | steps: 16 | - name: "Checkout" 17 | uses: "actions/checkout@v6" 18 | 19 | - name: "Label commenter" 20 | uses: "peaceiris/actions-label-commenter@v1" 21 | -------------------------------------------------------------------------------- /.php-cs-fixer.php: -------------------------------------------------------------------------------- 1 | in(__DIR__) 8 | ->name('*.php') 9 | ->ignoreVCSIgnored(true); 10 | 11 | $config = new Config(); 12 | 13 | $rules = [ 14 | '@PER-CS' => true, // Latest PER rules. 15 | ]; 16 | 17 | return $config 18 | ->setRules($rules) 19 | ->setFinder($finder) 20 | ->setCacheFile(__DIR__ . '/var/php-cs-fixer/.php-cs-fixer.cache') 21 | ; 22 | -------------------------------------------------------------------------------- /.github/workflows/init-script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt-get update -yq 4 | 5 | PHP_VERSION=$(php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;") 6 | 7 | sudo apt-get install -yq unixodbc-dev 8 | 9 | if [[ "$PHP_VERSION" == "7.4" ]]; then 10 | sudo pecl install sqlsrv-5.10.1 11 | elif [[ "$PHP_VERSION" == "8.0" ]]; then 12 | sudo pecl install sqlsrv-5.11.0 13 | else 14 | sudo pecl install sqlsrv 15 | fi 16 | 17 | echo "extension=sqlsrv.so" | sudo tee -a /usr/local/etc/php/php.ini 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: "GLPI professional support" 4 | url: "https://services.glpi-network.com" 5 | about: "Get professional support from the editor and a network of local partners." 6 | - name: "Find an official partner" 7 | url: "https://glpi-project.org/partners/" 8 | about: "Get support to deploy GLPI in a professional manner." 9 | - name: "GLPI Community Forum" 10 | url: "https://forum.glpi-project.org" 11 | about: "Ask questions and get help from the community." 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Ensure GitHub Actions are used in their latest version 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "monthly" 8 | 9 | # Strategy for composer dependencies 10 | - package-ecosystem: "composer" 11 | directory: "/" 12 | schedule: 13 | interval: "monthly" 14 | allow: 15 | - dependency-type: "direct" 16 | open-pull-requests-limit: 100 17 | versioning-strategy: "increase" 18 | groups: 19 | dev-dependencies: 20 | dependency-type: "development" 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Checklist before requesting a review 2 | 3 | *Please delete options that are not relevant.* 4 | 5 | - [ ] I have performed a self-review of my code. 6 | - [ ] I have added tests (when available) that prove my fix is effective or that my feature works. 7 | - [ ] I have updated the CHANGELOG with a short functional description of the fix or new feature. 8 | - [ ] This change requires a documentation update. 9 | 10 | ## Description 11 | 12 | - It fixes # (issue number, if applicable) 13 | - Here is a brief description of what this PR does 14 | 15 | ## Screenshots (if appropriate): 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [2.5.1] - 2025-10-07 9 | 10 | Compatible with GLPI 11.0.x 11 | 12 | ### Fixed 13 | 14 | - Fix config page error on display 15 | - Fix `password` value not saved 16 | - Drop `mssql_connect` prerequisites 17 | - Fix option ```verify_ssl_cert``` not working for connections 18 | 19 | ## [2.5.0] - 2025-10-01 20 | 21 | ### Added 22 | 23 | - GLPI 11 compatibility 24 | 25 | ## [2.4.4] - 2025-09-24 26 | 27 | Compatible with GLPI 10.0.x 28 | 29 | ### Added 30 | 31 | ### Fixed 32 | 33 | - Fix option ```Use LastHWScan``` that no longer worked. 34 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | **⚠️ Please never use standard issues to report security problems; vulnerabilities are published once a fix release is available. ⚠️** 4 | 5 | ## Reporting a Vulnerability 6 | 7 | If you found a security issue, please contact us by: 8 | 9 | - [our huntr page](https://huntr.dev/repos/pluginsGLPI/sccm/) 10 | - a mail to \[glpi-security AT ow2.org\] 11 | 12 | You should provide us all details about the issue and the way to reproduce it. 13 | You may also provide a script that can be used to check the issue exists. 14 | 15 | Once the report will be handled, and if the issue is not yet fixed (or in progress) 16 | we'll add it to the GitHub security tab, and add you as observer. Meanwhile, 17 | you will reserve a CVE for the issue. 18 | 19 | Thank you for improving the security of GLPI and its plugins. 20 | 21 | ## Supported Versions 22 | 23 | We follow the same version support policy as GLPI. 24 | This means that we provide security patches to versions of the plugin that target a version of GLPI itself maintained from a security point of view. 25 | -------------------------------------------------------------------------------- /.github/workflows/continuous-integration.yml: -------------------------------------------------------------------------------- 1 | name: "Continuous integration" 2 | 3 | on: 4 | push: 5 | branches: 6 | - "main" 7 | tags: 8 | - "*" 9 | pull_request: 10 | schedule: 11 | - cron: "0 0 * * *" 12 | workflow_dispatch: 13 | 14 | concurrency: 15 | group: "${{ github.workflow }}-${{ github.ref }}" 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | generate-ci-matrix: 20 | name: "Generate CI matrix" 21 | uses: "glpi-project/plugin-ci-workflows/.github/workflows/generate-ci-matrix.yml@v1" 22 | with: 23 | glpi-version: "11.0.x" 24 | ci: 25 | name: "GLPI ${{ matrix.glpi-version }} - php:${{ matrix.php-version }} - ${{ matrix.db-image }}" 26 | needs: "generate-ci-matrix" 27 | strategy: 28 | fail-fast: false 29 | matrix: ${{ fromJson(needs.generate-ci-matrix.outputs.matrix) }} 30 | uses: "glpi-project/plugin-ci-workflows/.github/workflows/continuous-integration.yml@v1" 31 | with: 32 | plugin-key: "sccm" 33 | glpi-version: "${{ matrix.glpi-version }}" 34 | php-version: "${{ matrix.php-version }}" 35 | db-image: "${{ matrix.db-image }}" 36 | init-script: "./.github/workflows/init-script.sh" 37 | -------------------------------------------------------------------------------- /.github/label-commenter-config.yml: -------------------------------------------------------------------------------- 1 | labels: 2 | - name: "invalid" 3 | labeled: 4 | issue: 5 | body: | 6 | This issue has been closed because you did not provide the requested information. 7 | action: "close" 8 | - name: "support" 9 | labeled: 10 | issue: 11 | body: | 12 | This issue has been closed as we only track bugs here. 13 | 14 | You can get community support on [forums](https://forum.glpi-project.org/) or you can consider [taking a subscription](https://glpi-project.org/subscriptions/) to get professional support. 15 | You can also [contact GLPI editor team](https://portal.glpi-network.com/contact-us) directly. 16 | action: close 17 | - name: "feature suggestion" 18 | labeled: 19 | issue: 20 | body: | 21 | This issue has been closed as we only track bugs here. 22 | 23 | You can open a topic to discuss with community about this enhancement on [suggestion website](https://glpi.userecho.com/). 24 | You can also [contact GLPI editor team](https://portal.glpi-network.com/contact-us) directly if you are willing to sponsor this feature. 25 | action: close 26 | -------------------------------------------------------------------------------- /tools/HEADER: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------- 2 | SCCM plugin for GLPI 3 | ------------------------------------------------------------------------- 4 | 5 | LICENSE 6 | 7 | This file is part of SCCM. 8 | 9 | SCCM is free software; you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation; either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | SCCM is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with SCCM. If not, see . 21 | ------------------------------------------------------------------------- 22 | @author François Legastelois 23 | @copyright Copyright (C) 2014-2023 by SCCM plugin team. 24 | @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 25 | @link https://github.com/pluginsGLPI/sccm 26 | ------------------------------------------------------------------------- 27 | -------------------------------------------------------------------------------- /.github/workflows/close_stale_issue.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues' 2 | on: 3 | schedule: 4 | - cron: '0 8 * * *' 5 | 6 | jobs: 7 | stale: 8 | if: github.repository == 'pluginsGLPI/sccm' 9 | permissions: 10 | issues: write # for actions/stale to close stale issues 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/stale@v10 14 | with: 15 | stale-issue-message: >- 16 | There has been no activity on this issue for some time and therefore it is considered stale 17 | and will be closed automatically in 10 days. 18 | 19 | 20 | If this issue is related to a bug, please try to reproduce on latest release. If the problem persist, 21 | feel free to add a comment to revive this issue. 22 | 23 | If it is related to a new feature, please open a topic to discuss with community about this enhancement 24 | on [suggestion website](https://glpi.userecho.com/). 25 | 26 | 27 | You may also consider taking a [subscription](https://glpi-project.org/subscriptions/) to get professionnal 28 | support or [contact GLPI editor team](https://portal.glpi-network.com/contact-us) directly. 29 | days-before-issue-stale: 15 30 | days-before-pr-stale: -1 # PR will be marked as stale manually. 31 | days-before-close: 5 32 | exempt-issue-labels: "bug,enhancement,question,security" # Issues with "bug", "enhancement", "question" or "security" labels will not be marked as stale 33 | exempt-all-milestones: true # Do not check issues/PR with defined milestone. 34 | ascending: true # First check older issues/PR. 35 | operations-per-run: 750 # Max API calls per run. 36 | -------------------------------------------------------------------------------- /inc/menu.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | class PluginSccmMenu extends CommonGLPI 33 | { 34 | public static function getTypeName($nb = 0) 35 | { 36 | return __s('SCCM', 'sccm'); 37 | } 38 | 39 | public static function getMenuName() 40 | { 41 | return __s('SCCM', 'sccm'); 42 | } 43 | 44 | public static function getMenuContent() 45 | { 46 | return [ 47 | 'title' => self::getMenuName(), 48 | 'page' => '/plugins/sccm/front/config.form.php', 49 | 'icon' => 'ti ti-database-cog', 50 | ]; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /front/config.form.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | include(__DIR__ . '/../../../inc/includes.php'); 33 | require_once(__DIR__ . '/../inc/config.class.php'); 34 | 35 | 36 | Session::checkRight("config", UPDATE); 37 | 38 | $config = new PluginSccmConfig(); 39 | 40 | if (isset($_POST["update"])) { 41 | $config->update($_POST); 42 | $sccm_db = new PluginSccmSccmdb(); 43 | if ($sccm_db->connect()) { 44 | Session::addMessageAfterRedirect("Connexion réussie !.", false, INFO, false); 45 | } else { 46 | Session::addMessageAfterRedirect("Connexion incorrecte.", false, ERROR, false); 47 | } 48 | 49 | Html::back(); 50 | } 51 | 52 | $menus = ['config', PluginSccmMenu::class]; 53 | PluginSccmConfig::displayFullPageForItem($_GET['id'], $menus, $_GET); 54 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | require_once __DIR__ . '/../../src/Plugin.php'; 33 | 34 | use Rector\Caching\ValueObject\Storage\FileCacheStorage; 35 | use Rector\Config\RectorConfig; 36 | use Rector\ValueObject\PhpVersion; 37 | 38 | return RectorConfig::configure() 39 | ->withPaths([ 40 | __DIR__ . '/front', 41 | __DIR__ . '/inc', 42 | ]) 43 | ->withPhpVersion(PhpVersion::PHP_82) 44 | ->withCache( 45 | cacheDirectory: __DIR__ . '/var/rector', 46 | cacheClass: FileCacheStorage::class, 47 | ) 48 | ->withRootFiles() 49 | ->withParallel(timeoutSeconds: 300) 50 | ->withImportNames(removeUnusedImports: true) 51 | ->withPreparedSets( 52 | deadCode: true, 53 | codeQuality: true, 54 | codingStyle: true, 55 | ) 56 | ->withPhpSets(php82: true) // apply PHP sets up to PHP 8.2 57 | ; 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data synchronization with Microsoft SCCM tool 2 | 3 | [![License](https://img.shields.io/github/license/pluginsGLPI/sccm.svg?&label=License)](https://github.com/pluginsGLPI/sccm/blob/develop/LICENSE) 4 | [![Follow twitter](https://img.shields.io/twitter/follow/Teclib.svg?style=social&label=Twitter&style=flat-square)](https://twitter.com/teclib) 5 | [![Telegram Group](https://img.shields.io/badge/Telegram-Group-blue.svg)](https://t.me/glpien) 6 | [![Project Status: Active](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active) 7 | [![GitHub release](https://img.shields.io/github/release/pluginsGLPI/sccm.svg)](https://github.com/pluginsGLPI/sccm/releases) 8 | [![GitHub build](https://travis-ci.org/pluginsGLPI/sccm.svg?)](https://travis-ci.org/pluginsGLPI/sccm/) 9 | 10 | 11 | ![GLPISCCMPluginSchema](screenshots/sccm.png "sccm") 12 | 13 | Plugin to synchronize computers from SCCM (version 1802) to GLPI. 14 | 15 | ### Workflow 16 | 17 | * The plugin integrates two automatic actions : "SCCMCollect" et "SCCMPush". 18 | * The automatic action "SCCMCollect" queries the SCCM server with MsSQL queries. 19 | * This same action builds an XML file for each computer. 20 | * The automatic action "SCCMPush" injects XML files into the GLPI native inventory over HTTP(s) (via cURL) to display computers in GLPI. 21 | 22 | 23 | ![GLPISCCMPluginSchema](screenshots/schema.png "GLPISCCMPluginSchema") 24 | 25 | 26 | ## Documentation 27 | 28 | We maintain a detailed documentation here -> [Documentation](https://glpi-plugins.readthedocs.io/en/latest/sccm/index.html) 29 | 30 | ## Contact 31 | 32 | For notices about major changes and general discussion of sccm, subscribe to the [/r/glpi](https://www.reddit.com/r/glpi/) subreddit. 33 | You can also chat with us via [@glpi on Telegram](https://t.me/glpien). 34 | 35 | ## Professional Services 36 | 37 | ![GLPI Network](./glpi_network.png "GLPI network") 38 | 39 | The GLPI Network services are available through our [Partner's Network](http://www.teclib-edition.com/en/partners/). We provide special training, bug fixes with editor subscription, contributions for new features, and more. 40 | 41 | Obtain a personalized service experience, associated with benefits and opportunities. 42 | 43 | ## Contributing 44 | 45 | * Open a ticket for each bug/feature so it can be discussed 46 | * Follow [development guidelines](http://glpi-developer-documentation.readthedocs.io/en/latest/plugins/index.html) 47 | * Refer to [GitFlow](http://git-flow.readthedocs.io/) process for branching 48 | * Work on a new branch on your own fork 49 | * Open a PR that will be reviewed by a developer 50 | 51 | ## Copying 52 | 53 | * **Code**: you can redistribute it and/or modify 54 | -------------------------------------------------------------------------------- /hook.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | function plugin_sccm_install() 33 | { 34 | /** @var DBmysql $DB */ 35 | global $DB; 36 | 37 | if (!is_dir(GLPI_PLUGIN_DOC_DIR . '/sccm')) { 38 | mkdir(GLPI_PLUGIN_DOC_DIR . '/sccm'); 39 | } 40 | 41 | if (!is_dir(GLPI_PLUGIN_DOC_DIR . '/sccm/xml')) { 42 | mkdir(GLPI_PLUGIN_DOC_DIR . '/sccm/xml'); 43 | } 44 | 45 | $migration = new Migration(PLUGIN_SCCM_VERSION); 46 | 47 | require __DIR__ . '/inc/config.class.php'; 48 | require __DIR__ . '/inc/sccm.class.php'; 49 | PluginSccmConfig::install($migration); 50 | PluginSccmSccm::install(); 51 | 52 | $migration->executeMigration(); 53 | 54 | return true; 55 | } 56 | 57 | function plugin_sccm_uninstall() 58 | { 59 | /** @var DBmysql $DB */ 60 | global $DB; 61 | 62 | if (is_dir(GLPI_PLUGIN_DOC_DIR . '/sccm')) { 63 | rrmdir(GLPI_PLUGIN_DOC_DIR . '/sccm'); 64 | } 65 | 66 | require __DIR__ . '/inc/config.class.php'; 67 | require __DIR__ . '/inc/sccm.class.php'; 68 | PluginSccmConfig::uninstall(); 69 | PluginSccmSccm::uninstall(); 70 | 71 | return true; 72 | } 73 | 74 | function rrmdir($dir) 75 | { 76 | 77 | if (is_dir($dir)) { 78 | $objects = scandir($dir); 79 | foreach ($objects as $object) { 80 | if ($object !== "." && $object !== "..") { 81 | if (filetype($dir . "/" . $object) == "dir") { 82 | rrmdir($dir . "/" . $object); 83 | } else { 84 | unlink($dir . "/" . $object); 85 | } 86 | } 87 | } 88 | 89 | reset($objects); 90 | rmdir($dir); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /locales/sccm.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-09-20 07:06+0000\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: inc/sccm.class.php:522 21 | msgid "Collect is disabled by configuration." 22 | msgstr "" 23 | 24 | #: inc/config.class.php:249 25 | msgid "Database name" 26 | msgstr "" 27 | 28 | #: inc/config.class.php:239 29 | msgid "Enable SCCM synchronization" 30 | msgstr "" 31 | 32 | #: inc/config.class.php:115 inc/config.class.php:124 33 | msgid "Error when using glpi_plugin_sccm_configs table." 34 | msgstr "" 35 | 36 | #: inc/config.class.php:57 setup.php:67 37 | msgid "Interface - SCCM" 38 | msgstr "" 39 | 40 | #: inc/sccm.class.php:466 41 | msgid "Interface - SCCMCollect" 42 | msgstr "" 43 | 44 | #: inc/sccm.class.php:469 45 | msgid "Interface - SCCMPush" 46 | msgstr "" 47 | 48 | #: inc/config.class.php:266 49 | msgid "Inventory server base URL" 50 | msgstr "" 51 | 52 | #: inc/config.class.php:261 53 | msgid "Password" 54 | msgstr "" 55 | 56 | #: inc/sccm.class.php:47 57 | msgid "Please, read the documentation before using that." 58 | msgstr "" 59 | 60 | #: inc/sccm.class.php:677 61 | msgid "Push is disabled by configuration." 62 | msgstr "" 63 | 64 | #: inc/sccm.class.php:43 65 | msgid "SCCM" 66 | msgstr "" 67 | 68 | #: front/test.php:38 69 | msgid "SCCM - TEST" 70 | msgstr "" 71 | 72 | #: inc/menu.class.php:35 inc/menu.class.php:39 73 | msgid "SCCM Connector" 74 | msgstr "" 75 | 76 | #: inc/config.class.php:291 77 | msgid "Send credentials to other hosts too" 78 | msgstr "" 79 | 80 | #: inc/config.class.php:244 81 | msgid "Server hostname (MSSQL)" 82 | msgstr "" 83 | 84 | #: inc/config.class.php:53 front/config.form.php:59 85 | msgid "Setup - SCCM" 86 | msgstr "" 87 | 88 | #: front/showtable.php:87 89 | msgid "Synchronization is disabled by configuration." 90 | msgstr "" 91 | 92 | #: inc/config.class.php:306 93 | msgid "Use LastHWScan as GLPI last inventory date" 94 | msgstr "" 95 | 96 | #: inc/config.class.php:286 97 | msgid "Use NLTM authentication" 98 | msgstr "" 99 | 100 | #: inc/config.class.php:296 101 | msgid "Use specific authentication information" 102 | msgstr "" 103 | 104 | #: inc/config.class.php:254 105 | msgid "Username" 106 | msgstr "" 107 | 108 | #: inc/config.class.php:301 109 | msgid "Value for spécific authentication" 110 | msgstr "" 111 | 112 | #: inc/config.class.php:281 113 | msgid "Verify SSL certificate" 114 | msgstr "" 115 | -------------------------------------------------------------------------------- /setup.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | use Glpi\Plugin\Hooks; 33 | 34 | define('PLUGIN_SCCM_VERSION', '2.5.1'); 35 | define("PLUGIN_SCCM_MIN_GLPI", "11.0.00"); 36 | define("PLUGIN_SCCM_MAX_GLPI", "11.0.99"); 37 | 38 | function plugin_init_sccm() 39 | { 40 | /** @var array $PLUGIN_HOOKS */ 41 | global $PLUGIN_HOOKS; 42 | 43 | $plugin = new Plugin(); 44 | 45 | if ($plugin->isActivated("sccm") && Session::getLoginUserID() && Session::haveRight("config", UPDATE)) { 46 | $PLUGIN_HOOKS[Hooks::CONFIG_PAGE]['sccm'] = "front/config.form.php"; 47 | $PLUGIN_HOOKS[Hooks::MENU_TOADD]['sccm'] = ['config' => PluginSccmMenu::class]; 48 | } 49 | 50 | // Encryption 51 | $PLUGIN_HOOKS[Hooks::SECURED_FIELDS]['sccm'] = ['glpi_plugin_sccm_configs.sccmdb_password']; 52 | } 53 | 54 | /** 55 | * function to define the version for glpi for plugin 56 | * 57 | * @return array 58 | */ 59 | function plugin_version_sccm() 60 | { 61 | return [ 62 | 'name' => __s("SCCM", "sccm"), 63 | 'version' => PLUGIN_SCCM_VERSION, 64 | 'author' => "TECLIB'", 65 | 'license' => 'GPLv3', 66 | 'homepage' => 'https://github.com/pluginsGLPI/sccm', 67 | 'requirements' => [ 68 | 'glpi' => [ 69 | 'min' => PLUGIN_SCCM_MIN_GLPI, 70 | 'max' => PLUGIN_SCCM_MAX_GLPI, 71 | ], 72 | 'php' => [ 73 | 'exts' => [ 74 | 'sqlsrv' => [ 75 | 'required' => true, 76 | 'function' => 'sqlsrv_connect', 77 | ], 78 | 'curl' => [ 79 | 'required' => true, 80 | 'function' => 'curl_init', 81 | ], 82 | ], 83 | ], 84 | ], 85 | ]; 86 | } 87 | -------------------------------------------------------------------------------- /locales/en_GB.po: -------------------------------------------------------------------------------- 1 | # English translations for PACKAGE package. 2 | # Copyright (C) 2024 THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # Automatically generated, 2024. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: PACKAGE VERSION\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2024-09-20 07:06+0000\n" 11 | "PO-Revision-Date: 2024-09-20 07:06+0000\n" 12 | "Last-Translator: Automatically generated\n" 13 | "Language-Team: none\n" 14 | "Language: en_GB\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 19 | 20 | #: inc/sccm.class.php:522 21 | msgid "Collect is disabled by configuration." 22 | msgstr "Collect is disabled by configuration." 23 | 24 | #: inc/config.class.php:249 25 | msgid "Database name" 26 | msgstr "Database name" 27 | 28 | #: inc/config.class.php:239 29 | msgid "Enable SCCM synchronization" 30 | msgstr "Enable SCCM synchronization" 31 | 32 | #: inc/config.class.php:115 inc/config.class.php:124 33 | msgid "Error when using glpi_plugin_sccm_configs table." 34 | msgstr "Error when using glpi_plugin_sccm_configs table." 35 | 36 | #: inc/config.class.php:57 setup.php:67 37 | msgid "Interface - SCCM" 38 | msgstr "Interface - SCCM" 39 | 40 | #: inc/sccm.class.php:466 41 | msgid "Interface - SCCMCollect" 42 | msgstr "Interface - SCCMCollect" 43 | 44 | #: inc/sccm.class.php:469 45 | msgid "Interface - SCCMPush" 46 | msgstr "Interface - SCCMPush" 47 | 48 | #: inc/config.class.php:266 49 | msgid "Inventory server base URL" 50 | msgstr "Inventory server base URL" 51 | 52 | #: inc/config.class.php:261 53 | msgid "Password" 54 | msgstr "Password" 55 | 56 | #: inc/sccm.class.php:47 57 | msgid "Please, read the documentation before using that." 58 | msgstr "Please, read the documentation before using that." 59 | 60 | #: inc/sccm.class.php:677 61 | msgid "Push is disabled by configuration." 62 | msgstr "Push is disabled by configuration." 63 | 64 | #: inc/sccm.class.php:43 65 | msgid "SCCM" 66 | msgstr "SCCM" 67 | 68 | #: front/test.php:38 69 | msgid "SCCM - TEST" 70 | msgstr "SCCM - TEST" 71 | 72 | #: inc/menu.class.php:35 inc/menu.class.php:39 73 | msgid "SCCM Connector" 74 | msgstr "SCCM Connector" 75 | 76 | #: inc/config.class.php:291 77 | msgid "Send credentials to other hosts too" 78 | msgstr "Send credentials to other hosts too" 79 | 80 | #: inc/config.class.php:244 81 | msgid "Server hostname (MSSQL)" 82 | msgstr "Server hostname (MSSQL)" 83 | 84 | #: inc/config.class.php:53 front/config.form.php:59 85 | msgid "Setup - SCCM" 86 | msgstr "Setup - SCCM" 87 | 88 | #: front/showtable.php:87 89 | msgid "Synchronization is disabled by configuration." 90 | msgstr "Synchronization is disabled by configuration." 91 | 92 | #: inc/config.class.php:306 93 | msgid "Use LastHWScan as GLPI last inventory date" 94 | msgstr "Use LastHWScan as GLPI last inventory date" 95 | 96 | #: inc/config.class.php:286 97 | msgid "Use NLTM authentication" 98 | msgstr "Use NLTM authentication" 99 | 100 | #: inc/config.class.php:296 101 | msgid "Use specific authentication information" 102 | msgstr "Use specific authentication information" 103 | 104 | #: inc/config.class.php:254 105 | msgid "Username" 106 | msgstr "Username" 107 | 108 | #: inc/config.class.php:301 109 | msgid "Value for spécific authentication" 110 | msgstr "Value for spécific authentication" 111 | 112 | #: inc/config.class.php:281 113 | msgid "Verify SSL certificate" 114 | msgstr "Verify SSL certificate" 115 | -------------------------------------------------------------------------------- /locales/fi_FI.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Markku Vepsä, 2018 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2024-09-18 14:11+0000\n" 15 | "PO-Revision-Date: 2018-08-21 14:04+0000\n" 16 | "Last-Translator: Markku Vepsä, 2018\n" 17 | "Language-Team: Finnish (Finland) (https://app.transifex.com/teclib/teams/28042/fi_FI/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: fi_FI\n" 22 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 23 | 24 | #: inc/sccm.class.php:522 25 | msgid "Collect is disabled by configuration." 26 | msgstr "\"Collect\" on poistettu käytöstä asetusten perusteella." 27 | 28 | #: inc/config.class.php:249 29 | msgid "Database name" 30 | msgstr "Tietokannan nimi" 31 | 32 | #: inc/config.class.php:239 33 | msgid "Enable SCCM synchronization" 34 | msgstr "Ota SCCM-synkronointi käyttöön" 35 | 36 | #: inc/config.class.php:115 inc/config.class.php:124 37 | msgid "Error when using glpi_plugin_sccm_configs table." 38 | msgstr "Virhe käytettäessä glpi_plugin_sccm_configs -taulukkoa." 39 | 40 | #: inc/config.class.php:57 setup.php:67 41 | msgid "Interface - SCCM" 42 | msgstr "Liitäntä - SCCM" 43 | 44 | #: inc/sccm.class.php:466 45 | msgid "Interface - SCCMCollect" 46 | msgstr "Liitäntä - SCCMCollect" 47 | 48 | #: inc/sccm.class.php:469 49 | msgid "Interface - SCCMPush" 50 | msgstr "Liitäntä - SCCMPush" 51 | 52 | #: inc/config.class.php:266 53 | msgid "Inventory server base URL" 54 | msgstr "" 55 | 56 | #: inc/config.class.php:261 57 | msgid "Password" 58 | msgstr "Salasana" 59 | 60 | #: inc/sccm.class.php:47 61 | msgid "Please, read the documentation before using that." 62 | msgstr "Lue käyttöohjeet ennen käyttöä." 63 | 64 | #: inc/sccm.class.php:677 65 | msgid "Push is disabled by configuration." 66 | msgstr "\"Push\" on poistettu käytöstä asetusten perusteella." 67 | 68 | #: inc/sccm.class.php:43 69 | msgid "SCCM" 70 | msgstr "SCCM" 71 | 72 | #: front/test.php:38 73 | msgid "SCCM - TEST" 74 | msgstr "SCCM - Testi" 75 | 76 | #: inc/menu.class.php:35 inc/menu.class.php:39 77 | msgid "SCCM Connector" 78 | msgstr "SCCM-liitin" 79 | 80 | #: inc/config.class.php:291 81 | msgid "Send credentials to other hosts too" 82 | msgstr "Lähetä valtuutukset myös muille isännille" 83 | 84 | #: inc/config.class.php:244 85 | msgid "Server hostname (MSSQL)" 86 | msgstr "Palvelimen isäntänimi (MSSQL)" 87 | 88 | #: inc/config.class.php:53 front/config.form.php:59 89 | msgid "Setup - SCCM" 90 | msgstr "Asetukset - SCCM" 91 | 92 | #: front/showtable.php:87 93 | msgid "Synchronization is disabled by configuration." 94 | msgstr "Synkronointi on poistettu käytöstä asetusten perusteella." 95 | 96 | #: inc/config.class.php:306 97 | msgid "Use LastHWScan as GLPI last inventory date" 98 | msgstr "" 99 | 100 | #: inc/config.class.php:286 101 | msgid "Use NLTM authentication" 102 | msgstr "Käytä NLTM-todennusta" 103 | 104 | #: inc/config.class.php:296 105 | msgid "Use specific authentication information" 106 | msgstr "Käytä tiettyjä todennustietoja" 107 | 108 | #: inc/config.class.php:254 109 | msgid "Username" 110 | msgstr "Käyttäjätunnus" 111 | 112 | #: inc/config.class.php:301 113 | msgid "Value for spécific authentication" 114 | msgstr "Todennustietojen arvo" 115 | 116 | #: inc/config.class.php:281 117 | msgid "Verify SSL certificate" 118 | msgstr "Vahvista SSL-varmenne" 119 | -------------------------------------------------------------------------------- /locales/it_IT.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Cédric Anne, 2019 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2024-09-18 14:11+0000\n" 15 | "PO-Revision-Date: 2018-08-21 14:04+0000\n" 16 | "Last-Translator: Cédric Anne, 2019\n" 17 | "Language-Team: Italian (Italy) (https://app.transifex.com/teclib/teams/28042/it_IT/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: it_IT\n" 22 | "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 23 | 24 | #: inc/sccm.class.php:522 25 | msgid "Collect is disabled by configuration." 26 | msgstr "La raccolta è disabilitata dalla configurazione." 27 | 28 | #: inc/config.class.php:249 29 | msgid "Database name" 30 | msgstr "Nome del database" 31 | 32 | #: inc/config.class.php:239 33 | msgid "Enable SCCM synchronization" 34 | msgstr "Abilita sincronizzazione SCCM" 35 | 36 | #: inc/config.class.php:115 inc/config.class.php:124 37 | msgid "Error when using glpi_plugin_sccm_configs table." 38 | msgstr "Errore durante l'utilizzo della tabella glpi_plugin_sccm_configs." 39 | 40 | #: inc/config.class.php:57 setup.php:67 41 | msgid "Interface - SCCM" 42 | msgstr "Interfaccia - SCCM" 43 | 44 | #: inc/sccm.class.php:466 45 | msgid "Interface - SCCMCollect" 46 | msgstr "Interfaccia: SCCMCollect" 47 | 48 | #: inc/sccm.class.php:469 49 | msgid "Interface - SCCMPush" 50 | msgstr "Interfaccia: SCCMPush" 51 | 52 | #: inc/config.class.php:266 53 | msgid "Inventory server base URL" 54 | msgstr "" 55 | 56 | #: inc/config.class.php:261 57 | msgid "Password" 58 | msgstr "Password" 59 | 60 | #: inc/sccm.class.php:47 61 | msgid "Please, read the documentation before using that." 62 | msgstr "Per favore, leggi la documentazione prima di usarla." 63 | 64 | #: inc/sccm.class.php:677 65 | msgid "Push is disabled by configuration." 66 | msgstr "Push è disabilitato dalla configurazione." 67 | 68 | #: inc/sccm.class.php:43 69 | msgid "SCCM" 70 | msgstr "SCCM" 71 | 72 | #: front/test.php:38 73 | msgid "SCCM - TEST" 74 | msgstr "SCCM - TEST" 75 | 76 | #: inc/menu.class.php:35 inc/menu.class.php:39 77 | msgid "SCCM Connector" 78 | msgstr "Connettore SCCM" 79 | 80 | #: inc/config.class.php:291 81 | msgid "Send credentials to other hosts too" 82 | msgstr "Invia credenziali anche ad altri host" 83 | 84 | #: inc/config.class.php:244 85 | msgid "Server hostname (MSSQL)" 86 | msgstr "Nome del server (MSSQL)" 87 | 88 | #: inc/config.class.php:53 front/config.form.php:59 89 | msgid "Setup - SCCM" 90 | msgstr "Installazione - SCCM" 91 | 92 | #: front/showtable.php:87 93 | msgid "Synchronization is disabled by configuration." 94 | msgstr "La sincronizzazione è disabilitata dalla configurazione." 95 | 96 | #: inc/config.class.php:306 97 | msgid "Use LastHWScan as GLPI last inventory date" 98 | msgstr "" 99 | 100 | #: inc/config.class.php:286 101 | msgid "Use NLTM authentication" 102 | msgstr "Usa autenticazione NLTM" 103 | 104 | #: inc/config.class.php:296 105 | msgid "Use specific authentication information" 106 | msgstr "Usa informazioni di autenticazione specifiche" 107 | 108 | #: inc/config.class.php:254 109 | msgid "Username" 110 | msgstr "Nome utente" 111 | 112 | #: inc/config.class.php:301 113 | msgid "Value for spécific authentication" 114 | msgstr "Valore per l'autenticazione specifica" 115 | 116 | #: inc/config.class.php:281 117 | msgid "Verify SSL certificate" 118 | msgstr "Verifica certificato SSL" 119 | -------------------------------------------------------------------------------- /locales/cs_CZ.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Pavel Borecki , 2018 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2024-09-18 14:11+0000\n" 15 | "PO-Revision-Date: 2018-08-21 14:04+0000\n" 16 | "Last-Translator: Pavel Borecki , 2018\n" 17 | "Language-Team: Czech (Czech Republic) (https://app.transifex.com/teclib/teams/28042/cs_CZ/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: cs_CZ\n" 22 | "Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" 23 | 24 | #: inc/sccm.class.php:522 25 | msgid "Collect is disabled by configuration." 26 | msgstr "Shromažďování je vypnuté nastavením." 27 | 28 | #: inc/config.class.php:249 29 | msgid "Database name" 30 | msgstr "Název databáze" 31 | 32 | #: inc/config.class.php:239 33 | msgid "Enable SCCM synchronization" 34 | msgstr "Zapnout synchronizaci s SCCM" 35 | 36 | #: inc/config.class.php:115 inc/config.class.php:124 37 | msgid "Error when using glpi_plugin_sccm_configs table." 38 | msgstr "Chyba při použití tabulky glpi_plugin_sccm_configs." 39 | 40 | #: inc/config.class.php:57 setup.php:67 41 | msgid "Interface - SCCM" 42 | msgstr "Rozhraní – SCCM" 43 | 44 | #: inc/sccm.class.php:466 45 | msgid "Interface - SCCMCollect" 46 | msgstr "Rozhraní – SCCMCollect" 47 | 48 | #: inc/sccm.class.php:469 49 | msgid "Interface - SCCMPush" 50 | msgstr "Rozhraní – SCCMPush" 51 | 52 | #: inc/config.class.php:266 53 | msgid "Inventory server base URL" 54 | msgstr "" 55 | 56 | #: inc/config.class.php:261 57 | msgid "Password" 58 | msgstr "Heslo" 59 | 60 | #: inc/sccm.class.php:47 61 | msgid "Please, read the documentation before using that." 62 | msgstr "Před použitím si přečtete dokumentaci." 63 | 64 | #: inc/sccm.class.php:677 65 | msgid "Push is disabled by configuration." 66 | msgstr "Odesílání je vypnuté nastavením." 67 | 68 | #: inc/sccm.class.php:43 69 | msgid "SCCM" 70 | msgstr "SCCM" 71 | 72 | #: front/test.php:38 73 | msgid "SCCM - TEST" 74 | msgstr "SCCM – TEST" 75 | 76 | #: inc/menu.class.php:35 inc/menu.class.php:39 77 | msgid "SCCM Connector" 78 | msgstr "Napojení na SCCM" 79 | 80 | #: inc/config.class.php:291 81 | msgid "Send credentials to other hosts too" 82 | msgstr "Poslat přihlašovací údaje také na ostatní stroje" 83 | 84 | #: inc/config.class.php:244 85 | msgid "Server hostname (MSSQL)" 86 | msgstr "Název serveru (MSSQL)" 87 | 88 | #: inc/config.class.php:53 front/config.form.php:59 89 | msgid "Setup - SCCM" 90 | msgstr "Nastavení – SCCM" 91 | 92 | #: front/showtable.php:87 93 | msgid "Synchronization is disabled by configuration." 94 | msgstr "Synchronizace je vypnutá nastavením." 95 | 96 | #: inc/config.class.php:306 97 | msgid "Use LastHWScan as GLPI last inventory date" 98 | msgstr "" 99 | 100 | #: inc/config.class.php:286 101 | msgid "Use NLTM authentication" 102 | msgstr "Použít NLTM ověřování" 103 | 104 | #: inc/config.class.php:296 105 | msgid "Use specific authentication information" 106 | msgstr "Použít konkrétní ověřovací informace" 107 | 108 | #: inc/config.class.php:254 109 | msgid "Username" 110 | msgstr "Uživatelské jméno" 111 | 112 | #: inc/config.class.php:301 113 | msgid "Value for spécific authentication" 114 | msgstr "Hodnota pro konkrétní ověření" 115 | 116 | #: inc/config.class.php:281 117 | msgid "Verify SSL certificate" 118 | msgstr "Ověřit SSL certifikát" 119 | -------------------------------------------------------------------------------- /locales/pt_PT.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Rui Melo , 2019 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2024-09-18 14:11+0000\n" 15 | "PO-Revision-Date: 2018-08-21 14:04+0000\n" 16 | "Last-Translator: Rui Melo , 2019\n" 17 | "Language-Team: Portuguese (Portugal) (https://app.transifex.com/teclib/teams/28042/pt_PT/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: pt_PT\n" 22 | "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 23 | 24 | #: inc/sccm.class.php:522 25 | msgid "Collect is disabled by configuration." 26 | msgstr "Recolha é desativada pela configuração." 27 | 28 | #: inc/config.class.php:249 29 | msgid "Database name" 30 | msgstr "Nome da base de dados" 31 | 32 | #: inc/config.class.php:239 33 | msgid "Enable SCCM synchronization" 34 | msgstr "Ativar a sincronização SCCM" 35 | 36 | #: inc/config.class.php:115 inc/config.class.php:124 37 | msgid "Error when using glpi_plugin_sccm_configs table." 38 | msgstr "Erro ao usar a tabela glpi_plugin_sccm_configs." 39 | 40 | #: inc/config.class.php:57 setup.php:67 41 | msgid "Interface - SCCM" 42 | msgstr "Interface - SCCM" 43 | 44 | #: inc/sccm.class.php:466 45 | msgid "Interface - SCCMCollect" 46 | msgstr "Interface - SCCMCollect" 47 | 48 | #: inc/sccm.class.php:469 49 | msgid "Interface - SCCMPush" 50 | msgstr "Interface - SCCMPush" 51 | 52 | #: inc/config.class.php:266 53 | msgid "Inventory server base URL" 54 | msgstr "" 55 | 56 | #: inc/config.class.php:261 57 | msgid "Password" 58 | msgstr "Senha" 59 | 60 | #: inc/sccm.class.php:47 61 | msgid "Please, read the documentation before using that." 62 | msgstr "Por favor, leia a documentação antes de usar isso." 63 | 64 | #: inc/sccm.class.php:677 65 | msgid "Push is disabled by configuration." 66 | msgstr "O impulso é desativado pela configuração." 67 | 68 | #: inc/sccm.class.php:43 69 | msgid "SCCM" 70 | msgstr "SCCM" 71 | 72 | #: front/test.php:38 73 | msgid "SCCM - TEST" 74 | msgstr "SCCM - TESTE" 75 | 76 | #: inc/menu.class.php:35 inc/menu.class.php:39 77 | msgid "SCCM Connector" 78 | msgstr "Conetor SCCM" 79 | 80 | #: inc/config.class.php:291 81 | msgid "Send credentials to other hosts too" 82 | msgstr "Envie credenciais para outros hosts também" 83 | 84 | #: inc/config.class.php:244 85 | msgid "Server hostname (MSSQL)" 86 | msgstr "Nome de host do servidor (MSSQL)" 87 | 88 | #: inc/config.class.php:53 front/config.form.php:59 89 | msgid "Setup - SCCM" 90 | msgstr "Configuração - SCCM" 91 | 92 | #: front/showtable.php:87 93 | msgid "Synchronization is disabled by configuration." 94 | msgstr "A sincronização é desativada pela configuração." 95 | 96 | #: inc/config.class.php:306 97 | msgid "Use LastHWScan as GLPI last inventory date" 98 | msgstr "" 99 | 100 | #: inc/config.class.php:286 101 | msgid "Use NLTM authentication" 102 | msgstr "Use autenticação NLTM" 103 | 104 | #: inc/config.class.php:296 105 | msgid "Use specific authentication information" 106 | msgstr "Usar informações de autenticação específicas" 107 | 108 | #: inc/config.class.php:254 109 | msgid "Username" 110 | msgstr "Nome de utilizador" 111 | 112 | #: inc/config.class.php:301 113 | msgid "Value for spécific authentication" 114 | msgstr "Valor para autenticação específica" 115 | 116 | #: inc/config.class.php:281 117 | msgid "Verify SSL certificate" 118 | msgstr "Verificar certificação SSL" 119 | -------------------------------------------------------------------------------- /locales/es_EC.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Soporte Infraestructura Standby, 2023 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2024-09-18 14:11+0000\n" 15 | "PO-Revision-Date: 2018-08-21 14:04+0000\n" 16 | "Last-Translator: Soporte Infraestructura Standby, 2023\n" 17 | "Language-Team: Spanish (Ecuador) (https://app.transifex.com/teclib/teams/28042/es_EC/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: es_EC\n" 22 | "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 23 | 24 | #: inc/sccm.class.php:522 25 | msgid "Collect is disabled by configuration." 26 | msgstr "Recopilar está desactivado por configuración." 27 | 28 | #: inc/config.class.php:249 29 | msgid "Database name" 30 | msgstr "Nombre de la base de datos" 31 | 32 | #: inc/config.class.php:239 33 | msgid "Enable SCCM synchronization" 34 | msgstr "Activar la sincronización de SCCM" 35 | 36 | #: inc/config.class.php:115 inc/config.class.php:124 37 | msgid "Error when using glpi_plugin_sccm_configs table." 38 | msgstr "Error al utilizar la tabla glpi_plugin_sccm_configs." 39 | 40 | #: inc/config.class.php:57 setup.php:67 41 | msgid "Interface - SCCM" 42 | msgstr "Interfaz - SCCM" 43 | 44 | #: inc/sccm.class.php:466 45 | msgid "Interface - SCCMCollect" 46 | msgstr "Interfaz - SCCMCollect" 47 | 48 | #: inc/sccm.class.php:469 49 | msgid "Interface - SCCMPush" 50 | msgstr "Interfaz - SCCMPush" 51 | 52 | #: inc/config.class.php:266 53 | msgid "Inventory server base URL" 54 | msgstr "URL base del servidor de inventario" 55 | 56 | #: inc/config.class.php:261 57 | msgid "Password" 58 | msgstr "Contraseña" 59 | 60 | #: inc/sccm.class.php:47 61 | msgid "Please, read the documentation before using that." 62 | msgstr "Por favor, lea la documentación antes de utilizarlo." 63 | 64 | #: inc/sccm.class.php:677 65 | msgid "Push is disabled by configuration." 66 | msgstr "Push está desactivado por configuración." 67 | 68 | #: inc/sccm.class.php:43 69 | msgid "SCCM" 70 | msgstr "SCCM" 71 | 72 | #: front/test.php:38 73 | msgid "SCCM - TEST" 74 | msgstr "SCCM - PRUEBA" 75 | 76 | #: inc/menu.class.php:35 inc/menu.class.php:39 77 | msgid "SCCM Connector" 78 | msgstr "Conector SCCM" 79 | 80 | #: inc/config.class.php:291 81 | msgid "Send credentials to other hosts too" 82 | msgstr "Enviar credenciales también a otros hosts" 83 | 84 | #: inc/config.class.php:244 85 | msgid "Server hostname (MSSQL)" 86 | msgstr "Nombre del servidor (MSSQL)" 87 | 88 | #: inc/config.class.php:53 front/config.form.php:59 89 | msgid "Setup - SCCM" 90 | msgstr "Configuración - SCCM" 91 | 92 | #: front/showtable.php:87 93 | msgid "Synchronization is disabled by configuration." 94 | msgstr "La sincronización se desactiva por configuración." 95 | 96 | #: inc/config.class.php:306 97 | msgid "Use LastHWScan as GLPI last inventory date" 98 | msgstr "" 99 | 100 | #: inc/config.class.php:286 101 | msgid "Use NLTM authentication" 102 | msgstr "Utilizar la autenticación NLTM" 103 | 104 | #: inc/config.class.php:296 105 | msgid "Use specific authentication information" 106 | msgstr "Utilizar información de autenticación específica" 107 | 108 | #: inc/config.class.php:254 109 | msgid "Username" 110 | msgstr "Nombre de usuario" 111 | 112 | #: inc/config.class.php:301 113 | msgid "Value for spécific authentication" 114 | msgstr "Valor para la autenticación específica" 115 | 116 | #: inc/config.class.php:281 117 | msgid "Verify SSL certificate" 118 | msgstr "Verificar certificado SSL" 119 | -------------------------------------------------------------------------------- /locales/tr_TR.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Kaya Zeren , 2024 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2024-09-20 00:43+0000\n" 15 | "PO-Revision-Date: 2018-08-21 14:04+0000\n" 16 | "Last-Translator: Kaya Zeren , 2024\n" 17 | "Language-Team: Turkish (Turkey) (https://app.transifex.com/teclib/teams/28042/tr_TR/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: tr_TR\n" 22 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 23 | 24 | #: inc/sccm.class.php:522 25 | msgid "Collect is disabled by configuration." 26 | msgstr "Derleme seçeneği yapılandırmada devre dışı bırakılmış." 27 | 28 | #: inc/config.class.php:249 29 | msgid "Database name" 30 | msgstr "Veri tabanı adı" 31 | 32 | #: inc/config.class.php:239 33 | msgid "Enable SCCM synchronization" 34 | msgstr "SCCM eşitlemesi yapılsın" 35 | 36 | #: inc/config.class.php:115 inc/config.class.php:124 37 | msgid "Error when using glpi_plugin_sccm_configs table." 38 | msgstr "glpi_plugin_sccm_configs tablosu kullanılırken sorun çıktı." 39 | 40 | #: inc/config.class.php:57 setup.php:67 41 | msgid "Interface - SCCM" 42 | msgstr "Arayüz - SCCM" 43 | 44 | #: inc/sccm.class.php:466 45 | msgid "Interface - SCCMCollect" 46 | msgstr "Arayüz - SCCMCollect" 47 | 48 | #: inc/sccm.class.php:469 49 | msgid "Interface - SCCMPush" 50 | msgstr "Arayüz - SCCMPush" 51 | 52 | #: inc/config.class.php:266 53 | msgid "Inventory server base URL" 54 | msgstr "Envanter sunucusunun temel adresi" 55 | 56 | #: inc/config.class.php:261 57 | msgid "Password" 58 | msgstr "Parola" 59 | 60 | #: inc/sccm.class.php:47 61 | msgid "Please, read the documentation before using that." 62 | msgstr "Lütfen kullanmadan önce belgeleri okuyun." 63 | 64 | #: inc/sccm.class.php:677 65 | msgid "Push is disabled by configuration." 66 | msgstr "İtme seçeneği yapılandırmada devre dışı bırakılmış." 67 | 68 | #: inc/sccm.class.php:43 69 | msgid "SCCM" 70 | msgstr "SCCM" 71 | 72 | #: front/test.php:38 73 | msgid "SCCM - TEST" 74 | msgstr "SCCM - DENEME" 75 | 76 | #: inc/menu.class.php:35 inc/menu.class.php:39 77 | msgid "SCCM Connector" 78 | msgstr "SCCM bağlantısı" 79 | 80 | #: inc/config.class.php:291 81 | msgid "Send credentials to other hosts too" 82 | msgstr "Kimlik doğrulama bilgileri diğer sunuculara da gönderilsin" 83 | 84 | #: inc/config.class.php:244 85 | msgid "Server hostname (MSSQL)" 86 | msgstr "Sunucu adı (MSSQL)" 87 | 88 | #: inc/config.class.php:53 front/config.form.php:59 89 | msgid "Setup - SCCM" 90 | msgstr "Kurulum - SCCM" 91 | 92 | #: front/showtable.php:87 93 | msgid "Synchronization is disabled by configuration." 94 | msgstr "Eşitleme seçeneği yapılandırmadan devre dışı bırakılmış." 95 | 96 | #: inc/config.class.php:306 97 | msgid "Use LastHWScan as GLPI last inventory date" 98 | msgstr "Son GLPI envanteri tarihi için LastHWScan kullanılsın" 99 | 100 | #: inc/config.class.php:286 101 | msgid "Use NLTM authentication" 102 | msgstr "Kimlik doğrulaması için NLTM kullanılsın" 103 | 104 | #: inc/config.class.php:296 105 | msgid "Use specific authentication information" 106 | msgstr "Belirli kimlik doğrulama bilgileri kullanılsın" 107 | 108 | #: inc/config.class.php:254 109 | msgid "Username" 110 | msgstr "Kullanıcı adı" 111 | 112 | #: inc/config.class.php:301 113 | msgid "Value for spécific authentication" 114 | msgstr "Belirli kimlik doğrulama değeri" 115 | 116 | #: inc/config.class.php:281 117 | msgid "Verify SSL certificate" 118 | msgstr "SSL sertifikası doğrulansın" 119 | -------------------------------------------------------------------------------- /locales/hr_HR.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Milo Ivir , 2023 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2024-09-18 14:11+0000\n" 15 | "PO-Revision-Date: 2018-08-21 14:04+0000\n" 16 | "Last-Translator: Milo Ivir , 2023\n" 17 | "Language-Team: Croatian (Croatia) (https://app.transifex.com/teclib/teams/28042/hr_HR/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: hr_HR\n" 22 | "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" 23 | 24 | #: inc/sccm.class.php:522 25 | msgid "Collect is disabled by configuration." 26 | msgstr "Slanje upita (collect) je deaktivirano u konfiguraciji." 27 | 28 | #: inc/config.class.php:249 29 | msgid "Database name" 30 | msgstr "Ime baze podataka" 31 | 32 | #: inc/config.class.php:239 33 | msgid "Enable SCCM synchronization" 34 | msgstr "Aktiviraj SCCM sinkronizaciju" 35 | 36 | #: inc/config.class.php:115 inc/config.class.php:124 37 | msgid "Error when using glpi_plugin_sccm_configs table." 38 | msgstr "Greška pri upotrebi tablice glpi_plugin_sccm_configs." 39 | 40 | #: inc/config.class.php:57 setup.php:67 41 | msgid "Interface - SCCM" 42 | msgstr "Sučelje – SCCM" 43 | 44 | #: inc/sccm.class.php:466 45 | msgid "Interface - SCCMCollect" 46 | msgstr "Sučelje – SCCMCollect (upit)" 47 | 48 | #: inc/sccm.class.php:469 49 | msgid "Interface - SCCMPush" 50 | msgstr "Sučelje – SCCMPush (umetanje datoteka)" 51 | 52 | #: inc/config.class.php:266 53 | msgid "Inventory server base URL" 54 | msgstr "Osnovni URL poslužitelja inventara" 55 | 56 | #: inc/config.class.php:261 57 | msgid "Password" 58 | msgstr "Lozinka" 59 | 60 | #: inc/sccm.class.php:47 61 | msgid "Please, read the documentation before using that." 62 | msgstr "Prije upotrebe pročitaj dokumentaciju." 63 | 64 | #: inc/sccm.class.php:677 65 | msgid "Push is disabled by configuration." 66 | msgstr "Umetanje je deaktivirano u konfiguraciji." 67 | 68 | #: inc/sccm.class.php:43 69 | msgid "SCCM" 70 | msgstr "SCCM" 71 | 72 | #: front/test.php:38 73 | msgid "SCCM - TEST" 74 | msgstr "SCCM – TEST" 75 | 76 | #: inc/menu.class.php:35 inc/menu.class.php:39 77 | msgid "SCCM Connector" 78 | msgstr "SCCM konektor" 79 | 80 | #: inc/config.class.php:291 81 | msgid "Send credentials to other hosts too" 82 | msgstr "Pošalji vjerodajnice i ostalim računalima" 83 | 84 | #: inc/config.class.php:244 85 | msgid "Server hostname (MSSQL)" 86 | msgstr "Ime računala poslužitelja (MSSQL)" 87 | 88 | #: inc/config.class.php:53 front/config.form.php:59 89 | msgid "Setup - SCCM" 90 | msgstr "Postavljanje – SCCM" 91 | 92 | #: front/showtable.php:87 93 | msgid "Synchronization is disabled by configuration." 94 | msgstr "Sinkronizacija je deaktivirana u konfiguraciji." 95 | 96 | #: inc/config.class.php:306 97 | msgid "Use LastHWScan as GLPI last inventory date" 98 | msgstr "" 99 | 100 | #: inc/config.class.php:286 101 | msgid "Use NLTM authentication" 102 | msgstr "Koristi NLTM autentifikaciju" 103 | 104 | #: inc/config.class.php:296 105 | msgid "Use specific authentication information" 106 | msgstr "Koristi određene podatke autentifikacije" 107 | 108 | #: inc/config.class.php:254 109 | msgid "Username" 110 | msgstr "Korisničko ime" 111 | 112 | #: inc/config.class.php:301 113 | msgid "Value for spécific authentication" 114 | msgstr "Vrijednost za određenu autentifikaciju" 115 | 116 | #: inc/config.class.php:281 117 | msgid "Verify SSL certificate" 118 | msgstr "Provjeri SSL certifikat" 119 | -------------------------------------------------------------------------------- /locales/fr_FR.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Cédric Anne, 2023 8 | # Stanislas , 2024 9 | # 10 | #, fuzzy 11 | msgid "" 12 | msgstr "" 13 | "Project-Id-Version: PACKAGE VERSION\n" 14 | "Report-Msgid-Bugs-To: \n" 15 | "POT-Creation-Date: 2024-09-20 07:06+0000\n" 16 | "PO-Revision-Date: 2018-08-21 14:04+0000\n" 17 | "Last-Translator: Stanislas , 2024\n" 18 | "Language-Team: French (France) (https://app.transifex.com/teclib/teams/28042/fr_FR/)\n" 19 | "MIME-Version: 1.0\n" 20 | "Content-Type: text/plain; charset=UTF-8\n" 21 | "Content-Transfer-Encoding: 8bit\n" 22 | "Language: fr_FR\n" 23 | "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 24 | 25 | #: inc/sccm.class.php:522 26 | msgid "Collect is disabled by configuration." 27 | msgstr "La collecte est désactivé par la configuration" 28 | 29 | #: inc/config.class.php:249 30 | msgid "Database name" 31 | msgstr "Nom de la base de donnée SCCM" 32 | 33 | #: inc/config.class.php:239 34 | msgid "Enable SCCM synchronization" 35 | msgstr "Activer la synchronisation SCCM" 36 | 37 | #: inc/config.class.php:115 inc/config.class.php:124 38 | msgid "Error when using glpi_plugin_sccm_configs table." 39 | msgstr "Erreur avec la table 'glpi_plugin_sccm_configs'" 40 | 41 | #: inc/config.class.php:57 setup.php:67 42 | msgid "Interface - SCCM" 43 | msgstr "Interface - SCCM" 44 | 45 | #: inc/sccm.class.php:466 46 | msgid "Interface - SCCMCollect" 47 | msgstr "Interface - SCCMCollect" 48 | 49 | #: inc/sccm.class.php:469 50 | msgid "Interface - SCCMPush" 51 | msgstr "Interface - SCCMPush" 52 | 53 | #: inc/config.class.php:266 54 | msgid "Inventory server base URL" 55 | msgstr "URL racine du serveur d'inventaire" 56 | 57 | #: inc/config.class.php:261 58 | msgid "Password" 59 | msgstr "Mot de passe utilisateur SCCM" 60 | 61 | #: inc/sccm.class.php:47 62 | msgid "Please, read the documentation before using that." 63 | msgstr "Merci de lire la documentation avant d'utiliser cette URL." 64 | 65 | #: inc/sccm.class.php:677 66 | msgid "Push is disabled by configuration." 67 | msgstr "L'implantation est désactivé par la configuration" 68 | 69 | #: inc/sccm.class.php:43 70 | msgid "SCCM" 71 | msgstr "SCCM" 72 | 73 | #: front/test.php:38 74 | msgid "SCCM - TEST" 75 | msgstr "SCCM - TEST" 76 | 77 | #: inc/menu.class.php:35 inc/menu.class.php:39 78 | msgid "SCCM Connector" 79 | msgstr "Connecteur SCCM" 80 | 81 | #: inc/config.class.php:291 82 | msgid "Send credentials to other hosts too" 83 | msgstr "Faire suivre les informations d'authentifciation au serveur" 84 | 85 | #: inc/config.class.php:244 86 | msgid "Server hostname (MSSQL)" 87 | msgstr "Hostname (MSSQL) ou IP" 88 | 89 | #: inc/config.class.php:53 front/config.form.php:59 90 | msgid "Setup - SCCM" 91 | msgstr "Configuration - SCCM" 92 | 93 | #: front/showtable.php:87 94 | msgid "Synchronization is disabled by configuration." 95 | msgstr "La synchonisation est désactivée dans la configuration." 96 | 97 | #: inc/config.class.php:306 98 | msgid "Use LastHWScan as GLPI last inventory date" 99 | msgstr "Utiliser LastHWScan comme date de dernier inventaire" 100 | 101 | #: inc/config.class.php:286 102 | msgid "Use NLTM authentication" 103 | msgstr "Utiliser l'authentification NTLM" 104 | 105 | #: inc/config.class.php:296 106 | msgid "Use specific authentication information" 107 | msgstr "Utiliser des informations d'authentification spécifique" 108 | 109 | #: inc/config.class.php:254 110 | msgid "Username" 111 | msgstr "Utilisateur SCCM" 112 | 113 | #: inc/config.class.php:301 114 | msgid "Value for spécific authentication" 115 | msgstr "Valeur à transmettre" 116 | 117 | #: inc/config.class.php:281 118 | msgid "Verify SSL certificate" 119 | msgstr "Vérification du certificat SSL" 120 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a report to help us improve sccm 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | 8 | Dear GLPI plugin user. 9 | 10 | **⚠️ Please never use standard issues to report security problems. See [security policy](https://github.com/pluginsGLPI/sccm/security/policy) for more details. ⚠️** 11 | 12 | BEFORE SUBMITTING YOUR ISSUE, please make sure to read and follow these steps: 13 | 14 | * We do not track feature requests nor enhancements here. Propose them on the [suggest dedicated site](https://suggest.glpi-project.org). 15 | * Keep this tracker in ENGLISH. If you want support in your language, the [community forum](https://forum.glpi-project.org) is the best place. 16 | * Always try to reproduce your issue at least on latest stable release. 17 | 18 | The GLPI team. 19 | - type: markdown 20 | attributes: 21 | value: | 22 | ## Professional Support 23 | 24 | We do not guarantee any processing / resolution time for community issues. 25 | 26 | If you need a quick fix or any guarantee, you should consider to buy a GLPI Network Subscription. 27 | 28 | More information here: https://glpi-project.org/subscriptions/ 29 | - type: checkboxes 30 | id: terms 31 | attributes: 32 | label: Code of Conduct 33 | description: By submitting this issue, you agree to follow hereinabove rules and [Contribution guide](https://github.com/glpi-project/glpi/blob/main/CONTRIBUTING.md) 34 | options: 35 | - label: I agree to follow this project's Code of Conduct 36 | validations: 37 | required: true 38 | - type: checkboxes 39 | attributes: 40 | label: Is there an existing issue for this? 41 | description: Please search to see if an issue already exists for the bug you encountered. 42 | options: 43 | - label: I have searched the existing issues 44 | validations: 45 | required: true 46 | - type: input 47 | id: glpi-version 48 | attributes: 49 | label: GLPI Version 50 | description: What version of our GLPI are you running? 51 | validations: 52 | required: true 53 | - type: input 54 | id: plugin-version 55 | attributes: 56 | label: Plugin version 57 | description: What version of `sccm` are you running? 58 | validations: 59 | required: true 60 | - type: textarea 61 | attributes: 62 | label: Bug description 63 | description: A concise description of the problem you are experiencing and what you expected to happen. 64 | validations: 65 | required: false 66 | - type: textarea 67 | id: logs 68 | attributes: 69 | label: Relevant log output 70 | description: | 71 | Please copy and paste any relevant log output. Find them in `*-error.log` files under `glpi/files/_log/`. 72 | 73 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 74 | render: shell 75 | - type: input 76 | id: url 77 | attributes: 78 | label: Page URL 79 | description: If applicable, page URL where the bug happens. 80 | validations: 81 | required: false 82 | - type: textarea 83 | attributes: 84 | label: Steps To reproduce 85 | description: Steps to reproduce the behavior. 86 | placeholder: | 87 | 1. With this config... 88 | 2. Go to... 89 | 3. Scroll down to... 90 | 4. See error... 91 | validations: 92 | required: false 93 | - type: textarea 94 | attributes: 95 | label: Your GLPI setup information 96 | description: Please copy and paste information you will find in GLPI in `Setup > General` menu, `System` tab. 97 | validations: 98 | required: false 99 | - type: textarea 100 | attributes: 101 | label: Anything else? 102 | description: Add any other context about the problem here. 103 | validations: 104 | required: false 105 | -------------------------------------------------------------------------------- /templates/config.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | # ------------------------------------------------------------------------- 3 | # SCCM plugin for GLPI 4 | # ------------------------------------------------------------------------- 5 | # 6 | # LICENSE 7 | # 8 | # This file is part of SCCM. 9 | # 10 | # SCCM is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # SCCM is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with SCCM. If not, see . 22 | # ------------------------------------------------------------------------- 23 | # @author François Legastelois 24 | # @copyright Copyright (C) 2014-2023 by SCCM plugin team. 25 | # @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 26 | # @link https://github.com/pluginsGLPI/sccm 27 | # ------------------------------------------------------------------------- 28 | #} 29 | 30 | {% extends "generic_show_form.html.twig" %} 31 | {% import "components/form/fields_macros.html.twig" as fields %} 32 | 33 | {% block more_fields %} 34 | 35 |
36 | 37 | 38 | 39 | {{ fields.checkboxField( 40 | 'active_sync', 41 | item.fields['active_sync'], 42 | __('Enable synchronization', 'sccm') 43 | ) }} 44 | 45 | {{ fields.textField( 46 | 'sccmdb_host', 47 | item.fields['sccmdb_host'], 48 | __('Server hostname (MSSQL)', 'sccm') 49 | ) }} 50 | 51 | {{ fields.textField( 52 | 'sccmdb_dbname', 53 | item.fields['sccmdb_dbname'], 54 | __('Database name', 'sccm') 55 | ) }} 56 | 57 | {{ fields.textField( 58 | 'sccmdb_user', 59 | item.fields['sccmdb_user'], 60 | __('Username', 'sccm') 61 | ) }} 62 | 63 | {{ fields.passwordField( 64 | 'sccmdb_password', 65 | item.fields['sccmdb_password'], 66 | __('Password', 'sccm'), 67 | {'autocomplete': 'off'} 68 | ) }} 69 | 70 | {% set alert %} 71 | {{ url }} 72 | {% endset %} 73 | 74 | {{ fields.textField( 75 | 'inventory_server_url', 76 | item.fields['inventory_server_url'], 77 | __('Inventory server base URL', 'sccm'), 78 | { 79 | 'add_field_html': alert, 80 | } 81 | ) }} 82 | 83 | {{ fields.checkboxField( 84 | 'verify_ssl_cert', 85 | item.fields['verify_ssl_cert'], 86 | __('Verify SSL certificate', 'sccm') 87 | ) }} 88 | 89 | {{ fields.checkboxField( 90 | 'use_auth_ntlm', 91 | item.fields['use_auth_ntlm'], 92 | __('Use NLTM authentication', 'sccm') 93 | ) }} 94 | 95 | {{ fields.checkboxField( 96 | 'unrestricted_auth', 97 | item.fields['unrestricted_auth'], 98 | __('Send credentials to other hosts too', 'sccm') 99 | ) }} 100 | 101 | {{ fields.checkboxField( 102 | 'use_auth_info', 103 | item.fields['use_auth_info'], 104 | __('Use specific authentication information', 'sccm') 105 | ) }} 106 | 107 | {{ fields.textField( 108 | 'auth_info', 109 | item.fields['auth_info'], 110 | __('Value for spécific authentication', 'sccm') 111 | ) }} 112 | 113 | {{ fields.checkboxField( 114 | 'use_lasthwscan', 115 | item.fields['use_lasthwscan'], 116 | __('Use LastHWScan as GLPI last inventory date', 'sccm') 117 | ) }} 118 | 119 | {{ fields.textareaField( 120 | 'comment', 121 | item.fields['comment'], 122 | _n('Comment', 'Comments', get_plural_number()), 123 | ) }} 124 | 125 | {% endblock %} 126 | -------------------------------------------------------------------------------- /inc/sccmdb.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | use Glpi\Exception\Http\BadRequestHttpException; 33 | 34 | /** 35 | * ------------------------------------------------------------------------- 36 | * SCCM plugin for GLPI 37 | * ------------------------------------------------------------------------- 38 | * 39 | * LICENSE 40 | * 41 | * This file is part of SCCM. 42 | * 43 | * SCCM is free software; you can redistribute it and/or modify 44 | * it under the terms of the GNU General Public License as published by 45 | * the Free Software Foundation; either version 3 of the License, or 46 | * (at your option) any later version. 47 | * 48 | * SCCM is distributed in the hope that it will be useful, 49 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 50 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51 | * GNU General Public License for more details. 52 | * 53 | * You should have received a copy of the GNU General Public License 54 | * along with SCCM. If not, see . 55 | * ------------------------------------------------------------------------- 56 | * @author François Legastelois 57 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 58 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 59 | * @link https://github.com/pluginsGLPI/sccm 60 | * ------------------------------------------------------------------------- 61 | */ 62 | 63 | class PluginSccmSccmdb 64 | { 65 | public $dbconn; 66 | 67 | public function connect() 68 | { 69 | $config = new PluginSccmConfig(); 70 | $config->getFromDB(1); 71 | 72 | $host = $config->getField('sccmdb_host'); 73 | $dbname = $config->getField('sccmdb_dbname'); 74 | $user = $config->getField('sccmdb_user'); 75 | $verify_ssl_cert = (bool) $config->getField('verify_ssl_cert'); 76 | 77 | $password = $config->getField('sccmdb_password'); 78 | $password = (new GLPIKey())->decrypt($password); 79 | 80 | $connection_options = [ 81 | "Database" => $dbname, 82 | "Uid" => $user, 83 | "PWD" => $password, 84 | "CharacterSet" => "UTF-8", 85 | "TrustServerCertificate" => !$verify_ssl_cert, 86 | ]; 87 | 88 | $this->dbconn = sqlsrv_connect($host, $connection_options); 89 | if ($this->dbconn === false) { 90 | $this->FormatErrors(sqlsrv_errors()); 91 | return false; 92 | } 93 | 94 | return true; 95 | } 96 | 97 | public function disconnect() 98 | { 99 | sqlsrv_close($this->dbconn); 100 | } 101 | 102 | public function exec_query($query) 103 | { 104 | $result = sqlsrv_query($this->dbconn, $query); 105 | if ($result == false) { 106 | throw new BadRequestHttpException('Query error: ' . print_r(sqlsrv_errors(), true)); 107 | } 108 | 109 | return $result; 110 | } 111 | 112 | public function FormatErrors($errors) 113 | { 114 | foreach ($errors as $error) { 115 | $state = "SQLSTATE: " . $error['SQLSTATE']; 116 | $code = "Code: " . $error['code']; 117 | $message = "Message: " . $error['message']; 118 | echo $state . "
" . $code . "
" . $message . "
"; 119 | Toolbox::logInFile("sccm", $state . PHP_EOL . $code . PHP_EOL . $message . PHP_EOL); 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /sccm.xml: -------------------------------------------------------------------------------- 1 | 2 | SCCM 3 | sccm 4 | stable 5 | https://raw.githubusercontent.com/TECLIB/sccm/master/screenshots/iconmonstr-database-10-icon-128.png 6 | 7 | 8 | Synchronisation des données avec l'outil Microsoft SCCM 9 | Data synchronization with Microsoft SCCM 10 | 11 | 12 | Synchronisation des données avec l'outil Microsoft SCCM 13 | 14 | Plugin permettant de synchroniser les ordinateurs présents dans SCCM avec GLPI. 15 | 16 | * Le plugin interroge le serveur SCCM au moyen de requêtes MsSQL ; 17 | * il construit un XML au format GLPI ; 18 | * et l'injecte directement dans l'inventaire natif GLPI en HTTP (via cURL). 19 | 20 | 21 | Pré-requis : 22 | 23 | * PHP curl_init : http://php.net/manual/fr/function.curl-init.php 24 | * PHP mssql_connect : http://php.net/manual/fr/function.mssql-connect.php 25 | * Microsoft System Center Configuration Manager 26 | Data synchronization with Microsoft SCCM 27 | 28 | Plugin to synchronize computers from SCCM to GLPI. 29 | 30 | * The plugin ask the SCCM server with MsSQL queries ; 31 | * it builds an XML file for each computer 32 | * and injects it directly into the GLPI native inventory over HTTP(s) (via cURL). 33 | 34 | 35 | Prerequisite : 36 | 37 | * PHP curl_init : http://php.net/manual/en/function.curl-init.php 38 | * PHP mssql_connect : http://php.net/manual/en/function.mssql-connect.php 39 | * Microsoft System Center Configuration Manager 40 | 41 | 42 | https://pluginsglpi.github.io/sccm/ 43 | https://github.com/pluginsGLPI/sccm/releases 44 | https://github.com/pluginsGLPI/sccm/issues 45 | https://github.com/pluginsGLPI/sccm/blob/develop/README.md 46 | 47 | TECLIB' 48 | 49 | 50 | 51 | 2.5.1 52 | ~11.0.0 53 | https://github.com/pluginsGLPI/sccm/releases/download/2.5.1/glpi-sccm-2.5.1.tar.bz2 54 | 55 | 56 | 2.5.0 57 | ~11.0.0 58 | https://github.com/pluginsGLPI/sccm/releases/download/2.5.0/glpi-sccm-2.5.0.tar.bz2 59 | 60 | 61 | 2.4.5 62 | ~10.0.11 63 | https://github.com/pluginsGLPI/sccm/releases/download/2.4.5/glpi-sccm-2.4.5.tar.bz2 64 | 65 | 66 | 2.4.4 67 | ~10.0.11 68 | https://github.com/pluginsGLPI/sccm/releases/download/2.4.4/glpi-sccm-2.4.4.tar.bz2 69 | 70 | 71 | 2.4.3 72 | ~10.0.0 73 | https://github.com/pluginsGLPI/sccm/releases/download/2.4.3/glpi-sccm-2.4.3.tar.bz2 74 | 75 | 76 | 2.4.2 77 | ~10.0.0 78 | https://github.com/pluginsGLPI/sccm/releases/download/2.4.2/glpi-sccm-2.4.2.tar.bz2 79 | 80 | 81 | 2.4.1 82 | ~10.0.0 83 | https://github.com/pluginsGLPI/sccm/releases/download/2.4.1/glpi-sccm-2.4.1.tar.bz2 84 | 85 | 86 | 2.4.0 87 | ~10.0.0 88 | https://github.com/pluginsGLPI/sccm/releases/download/2.4.0/glpi-sccm-2.4.0.tar.bz2 89 | 90 | 91 | 2.3.2 92 | ~9.5.0 93 | https://github.com/pluginsGLPI/sccm/releases/download/2.3.2/glpi-sccm-2.3.2.tar.bz2 94 | 95 | 96 | 2.3.1 97 | ~9.5.0 98 | https://github.com/pluginsGLPI/sccm/releases/download/2.3.1/glpi-sccm-2.3.1.tar.bz2 99 | 100 | 101 | 2.3.0 102 | ~9.5.0 103 | https://github.com/pluginsGLPI/sccm/releases/download/2.3.0/glpi-sccm-2.3.0.tar.bz2 104 | 105 | 106 | 2.2.2 107 | ~9.5.0 108 | https://github.com/pluginsGLPI/sccm/releases/download/2.2.2/glpi-sccm-2.2.2.tar.bz2 109 | 110 | 111 | 2.2.1 112 | ~9.5.0 113 | https://github.com/pluginsGLPI/sccm/releases/download/2.2.1/glpi-sccm-2.2.1.tar.bz2 114 | 115 | 116 | 2.2.0 117 | ~9.5.0 118 | https://github.com/pluginsGLPI/sccm/releases/download/2.2.0/glpi-sccm-2.2.0.tar.bz2 119 | 120 | 121 | 2.1.1 122 | ~9.4.0 123 | ~9.3.0 124 | ~9.2.0 125 | https://github.com/pluginsGLPI/sccm/releases/download/2.1.1/glpi-sccm-2.1.1.tar.bz2 126 | 127 | 128 | 2.1.0 129 | ~9.4.0 130 | ~9.3.0 131 | ~9.2.0 132 | https://github.com/pluginsGLPI/sccm/releases/download/2.1.0/glpi-sccm-2.1.0.tar.bz2 133 | 134 | 135 | 2.0.4 136 | 9.2 137 | 9.3 138 | 139 | 140 | 2.0.3 141 | 9.2 142 | 143 | 144 | 0.85-1.0Beta 145 | 0.85 146 | 147 | 148 | 0.84-1.0.0 149 | 0.84 150 | 151 | 152 | 153 | en_GB 154 | fr_FR 155 | 156 | GPL v2+ 157 | 158 | 159 | inventaire 160 | données 161 | configuration 162 | import 163 | synchronisation 164 | 165 | 166 | inventory 167 | data 168 | configuration 169 | import 170 | synchronization 171 | 172 | 173 | 174 | https://raw.githubusercontent.com/pluginsGLPI/sccm/develop/screenshots/schema.png 175 | https://raw.githubusercontent.com/pluginsGLPI/sccm/develop/screenshots/sccm.png 176 | 177 | 178 | -------------------------------------------------------------------------------- /inc/config.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | use Glpi\Application\View\TemplateRenderer; 33 | 34 | /** 35 | * ------------------------------------------------------------------------- 36 | * SCCM plugin for GLPI 37 | * ------------------------------------------------------------------------- 38 | * 39 | * LICENSE 40 | * 41 | * This file is part of SCCM. 42 | * 43 | * SCCM is free software; you can redistribute it and/or modify 44 | * it under the terms of the GNU General Public License as published by 45 | * the Free Software Foundation; either version 3 of the License, or 46 | * (at your option) any later version. 47 | * 48 | * SCCM is distributed in the hope that it will be useful, 49 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 50 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51 | * GNU General Public License for more details. 52 | * 53 | * You should have received a copy of the GNU General Public License 54 | * along with SCCM. If not, see . 55 | * ------------------------------------------------------------------------- 56 | * @author François Legastelois 57 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 58 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 59 | * @link https://github.com/pluginsGLPI/sccm 60 | * ------------------------------------------------------------------------- 61 | */ 62 | 63 | class PluginSccmConfig extends CommonDBTM 64 | { 65 | private static $_instance; 66 | 67 | public static function canCreate(): bool 68 | { 69 | return Session::haveRight('config', UPDATE); 70 | } 71 | 72 | public static function canUpdate(): bool 73 | { 74 | return Session::haveRight('config', UPDATE); 75 | } 76 | 77 | public static function canView(): bool 78 | { 79 | return Session::haveRight('config', UPDATE); 80 | } 81 | 82 | public static function getTypeName($nb = 0) 83 | { 84 | return __s("Setup - SCCM", "sccm"); 85 | } 86 | 87 | public function getName($options = []) 88 | { 89 | return __s("Interface - SCCM", "sccm"); 90 | } 91 | 92 | public static function getInstance() 93 | { 94 | if (!isset(self::$_instance)) { 95 | self::$_instance = new self(); 96 | if (!self::$_instance->getFromDB(1)) { 97 | self::$_instance->getEmpty(); 98 | } 99 | } 100 | 101 | return self::$_instance; 102 | } 103 | 104 | public function prepareInputForUpdate($input) 105 | { 106 | if (isset($input["sccmdb_password"]) && !empty($input["sccmdb_password"])) { 107 | $input["sccmdb_password"] = (new GLPIKey())->encrypt($input["sccmdb_password"]); 108 | } 109 | 110 | if (array_key_exists('inventory_server_url', $input) && !empty($input['inventory_server_url'])) { 111 | $input['inventory_server_url'] = trim((string) $input['inventory_server_url'], '/ '); 112 | } 113 | 114 | return $input; 115 | } 116 | 117 | public static function install(Migration $migration) 118 | { 119 | /** @var array $CFG_GLPI */ 120 | /** @var DBmysql $DB */ 121 | global $CFG_GLPI, $DB; 122 | 123 | $default_charset = DBConnection::getDefaultCharset(); 124 | $default_collation = DBConnection::getDefaultCollation(); 125 | $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); 126 | 127 | $table = 'glpi_plugin_sccm_configs'; 128 | 129 | if (!$DB->tableExists($table)) { 130 | 131 | $query = "CREATE TABLE `" . $table . "`( 132 | `id` int {$default_key_sign} NOT NULL, 133 | `sccmdb_host` VARCHAR(255) NULL, 134 | `sccmdb_dbname` VARCHAR(255) NULL, 135 | `sccmdb_user` VARCHAR(255) NULL, 136 | `sccmdb_password` VARCHAR(255) NULL, 137 | `inventory_server_url` VARCHAR(255) NULL, 138 | `active_sync` tinyint NOT NULL default '0', 139 | `verify_ssl_cert` tinyint NOT NULL default '0', 140 | `use_auth_ntlm` tinyint NOT NULL default '0', 141 | `unrestricted_auth` tinyint NOT NULL default '0', 142 | `use_auth_info` tinyint NOT NULL default '0', 143 | `auth_info` VARCHAR(255) NULL, 144 | `is_password_sodium_encrypted` tinyint NOT NULL default '1', 145 | `use_lasthwscan` tinyint NOT NULL default '0', 146 | `date_mod` timestamp NULL default NULL, 147 | `comment` text, 148 | PRIMARY KEY (`id`) 149 | ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; 150 | 151 | $DB->doQuery($query); 152 | 153 | $query = "INSERT INTO `{$table}` 154 | (id, date_mod, sccmdb_host, sccmdb_dbname, 155 | sccmdb_user, sccmdb_password, inventory_server_url) 156 | VALUES (1, NOW(), 'srv_sccm','bdd_sccm','user_sccm','', 157 | NULL)"; 158 | 159 | $DB->doQuery($query); 160 | 161 | } else { 162 | 163 | if (!$DB->fieldExists($table, 'verify_ssl_cert')) { 164 | $migration->addField("glpi_plugin_sccm_configs", "verify_ssl_cert", "tinyint NOT NULL default '0'"); 165 | $migration->migrationOneTable('glpi_plugin_sccm_configs'); 166 | } 167 | 168 | if (!$DB->fieldExists($table, 'use_auth_ntlm')) { 169 | $migration->addField("glpi_plugin_sccm_configs", "use_auth_ntlm", "tinyint NOT NULL default '0'"); 170 | $migration->migrationOneTable('glpi_plugin_sccm_configs'); 171 | } 172 | 173 | if (!$DB->fieldExists($table, 'unrestricted_auth')) { 174 | $migration->addField("glpi_plugin_sccm_configs", "unrestricted_auth", "tinyint NOT NULL default '0'"); 175 | $migration->migrationOneTable('glpi_plugin_sccm_configs'); 176 | } 177 | 178 | if (!$DB->fieldExists($table, 'use_auth_info')) { 179 | $migration->addField("glpi_plugin_sccm_configs", "use_auth_info", "tinyint NOT NULL default '0'"); 180 | $migration->migrationOneTable('glpi_plugin_sccm_configs'); 181 | } 182 | 183 | if (!$DB->fieldExists($table, 'auth_info')) { 184 | $migration->addField("glpi_plugin_sccm_configs", "auth_info", "varchar(255)"); 185 | $migration->migrationOneTable('glpi_plugin_sccm_configs'); 186 | } 187 | 188 | if (!$DB->fieldExists($table, 'is_password_sodium_encrypted')) { 189 | $config = self::getInstance(); 190 | if (!empty($config->fields['sccmdb_password'])) { 191 | $key = new GLPIKey(); 192 | $migration->addPostQuery( 193 | $DB->buildUpdate( 194 | 'glpi_plugin_sccm_configs', 195 | [ 196 | 'sccmdb_password' => $key->encrypt( 197 | $key->decryptUsingLegacyKey( 198 | $config->fields['sccmdb_password'], 199 | ), 200 | ), 201 | ], 202 | [ 203 | 'id' => 1, 204 | ], 205 | ), 206 | ); 207 | } 208 | 209 | $migration->addField("glpi_plugin_sccm_configs", "is_password_sodium_encrypted", "tinyint NOT NULL default '1'"); 210 | $migration->migrationOneTable('glpi_plugin_sccm_configs'); 211 | } 212 | 213 | if (!$DB->fieldExists($table, 'use_lasthwscan')) { 214 | $migration->addField("glpi_plugin_sccm_configs", "use_lasthwscan", "tinyint NOT NULL default '0'"); 215 | $migration->migrationOneTable('glpi_plugin_sccm_configs'); 216 | } 217 | 218 | if (!$DB->fieldExists($table, 'fusioninventory_url')) { 219 | $migration->changeField("glpi_plugin_sccm_configs", "fusioninventory_url", "inventory_server_url", "string"); 220 | $migration->migrationOneTable('glpi_plugin_sccm_configs'); 221 | } 222 | 223 | $sccm_config = $DB->request(['FROM' => 'glpi_plugin_sccm_configs'])->current(); 224 | $inventory_server_url = trim($sccm_config['inventory_server_url'] ?? ''); 225 | $url_matches = []; 226 | if ( 227 | $inventory_server_url !== '' 228 | && ( 229 | preg_match('/^(?.+)\/front\/inventory\.php$/', $inventory_server_url, $url_matches) === 1 230 | || preg_match('/^(?.+)\/(marketplace|plugins)\/(fusioninventory)\//', $inventory_server_url, $url_matches) === 1 231 | ) 232 | ) { 233 | // Strip script path from base URL. 234 | $inventory_server_url = $url_matches['base_url']; 235 | if ($inventory_server_url === $CFG_GLPI['url_base']) { 236 | $inventory_server_url = ''; 237 | } 238 | 239 | $sccm_config = $DB->update( 240 | 'glpi_plugin_sccm_configs', 241 | [ 242 | 'inventory_server_url' => $inventory_server_url, 243 | ], 244 | [ 245 | 'id' => 1, 246 | ], 247 | ); 248 | } 249 | } 250 | 251 | return true; 252 | } 253 | 254 | public static function uninstall() 255 | { 256 | /** @var DBmysql $DB */ 257 | global $DB; 258 | 259 | if ($DB->tableExists('glpi_plugin_sccm_configs')) { 260 | 261 | $query = "DROP TABLE `glpi_plugin_sccm_configs`"; 262 | $DB->doQuery($query); 263 | } 264 | 265 | return true; 266 | } 267 | 268 | public function getFormFields(): array 269 | { 270 | return []; 271 | } 272 | 273 | public function showForm($ID, array $options = []) 274 | { 275 | /** 276 | * @var array $CFG_GLPI 277 | */ 278 | global $CFG_GLPI; 279 | 280 | $config = self::getInstance(); 281 | $password = $config->getField('sccmdb_password'); 282 | $password = (new GLPIKey())->decrypt($password); 283 | $config->fields['sccmdb_password'] = $password; 284 | 285 | $url = ($config->getField('inventory_server_url') ?: "Ex : " . $CFG_GLPI['url_base']) . '/front/inventory.php'; 286 | 287 | TemplateRenderer::getInstance()->display( 288 | '@sccm/config.html.twig', 289 | [ 290 | 'action' => Toolbox::getItemTypeFormURL(self::class), 291 | 'item' => $config, 292 | 'url' => $url, 293 | ], 294 | ); 295 | 296 | return true; 297 | } 298 | 299 | } 300 | -------------------------------------------------------------------------------- /inc/sccmxml.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | 33 | class PluginSccmSccmxml 34 | { 35 | public $device_id; 36 | 37 | public $sxml; 38 | 39 | public $agentbuildnumber; 40 | 41 | public $username; 42 | 43 | public function __construct(public $data) 44 | { 45 | 46 | $plug = new Plugin(); 47 | $plug->getFromDBbyDir("sccm"); 48 | 49 | $this->device_id = $this->data['CSD-MachineID']; 50 | $this->agentbuildnumber = "SCCM-v" . $plug->fields['version']; 51 | 52 | $SXML = << 54 | 55 | 56 | {$this->agentbuildnumber} 57 | 58 | {$this->device_id} 59 | INVENTORY 60 | 61 | 62 | XML; 63 | $this->sxml = new SimpleXMLElement($SXML); 64 | } 65 | 66 | public function setAccessLog() 67 | { 68 | $CONTENT = $this->sxml->CONTENT[0]; 69 | $CONTENT->addChild('ACCESSLOG'); 70 | 71 | $ACCESSLOG = $this->sxml->CONTENT[0]->ACCESSLOG; 72 | $ACCESSLOG->addChild('LOGDATE', date('Y-m-d h:i:s')); 73 | 74 | if (!empty($this->data['VrS-UserName'])) { 75 | $this->username = $this->data['VrS-UserName']; 76 | } elseif (!empty($this->data['SDI-UserName'])) { 77 | $this->username = $this->data['SDI-UserName']; 78 | } elseif (!empty($this->data['CSD-UserName'])) { 79 | if (preg_match_all("#\\ (.*)#", (string) $this->data['CSD-UserName'], $matches)) { 80 | $this->data['CSD-UserName'] = $matches[1][0]; 81 | } 82 | 83 | $this->username = $this->data['CSD-UserName']; 84 | } else { 85 | $this->username = ""; 86 | } 87 | 88 | $ACCESSLOG->addChild('USERID', $this->username); 89 | } 90 | 91 | public function setAccountInfos() 92 | { 93 | $CONTENT = $this->sxml->CONTENT[0]; 94 | $CONTENT->addChild('ACCOUNTINFO'); 95 | 96 | $ACCOUNTINFO = $this->sxml->CONTENT[0]->ACCOUNTINFO; 97 | $ACCOUNTINFO->addChild('KEYNAME', 'TAG'); 98 | $ACCOUNTINFO->addChild('KEYVALUE', 'SCCM'); 99 | } 100 | 101 | public function setHardware() 102 | { 103 | $CONTENT = $this->sxml->CONTENT[0]; 104 | $CONTENT->addChild('HARDWARE'); 105 | 106 | $HARDWARE = $this->sxml->CONTENT[0]->HARDWARE; 107 | $HARDWARE->addChild('NAME', strtoupper((string) $this->data['MD-SystemName'])); 108 | //$HARDWARE->addChild('CHASSIS_TYPE',$this->data['SD-SystemRole']); 109 | $HARDWARE->addChild('LASTLOGGEDUSER', $this->username); 110 | $HARDWARE->addChild('UUID', substr((string) $this->data['SD-UUID'], 5)); 111 | $HARDWARE->addChild('USERID', $this->username); 112 | $HARDWARE->addChild('WORKGROUP', $this->data['CSD-Domain']); 113 | } 114 | 115 | public function setOS() 116 | { 117 | $versionOS = $this->data['OSD-Version']; 118 | 119 | $CONTENT = $this->sxml->CONTENT[0]; 120 | $CONTENT->addChild('OPERATINGSYSTEM'); 121 | 122 | $HARDWARE = $this->sxml->CONTENT[0]->HARDWARE; 123 | $HARDWARE->addChild('OSNAME', $this->data['OSD-Caption']); 124 | $HARDWARE->addChild('OSCOMMENTS', $this->data['OSD-CSDVersion']); 125 | $HARDWARE->addChild('OSVERSION', $versionOS); 126 | //$HARDWARE->addChild('WINPRODID', $this->data['CSD-MachineID']); 127 | 128 | $OPERATINGSYSTEM = $this->sxml->CONTENT[0]->OPERATINGSYSTEM; 129 | $OPERATINGSYSTEM->addChild('NAME', $this->data['OSD-Caption']); 130 | $OPERATINGSYSTEM->addChild('FULL_NAME', $this->data['OSD-Caption']); 131 | $OPERATINGSYSTEM->addChild('ARCH', $this->data['CSD-SystemType']); 132 | $OPERATINGSYSTEM->addChild('VERSION', $versionOS); 133 | //$OPERATINGSYSTEM->addChild('SERIALNUMBER', $this->data['OSD-BuildNumber']); 134 | $OPERATINGSYSTEM->addChild('SERVICE_PACK', $this->data['OSD-CSDVersion']); 135 | } 136 | 137 | public function setBios() 138 | { 139 | $CONTENT = $this->sxml->CONTENT[0]; 140 | $CONTENT->addChild('BIOS'); 141 | 142 | $BIOS = $this->sxml->CONTENT[0]->BIOS; 143 | //$BIOS->addChild('ASSETTAG', $this->data['PBD-SerialNumber']); 144 | $BIOS->addChild('SMODEL', $this->data['CSD-Model']); 145 | $BIOS->addChild('TYPE', $this->data['SD-SystemRole']); 146 | $BIOS->addChild('MMANUFACTURER', $this->data['CSD-Manufacturer']); 147 | $BIOS->addChild('SMANUFACTURER', $this->data['CSD-Manufacturer']); 148 | $BIOS->addChild('SSN', $this->data['PBD-SerialNumber']); 149 | 150 | // Jul 17 2012 12:00:00:000AM 151 | if (is_object($this->data['PBD-ReleaseDate'])) { 152 | $Date_Sccm = DateTime::createFromFormat( 153 | 'M d Y', 154 | $this->data['PBD-ReleaseDate']->format('M d Y'), 155 | ); 156 | } else { 157 | $Date_Sccm = DateTime::createFromFormat( 158 | 'M d Y', 159 | substr((string) $this->data['PBD-ReleaseDate'], 0, 12), 160 | ); 161 | } 162 | 163 | if ($Date_Sccm != false) { 164 | $this->data['PBD-ReleaseDate'] = $Date_Sccm->format('m/d/Y'); 165 | } 166 | 167 | $BIOS->addChild('BDATE', $this->data['PBD-ReleaseDate']); 168 | $BIOS->addChild('BMANUFACTURER', $this->data['PBD-Manufacturer']); 169 | $BIOS->addChild('BVERSION', $this->data['PBD-BiosVersion']); 170 | $BIOS->addChild('SKUNUMBER', $this->data['PBD-Version']); 171 | } 172 | 173 | public function setProcessors() 174 | { 175 | $sccm = new PluginSccmSccm(); 176 | 177 | $cpukeys = []; 178 | 179 | $CONTENT = $this->sxml->CONTENT[0]; 180 | $i = 0; 181 | foreach ($sccm->getDatas('processors', $this->device_id) as $value) { 182 | if (!in_array($value['CPUKey00'], $cpukeys)) { 183 | $CONTENT->addChild('CPUS'); 184 | $CPUS = $this->sxml->CONTENT[0]->CPUS[$i]; 185 | $CPUS->addChild('DESCRIPTION', $value['Name00']); 186 | $CPUS->addChild('MANUFACTURER', $value['Manufacturer00']); 187 | $CPUS->addChild('NAME', $value['Name00']); 188 | $CPUS->addChild('SPEED', $value['NormSpeed00']); 189 | $CPUS->addChild('TYPE', $value['AddressWidth00']); 190 | $CPUS->addChild('CORE', $value['NumberOfCores00']); 191 | $CPUS->addChild('THREAD', $value['NumberOfLogicalProcessors00']); 192 | $i++; 193 | 194 | // save actual cpukeys for duplicity 195 | $cpukeys[] = $value['CPUKey00']; 196 | } 197 | } 198 | } 199 | 200 | public function setSoftwares() 201 | { 202 | $sccm = new PluginSccmSccm(); 203 | 204 | $antivirus = []; 205 | $inject_antivirus = false; 206 | $CONTENT = $this->sxml->CONTENT[0]; 207 | $i = 0; 208 | foreach ($sccm->getSoftware($this->device_id) as $value) { 209 | 210 | $CONTENT->addChild('SOFTWARES'); 211 | $SOFTWARES = $this->sxml->CONTENT[0]->SOFTWARES[$i]; 212 | 213 | if (isset($value['ArPd-DisplayName']) && preg_match("#&#", $value['ArPd-DisplayName'])) { 214 | $value['ArPd-DisplayName'] = preg_replace("#&#", "&", $value['ArPd-DisplayName']); 215 | } 216 | 217 | if (isset($value['ArPd-Publisher']) && preg_match("#&#", $value['ArPd-Publisher'])) { 218 | $value['ArPd-Publisher'] = preg_replace("#&#", "&", $value['ArPd-Publisher']); 219 | } 220 | 221 | $SOFTWARES->addChild('NAME', $value['ArPd-DisplayName'] ?: NOT_AVAILABLE); 222 | 223 | if (isset($value['ArPd-Version'])) { 224 | $SOFTWARES->addChild('VERSION', $value['ArPd-Version']); 225 | } 226 | 227 | if (isset($value['ArPd-Publisher'])) { 228 | $SOFTWARES->addChild('PUBLISHER', $value['ArPd-Publisher']); 229 | } 230 | 231 | if (isset($value['ArPd-InstallDate'])) { 232 | $Date_Sccm = DateTime::createFromFormat('Ymd', $value['ArPd-InstallDate']); 233 | if ($Date_Sccm != false) { 234 | $SOFTWARES->addChild('INSTALLDATE', $Date_Sccm->format('d/m/Y')); 235 | } 236 | } 237 | 238 | $i++; 239 | 240 | if (isset($value['ArPd-DisplayName']) && preg_match('#Kaspersky Endpoint Security#', $value['ArPd-DisplayName'])) { 241 | $antivirus = $value['ArPd-DisplayName']; 242 | $inject_antivirus = true; 243 | } 244 | } 245 | 246 | if ($inject_antivirus) { 247 | $this->setAntivirus($antivirus); 248 | } 249 | } 250 | 251 | public function setMemories() 252 | { 253 | $sccm = new PluginSccmSccm(); 254 | 255 | $CONTENT = $this->sxml->CONTENT[0]; 256 | $i = 0; 257 | foreach ($sccm->getMemories($this->device_id) as $value) { 258 | 259 | $CONTENT->addChild('MEMORIES'); 260 | $MEMORIES = $this->sxml->CONTENT[0]->MEMORIES[$i]; 261 | 262 | $MEMORIES->addChild('CAPACITY', $value['Mem-Capacity']); 263 | $MEMORIES->addChild('CAPTION', $value['Mem-Caption']); 264 | $MEMORIES->addChild('DESCRIPTION', $value['Mem-Description']); 265 | $MEMORIES->addChild('FORMFACTOR', $value['Mem-FormFactor']); 266 | $MEMORIES->addChild('REMOVABLE', $value['Mem-Removable']); 267 | $MEMORIES->addChild('PURPOSE', $value['Mem-Purpose']); 268 | $MEMORIES->addChild('SPEED', $value['Mem-Speed']); 269 | $MEMORIES->addChild('TYPE', $value['Mem-Type']); 270 | $MEMORIES->addChild('NUMSLOTS', $value['Mem-NumSlots']); 271 | $MEMORIES->addChild('SERIALNUMBER', $value['Mem-SerialNumber']); 272 | $MEMORIES->addChild('MANUFACTURER', $value['Mem-Manufacturer']); 273 | 274 | $i++; 275 | } 276 | } 277 | 278 | public function setVideos() 279 | { 280 | $sccm = new PluginSccmSccm(); 281 | 282 | $CONTENT = $this->sxml->CONTENT[0]; 283 | $i = 0; 284 | foreach ($sccm->getVideos($this->device_id) as $value) { 285 | 286 | $CONTENT->addChild('VIDEOS'); 287 | $VIDEOS = $this->sxml->CONTENT[0]->VIDEOS[$i]; 288 | 289 | $VIDEOS->addChild('CHIPSET', $value['Vid-Chipset']); 290 | $VIDEOS->addChild('MEMORY', $value['Vid-Memory']); 291 | $VIDEOS->addChild('NAME', $value['Vid-Name']); 292 | $VIDEOS->addChild('RESOLUTION', $value['Vid-Resolution']); 293 | $VIDEOS->addChild('PCISLOT', $value['Vid-PciSlot']); 294 | 295 | $i++; 296 | } 297 | } 298 | 299 | public function setSounds() 300 | { 301 | $sccm = new PluginSccmSccm(); 302 | 303 | $CONTENT = $this->sxml->CONTENT[0]; 304 | $i = 0; 305 | foreach ($sccm->getSounds($this->device_id) as $value) { 306 | 307 | $CONTENT->addChild('SOUNDS'); 308 | $SOUNDS = $this->sxml->CONTENT[0]->SOUNDS[$i]; 309 | 310 | $SOUNDS->addChild('DESCRIPTION', $value['Snd-Description']); 311 | $SOUNDS->addChild('MANUFACTURER', $value['Snd-Manufacturer']); 312 | $SOUNDS->addChild('NAME', $value['Snd-Name']); 313 | 314 | $i++; 315 | } 316 | } 317 | 318 | public function setAntivirus($value) 319 | { 320 | $CONTENT = $this->sxml->CONTENT[0]; 321 | $CONTENT->addChild('ANTIVIRUS'); 322 | 323 | $ANTIVIRUS = $this->sxml->CONTENT[0]->ANTIVIRUS; 324 | $ANTIVIRUS->addChild('NAME', $value); 325 | } 326 | 327 | public function setUsers() 328 | { 329 | $CONTENT = $this->sxml->CONTENT[0]; 330 | $CONTENT->addChild('USERS'); 331 | 332 | $USERS = $this->sxml->CONTENT[0]->USERS; 333 | $USERS->addChild('LOGIN', $this->username); 334 | } 335 | 336 | public function determineNetworkType($network_description) 337 | { 338 | $description = strtolower((string) $network_description); 339 | 340 | $networkTypes = [ 341 | 'wifi' => ['wi-fi', 'wireless', 'wifi'], 342 | 'infiniband' => ['infiniband'], 343 | 'aggregate' => ['aggregation', 'aggregate'], 344 | 'alias' => ['alias'], 345 | 'dialup' => ['dialup', 'dial-up'], 346 | 'loopback' => ['loop'], 347 | 'bridge' => ['bridge'], 348 | 'fibrechannel' => ['fibre', 'fiber'], 349 | 'bluetooth' => ['bluetooth'], 350 | ]; 351 | 352 | foreach ($networkTypes as $type => $keywords) { 353 | foreach ($keywords as $keyword) { 354 | if (str_contains($description, $keyword)) { 355 | return $type; 356 | } 357 | } 358 | } 359 | 360 | return "ethernet"; 361 | } 362 | 363 | public function setNetworks() 364 | { 365 | $sccm = new PluginSccmSccm(); 366 | 367 | $CONTENT = $this->sxml->CONTENT[0]; 368 | 369 | $networks = $sccm->getNetwork($this->device_id); 370 | 371 | if (count($networks) > 0) { 372 | 373 | $i = 0; 374 | 375 | foreach ($networks as $value) { 376 | //SCCM database store each IP format in one row, we need to split it 377 | //and add each IP in dedicated XML node 378 | $parts = explode(",", $value['ND-IpAddress'] ?? ''); 379 | foreach ($parts as $ip) { 380 | $CONTENT->addChild('NETWORKS'); 381 | $NETWORKS = $this->sxml->CONTENT[0]->NETWORKS[$i]; 382 | 383 | if (filter_var(trim($ip), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { 384 | $NETWORKS->addChild('IPADDRESS', trim($ip)); 385 | } else { 386 | $NETWORKS->addChild('IPADDRESS6', trim($ip)); 387 | } 388 | 389 | $NETWORKS->addChild('DESCRIPTION', $value['ND-Name']); 390 | $NETWORKS->addChild('IPMASK', $value['ND-IpSubnet']); 391 | $NETWORKS->addChild('IPDHCP', $value['ND-DHCPServer']); 392 | $NETWORKS->addChild('IPGATEWAY', $value['ND-IpGateway']); 393 | $NETWORKS->addChild('MACADDR', $value['ND-MacAddress']); 394 | $NETWORKS->addChild('TYPE', $this->determineNetworkType($value['ND-Name'])); 395 | 396 | $i++; 397 | } 398 | } 399 | } 400 | } 401 | 402 | public function setStorages() 403 | { 404 | $sccm = new PluginSccmSccm(); 405 | $CONTENT = $this->sxml->CONTENT[0]; 406 | $i = 0; 407 | foreach ($sccm->getStorages($this->device_id) as $value) { 408 | $value['gld-TotalSize'] = intval($value['gld-TotalSize']) * 1024; 409 | $value['gld-FreeSpace'] = intval($value['gld-FreeSpace']) * 1024; 410 | $CONTENT->addChild('DRIVES'); 411 | $DRIVES = $this->sxml->CONTENT[0]->DRIVES[$i]; 412 | $DRIVES->addChild('DESCRIPTION', $value['gld-Description']); 413 | $DRIVES->addChild('FILESYSTEM', $value['gld-FileSystem']); 414 | $DRIVES->addChild('FREE', $value['gld-FreeSpace']); 415 | $DRIVES->addChild('LABEL', $value['gdi-Caption']); 416 | $DRIVES->addChild('LETTER', $value['gld-MountingPoint']); 417 | $DRIVES->addChild('TOTAL', $value['gld-TotalSize']); 418 | $DRIVES->addChild('VOLUMN', $value['gld-Partition']); 419 | $i++; 420 | } 421 | 422 | $i = 0; 423 | foreach ($sccm->getMedias($this->device_id) as $value) { 424 | $CONTENT->addChild('STORAGES'); 425 | $STORAGES = $this->sxml->CONTENT[0]->STORAGES[$i]; 426 | $STORAGES->addChild('DESCRIPTION', $value['Med-Description']); 427 | $STORAGES->addChild('MANUFACTURER', $value['Med-Manufacturer']); 428 | $STORAGES->addChild('MODEL', $value['Med-Model']); 429 | $STORAGES->addChild('NAME', $value['Med-Name']); 430 | $STORAGES->addChild('SCSI_COID', $value['Med-SCSITargetId']); 431 | $STORAGES->addChild('SCSI_LUN', 0); 432 | $STORAGES->addChild('SCSI_UNID', 0); 433 | $STORAGES->addChild('TYPE', $value['Med-Type']); 434 | $i++; 435 | } 436 | } 437 | 438 | public function object2array($object) 439 | { 440 | return @json_decode(@json_encode($object), true); 441 | } 442 | } 443 | -------------------------------------------------------------------------------- /inc/sccm.class.php: -------------------------------------------------------------------------------- 1 | . 24 | * ------------------------------------------------------------------------- 25 | * @author François Legastelois 26 | * @copyright Copyright (C) 2014-2023 by SCCM plugin team. 27 | * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html 28 | * @link https://github.com/pluginsGLPI/sccm 29 | * ------------------------------------------------------------------------- 30 | */ 31 | 32 | use Glpi\Exception\Http\BadRequestHttpException; 33 | 34 | class PluginSccmSccm 35 | { 36 | public $devices; 37 | 38 | public function __construct() 39 | { 40 | if (!function_exists('curl_init')) { 41 | throw new BadRequestHttpException( 42 | __s('cURL extension (PHP) is required... !!', 'sccm'), 43 | ); 44 | } 45 | 46 | if (!function_exists('sqlsrv_connect')) { 47 | throw new BadRequestHttpException( 48 | __s('SQLSRV extension (PHP) is required... !!', 'sccm'), 49 | ); 50 | } 51 | } 52 | 53 | public static function getTypeName($nb = 0) 54 | { 55 | return __s('SCCM', 'sccm'); 56 | } 57 | 58 | public function getDevices($where = 0, $limit = 99999999) 59 | { 60 | $sccm_db = new PluginSccmSccmdb(); 61 | $res = $sccm_db->connect(); 62 | if (!$res) { 63 | throw new BadRequestHttpException( 64 | __s('Cannot connect to SCCM database', 'sccm'), 65 | ); 66 | } 67 | 68 | $query = self::getcomputerQuery(); 69 | 70 | if ($where != 0) { 71 | $query .= " WHERE csd.MachineID = '" . $where . "'"; 72 | } 73 | 74 | $result = $sccm_db->exec_query($query); 75 | 76 | $i = 0; 77 | $tab = []; 78 | 79 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 80 | $tab['MD-SystemName'] = strtoupper((string) $tab['MD-SystemName']); 81 | $this->devices[] = $tab; 82 | $i++; 83 | } 84 | 85 | $sccm_db->disconnect(); 86 | } 87 | 88 | public function getDatas($type, $deviceid, $limit = 99999999) 89 | { 90 | 91 | $sccm_db = new PluginSccmSccmdb(); 92 | $res = $sccm_db->connect(); 93 | if (!$res) { 94 | throw new BadRequestHttpException( 95 | __s('Cannot connect to SCCM database', 'sccm'), 96 | ); 97 | } 98 | 99 | if ($type == 'processors') { 100 | $fields = ['Manufacturer00','Name00','NormSpeed00','AddressWidth00','CPUKey00','NumberOfCores00', 'NumberOfLogicalProcessors00']; 101 | $table = 'Processor_DATA'; 102 | } else { 103 | return []; 104 | } 105 | 106 | $query = "SELECT " . implode(',', $fields) . "\n"; 107 | $query .= " FROM " . $table . "\n"; 108 | $query .= " WHERE MachineID = '" . $deviceid . "'" . "\n"; 109 | 110 | $result = $sccm_db->exec_query($query); 111 | 112 | $data = []; 113 | 114 | $i = 0; 115 | $tab = []; 116 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 117 | $tmp = []; 118 | foreach ($tab as $key => $value) { 119 | $tmp[$key] = $value; 120 | } 121 | 122 | $data[] = $tmp; 123 | $i++; 124 | } 125 | 126 | $sccm_db->disconnect(); 127 | return $data; 128 | } 129 | 130 | public function getNetwork($deviceid, $limit = 99999999) 131 | { 132 | 133 | $sccm_db = new PluginSccmSccmdb(); 134 | $res = $sccm_db->connect(); 135 | if (!$res) { 136 | throw new BadRequestHttpException( 137 | __s('Cannot connect to SCCM database', 'sccm'), 138 | ); 139 | } 140 | 141 | $query = "SELECT NeDa.IPAddress00 as \"ND-IpAddress\", 142 | NeDa.MACAddress00 as \"ND-MacAddress\", 143 | NeDa.IPSubnet00 as \"ND-IpSubnet\", 144 | NeDa.DefaultIPGateway00 as \"ND-IpGateway\", 145 | NeDa.DHCPServer00 as \"ND-DHCPServer\", 146 | NeDa.DNSDomain00 as \"ND-DomainName\", 147 | net.Name0 as \"ND-Name\" 148 | FROM Network_DATA NeDa 149 | INNER JOIN v_R_System VrS ON VrS.ResourceID=NeDa.MachineID 150 | INNER JOIN v_GS_NETWORK_ADAPTER net ON net.ResourceID=NeDa.MachineID AND NeDa.ServiceName00=net.ServiceName0 151 | WHERE MACAddress00 is not null 152 | AND NeDa.MachineID = '" . $deviceid . "'"; 153 | 154 | $result = $sccm_db->exec_query($query); 155 | 156 | $data = []; 157 | 158 | $i = 0; 159 | $tab = []; 160 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 161 | $tmp = []; 162 | foreach ($tab as $key => $value) { 163 | $tmp[$key] = $value; 164 | } 165 | 166 | $data[] = $tmp; 167 | $i++; 168 | } 169 | 170 | $sccm_db->disconnect(); 171 | return $data; 172 | } 173 | 174 | public function getSoftware($deviceid, $limit = 99999999) 175 | { 176 | $sccm_db = new PluginSccmSccmdb(); 177 | $res = $sccm_db->connect(); 178 | if (!$res) { 179 | throw new BadRequestHttpException( 180 | __s('Cannot connect to SCCM database', 'sccm'), 181 | ); 182 | } 183 | 184 | $query = "SELECT ArPd_64.DisplayName0 as \"ArPd-DisplayName\", 185 | ArPd_64.InstallDate0 as \"ArPd-InstallDate\", 186 | ArPd_64.Version0 as \"ArPd-Version\", 187 | ArPd_64.Publisher0 as \"ArPd-Publisher\" 188 | FROM v_GS_ADD_REMOVE_PROGRAMS_64 ArPd_64 189 | INNER JOIN v_R_System VrS on VrS.ResourceID=ArPd_64.ResourceID 190 | WHERE ArPd_64.ResourceID = {$deviceid} 191 | AND (ArPd_64.DisplayName0 is not null and ArPd_64.DisplayName0 <> '') 192 | UNION 193 | SELECT ArPd.DisplayName0 as \"ArPd-DisplayName\", 194 | ArPd.InstallDate0 as \"ArPd-InstallDate\", 195 | ArPd.Version0 as \"ArPd-Version\", 196 | ArPd.Publisher0 as \"ArPd-Publisher\" 197 | FROM v_GS_ADD_REMOVE_PROGRAMS ArPd 198 | INNER JOIN v_R_System VrS on VrS.ResourceID=ArPd.ResourceID 199 | WHERE ArPd.ResourceID = {$deviceid} 200 | AND (ArPd.DisplayName0 is not null and ArPd.DisplayName0 <> '')"; 201 | 202 | $result = $sccm_db->exec_query($query); 203 | 204 | $data = []; 205 | 206 | $i = 0; 207 | $tab = []; 208 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 209 | $tmp = []; 210 | foreach ($tab as $key => $value) { 211 | $tmp[$key] = $value; 212 | } 213 | 214 | $data[] = $tmp; 215 | $i++; 216 | } 217 | 218 | $sccm_db->disconnect(); 219 | return $data; 220 | } 221 | 222 | public function getMemories($deviceid, $limit = 99999999) 223 | { 224 | 225 | $sccm_db = new PluginSccmSccmdb(); 226 | $res = $sccm_db->connect(); 227 | if (!$res) { 228 | throw new BadRequestHttpException( 229 | __s('Cannot connect to SCCM database', 'sccm'), 230 | ); 231 | } 232 | 233 | $query = "SELECT 234 | Capacity0 as \"Mem-Capacity\", 235 | Caption0 as \"Mem-Caption\", 236 | Description0 as \"Mem-Description\", 237 | FormFactor0 as \"Mem-FormFactor\", 238 | Manufacturer0 as \"Mem-Manufacturer\", 239 | Removable0 as \"Mem-Removable\", 240 | '' as \"Mem-Purpose\", 241 | Speed0 as \"Mem-Speed\", 242 | BankLabel0 as \"Mem-Type\", 243 | GroupID as \"Mem-NumSlots\", 244 | '' as \"Mem-SerialNumber\" 245 | FROM v_GS_PHYSICAL_MEMORY 246 | 247 | WHERE ResourceID = '" . $deviceid . "' 248 | 249 | ORDER BY \"Mem-NumSlots\""; 250 | 251 | $result = $sccm_db->exec_query($query); 252 | $data = []; 253 | 254 | $i = 0; 255 | $tab = []; 256 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 257 | $tmp = []; 258 | foreach ($tab as $key => $value) { 259 | $tmp[$key] = $value; 260 | } 261 | 262 | $data[] = $tmp; 263 | $i++; 264 | } 265 | 266 | $sccm_db->disconnect(); 267 | return $data; 268 | } 269 | 270 | public function getVideos($deviceid, $limit = 99999999) 271 | { 272 | $sccm_db = new PluginSccmSccmdb(); 273 | $res = $sccm_db->connect(); 274 | if (!$res) { 275 | throw new BadRequestHttpException( 276 | __s('Cannot connect to SCCM database', 'sccm'), 277 | ); 278 | } 279 | 280 | $query = " 281 | SELECT 282 | VideoProcessor0 as \"Vid-Chipset\", 283 | AdapterRAM0/1024 as \"Vid-Memory\", 284 | Name0 as \"Vid-Name\", 285 | CONCAT(CurrentHorizontalResolution0, 'x', CurrentVerticalResolution0) as \"Vid-Resolution\", 286 | GroupID as \"Vid-PciSlot\" 287 | FROM v_GS_VIDEO_CONTROLLER 288 | WHERE VideoProcessor0 is not null 289 | AND ResourceID = '" . $deviceid . "' 290 | ORDER BY GroupID"; 291 | 292 | $result = $sccm_db->exec_query($query); 293 | 294 | $data = []; 295 | 296 | $i = 0; 297 | $tab = []; 298 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 299 | $tmp = []; 300 | foreach ($tab as $key => $value) { 301 | $tmp[$key] = $value; 302 | } 303 | 304 | $data[] = $tmp; 305 | $i++; 306 | } 307 | 308 | $sccm_db->disconnect(); 309 | return $data; 310 | } 311 | 312 | public function getSounds($deviceid, $limit = 99999999) 313 | { 314 | 315 | $sccm_db = new PluginSccmSccmdb(); 316 | $res = $sccm_db->connect(); 317 | if (!$res) { 318 | throw new BadRequestHttpException( 319 | __s('Cannot connect to SCCM database', 'sccm'), 320 | ); 321 | } 322 | 323 | $query = " 324 | SELECT distinct 325 | Description0 as \"Snd-Description\", 326 | Manufacturer0 as \"Snd-Manufacturer\", 327 | Name0 as \"Snd-Name\" 328 | FROM v_GS_SOUND_DEVICE 329 | WHERE ResourceID = '" . $deviceid . "'"; 330 | 331 | $result = $sccm_db->exec_query($query); 332 | 333 | $data = []; 334 | 335 | $i = 0; 336 | $tab = []; 337 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 338 | $tmp = []; 339 | foreach ($tab as $key => $value) { 340 | $tmp[$key] = $value; 341 | } 342 | 343 | $data[] = $tmp; 344 | 345 | $i++; 346 | } 347 | 348 | $sccm_db->disconnect(); 349 | 350 | return $data; 351 | } 352 | 353 | public function getStorages($deviceid, $limit = 99999999) 354 | { 355 | 356 | $sccm_db = new PluginSccmSccmdb(); 357 | $res = $sccm_db->connect(); 358 | if (!$res) { 359 | throw new BadRequestHttpException( 360 | __s('Cannot connect to SCCM database', 'sccm'), 361 | ); 362 | } 363 | 364 | $query = " 365 | SELECT 366 | md.SystemName00, 367 | gld.ResourceID as \"gld-ResourceID\", 368 | gld.Description0 as \"gld-Description\", 369 | gld.DeviceID0 as \"gld-Partition\", 370 | gld.FileSystem0 as \"gld-FileSystem\", 371 | gld.Size0 as \"gld-TotalSize\", 372 | gld.FreeSpace0 as \"gld-FreeSpace\", 373 | gld.VolumeName0 as \"gld-MountingPoint\", 374 | gdi.Caption0 as \"gdi-Caption\" 375 | FROM v_GS_LOGICAL_DISK as gld 376 | INNER JOIN v_gs_Disk as gdi on gdi.ResourceID = gld.ResourceID 377 | LEFT JOIN Motherboard_DATA as md on gld.ResourceID = md.MachineID 378 | WHERE gld.GroupID = gdi.GroupID 379 | AND gld.ResourceID = '" . $deviceid . "'"; 380 | 381 | $result = $sccm_db->exec_query($query); 382 | 383 | $data = []; 384 | 385 | $i = 0; 386 | $tab = []; 387 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 388 | $tmp = []; 389 | 390 | foreach ($tab as $key => $value) { 391 | $tmp[$key] = $value; 392 | } 393 | 394 | $data[] = $tmp; 395 | 396 | $i++; 397 | } 398 | 399 | $sccm_db->disconnect(); 400 | 401 | return $data; 402 | } 403 | 404 | public function getMedias($deviceid, $limit = 99999999) 405 | { 406 | 407 | $sccm_db = new PluginSccmSccmdb(); 408 | $res = $sccm_db->connect(); 409 | if (!$res) { 410 | throw new BadRequestHttpException( 411 | __s('Cannot connect to SCCM database', 'sccm'), 412 | ); 413 | } 414 | 415 | $query = " 416 | SELECT distinct 417 | Description0 as \"Med-Description\", 418 | Manufacturer0 as \"Med-Manufacturer\", 419 | Caption0 as \"Med-Model\", 420 | Name0 as \"Med-Name\", 421 | SCSITargetID0 as \"Med-SCSITargetId\", 422 | MediaType0 as \"Med-Type\" 423 | FROM v_GS_CDROM 424 | WHERE ResourceID = '" . $deviceid . "'"; 425 | 426 | $result = $sccm_db->exec_query($query); 427 | 428 | $data = []; 429 | 430 | $i = 0; 431 | $tab = []; 432 | while (($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) and $i < $limit) { 433 | $tmp = []; 434 | 435 | foreach ($tab as $key => $value) { 436 | $tmp[$key] = $value; 437 | } 438 | 439 | $data[] = $tmp; 440 | 441 | $i++; 442 | } 443 | 444 | $sccm_db->disconnect(); 445 | 446 | return $data; 447 | } 448 | 449 | public static function install() 450 | { 451 | $cronCollect = new CronTask(); 452 | 453 | if ($cronCollect->getFromDBbyName(self::class, 'sccm')) { 454 | 455 | $cronCollect->fields["name"] = "SCCMCollect"; 456 | $cronCollect->fields["hourmin"] = 4; 457 | $cronCollect->fields["hourmax"] = 5; 458 | $cronCollect->update($cronCollect->fields); 459 | 460 | } elseif (!$cronCollect->getFromDBbyName(self::class, 'SCCMCollect')) { 461 | 462 | CronTask::register( 463 | self::class, 464 | 'SCCMCollect', 465 | 7 * DAY_TIMESTAMP, 466 | ['param' => 24, 'mode' => CronTask::MODE_EXTERNAL, 'hourmin' => 4, 'hourmax' => 5], 467 | ); 468 | 469 | } 470 | 471 | CronTask::register( 472 | self::class, 473 | 'SCCMPush', 474 | 7 * DAY_TIMESTAMP, 475 | ['param' => 24, 'mode' => CronTask::MODE_EXTERNAL, 'hourmin' => 6, 'hourmax' => 7], 476 | ); 477 | } 478 | 479 | public static function uninstall() 480 | { 481 | CronTask::unregister(self::class); 482 | } 483 | 484 | public static function cronSCCMCollect($task) 485 | { 486 | return self::executeCollect($task); 487 | } 488 | 489 | public static function cronSCCMPush($task) 490 | { 491 | return self::executePush($task); 492 | } 493 | 494 | public static function cronInfo($name) 495 | { 496 | if ($name == "SCCMCollect") { 497 | return ['description' => __s("Interface - SCCMCollect", "sccm")]; 498 | } 499 | 500 | if ($name == "SCCMPush") { 501 | return ['description' => __s("Interface - SCCMPush", "sccm")]; 502 | } 503 | 504 | return null; 505 | 506 | } 507 | 508 | public static function executeCollect($task) 509 | { 510 | ini_set('max_execution_time', '0'); 511 | $retcode = -1; 512 | 513 | $REP_XML = GLPI_PLUGIN_DOC_DIR . '/sccm/xml/'; 514 | 515 | $PluginSccmConfig = new PluginSccmConfig(); 516 | $PluginSccmConfig->getFromDB(1); 517 | 518 | $PluginSccmSccm = new PluginSccmSccm(); 519 | 520 | if ($PluginSccmConfig->getField('active_sync') == 1) { 521 | 522 | $PluginSccmSccm->getDevices(); 523 | Toolbox::logInFile('sccm', "getDevices OK \n", true); 524 | 525 | Toolbox::logInFile('sccm', "Generate XML start : " 526 | . count($PluginSccmSccm->devices) . " files\n", true); 527 | 528 | foreach ($PluginSccmSccm->devices as $device_values) { 529 | 530 | $PluginSccmSccmxml = new PluginSccmSccmxml($device_values); 531 | 532 | $PluginSccmSccmxml->setAccessLog(); 533 | $PluginSccmSccmxml->setAccountInfos(); 534 | $PluginSccmSccmxml->setHardware(); 535 | $PluginSccmSccmxml->setOS(); 536 | $PluginSccmSccmxml->setBios(); 537 | $PluginSccmSccmxml->setProcessors(); 538 | $PluginSccmSccmxml->setSoftwares(); 539 | $PluginSccmSccmxml->setMemories(); 540 | $PluginSccmSccmxml->setVideos(); 541 | $PluginSccmSccmxml->setSounds(); 542 | $PluginSccmSccmxml->setUsers(); 543 | $PluginSccmSccmxml->setNetworks(); 544 | $PluginSccmSccmxml->setStorages(); 545 | 546 | $SXML = $PluginSccmSccmxml->sxml; 547 | 548 | $SXML->asXML($REP_XML . $PluginSccmSccmxml->device_id . ".ocs"); 549 | 550 | Toolbox::logInFile('sccm', "Collect OK for device - " . $PluginSccmSccmxml->device_id . " \n", true); 551 | $task->addVolume(1); 552 | } 553 | 554 | $retcode = 1; 555 | Toolbox::logInFile('sccm', "Collect completed \n", true); 556 | 557 | } else { 558 | echo __s("Collect is disabled by configuration.", "sccm"); 559 | } 560 | 561 | return $retcode; 562 | } 563 | 564 | public static function getcomputerQuery() 565 | { 566 | return "SELECT csd.Description00 as \"CSD-Description\", 567 | csd.Domain00 as \"CSD-Domain\", 568 | csd.Manufacturer00 as \"CSD-Manufacturer\", 569 | csd.Model00 as \"CSD-Model\", 570 | csd.Roles00 as \"CSD-Roles\", 571 | csd.SystemType00 as \"CSD-SystemType\", 572 | csd.UserName00 as \"CSD-UserName\", 573 | csd.MachineID as \"CSD-MachineID\", 574 | csd.TimeKey as \"CSD-TimeKey\", 575 | md.SystemName00 as \"MD-SystemName\", 576 | osd.BuildNumber00 as \"OSD-BuildNumber\", 577 | osd.Caption00 as \"OSD-Caption\", 578 | osd.CSDVersion00 as \"OSD-CSDVersion\", 579 | osd.BootDevice00 as \"OSD-BootDevice\", 580 | osd.InstallDate00 as \"OSD-InstallDate\", 581 | osd.LastBootUpTime00 as \"OSD-LastBootUpTime\", 582 | osd.Manufacturer00 as \"OSD-Manufacturer\", 583 | osd.Name00 as \"OSD-Name\", 584 | osd.Organization00 as \"OSD-Organization\", 585 | osd.RegisteredUser00 as \"OSD-RegisteredUser\", 586 | osd.TotalVirtualMemorySize00 as \"OSD-TotalVirtualMemory\", 587 | osd.TotalVisibleMemorySize00 as \"OSD-TotalVisibleMemory\", 588 | osd.Version00 as \"OSD-Version\", 589 | pbd.SerialNumber00 as \"PBD-SerialNumber\", 590 | pbd.ReleaseDate00 as \"PBD-ReleaseDate\", 591 | pbd.Name00 as \"PBD-Name\", 592 | pbd.SMBIOSBIOSVersion00 as \"PBD-BiosVersion\", 593 | pbd.Version00 as \"PBD-Version\", 594 | pbd.Manufacturer00 as \"PBD-Manufacturer\", 595 | sdi.User_Name0 as \"SDI-UserName\", 596 | sd.SMSID0 as \"SD-UUID\", 597 | sd.SystemRole0 as \"SD-SystemRole\", 598 | VrS.User_Name0 as \"VrS-UserName\", 599 | vWD.LastHWScan as \"vWD-LastScan\" 600 | FROM Computer_System_DATA csd 601 | LEFT JOIN Motherboard_DATA md ON csd.MachineID = md.MachineID 602 | LEFT JOIN Operating_System_DATA osd ON csd.MachineID = osd.MachineID 603 | LEFT JOIN v_GS_WORKSTATION_STATUS vWD ON csd.MachineID = vWD.ResourceID 604 | LEFT JOIN PC_BIOS_DATA pbd ON csd.MachineID = pbd.MachineID 605 | LEFT JOIN System_DISC sdi ON csd.MachineID = sdi.ItemKey 606 | LEFT JOIN System_DATA sd ON csd.MachineID = sd.MachineID 607 | INNER JOIN v_R_System VrS ON csd.MachineID = VrS.ResourceID 608 | WHERE csd.MachineID is not null and csd.MachineID != ''"; 609 | } 610 | 611 | 612 | public static function executePush($task) 613 | { 614 | /** @var array $CFG_GLPI */ 615 | global $CFG_GLPI; 616 | 617 | $PluginSccmSccmdb = new PluginSccmSccmdb(); 618 | $res = $PluginSccmSccmdb->connect(); 619 | $PluginSccmConfig = new PluginSccmConfig(); 620 | $PluginSccmConfig->getFromDB(1); 621 | 622 | $retcode = -1; 623 | 624 | if ($PluginSccmConfig->getField('active_sync') == 1) { 625 | if ($res) { 626 | 627 | $query = self::getcomputerQuery(); 628 | $result = $PluginSccmSccmdb->exec_query($query); 629 | 630 | $tab = []; 631 | 632 | while ($tab = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) { 633 | 634 | $REP_XML = realpath(GLPI_PLUGIN_DOC_DIR . '/sccm/xml/' . $tab['CSD-MachineID'] . '.ocs'); 635 | 636 | if ($REP_XML === false) { 637 | Toolbox::logInFile('sccm', "There is a problem with the path, realpath function return false.\nPath : " . $REP_XML . "\n", true); 638 | continue; 639 | } 640 | 641 | $xmlFile = simplexml_load_file($REP_XML, 'SimpleXMLElement', LIBXML_NOCDATA); 642 | if ($xmlFile !== false) { 643 | 644 | $ch = curl_init(); 645 | if ($PluginSccmConfig->getField('verify_ssl_cert') != "1") { 646 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 647 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 648 | } 649 | 650 | if ($PluginSccmConfig->getField('use_auth_ntlm') == "1") { 651 | curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); 652 | } 653 | 654 | if ($PluginSccmConfig->getField('unrestricted_auth') == "1") { 655 | curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, true); 656 | } 657 | 658 | if ($PluginSccmConfig->getField('use_auth_info') == "1") { 659 | curl_setopt($ch, CURLOPT_USERPWD, $PluginSccmConfig->getField('auth_info')); 660 | } 661 | 662 | $url = ($PluginSccmConfig->getField('inventory_server_url') ?: $CFG_GLPI['url_base']) . '/front/inventory.php'; 663 | 664 | curl_setopt($ch, CURLOPT_URL, $url); 665 | curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']); 666 | curl_setopt($ch, CURLOPT_HEADER, true); 667 | curl_setopt($ch, CURLOPT_POST, true); 668 | curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlFile->asXML()); 669 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); 670 | curl_setopt($ch, CURLOPT_REFERER, $CFG_GLPI['url_base']); 671 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 672 | $ch_result = curl_exec($ch); 673 | if ($ch_result === false) { 674 | Toolbox::logInFile('sccm', curl_error($ch) . "\n", true); 675 | } else { 676 | 677 | $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 678 | if ($httpcode != 200) { 679 | $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 680 | $body = substr($ch_result, $header_size); 681 | 682 | Toolbox::logInFile('sccm', "Push KO - " . $tab['CSD-MachineID'] . " -> STATUS CODE : " . $httpcode . " \n", true); 683 | Toolbox::logInFile('sccm', "ERROR RETURNED : " . $body . " \n", true); 684 | } else { 685 | $task->addVolume(1); 686 | 687 | if ($PluginSccmConfig->getField('use_lasthwscan') == 1) { 688 | $agent = new Agent(); 689 | if ($agent->getFromDBByCrit(["name" => $tab['CSD-MachineID']]) && (class_exists($agent->fields['itemtype']) && is_a($agent->fields['itemtype'], CommonDBTM::class, true))) { 690 | $asset = new $agent->fields['itemtype'](); 691 | if ($asset->getFromDB($agent->fields['items_id'])) { 692 | $asset->update([ 693 | "id" => $asset->fields['id'], 694 | "last_inventory_update" => $tab['vWD-LastScan']->format('Y-m-d h:i'), 695 | ]); 696 | } 697 | } 698 | } 699 | 700 | Toolbox::logInFile('sccm', "Push OK - " . $tab['CSD-MachineID'] . " \n", true); 701 | } 702 | 703 | } 704 | 705 | curl_close($ch); 706 | } else { 707 | $errors = ""; 708 | foreach (libxml_get_errors() as $error) { 709 | $errors = $errors . $error->message . "\n"; 710 | } 711 | 712 | Toolbox::logInFile('sccm', "Can't load the file with the path : " . $REP_XML . "\n\n" . $errors . "\n", true); 713 | } 714 | } 715 | 716 | Toolbox::logInFile('sccm', "Push completed \n", true); 717 | $PluginSccmSccmdb->disconnect(); 718 | $retcode = 1; 719 | } 720 | } else { 721 | echo __s("Push is disabled by configuration.", "sccm"); 722 | } 723 | 724 | return $retcode; 725 | } 726 | 727 | } 728 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "3b0805ca810a8f2c1092a852c12f1234", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "glpi-project/tools", 12 | "version": "0.8.3", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/glpi-project/tools.git", 16 | "reference": "8ea2a7d4702a858f4b0360ba7d4f1841a5e77026" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/glpi-project/tools/zipball/8ea2a7d4702a858f4b0360ba7d4f1841a5e77026", 21 | "reference": "8ea2a7d4702a858f4b0360ba7d4f1841a5e77026", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "symfony/console": "^5.4 || ^6.0", 26 | "twig/twig": "^3.3" 27 | }, 28 | "require-dev": { 29 | "nikic/php-parser": "^4.13", 30 | "phpstan/phpstan-src": "^1.10" 31 | }, 32 | "bin": [ 33 | "bin/extract-locales", 34 | "bin/licence-headers-check", 35 | "tools/plugin-release" 36 | ], 37 | "type": "library", 38 | "autoload": { 39 | "psr-4": { 40 | "GlpiProject\\Tools\\": "src/" 41 | } 42 | }, 43 | "notification-url": "https://packagist.org/downloads/", 44 | "license": [ 45 | "GPL-3.0-or-later" 46 | ], 47 | "authors": [ 48 | { 49 | "name": "Teclib'", 50 | "email": "glpi@teclib.com", 51 | "homepage": "http://teclib-group.com" 52 | } 53 | ], 54 | "description": "Various tools for GLPI and its plugins", 55 | "keywords": [ 56 | "glpi", 57 | "plugins", 58 | "tools" 59 | ], 60 | "support": { 61 | "issues": "https://github.com/glpi-project/tools/issues", 62 | "source": "https://github.com/glpi-project/tools" 63 | }, 64 | "time": "2025-10-14T10:26:06+00:00" 65 | }, 66 | { 67 | "name": "psr/container", 68 | "version": "2.0.2", 69 | "source": { 70 | "type": "git", 71 | "url": "https://github.com/php-fig/container.git", 72 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" 73 | }, 74 | "dist": { 75 | "type": "zip", 76 | "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", 77 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", 78 | "shasum": "" 79 | }, 80 | "require": { 81 | "php": ">=7.4.0" 82 | }, 83 | "type": "library", 84 | "extra": { 85 | "branch-alias": { 86 | "dev-master": "2.0.x-dev" 87 | } 88 | }, 89 | "autoload": { 90 | "psr-4": { 91 | "Psr\\Container\\": "src/" 92 | } 93 | }, 94 | "notification-url": "https://packagist.org/downloads/", 95 | "license": [ 96 | "MIT" 97 | ], 98 | "authors": [ 99 | { 100 | "name": "PHP-FIG", 101 | "homepage": "https://www.php-fig.org/" 102 | } 103 | ], 104 | "description": "Common Container Interface (PHP FIG PSR-11)", 105 | "homepage": "https://github.com/php-fig/container", 106 | "keywords": [ 107 | "PSR-11", 108 | "container", 109 | "container-interface", 110 | "container-interop", 111 | "psr" 112 | ], 113 | "support": { 114 | "issues": "https://github.com/php-fig/container/issues", 115 | "source": "https://github.com/php-fig/container/tree/2.0.2" 116 | }, 117 | "time": "2021-11-05T16:47:00+00:00" 118 | }, 119 | { 120 | "name": "symfony/console", 121 | "version": "v6.4.30", 122 | "source": { 123 | "type": "git", 124 | "url": "https://github.com/symfony/console.git", 125 | "reference": "1b2813049506b39eb3d7e64aff033fd5ca26c97e" 126 | }, 127 | "dist": { 128 | "type": "zip", 129 | "url": "https://api.github.com/repos/symfony/console/zipball/1b2813049506b39eb3d7e64aff033fd5ca26c97e", 130 | "reference": "1b2813049506b39eb3d7e64aff033fd5ca26c97e", 131 | "shasum": "" 132 | }, 133 | "require": { 134 | "php": ">=8.1", 135 | "symfony/deprecation-contracts": "^2.5|^3", 136 | "symfony/polyfill-mbstring": "~1.0", 137 | "symfony/service-contracts": "^2.5|^3", 138 | "symfony/string": "^5.4|^6.0|^7.0" 139 | }, 140 | "conflict": { 141 | "symfony/dependency-injection": "<5.4", 142 | "symfony/dotenv": "<5.4", 143 | "symfony/event-dispatcher": "<5.4", 144 | "symfony/lock": "<5.4", 145 | "symfony/process": "<5.4" 146 | }, 147 | "provide": { 148 | "psr/log-implementation": "1.0|2.0|3.0" 149 | }, 150 | "require-dev": { 151 | "psr/log": "^1|^2|^3", 152 | "symfony/config": "^5.4|^6.0|^7.0", 153 | "symfony/dependency-injection": "^5.4|^6.0|^7.0", 154 | "symfony/event-dispatcher": "^5.4|^6.0|^7.0", 155 | "symfony/http-foundation": "^6.4|^7.0", 156 | "symfony/http-kernel": "^6.4|^7.0", 157 | "symfony/lock": "^5.4|^6.0|^7.0", 158 | "symfony/messenger": "^5.4|^6.0|^7.0", 159 | "symfony/process": "^5.4|^6.0|^7.0", 160 | "symfony/stopwatch": "^5.4|^6.0|^7.0", 161 | "symfony/var-dumper": "^5.4|^6.0|^7.0" 162 | }, 163 | "type": "library", 164 | "autoload": { 165 | "psr-4": { 166 | "Symfony\\Component\\Console\\": "" 167 | }, 168 | "exclude-from-classmap": [ 169 | "/Tests/" 170 | ] 171 | }, 172 | "notification-url": "https://packagist.org/downloads/", 173 | "license": [ 174 | "MIT" 175 | ], 176 | "authors": [ 177 | { 178 | "name": "Fabien Potencier", 179 | "email": "fabien@symfony.com" 180 | }, 181 | { 182 | "name": "Symfony Community", 183 | "homepage": "https://symfony.com/contributors" 184 | } 185 | ], 186 | "description": "Eases the creation of beautiful and testable command line interfaces", 187 | "homepage": "https://symfony.com", 188 | "keywords": [ 189 | "cli", 190 | "command-line", 191 | "console", 192 | "terminal" 193 | ], 194 | "support": { 195 | "source": "https://github.com/symfony/console/tree/v6.4.30" 196 | }, 197 | "funding": [ 198 | { 199 | "url": "https://symfony.com/sponsor", 200 | "type": "custom" 201 | }, 202 | { 203 | "url": "https://github.com/fabpot", 204 | "type": "github" 205 | }, 206 | { 207 | "url": "https://github.com/nicolas-grekas", 208 | "type": "github" 209 | }, 210 | { 211 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 212 | "type": "tidelift" 213 | } 214 | ], 215 | "time": "2025-12-05T13:47:41+00:00" 216 | }, 217 | { 218 | "name": "symfony/deprecation-contracts", 219 | "version": "v3.6.0", 220 | "source": { 221 | "type": "git", 222 | "url": "https://github.com/symfony/deprecation-contracts.git", 223 | "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" 224 | }, 225 | "dist": { 226 | "type": "zip", 227 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", 228 | "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", 229 | "shasum": "" 230 | }, 231 | "require": { 232 | "php": ">=8.1" 233 | }, 234 | "type": "library", 235 | "extra": { 236 | "thanks": { 237 | "url": "https://github.com/symfony/contracts", 238 | "name": "symfony/contracts" 239 | }, 240 | "branch-alias": { 241 | "dev-main": "3.6-dev" 242 | } 243 | }, 244 | "autoload": { 245 | "files": [ 246 | "function.php" 247 | ] 248 | }, 249 | "notification-url": "https://packagist.org/downloads/", 250 | "license": [ 251 | "MIT" 252 | ], 253 | "authors": [ 254 | { 255 | "name": "Nicolas Grekas", 256 | "email": "p@tchwork.com" 257 | }, 258 | { 259 | "name": "Symfony Community", 260 | "homepage": "https://symfony.com/contributors" 261 | } 262 | ], 263 | "description": "A generic function and convention to trigger deprecation notices", 264 | "homepage": "https://symfony.com", 265 | "support": { 266 | "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" 267 | }, 268 | "funding": [ 269 | { 270 | "url": "https://symfony.com/sponsor", 271 | "type": "custom" 272 | }, 273 | { 274 | "url": "https://github.com/fabpot", 275 | "type": "github" 276 | }, 277 | { 278 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 279 | "type": "tidelift" 280 | } 281 | ], 282 | "time": "2024-09-25T14:21:43+00:00" 283 | }, 284 | { 285 | "name": "symfony/polyfill-ctype", 286 | "version": "v1.33.0", 287 | "source": { 288 | "type": "git", 289 | "url": "https://github.com/symfony/polyfill-ctype.git", 290 | "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" 291 | }, 292 | "dist": { 293 | "type": "zip", 294 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", 295 | "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", 296 | "shasum": "" 297 | }, 298 | "require": { 299 | "php": ">=7.2" 300 | }, 301 | "provide": { 302 | "ext-ctype": "*" 303 | }, 304 | "suggest": { 305 | "ext-ctype": "For best performance" 306 | }, 307 | "type": "library", 308 | "extra": { 309 | "thanks": { 310 | "url": "https://github.com/symfony/polyfill", 311 | "name": "symfony/polyfill" 312 | } 313 | }, 314 | "autoload": { 315 | "files": [ 316 | "bootstrap.php" 317 | ], 318 | "psr-4": { 319 | "Symfony\\Polyfill\\Ctype\\": "" 320 | } 321 | }, 322 | "notification-url": "https://packagist.org/downloads/", 323 | "license": [ 324 | "MIT" 325 | ], 326 | "authors": [ 327 | { 328 | "name": "Gert de Pagter", 329 | "email": "BackEndTea@gmail.com" 330 | }, 331 | { 332 | "name": "Symfony Community", 333 | "homepage": "https://symfony.com/contributors" 334 | } 335 | ], 336 | "description": "Symfony polyfill for ctype functions", 337 | "homepage": "https://symfony.com", 338 | "keywords": [ 339 | "compatibility", 340 | "ctype", 341 | "polyfill", 342 | "portable" 343 | ], 344 | "support": { 345 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" 346 | }, 347 | "funding": [ 348 | { 349 | "url": "https://symfony.com/sponsor", 350 | "type": "custom" 351 | }, 352 | { 353 | "url": "https://github.com/fabpot", 354 | "type": "github" 355 | }, 356 | { 357 | "url": "https://github.com/nicolas-grekas", 358 | "type": "github" 359 | }, 360 | { 361 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 362 | "type": "tidelift" 363 | } 364 | ], 365 | "time": "2024-09-09T11:45:10+00:00" 366 | }, 367 | { 368 | "name": "symfony/polyfill-intl-grapheme", 369 | "version": "v1.33.0", 370 | "source": { 371 | "type": "git", 372 | "url": "https://github.com/symfony/polyfill-intl-grapheme.git", 373 | "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" 374 | }, 375 | "dist": { 376 | "type": "zip", 377 | "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", 378 | "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", 379 | "shasum": "" 380 | }, 381 | "require": { 382 | "php": ">=7.2" 383 | }, 384 | "suggest": { 385 | "ext-intl": "For best performance" 386 | }, 387 | "type": "library", 388 | "extra": { 389 | "thanks": { 390 | "url": "https://github.com/symfony/polyfill", 391 | "name": "symfony/polyfill" 392 | } 393 | }, 394 | "autoload": { 395 | "files": [ 396 | "bootstrap.php" 397 | ], 398 | "psr-4": { 399 | "Symfony\\Polyfill\\Intl\\Grapheme\\": "" 400 | } 401 | }, 402 | "notification-url": "https://packagist.org/downloads/", 403 | "license": [ 404 | "MIT" 405 | ], 406 | "authors": [ 407 | { 408 | "name": "Nicolas Grekas", 409 | "email": "p@tchwork.com" 410 | }, 411 | { 412 | "name": "Symfony Community", 413 | "homepage": "https://symfony.com/contributors" 414 | } 415 | ], 416 | "description": "Symfony polyfill for intl's grapheme_* functions", 417 | "homepage": "https://symfony.com", 418 | "keywords": [ 419 | "compatibility", 420 | "grapheme", 421 | "intl", 422 | "polyfill", 423 | "portable", 424 | "shim" 425 | ], 426 | "support": { 427 | "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" 428 | }, 429 | "funding": [ 430 | { 431 | "url": "https://symfony.com/sponsor", 432 | "type": "custom" 433 | }, 434 | { 435 | "url": "https://github.com/fabpot", 436 | "type": "github" 437 | }, 438 | { 439 | "url": "https://github.com/nicolas-grekas", 440 | "type": "github" 441 | }, 442 | { 443 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 444 | "type": "tidelift" 445 | } 446 | ], 447 | "time": "2025-06-27T09:58:17+00:00" 448 | }, 449 | { 450 | "name": "symfony/polyfill-intl-normalizer", 451 | "version": "v1.33.0", 452 | "source": { 453 | "type": "git", 454 | "url": "https://github.com/symfony/polyfill-intl-normalizer.git", 455 | "reference": "3833d7255cc303546435cb650316bff708a1c75c" 456 | }, 457 | "dist": { 458 | "type": "zip", 459 | "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", 460 | "reference": "3833d7255cc303546435cb650316bff708a1c75c", 461 | "shasum": "" 462 | }, 463 | "require": { 464 | "php": ">=7.2" 465 | }, 466 | "suggest": { 467 | "ext-intl": "For best performance" 468 | }, 469 | "type": "library", 470 | "extra": { 471 | "thanks": { 472 | "url": "https://github.com/symfony/polyfill", 473 | "name": "symfony/polyfill" 474 | } 475 | }, 476 | "autoload": { 477 | "files": [ 478 | "bootstrap.php" 479 | ], 480 | "psr-4": { 481 | "Symfony\\Polyfill\\Intl\\Normalizer\\": "" 482 | }, 483 | "classmap": [ 484 | "Resources/stubs" 485 | ] 486 | }, 487 | "notification-url": "https://packagist.org/downloads/", 488 | "license": [ 489 | "MIT" 490 | ], 491 | "authors": [ 492 | { 493 | "name": "Nicolas Grekas", 494 | "email": "p@tchwork.com" 495 | }, 496 | { 497 | "name": "Symfony Community", 498 | "homepage": "https://symfony.com/contributors" 499 | } 500 | ], 501 | "description": "Symfony polyfill for intl's Normalizer class and related functions", 502 | "homepage": "https://symfony.com", 503 | "keywords": [ 504 | "compatibility", 505 | "intl", 506 | "normalizer", 507 | "polyfill", 508 | "portable", 509 | "shim" 510 | ], 511 | "support": { 512 | "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" 513 | }, 514 | "funding": [ 515 | { 516 | "url": "https://symfony.com/sponsor", 517 | "type": "custom" 518 | }, 519 | { 520 | "url": "https://github.com/fabpot", 521 | "type": "github" 522 | }, 523 | { 524 | "url": "https://github.com/nicolas-grekas", 525 | "type": "github" 526 | }, 527 | { 528 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 529 | "type": "tidelift" 530 | } 531 | ], 532 | "time": "2024-09-09T11:45:10+00:00" 533 | }, 534 | { 535 | "name": "symfony/polyfill-mbstring", 536 | "version": "v1.33.0", 537 | "source": { 538 | "type": "git", 539 | "url": "https://github.com/symfony/polyfill-mbstring.git", 540 | "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" 541 | }, 542 | "dist": { 543 | "type": "zip", 544 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", 545 | "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", 546 | "shasum": "" 547 | }, 548 | "require": { 549 | "ext-iconv": "*", 550 | "php": ">=7.2" 551 | }, 552 | "provide": { 553 | "ext-mbstring": "*" 554 | }, 555 | "suggest": { 556 | "ext-mbstring": "For best performance" 557 | }, 558 | "type": "library", 559 | "extra": { 560 | "thanks": { 561 | "url": "https://github.com/symfony/polyfill", 562 | "name": "symfony/polyfill" 563 | } 564 | }, 565 | "autoload": { 566 | "files": [ 567 | "bootstrap.php" 568 | ], 569 | "psr-4": { 570 | "Symfony\\Polyfill\\Mbstring\\": "" 571 | } 572 | }, 573 | "notification-url": "https://packagist.org/downloads/", 574 | "license": [ 575 | "MIT" 576 | ], 577 | "authors": [ 578 | { 579 | "name": "Nicolas Grekas", 580 | "email": "p@tchwork.com" 581 | }, 582 | { 583 | "name": "Symfony Community", 584 | "homepage": "https://symfony.com/contributors" 585 | } 586 | ], 587 | "description": "Symfony polyfill for the Mbstring extension", 588 | "homepage": "https://symfony.com", 589 | "keywords": [ 590 | "compatibility", 591 | "mbstring", 592 | "polyfill", 593 | "portable", 594 | "shim" 595 | ], 596 | "support": { 597 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" 598 | }, 599 | "funding": [ 600 | { 601 | "url": "https://symfony.com/sponsor", 602 | "type": "custom" 603 | }, 604 | { 605 | "url": "https://github.com/fabpot", 606 | "type": "github" 607 | }, 608 | { 609 | "url": "https://github.com/nicolas-grekas", 610 | "type": "github" 611 | }, 612 | { 613 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 614 | "type": "tidelift" 615 | } 616 | ], 617 | "time": "2024-12-23T08:48:59+00:00" 618 | }, 619 | { 620 | "name": "symfony/service-contracts", 621 | "version": "v3.6.1", 622 | "source": { 623 | "type": "git", 624 | "url": "https://github.com/symfony/service-contracts.git", 625 | "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" 626 | }, 627 | "dist": { 628 | "type": "zip", 629 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", 630 | "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", 631 | "shasum": "" 632 | }, 633 | "require": { 634 | "php": ">=8.1", 635 | "psr/container": "^1.1|^2.0", 636 | "symfony/deprecation-contracts": "^2.5|^3" 637 | }, 638 | "conflict": { 639 | "ext-psr": "<1.1|>=2" 640 | }, 641 | "type": "library", 642 | "extra": { 643 | "thanks": { 644 | "url": "https://github.com/symfony/contracts", 645 | "name": "symfony/contracts" 646 | }, 647 | "branch-alias": { 648 | "dev-main": "3.6-dev" 649 | } 650 | }, 651 | "autoload": { 652 | "psr-4": { 653 | "Symfony\\Contracts\\Service\\": "" 654 | }, 655 | "exclude-from-classmap": [ 656 | "/Test/" 657 | ] 658 | }, 659 | "notification-url": "https://packagist.org/downloads/", 660 | "license": [ 661 | "MIT" 662 | ], 663 | "authors": [ 664 | { 665 | "name": "Nicolas Grekas", 666 | "email": "p@tchwork.com" 667 | }, 668 | { 669 | "name": "Symfony Community", 670 | "homepage": "https://symfony.com/contributors" 671 | } 672 | ], 673 | "description": "Generic abstractions related to writing services", 674 | "homepage": "https://symfony.com", 675 | "keywords": [ 676 | "abstractions", 677 | "contracts", 678 | "decoupling", 679 | "interfaces", 680 | "interoperability", 681 | "standards" 682 | ], 683 | "support": { 684 | "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" 685 | }, 686 | "funding": [ 687 | { 688 | "url": "https://symfony.com/sponsor", 689 | "type": "custom" 690 | }, 691 | { 692 | "url": "https://github.com/fabpot", 693 | "type": "github" 694 | }, 695 | { 696 | "url": "https://github.com/nicolas-grekas", 697 | "type": "github" 698 | }, 699 | { 700 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 701 | "type": "tidelift" 702 | } 703 | ], 704 | "time": "2025-07-15T11:30:57+00:00" 705 | }, 706 | { 707 | "name": "symfony/string", 708 | "version": "v7.4.0", 709 | "source": { 710 | "type": "git", 711 | "url": "https://github.com/symfony/string.git", 712 | "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003" 713 | }, 714 | "dist": { 715 | "type": "zip", 716 | "url": "https://api.github.com/repos/symfony/string/zipball/d50e862cb0a0e0886f73ca1f31b865efbb795003", 717 | "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003", 718 | "shasum": "" 719 | }, 720 | "require": { 721 | "php": ">=8.2", 722 | "symfony/deprecation-contracts": "^2.5|^3.0", 723 | "symfony/polyfill-ctype": "~1.8", 724 | "symfony/polyfill-intl-grapheme": "~1.33", 725 | "symfony/polyfill-intl-normalizer": "~1.0", 726 | "symfony/polyfill-mbstring": "~1.0" 727 | }, 728 | "conflict": { 729 | "symfony/translation-contracts": "<2.5" 730 | }, 731 | "require-dev": { 732 | "symfony/emoji": "^7.1|^8.0", 733 | "symfony/http-client": "^6.4|^7.0|^8.0", 734 | "symfony/intl": "^6.4|^7.0|^8.0", 735 | "symfony/translation-contracts": "^2.5|^3.0", 736 | "symfony/var-exporter": "^6.4|^7.0|^8.0" 737 | }, 738 | "type": "library", 739 | "autoload": { 740 | "files": [ 741 | "Resources/functions.php" 742 | ], 743 | "psr-4": { 744 | "Symfony\\Component\\String\\": "" 745 | }, 746 | "exclude-from-classmap": [ 747 | "/Tests/" 748 | ] 749 | }, 750 | "notification-url": "https://packagist.org/downloads/", 751 | "license": [ 752 | "MIT" 753 | ], 754 | "authors": [ 755 | { 756 | "name": "Nicolas Grekas", 757 | "email": "p@tchwork.com" 758 | }, 759 | { 760 | "name": "Symfony Community", 761 | "homepage": "https://symfony.com/contributors" 762 | } 763 | ], 764 | "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", 765 | "homepage": "https://symfony.com", 766 | "keywords": [ 767 | "grapheme", 768 | "i18n", 769 | "string", 770 | "unicode", 771 | "utf-8", 772 | "utf8" 773 | ], 774 | "support": { 775 | "source": "https://github.com/symfony/string/tree/v7.4.0" 776 | }, 777 | "funding": [ 778 | { 779 | "url": "https://symfony.com/sponsor", 780 | "type": "custom" 781 | }, 782 | { 783 | "url": "https://github.com/fabpot", 784 | "type": "github" 785 | }, 786 | { 787 | "url": "https://github.com/nicolas-grekas", 788 | "type": "github" 789 | }, 790 | { 791 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 792 | "type": "tidelift" 793 | } 794 | ], 795 | "time": "2025-11-27T13:27:24+00:00" 796 | }, 797 | { 798 | "name": "twig/twig", 799 | "version": "v3.22.1", 800 | "source": { 801 | "type": "git", 802 | "url": "https://github.com/twigphp/Twig.git", 803 | "reference": "1de2ec1fc43ab58a4b7e80b214b96bfc895750f3" 804 | }, 805 | "dist": { 806 | "type": "zip", 807 | "url": "https://api.github.com/repos/twigphp/Twig/zipball/1de2ec1fc43ab58a4b7e80b214b96bfc895750f3", 808 | "reference": "1de2ec1fc43ab58a4b7e80b214b96bfc895750f3", 809 | "shasum": "" 810 | }, 811 | "require": { 812 | "php": ">=8.1.0", 813 | "symfony/deprecation-contracts": "^2.5|^3", 814 | "symfony/polyfill-ctype": "^1.8", 815 | "symfony/polyfill-mbstring": "^1.3" 816 | }, 817 | "require-dev": { 818 | "phpstan/phpstan": "^2.0", 819 | "psr/container": "^1.0|^2.0", 820 | "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" 821 | }, 822 | "type": "library", 823 | "autoload": { 824 | "files": [ 825 | "src/Resources/core.php", 826 | "src/Resources/debug.php", 827 | "src/Resources/escaper.php", 828 | "src/Resources/string_loader.php" 829 | ], 830 | "psr-4": { 831 | "Twig\\": "src/" 832 | } 833 | }, 834 | "notification-url": "https://packagist.org/downloads/", 835 | "license": [ 836 | "BSD-3-Clause" 837 | ], 838 | "authors": [ 839 | { 840 | "name": "Fabien Potencier", 841 | "email": "fabien@symfony.com", 842 | "homepage": "http://fabien.potencier.org", 843 | "role": "Lead Developer" 844 | }, 845 | { 846 | "name": "Twig Team", 847 | "role": "Contributors" 848 | }, 849 | { 850 | "name": "Armin Ronacher", 851 | "email": "armin.ronacher@active-4.com", 852 | "role": "Project Founder" 853 | } 854 | ], 855 | "description": "Twig, the flexible, fast, and secure template language for PHP", 856 | "homepage": "https://twig.symfony.com", 857 | "keywords": [ 858 | "templating" 859 | ], 860 | "support": { 861 | "issues": "https://github.com/twigphp/Twig/issues", 862 | "source": "https://github.com/twigphp/Twig/tree/v3.22.1" 863 | }, 864 | "funding": [ 865 | { 866 | "url": "https://github.com/fabpot", 867 | "type": "github" 868 | }, 869 | { 870 | "url": "https://tidelift.com/funding/github/packagist/twig/twig", 871 | "type": "tidelift" 872 | } 873 | ], 874 | "time": "2025-11-16T16:01:12+00:00" 875 | } 876 | ], 877 | "aliases": [], 878 | "minimum-stability": "stable", 879 | "stability-flags": {}, 880 | "prefer-stable": false, 881 | "prefer-lowest": false, 882 | "platform": { 883 | "php": ">=8.2" 884 | }, 885 | "platform-dev": {}, 886 | "platform-overrides": { 887 | "php": "8.2.99" 888 | }, 889 | "plugin-api-version": "2.9.0" 890 | } 891 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ### GNU GENERAL PUBLIC LICENSE 2 | 3 | Version 3, 29 June 2007 4 | 5 | Copyright (C) 2007 Free Software Foundation, Inc. 6 | 7 | 8 | Everyone is permitted to copy and distribute verbatim copies of this 9 | license document, but changing it is not allowed. 10 | 11 | ### Preamble 12 | 13 | The GNU General Public License is a free, copyleft license for 14 | software and other kinds of works. 15 | 16 | The licenses for most software and other practical works are designed 17 | to take away your freedom to share and change the works. By contrast, 18 | the GNU General Public License is intended to guarantee your freedom 19 | to share and change all versions of a program--to make sure it remains 20 | free software for all its users. We, the Free Software Foundation, use 21 | the GNU General Public License for most of our software; it applies 22 | also to any other work released this way by its authors. You can apply 23 | it to your programs, too. 24 | 25 | When we speak of free software, we are referring to freedom, not 26 | price. Our General Public Licenses are designed to make sure that you 27 | have the freedom to distribute copies of free software (and charge for 28 | them if you wish), that you receive source code or can get it if you 29 | want it, that you can change the software or use pieces of it in new 30 | free programs, and that you know you can do these things. 31 | 32 | To protect your rights, we need to prevent others from denying you 33 | these rights or asking you to surrender the rights. Therefore, you 34 | have certain responsibilities if you distribute copies of the 35 | software, or if you modify it: responsibilities to respect the freedom 36 | of others. 37 | 38 | For example, if you distribute copies of such a program, whether 39 | gratis or for a fee, you must pass on to the recipients the same 40 | freedoms that you received. You must make sure that they, too, receive 41 | or can get the source code. And you must show them these terms so they 42 | know their rights. 43 | 44 | Developers that use the GNU GPL protect your rights with two steps: 45 | (1) assert copyright on the software, and (2) offer you this License 46 | giving you legal permission to copy, distribute and/or modify it. 47 | 48 | For the developers' and authors' protection, the GPL clearly explains 49 | that there is no warranty for this free software. For both users' and 50 | authors' sake, the GPL requires that modified versions be marked as 51 | changed, so that their problems will not be attributed erroneously to 52 | authors of previous versions. 53 | 54 | Some devices are designed to deny users access to install or run 55 | modified versions of the software inside them, although the 56 | manufacturer can do so. This is fundamentally incompatible with the 57 | aim of protecting users' freedom to change the software. The 58 | systematic pattern of such abuse occurs in the area of products for 59 | individuals to use, which is precisely where it is most unacceptable. 60 | Therefore, we have designed this version of the GPL to prohibit the 61 | practice for those products. If such problems arise substantially in 62 | other domains, we stand ready to extend this provision to those 63 | domains in future versions of the GPL, as needed to protect the 64 | freedom of users. 65 | 66 | Finally, every program is threatened constantly by software patents. 67 | States should not allow patents to restrict development and use of 68 | software on general-purpose computers, but in those that do, we wish 69 | to avoid the special danger that patents applied to a free program 70 | could make it effectively proprietary. To prevent this, the GPL 71 | assures that patents cannot be used to render the program non-free. 72 | 73 | The precise terms and conditions for copying, distribution and 74 | modification follow. 75 | 76 | ### TERMS AND CONDITIONS 77 | 78 | #### 0. Definitions. 79 | 80 | "This License" refers to version 3 of the GNU General Public License. 81 | 82 | "Copyright" also means copyright-like laws that apply to other kinds 83 | of works, such as semiconductor masks. 84 | 85 | "The Program" refers to any copyrightable work licensed under this 86 | License. Each licensee is addressed as "you". "Licensees" and 87 | "recipients" may be individuals or organizations. 88 | 89 | To "modify" a work means to copy from or adapt all or part of the work 90 | in a fashion requiring copyright permission, other than the making of 91 | an exact copy. The resulting work is called a "modified version" of 92 | the earlier work or a work "based on" the earlier work. 93 | 94 | A "covered work" means either the unmodified Program or a work based 95 | on the Program. 96 | 97 | To "propagate" a work means to do anything with it that, without 98 | permission, would make you directly or secondarily liable for 99 | infringement under applicable copyright law, except executing it on a 100 | computer or modifying a private copy. Propagation includes copying, 101 | distribution (with or without modification), making available to the 102 | public, and in some countries other activities as well. 103 | 104 | To "convey" a work means any kind of propagation that enables other 105 | parties to make or receive copies. Mere interaction with a user 106 | through a computer network, with no transfer of a copy, is not 107 | conveying. 108 | 109 | An interactive user interface displays "Appropriate Legal Notices" to 110 | the extent that it includes a convenient and prominently visible 111 | feature that (1) displays an appropriate copyright notice, and (2) 112 | tells the user that there is no warranty for the work (except to the 113 | extent that warranties are provided), that licensees may convey the 114 | work under this License, and how to view a copy of this License. If 115 | the interface presents a list of user commands or options, such as a 116 | menu, a prominent item in the list meets this criterion. 117 | 118 | #### 1. Source Code. 119 | 120 | The "source code" for a work means the preferred form of the work for 121 | making modifications to it. "Object code" means any non-source form of 122 | a work. 123 | 124 | A "Standard Interface" means an interface that either is an official 125 | standard defined by a recognized standards body, or, in the case of 126 | interfaces specified for a particular programming language, one that 127 | is widely used among developers working in that language. 128 | 129 | The "System Libraries" of an executable work include anything, other 130 | than the work as a whole, that (a) is included in the normal form of 131 | packaging a Major Component, but which is not part of that Major 132 | Component, and (b) serves only to enable use of the work with that 133 | Major Component, or to implement a Standard Interface for which an 134 | implementation is available to the public in source code form. A 135 | "Major Component", in this context, means a major essential component 136 | (kernel, window system, and so on) of the specific operating system 137 | (if any) on which the executable work runs, or a compiler used to 138 | produce the work, or an object code interpreter used to run it. 139 | 140 | The "Corresponding Source" for a work in object code form means all 141 | the source code needed to generate, install, and (for an executable 142 | work) run the object code and to modify the work, including scripts to 143 | control those activities. However, it does not include the work's 144 | System Libraries, or general-purpose tools or generally available free 145 | programs which are used unmodified in performing those activities but 146 | which are not part of the work. For example, Corresponding Source 147 | includes interface definition files associated with source files for 148 | the work, and the source code for shared libraries and dynamically 149 | linked subprograms that the work is specifically designed to require, 150 | such as by intimate data communication or control flow between those 151 | subprograms and other parts of the work. 152 | 153 | The Corresponding Source need not include anything that users can 154 | regenerate automatically from other parts of the Corresponding Source. 155 | 156 | The Corresponding Source for a work in source code form is that same 157 | work. 158 | 159 | #### 2. Basic Permissions. 160 | 161 | All rights granted under this License are granted for the term of 162 | copyright on the Program, and are irrevocable provided the stated 163 | conditions are met. This License explicitly affirms your unlimited 164 | permission to run the unmodified Program. The output from running a 165 | covered work is covered by this License only if the output, given its 166 | content, constitutes a covered work. This License acknowledges your 167 | rights of fair use or other equivalent, as provided by copyright law. 168 | 169 | You may make, run and propagate covered works that you do not convey, 170 | without conditions so long as your license otherwise remains in force. 171 | You may convey covered works to others for the sole purpose of having 172 | them make modifications exclusively for you, or provide you with 173 | facilities for running those works, provided that you comply with the 174 | terms of this License in conveying all material for which you do not 175 | control copyright. Those thus making or running the covered works for 176 | you must do so exclusively on your behalf, under your direction and 177 | control, on terms that prohibit them from making any copies of your 178 | copyrighted material outside their relationship with you. 179 | 180 | Conveying under any other circumstances is permitted solely under the 181 | conditions stated below. Sublicensing is not allowed; section 10 makes 182 | it unnecessary. 183 | 184 | #### 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 185 | 186 | No covered work shall be deemed part of an effective technological 187 | measure under any applicable law fulfilling obligations under article 188 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 189 | similar laws prohibiting or restricting circumvention of such 190 | measures. 191 | 192 | When you convey a covered work, you waive any legal power to forbid 193 | circumvention of technological measures to the extent such 194 | circumvention is effected by exercising rights under this License with 195 | respect to the covered work, and you disclaim any intention to limit 196 | operation or modification of the work as a means of enforcing, against 197 | the work's users, your or third parties' legal rights to forbid 198 | circumvention of technological measures. 199 | 200 | #### 4. Conveying Verbatim Copies. 201 | 202 | You may convey verbatim copies of the Program's source code as you 203 | receive it, in any medium, provided that you conspicuously and 204 | appropriately publish on each copy an appropriate copyright notice; 205 | keep intact all notices stating that this License and any 206 | non-permissive terms added in accord with section 7 apply to the code; 207 | keep intact all notices of the absence of any warranty; and give all 208 | recipients a copy of this License along with the Program. 209 | 210 | You may charge any price or no price for each copy that you convey, 211 | and you may offer support or warranty protection for a fee. 212 | 213 | #### 5. Conveying Modified Source Versions. 214 | 215 | You may convey a work based on the Program, or the modifications to 216 | produce it from the Program, in the form of source code under the 217 | terms of section 4, provided that you also meet all of these 218 | conditions: 219 | 220 | - a) The work must carry prominent notices stating that you modified 221 | it, and giving a relevant date. 222 | - b) The work must carry prominent notices stating that it is 223 | released under this License and any conditions added under 224 | section 7. This requirement modifies the requirement in section 4 225 | to "keep intact all notices". 226 | - c) You must license the entire work, as a whole, under this 227 | License to anyone who comes into possession of a copy. This 228 | License will therefore apply, along with any applicable section 7 229 | additional terms, to the whole of the work, and all its parts, 230 | regardless of how they are packaged. This License gives no 231 | permission to license the work in any other way, but it does not 232 | invalidate such permission if you have separately received it. 233 | - d) If the work has interactive user interfaces, each must display 234 | Appropriate Legal Notices; however, if the Program has interactive 235 | interfaces that do not display Appropriate Legal Notices, your 236 | work need not make them do so. 237 | 238 | A compilation of a covered work with other separate and independent 239 | works, which are not by their nature extensions of the covered work, 240 | and which are not combined with it such as to form a larger program, 241 | in or on a volume of a storage or distribution medium, is called an 242 | "aggregate" if the compilation and its resulting copyright are not 243 | used to limit the access or legal rights of the compilation's users 244 | beyond what the individual works permit. Inclusion of a covered work 245 | in an aggregate does not cause this License to apply to the other 246 | parts of the aggregate. 247 | 248 | #### 6. Conveying Non-Source Forms. 249 | 250 | You may convey a covered work in object code form under the terms of 251 | sections 4 and 5, provided that you also convey the machine-readable 252 | Corresponding Source under the terms of this License, in one of these 253 | ways: 254 | 255 | - a) Convey the object code in, or embodied in, a physical product 256 | (including a physical distribution medium), accompanied by the 257 | Corresponding Source fixed on a durable physical medium 258 | customarily used for software interchange. 259 | - b) Convey the object code in, or embodied in, a physical product 260 | (including a physical distribution medium), accompanied by a 261 | written offer, valid for at least three years and valid for as 262 | long as you offer spare parts or customer support for that product 263 | model, to give anyone who possesses the object code either (1) a 264 | copy of the Corresponding Source for all the software in the 265 | product that is covered by this License, on a durable physical 266 | medium customarily used for software interchange, for a price no 267 | more than your reasonable cost of physically performing this 268 | conveying of source, or (2) access to copy the Corresponding 269 | Source from a network server at no charge. 270 | - c) Convey individual copies of the object code with a copy of the 271 | written offer to provide the Corresponding Source. This 272 | alternative is allowed only occasionally and noncommercially, and 273 | only if you received the object code with such an offer, in accord 274 | with subsection 6b. 275 | - d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | - e) Convey the object code using peer-to-peer transmission, 288 | provided you inform other peers where the object code and 289 | Corresponding Source of the work are being offered to the general 290 | public at no charge under subsection 6d. 291 | 292 | A separable portion of the object code, whose source code is excluded 293 | from the Corresponding Source as a System Library, need not be 294 | included in conveying the object code work. 295 | 296 | A "User Product" is either (1) a "consumer product", which means any 297 | tangible personal property which is normally used for personal, 298 | family, or household purposes, or (2) anything designed or sold for 299 | incorporation into a dwelling. In determining whether a product is a 300 | consumer product, doubtful cases shall be resolved in favor of 301 | coverage. For a particular product received by a particular user, 302 | "normally used" refers to a typical or common use of that class of 303 | product, regardless of the status of the particular user or of the way 304 | in which the particular user actually uses, or expects or is expected 305 | to use, the product. A product is a consumer product regardless of 306 | whether the product has substantial commercial, industrial or 307 | non-consumer uses, unless such uses represent the only significant 308 | mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to 312 | install and execute modified versions of a covered work in that User 313 | Product from a modified version of its Corresponding Source. The 314 | information must suffice to ensure that the continued functioning of 315 | the modified object code is in no case prevented or interfered with 316 | solely because modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or 331 | updates for a work that has been modified or installed by the 332 | recipient, or for the User Product in which it has been modified or 333 | installed. Access to a network may be denied when the modification 334 | itself materially and adversely affects the operation of the network 335 | or violates the rules and protocols for communication across the 336 | network. 337 | 338 | Corresponding Source conveyed, and Installation Information provided, 339 | in accord with this section must be in a format that is publicly 340 | documented (and with an implementation available to the public in 341 | source code form), and must require no special password or key for 342 | unpacking, reading or copying. 343 | 344 | #### 7. Additional Terms. 345 | 346 | "Additional permissions" are terms that supplement the terms of this 347 | License by making exceptions from one or more of its conditions. 348 | Additional permissions that are applicable to the entire Program shall 349 | be treated as though they were included in this License, to the extent 350 | that they are valid under applicable law. If additional permissions 351 | apply only to part of the Program, that part may be used separately 352 | under those permissions, but the entire Program remains governed by 353 | this License without regard to the additional permissions. 354 | 355 | When you convey a copy of a covered work, you may at your option 356 | remove any additional permissions from that copy, or from any part of 357 | it. (Additional permissions may be written to require their own 358 | removal in certain cases when you modify the work.) You may place 359 | additional permissions on material, added by you to a covered work, 360 | for which you have or can give appropriate copyright permission. 361 | 362 | Notwithstanding any other provision of this License, for material you 363 | add to a covered work, you may (if authorized by the copyright holders 364 | of that material) supplement the terms of this License with terms: 365 | 366 | - a) Disclaiming warranty or limiting liability differently from the 367 | terms of sections 15 and 16 of this License; or 368 | - b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | - c) Prohibiting misrepresentation of the origin of that material, 372 | or requiring that modified versions of such material be marked in 373 | reasonable ways as different from the original version; or 374 | - d) Limiting the use for publicity purposes of names of licensors 375 | or authors of the material; or 376 | - e) Declining to grant rights under trademark law for use of some 377 | trade names, trademarks, or service marks; or 378 | - f) Requiring indemnification of licensors and authors of that 379 | material by anyone who conveys the material (or modified versions 380 | of it) with contractual assumptions of liability to the recipient, 381 | for any liability that these contractual assumptions directly 382 | impose on those licensors and authors. 383 | 384 | All other non-permissive additional terms are considered "further 385 | restrictions" within the meaning of section 10. If the Program as you 386 | received it, or any part of it, contains a notice stating that it is 387 | governed by this License along with a term that is a further 388 | restriction, you may remove that term. If a license document contains 389 | a further restriction but permits relicensing or conveying under this 390 | License, you may add to a covered work material governed by the terms 391 | of that license document, provided that the further restriction does 392 | not survive such relicensing or conveying. 393 | 394 | If you add terms to a covered work in accord with this section, you 395 | must place, in the relevant source files, a statement of the 396 | additional terms that apply to those files, or a notice indicating 397 | where to find the applicable terms. 398 | 399 | Additional terms, permissive or non-permissive, may be stated in the 400 | form of a separately written license, or stated as exceptions; the 401 | above requirements apply either way. 402 | 403 | #### 8. Termination. 404 | 405 | You may not propagate or modify a covered work except as expressly 406 | provided under this License. Any attempt otherwise to propagate or 407 | modify it is void, and will automatically terminate your rights under 408 | this License (including any patent licenses granted under the third 409 | paragraph of section 11). 410 | 411 | However, if you cease all violation of this License, then your license 412 | from a particular copyright holder is reinstated (a) provisionally, 413 | unless and until the copyright holder explicitly and finally 414 | terminates your license, and (b) permanently, if the copyright holder 415 | fails to notify you of the violation by some reasonable means prior to 416 | 60 days after the cessation. 417 | 418 | Moreover, your license from a particular copyright holder is 419 | reinstated permanently if the copyright holder notifies you of the 420 | violation by some reasonable means, this is the first time you have 421 | received notice of violation of this License (for any work) from that 422 | copyright holder, and you cure the violation prior to 30 days after 423 | your receipt of the notice. 424 | 425 | Termination of your rights under this section does not terminate the 426 | licenses of parties who have received copies or rights from you under 427 | this License. If your rights have been terminated and not permanently 428 | reinstated, you do not qualify to receive new licenses for the same 429 | material under section 10. 430 | 431 | #### 9. Acceptance Not Required for Having Copies. 432 | 433 | You are not required to accept this License in order to receive or run 434 | a copy of the Program. Ancillary propagation of a covered work 435 | occurring solely as a consequence of using peer-to-peer transmission 436 | to receive a copy likewise does not require acceptance. However, 437 | nothing other than this License grants you permission to propagate or 438 | modify any covered work. These actions infringe copyright if you do 439 | not accept this License. Therefore, by modifying or propagating a 440 | covered work, you indicate your acceptance of this License to do so. 441 | 442 | #### 10. Automatic Licensing of Downstream Recipients. 443 | 444 | Each time you convey a covered work, the recipient automatically 445 | receives a license from the original licensors, to run, modify and 446 | propagate that work, subject to this License. You are not responsible 447 | for enforcing compliance by third parties with this License. 448 | 449 | An "entity transaction" is a transaction transferring control of an 450 | organization, or substantially all assets of one, or subdividing an 451 | organization, or merging organizations. If propagation of a covered 452 | work results from an entity transaction, each party to that 453 | transaction who receives a copy of the work also receives whatever 454 | licenses to the work the party's predecessor in interest had or could 455 | give under the previous paragraph, plus a right to possession of the 456 | Corresponding Source of the work from the predecessor in interest, if 457 | the predecessor has it or can get it with reasonable efforts. 458 | 459 | You may not impose any further restrictions on the exercise of the 460 | rights granted or affirmed under this License. For example, you may 461 | not impose a license fee, royalty, or other charge for exercise of 462 | rights granted under this License, and you may not initiate litigation 463 | (including a cross-claim or counterclaim in a lawsuit) alleging that 464 | any patent claim is infringed by making, using, selling, offering for 465 | sale, or importing the Program or any portion of it. 466 | 467 | #### 11. Patents. 468 | 469 | A "contributor" is a copyright holder who authorizes use under this 470 | License of the Program or a work on which the Program is based. The 471 | work thus licensed is called the contributor's "contributor version". 472 | 473 | A contributor's "essential patent claims" are all patent claims owned 474 | or controlled by the contributor, whether already acquired or 475 | hereafter acquired, that would be infringed by some manner, permitted 476 | by this License, of making, using, or selling its contributor version, 477 | but do not include claims that would be infringed only as a 478 | consequence of further modification of the contributor version. For 479 | purposes of this definition, "control" includes the right to grant 480 | patent sublicenses in a manner consistent with the requirements of 481 | this License. 482 | 483 | Each contributor grants you a non-exclusive, worldwide, royalty-free 484 | patent license under the contributor's essential patent claims, to 485 | make, use, sell, offer for sale, import and otherwise run, modify and 486 | propagate the contents of its contributor version. 487 | 488 | In the following three paragraphs, a "patent license" is any express 489 | agreement or commitment, however denominated, not to enforce a patent 490 | (such as an express permission to practice a patent or covenant not to 491 | sue for patent infringement). To "grant" such a patent license to a 492 | party means to make such an agreement or commitment not to enforce a 493 | patent against the party. 494 | 495 | If you convey a covered work, knowingly relying on a patent license, 496 | and the Corresponding Source of the work is not available for anyone 497 | to copy, free of charge and under the terms of this License, through a 498 | publicly available network server or other readily accessible means, 499 | then you must either (1) cause the Corresponding Source to be so 500 | available, or (2) arrange to deprive yourself of the benefit of the 501 | patent license for this particular work, or (3) arrange, in a manner 502 | consistent with the requirements of this License, to extend the patent 503 | license to downstream recipients. "Knowingly relying" means you have 504 | actual knowledge that, but for the patent license, your conveying the 505 | covered work in a country, or your recipient's use of the covered work 506 | in a country, would infringe one or more identifiable patents in that 507 | country that you have reason to believe are valid. 508 | 509 | If, pursuant to or in connection with a single transaction or 510 | arrangement, you convey, or propagate by procuring conveyance of, a 511 | covered work, and grant a patent license to some of the parties 512 | receiving the covered work authorizing them to use, propagate, modify 513 | or convey a specific copy of the covered work, then the patent license 514 | you grant is automatically extended to all recipients of the covered 515 | work and works based on it. 516 | 517 | A patent license is "discriminatory" if it does not include within the 518 | scope of its coverage, prohibits the exercise of, or is conditioned on 519 | the non-exercise of one or more of the rights that are specifically 520 | granted under this License. You may not convey a covered work if you 521 | are a party to an arrangement with a third party that is in the 522 | business of distributing software, under which you make payment to the 523 | third party based on the extent of your activity of conveying the 524 | work, and under which the third party grants, to any of the parties 525 | who would receive the covered work from you, a discriminatory patent 526 | license (a) in connection with copies of the covered work conveyed by 527 | you (or copies made from those copies), or (b) primarily for and in 528 | connection with specific products or compilations that contain the 529 | covered work, unless you entered into that arrangement, or that patent 530 | license was granted, prior to 28 March 2007. 531 | 532 | Nothing in this License shall be construed as excluding or limiting 533 | any implied license or other defenses to infringement that may 534 | otherwise be available to you under applicable patent law. 535 | 536 | #### 12. No Surrender of Others' Freedom. 537 | 538 | If conditions are imposed on you (whether by court order, agreement or 539 | otherwise) that contradict the conditions of this License, they do not 540 | excuse you from the conditions of this License. If you cannot convey a 541 | covered work so as to satisfy simultaneously your obligations under 542 | this License and any other pertinent obligations, then as a 543 | consequence you may not convey it at all. For example, if you agree to 544 | terms that obligate you to collect a royalty for further conveying 545 | from those to whom you convey the Program, the only way you could 546 | satisfy both those terms and this License would be to refrain entirely 547 | from conveying the Program. 548 | 549 | #### 13. Use with the GNU Affero General Public License. 550 | 551 | Notwithstanding any other provision of this License, you have 552 | permission to link or combine any covered work with a work licensed 553 | under version 3 of the GNU Affero General Public License into a single 554 | combined work, and to convey the resulting work. The terms of this 555 | License will continue to apply to the part which is the covered work, 556 | but the special requirements of the GNU Affero General Public License, 557 | section 13, concerning interaction through a network will apply to the 558 | combination as such. 559 | 560 | #### 14. Revised Versions of this License. 561 | 562 | The Free Software Foundation may publish revised and/or new versions 563 | of the GNU General Public License from time to time. Such new versions 564 | will be similar in spirit to the present version, but may differ in 565 | detail to address new problems or concerns. 566 | 567 | Each version is given a distinguishing version number. If the Program 568 | specifies that a certain numbered version of the GNU General Public 569 | License "or any later version" applies to it, you have the option of 570 | following the terms and conditions either of that numbered version or 571 | of any later version published by the Free Software Foundation. If the 572 | Program does not specify a version number of the GNU General Public 573 | License, you may choose any version ever published by the Free 574 | Software Foundation. 575 | 576 | If the Program specifies that a proxy can decide which future versions 577 | of the GNU General Public License can be used, that proxy's public 578 | statement of acceptance of a version permanently authorizes you to 579 | choose that version for the Program. 580 | 581 | Later license versions may give you additional or different 582 | permissions. However, no additional obligations are imposed on any 583 | author or copyright holder as a result of your choosing to follow a 584 | later version. 585 | 586 | #### 15. Disclaimer of Warranty. 587 | 588 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 589 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 590 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT 591 | WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT 592 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 593 | A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 594 | PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE 595 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR 596 | CORRECTION. 597 | 598 | #### 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR 602 | CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 603 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES 604 | ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT 605 | NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR 606 | LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM 607 | TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER 608 | PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 609 | 610 | #### 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | ### How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these 626 | terms. 627 | 628 | To do so, attach the following notices to the program. It is safest to 629 | attach them to the start of each source file to most effectively state 630 | the exclusion of warranty; and each file should have at least the 631 | "copyright" line and a pointer to where the full notice is found. 632 | 633 | 634 | Copyright (C) 635 | 636 | This program is free software: you can redistribute it and/or modify 637 | it under the terms of the GNU General Public License as published by 638 | the Free Software Foundation, either version 3 of the License, or 639 | (at your option) any later version. 640 | 641 | This program is distributed in the hope that it will be useful, 642 | but WITHOUT ANY WARRANTY; without even the implied warranty of 643 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 644 | GNU General Public License for more details. 645 | 646 | You should have received a copy of the GNU General Public License 647 | along with this program. If not, see . 648 | 649 | Also add information on how to contact you by electronic and paper 650 | mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands \`show w' and \`show c' should show the 661 | appropriate parts of the General Public License. Of course, your 662 | program's commands might be different; for a GUI interface, you would 663 | use an "about box". 664 | 665 | You should also get your employer (if you work as a programmer) or 666 | school, if any, to sign a "copyright disclaimer" for the program, if 667 | necessary. For more information on this, and how to apply and follow 668 | the GNU GPL, see . 669 | 670 | The GNU General Public License does not permit incorporating your 671 | program into proprietary programs. If your program is a subroutine 672 | library, you may consider it more useful to permit linking proprietary 673 | applications with the library. If this is what you want to do, use the 674 | GNU Lesser General Public License instead of this License. But first, 675 | please read . 676 | --------------------------------------------------------------------------------