diff --git a/.travis.yml b/.travis.yml index 5d7eb7a1678..44d784ea091 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ jobs: env: DB=postgresql - stage: PHP 5.6-7.4 if: type = pull_request OR type = push - php: '7.4' + php: '7.4.22' env: DB=mysql - stage: PHP Dev if: type = push AND branch = develop @@ -106,7 +106,7 @@ install: php-parallel-lint/php-console-highlighter ^0 \ squizlabs/php_codesniffer ^3 fi - if [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ]; then + if [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '7.4.22' ]; then composer -n require phpunit/phpunit ^7 \ php-parallel-lint/php-parallel-lint ^1.2 \ php-parallel-lint/php-console-highlighter ^0 \ @@ -241,7 +241,7 @@ before_script: # enable php-fpm - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf - | - if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then + if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '7.4.22' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then # Copy the included pool sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf fi @@ -276,7 +276,7 @@ script: set -e #parallel-lint --exclude htdocs/includes --blame . # Exclusions are defined in the ruleset.xml file - if [ "$TRAVIS_PHP_VERSION" = "7.4" ]; then + if [ "$TRAVIS_PHP_VERSION" = "7.4.22" ]; then parallel-lint -e php --exclude dev/tools/test/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes \ --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian \ --exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/php-parallel-lint --exclude htdocs/includes/symfony \ @@ -291,7 +291,7 @@ script: # Ensure we catch errors set -e # Exclusions are defined in the ruleset.xml file - if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4" ]; then + if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4.22" ]; then phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; fi set +e diff --git a/COPYRIGHT b/COPYRIGHT index c43d77581a7..a2101a1db0a 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -28,7 +28,7 @@ CKEditor 4.12.1 LGPL-2.1+ Yes EvalMath 1.0 BSD Yes Safe math expressions evaluation Escpos-php 2.2 MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers GeoIP2 0.2.0 Apache License 2.0 Yes Lib to make geoip convert -Mobiledetect 2.8.34 MIT License Yes Detect mobile devices browsers +Mobiledetect 2.8.39 MIT License Yes Detect mobile devices browsers NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package) PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency ParseDown 1.6 MIT License Yes Markdown parser @@ -48,10 +48,10 @@ TCPDF 6.3.2 LGPL-3+ Yes TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement JS libraries: -Ace 1.4.8 BSD Yes JS library to get code syntaxique coloration in a textarea. -ChartJS 2.9.4 MIT License Yes JS library for graph -jQuery 3.5.1 MIT License Yes JS library -jQuery UI 1.12.1 GPL and MIT License Yes JS library plugin UI +Ace 1.4.14 BSD Yes JS library to get code syntaxique coloration in a textarea. +ChartJS 3.7.1 MIT License Yes JS library for graph +jQuery 3.6.0 MIT License Yes JS library +jQuery UI 1.13.1 GPL and MIT License Yes JS library plugin UI jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect. Warning: 4.0.6+ create troubles without patching css jQuery blockUI 2.70.0 GPL and MIT License Yes JS library plugin blockUI (to use ajax popups) jQuery Colorpicker 1.1 MIT License Yes JS library for color picker for a defined list of colors diff --git a/ChangeLog b/ChangeLog index a9a42c8d878..31bfa1c1cff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,67 @@ English Dolibarr ChangeLog -------------------------------------------------------------- + +***** ChangeLog for 16.0.0 compared to 15.0.0 ***** + +For users: +--------------- + +NEW: PHP 8.0 compatibility + + + + Modules +NEW: Experimental module Event Organization Management +NEW: Experimental module Workstations Management +NEW: Experimental module Partnership Management + + +For developers: +--------------- + +NEW: A lot of addition of hooks. + + + +Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: +* The default value for MAIN_SECURITY_CSRF_WITH_TOKEN has been set to 2. It means any POST and any GET request that contains the "action" or "massaction" + with a value of a sensitive action must also a valid token parameter (With previous value 1, only POST was concerned). Note: With value 3, any URL + with parameter "action" or "massaction" need the token, whatever is the value of the action. +* verifCond('stringtoevaluate') now return false when string contains a bad syntax content instead of true. +* The deprecated method thirdparty_doc_create() has been removed. You can use the generateDocument() instead. +* All triggers with a name XXX_UPDATE have been rename with name XXX_MODIFY for code consistency purpose. +* Rename build_path_from_id_categ() into buildPathFromId() and set method to private + + +***** ChangeLog for 15.0.1 compared to 15.0.0 ***** +FIX: #19777 #20281 +FIX: bad position of extrafields for interventions +FIX: Blocking situation when a payment was deleted in bank. +FIX: creation of the shipment if order contains services +FIX: Drag and drop line of files on join files tab +FIX: Error management on mass action "Approve holiday" +FIX: error with php8 +FIX: in case of VAT refund, negative amount must be allowed +FIX: invoice pdf: lines originating from deposits were not detailed anymore +FIX: Invoice - When you create an invoice for a given thirdparty, fk_account is not retrieved from company card +FIX: list of visible type of event was not correctly filtered +FIX: Missing or bad permissions +FIX: Missing the field date start/end in export supplier invoice/order +FIX: On large proposal or invoice, fix n(n+1) sql into a n sql. +FIX: options should not exists on invoices +FIX: payment not completed when using Paypal. +FIX: permission to download files of expense report with readall. +FIX- Preview icon in documents list PDF in the admin page third-party +FIX: shipping list, e.shipping_method_id should be e.fk_shipping_method. +FIX: Show product photo on Supplier order Cornas model. +FIX: User name in ManufacturingOrder +FIX: viewimage.php blocks requests with multicompany from other enties +FIX: #yogosha9048 +FIX: #yogosha9054 +FIX: #yogosha9095 + + ***** ChangeLog for 15.0.0 compared to 14.0.0 ***** For users: @@ -10,6 +71,7 @@ For users: NEW: Online proposal signature NEW: Can define some max limit on expense report (per period, per type or expense, ...) +NEW: Provide a special pages for bookmarks and multicompany for a better use of some mobile applications (like DoliDroid) NEW: Allow the use of __NEWREF__ to get for example the new reference a draft order will get after validation. NEW: Add option to disable globaly some notifications emails. NEW: #18401 Add __NEWREF__ subtitute to get new object reference. diff --git a/SECURITY.md b/SECURITY.md index cadd4a23791..c55d6d26ab0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -17,7 +17,7 @@ Alternatively send an email to security@dolibarr.org (for everybody) ## Hunting vulnerabilities on Dolibarr -We believe that future of software is online SaaS. This means software are more and more critical and no technology is perfect. Working with skilled security researchers is crucial in identifying weaknesses in our technology. +We believe that the future of software is online SaaS. This means software are more and more critical and no technology is perfect. Working with skilled security researchers is crucial in identifying weaknesses in our technology. If you believe you've found a security bug in our service, we are happy to work with you to resolve the issue promptly and ensure you are fairly rewarded for your discovery. @@ -35,13 +35,13 @@ You can install the web application yourself on your own platform/server so you ## Eligibility and Responsible Disclosure -We are happy to thank everyone who submits valid reports which help us improve the security of Dolibarr however, only those that meet the following eligibility requirements will be "validated reports" (if not, we may close the report without any answer): +We are happy to thank everyone who submits valid reports which help us improve the security of Dolibarr, however only those that meet the following eligibility requirements will be "validated reports" (if not, we may close the report without any answer): You must be the first reporter of the vulnerability (duplicate reports are closed). You must send a clear textual description of the report along with steps to reproduce the issue, include attachments such as screenshots or proof of concept code as necessary. -You must avoid tests that could cause degradation or interruption of our service (refrain from using automated tools, and limit yourself about requests per second), that's why we recommand to install softwate on your own platform. +You must avoid tests that could cause degradation or interruption of our service (refrain from using automated tools, and limit yourself about requests per second), that's why we recommand to install software on your own platform. You must not leak, manipulate, or destroy any user data of third parties to find your vulnerability. @@ -56,7 +56,7 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us * The module DebugBar and ModuleBuilder must NOT be enabled (by default, these modules are not enabled. They are developer tools) * ONLY security reports on modules provided by default and with the "stable" status are valid (troubles into "experimental", "developement" or external modules are not valid vulnerabilities). * The root of web server must link to htdocs and the documents directory must be outside of the web server root (this is the default when using the default installer but may differs with external installer). -* The web server setup must be done so only the documents directory is in write mode. The root directory called htdocs must be readonly. +* The web server setup must be done so that only the documents directory is in write mode. The root directory called htdocs must be read-only. * CSRF attacks are accepted but double check that you have set MAIN_SECURITY_CSRF_WITH_TOKEN to value 3. * Ability for a high level user to edit web site pages into the CMS by including HTML or Javascript is an expected feature. Vulnerabilities into the website module are validated only if HTML or Javascript injection can be done by a non allowed user. diff --git a/composer.json b/composer.json.disabled similarity index 97% rename from composer.json rename to composer.json.disabled index 8d82f530df8..adeaffd2334 100644 --- a/composer.json +++ b/composer.json.disabled @@ -28,7 +28,7 @@ "ext-curl" : "*", "ckeditor/ckeditor" : "4.12.1", "mike42/escpos-php" : "2.2", - "mobiledetect/mobiledetectlib" : "2.8.34", + "mobiledetect/mobiledetectlib" : "2.8.39", "phpoffice/phpexcel" : "1.8.2", "restler/framework" : "3.0.0-RC6", "tecnickcom/tcpdf" : "6.3.2", @@ -59,4 +59,4 @@ "ext-zip" : "ODT, Excel and file compression support", "ext-xml" : "Excel support" } -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 5f761cb63fe..00000000000 --- a/composer.lock +++ /dev/null @@ -1,2349 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "1dbd2d05cc0836acfca5988f29005cf2", - "packages": [ - { - "name": "ckeditor/ckeditor", - "version": "4.12.1", - "source": { - "type": "git", - "url": "https://github.com/ckeditor/ckeditor-releases.git", - "reference": "b1a25e93ae0b038f45dcba458f4c2c18bd7318e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ckeditor/ckeditor-releases/zipball/b1a25e93ae0b038f45dcba458f4c2c18bd7318e5", - "reference": "b1a25e93ae0b038f45dcba458f4c2c18bd7318e5", - "shasum": "" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0+", - "LGPL-2.1+", - "MPL-1.1+" - ], - "authors": [ - { - "name": "CKSource", - "homepage": "http://cksource.com" - } - ], - "description": "JavaScript WYSIWYG web text editor.", - "homepage": "http://ckeditor.com", - "keywords": [ - "CKEditor", - "editor", - "fckeditor", - "html", - "javascript", - "richtext", - "text", - "wysiwyg" - ], - "support": { - "forum": "http://ckeditor.com/forums", - "issues": "http://dev.ckeditor.com", - "source": "http://github.com/ckeditor/ckeditor-dev", - "wiki": "http://docs.ckeditor.com" - }, - "time": "2019-06-28T10:41:23+00:00" - }, - { - "name": "maximebf/debugbar", - "version": "v1.15.1", - "source": { - "type": "git", - "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "6c4277f6117e4864966c9cb58fb835cee8c74a1e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/6c4277f6117e4864966c9cb58fb835cee8c74a1e", - "reference": "6c4277f6117e4864966c9cb58fb835cee8c74a1e", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "psr/log": "^1.0", - "symfony/var-dumper": "^2.6|^3|^4" - }, - "require-dev": { - "phpunit/phpunit": "^5" - }, - "suggest": { - "kriswallsmith/assetic": "The best way to manage assets", - "monolog/monolog": "Log using Monolog", - "predis/predis": "Redis storage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15-dev" - } - }, - "autoload": { - "psr-4": { - "DebugBar\\": "src/DebugBar/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Maxime Bouroumeau-Fuseau", - "email": "maxime.bouroumeau@gmail.com", - "homepage": "http://maximebf.com" - }, - { - "name": "Barry vd. Heuvel", - "email": "barryvdh@gmail.com" - } - ], - "description": "Debug bar in the browser for php application", - "homepage": "https://github.com/maximebf/php-debugbar", - "keywords": [ - "debug", - "debugbar" - ], - "support": { - "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.15.1" - }, - "time": "2019-09-24T14:55:42+00:00" - }, - { - "name": "mike42/escpos-php", - "version": "v2.2", - "source": { - "type": "git", - "url": "https://github.com/mike42/escpos-php.git", - "reference": "e5496cf819b048b11877117bd14a9cea4fb17c03" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mike42/escpos-php/zipball/e5496cf819b048b11877117bd14a9cea4fb17c03", - "reference": "e5496cf819b048b11877117bd14a9cea4fb17c03", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "guzzlehttp/guzzle": "^5.3", - "phpunit/phpunit": "^4.8", - "squizlabs/php_codesniffer": "^3.2" - }, - "suggest": { - "ext-gd": "Used for image printing if present.", - "ext-imagick": "Will be used for image printing if present. Required for PDF printing or use of custom fonts.", - "guzzlehttp/guzzle": "Allows the use of the ApiConnector to send print jobs over HTTP." - }, - "type": "library", - "autoload": { - "psr-4": { - "Mike42\\": "src/Mike42" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Billington", - "email": "michael.billington@gmail.com" - } - ], - "description": "PHP receipt printer library for use with ESC/POS-compatible thermal and impact printers", - "homepage": "https://github.com/mike42/escpos-php", - "keywords": [ - "ESC-POS", - "driver", - "escpos", - "print", - "receipt" - ], - "support": { - "issues": "https://github.com/mike42/escpos-php/issues", - "source": "https://github.com/mike42/escpos-php/tree/v2.2" - }, - "time": "2019-10-05T05:59:00+00:00" - }, - { - "name": "mobiledetect/mobiledetectlib", - "version": "2.8.34", - "source": { - "type": "git", - "url": "https://github.com/serbanghita/Mobile-Detect.git", - "reference": "6f8113f57a508494ca36acbcfa2dc2d923c7ed5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/6f8113f57a508494ca36acbcfa2dc2d923c7ed5b", - "reference": "6f8113f57a508494ca36acbcfa2dc2d923c7ed5b", - "shasum": "" - }, - "require": { - "php": ">=5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.35||~5.7" - }, - "type": "library", - "autoload": { - "classmap": [ - "Mobile_Detect.php" - ], - "psr-0": { - "Detection": "namespaced/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Serban Ghita", - "email": "serbanghita@gmail.com", - "homepage": "http://mobiledetect.net", - "role": "Developer" - } - ], - "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", - "homepage": "https://github.com/serbanghita/Mobile-Detect", - "keywords": [ - "detect mobile devices", - "mobile", - "mobile detect", - "mobile detector", - "php mobile detect" - ], - "support": { - "issues": "https://github.com/serbanghita/Mobile-Detect/issues", - "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.34" - }, - "time": "2019-09-18T18:44:20+00:00" - }, - { - "name": "nnnick/chartjs", - "version": "v2.9.4", - "source": { - "type": "git", - "url": "https://github.com/chartjs/Chart.js.git", - "reference": "9bd4cf82fda9f50a5fb50b72843e06ab88124278" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chartjs/Chart.js/zipball/9bd4cf82fda9f50a5fb50b72843e06ab88124278", - "reference": "9bd4cf82fda9f50a5fb50b72843e06ab88124278", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "release/2.0": "v2.0-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "NICK DOWNIE", - "email": "hello@nickdownie.com" - } - ], - "description": "Simple HTML5 charts using the canvas element.", - "homepage": "https://www.chartjs.org/", - "keywords": [ - "JS", - "chart" - ], - "support": { - "issues": "https://github.com/chartjs/Chart.js/issues", - "source": "https://github.com/chartjs/Chart.js/tree/v2.9.4" - }, - "time": "2020-10-19T12:22:11+00:00" - }, - { - "name": "psr/log", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/1.1.3" - }, - "time": "2020-03-23T09:12:05+00:00" - }, - { - "name": "phpoffice/phpexcel", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/PHPOffice/PHPExcel.git", - "reference": "1441011fb7ecdd8cc689878f54f8b58a6805f870" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/1441011fb7ecdd8cc689878f54f8b58a6805f870", - "reference": "1441011fb7ecdd8cc689878f54f8b58a6805f870", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "php": "^5.2|^7.0" - }, - "require-dev": { - "squizlabs/php_codesniffer": "2.*" - }, - "type": "library", - "autoload": { - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1" - ], - "authors": [ - { - "name": "Maarten Balliauw", - "homepage": "http://blog.maartenballiauw.be" - }, - { - "name": "Erik Tilt" - }, - { - "name": "Franck Lefevre", - "homepage": "http://rootslabs.net" - }, - { - "name": "Mark Baker", - "homepage": "http://markbakeruk.net" - } - ], - "description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", - "homepage": "https://github.com/PHPOffice/PHPExcel", - "keywords": [ - "OpenXML", - "excel", - "xlsx" - ], - "abandoned": "phpoffice/phpspreadsheet", - "time": "2018-11-22T23:07:24+00:00" - }, - { - "name": "restler/framework", - "version": "3.0.0-RC6", - "target-dir": "Luracast/Restler", - "source": { - "type": "git", - "url": "https://github.com/Luracast/Restler-Framework.git", - "reference": "d52e61600d153bca60a287c35141c5c01863127b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Luracast/Restler-Framework/zipball/d52e61600d153bca60a287c35141c5c01863127b", - "reference": "d52e61600d153bca60a287c35141c5c01863127b", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "replace": { - "luracast/restler": "3.*" - }, - "suggest": { - "bshaffer/oauth2-server-php": "If you want to use OAuth2 for authentication", - "illuminate/view": "If you want to use laravel blade templates with Html format", - "mustache/mustache": "If you want to use mustache/handlebar templates with Html format", - "rodneyrehm/plist": "If you need Apple plist binary/xml format", - "symfony/yaml": "If you need YAML format", - "twig/twig": "If you want to use twig templates with Html format", - "zendframework/zendamf": "If you need AMF format" - }, - "type": "library", - "extra": { - "branch-alias": { - "master": "v3.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Luracast\\Restler": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1" - ], - "authors": [ - { - "name": "Luracast", - "email": "arul@luracast.com" - } - ], - "description": "Just the Restler Framework without the tests and examples", - "homepage": "http://luracast.com/products/restler/", - "keywords": [ - "api", - "framework", - "rest", - "server" - ], - "support": { - "source": "https://github.com/Luracast/Restler-Framework/tree/3.0.0-RC6" - }, - "time": "2020-02-13T16:05:12+00:00" - }, - { - "name": "stripe/stripe-php", - "version": "v6.43.1", - "source": { - "type": "git", - "url": "https://github.com/stripe/stripe-php.git", - "reference": "42fcdaf99c44bb26937223f8eae1f263491d5ab8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/stripe/stripe-php/zipball/42fcdaf99c44bb26937223f8eae1f263491d5ab8", - "reference": "42fcdaf99c44bb26937223f8eae1f263491d5ab8", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "1.*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0", - "symfony/process": "~2.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Stripe\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Stripe and contributors", - "homepage": "https://github.com/stripe/stripe-php/contributors" - } - ], - "description": "Stripe PHP Library", - "homepage": "https://stripe.com/", - "keywords": [ - "api", - "payment processing", - "stripe" - ], - "support": { - "issues": "https://github.com/stripe/stripe-php/issues", - "source": "https://github.com/stripe/stripe-php/tree/master" - }, - "time": "2019-08-29T16:56:12+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/var-dumper", - "version": "v3.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "737e07704cca83f9dd0af926d45ce27eedc25657" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/737e07704cca83f9dd0af926d45ce27eedc25657", - "reference": "737e07704cca83f9dd0af926d45ce27eedc25657", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "twig/twig": "~1.20|~2.0" - }, - "suggest": { - "ext-symfony_debug": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony mechanism for exploring and dumping PHP variables", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/master" - }, - "time": "2015-11-18T13:48:51+00:00" - }, - { - "name": "tecnickcom/tcpdf", - "version": "6.3.2", - "source": { - "type": "git", - "url": "https://github.com/tecnickcom/TCPDF.git", - "reference": "9fde7bb9b404b945e7ea88fb7eccd23d9a4e324b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/9fde7bb9b404b945e7ea88fb7eccd23d9a4e324b", - "reference": "9fde7bb9b404b945e7ea88fb7eccd23d9a4e324b", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "config", - "include", - "tcpdf.php", - "tcpdf_parser.php", - "tcpdf_import.php", - "tcpdf_barcodes_1d.php", - "tcpdf_barcodes_2d.php", - "include/tcpdf_colors.php", - "include/tcpdf_filters.php", - "include/tcpdf_font_data.php", - "include/tcpdf_fonts.php", - "include/tcpdf_images.php", - "include/tcpdf_static.php", - "include/barcodes/datamatrix.php", - "include/barcodes/pdf417.php", - "include/barcodes/qrcode.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0" - ], - "authors": [ - { - "name": "Nicola Asuni", - "email": "info@tecnick.com", - "role": "lead" - } - ], - "description": "TCPDF is a PHP class for generating PDF documents and barcodes.", - "homepage": "http://www.tcpdf.org/", - "keywords": [ - "PDFD32000-2008", - "TCPDF", - "barcodes", - "datamatrix", - "pdf", - "pdf417", - "qrcode" - ], - "support": { - "source": "https://github.com/tecnickcom/TCPDF/tree/6.3.2" - }, - "time": "2019-09-20T09:35:01+00:00" - } - ], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^8.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2020-11-10T18:47:58+00:00" - }, - { - "name": "php-parallel-lint/php-console-color", - "version": "v0.3", - "source": { - "type": "git", - "url": "https://github.com/php-parallel-lint/PHP-Console-Color.git", - "reference": "b6af326b2088f1ad3b264696c9fd590ec395b49e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-parallel-lint/PHP-Console-Color/zipball/b6af326b2088f1ad3b264696c9fd590ec395b49e", - "reference": "b6af326b2088f1ad3b264696c9fd590ec395b49e", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "replace": { - "jakub-onderka/php-console-color": "*" - }, - "require-dev": { - "php-parallel-lint/php-code-style": "1.0", - "php-parallel-lint/php-parallel-lint": "1.0", - "php-parallel-lint/php-var-dump-check": "0.*", - "phpunit/phpunit": "~4.3", - "squizlabs/php_codesniffer": "1.*" - }, - "type": "library", - "autoload": { - "psr-4": { - "JakubOnderka\\PhpConsoleColor\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "jakub.onderka@gmail.com" - } - ], - "support": { - "issues": "https://github.com/php-parallel-lint/PHP-Console-Color/issues", - "source": "https://github.com/php-parallel-lint/PHP-Console-Color/tree/master" - }, - "time": "2020-05-14T05:47:14+00:00" - }, - { - "name": "php-parallel-lint/php-console-highlighter", - "version": "v0.5", - "source": { - "type": "git", - "url": "https://github.com/php-parallel-lint/PHP-Console-Highlighter.git", - "reference": "21bf002f077b177f056d8cb455c5ed573adfdbb8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-parallel-lint/PHP-Console-Highlighter/zipball/21bf002f077b177f056d8cb455c5ed573adfdbb8", - "reference": "21bf002f077b177f056d8cb455c5ed573adfdbb8", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.4.0", - "php-parallel-lint/php-console-color": "~0.2" - }, - "replace": { - "jakub-onderka/php-console-highlighter": "*" - }, - "require-dev": { - "php-parallel-lint/php-code-style": "~1.0", - "php-parallel-lint/php-parallel-lint": "~1.0", - "php-parallel-lint/php-var-dump-check": "~0.1", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "JakubOnderka\\PhpConsoleHighlighter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "acci@acci.cz", - "homepage": "http://www.acci.cz/" - } - ], - "description": "Highlight PHP code in terminal", - "support": { - "issues": "https://github.com/php-parallel-lint/PHP-Console-Highlighter/issues", - "source": "https://github.com/php-parallel-lint/PHP-Console-Highlighter/tree/master" - }, - "time": "2020-05-13T07:37:49+00:00" - }, - { - "name": "php-parallel-lint/php-parallel-lint", - "version": "v0.9.2", - "source": { - "type": "git", - "url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git", - "reference": "2ead2e4043ab125bee9554f356e0a86742c2d4fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/2ead2e4043ab125bee9554f356e0a86742c2d4fa", - "reference": "2ead2e4043ab125bee9554f356e0a86742c2d4fa", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "jakub-onderka/php-console-highlighter": "~0.3", - "nette/tester": "~1.3" - }, - "suggest": { - "jakub-onderka/php-console-highlighter": "Highlight syntax in code snippet" - }, - "bin": [ - "parallel-lint" - ], - "type": "library", - "autoload": { - "classmap": [ - "./" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "jakub.onderka@gmail.com" - } - ], - "description": "This tool check syntax of PHP files about 20x faster than serial check.", - "homepage": "https://github.com/JakubOnderka/PHP-Parallel-Lint", - "support": { - "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v0.9.2" - }, - "time": "2015-12-15T10:42:16+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" - }, - "time": "2020-09-03T19:13:55+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" - }, - "time": "2020-09-17T18:55:26+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.10.3", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" - }, - "time": "2020-03-05T15:02:03+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/2.2" - }, - "time": "2015-10-06T15:47:00+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" - }, - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" - }, - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/master" - }, - "time": "2017-02-26T11:10:40+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.4.12", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/1.4" - }, - "abandoned": true, - "time": "2017-12-04T08:55:13+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "4.8.36", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.2.2", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.8.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/4.8.36" - }, - "time": "2017-06-21T08:07:12+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", - "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/2.3" - }, - "abandoned": true, - "time": "2015-10-02T06:51:40+00:00" - }, - { - "name": "phpunit/phpunit-selenium", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/giorgiosironi/phpunit-selenium.git", - "reference": "013037eeea481657d236431634042648797e1da8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/giorgiosironi/phpunit-selenium/zipball/013037eeea481657d236431634042648797e1da8", - "reference": "013037eeea481657d236431634042648797e1da8", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-dom": "*", - "php": ">=5.3.3", - "phpunit/phpunit": "~4.8", - "sebastian/comparator": "~1.0" - }, - "require-dev": { - "phing/phing": "2.*" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Giorgio Sironi", - "email": "info@giorgiosironi.com", - "role": "developer" - }, - { - "name": "Ivan Kurnosov", - "email": "zerkms@zerkms.com", - "role": "developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "original developer" - } - ], - "description": "Selenium Server integration for PHPUnit", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "selenium", - "testing", - "xunit" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/phpunit-selenium/issues", - "source": "https://github.com/giorgiosironi/phpunit-selenium/tree/2.x" - }, - "time": "2017-01-23T22:15:32+00:00" - }, - { - "name": "sebastian/comparator", - "version": "1.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" - }, - "time": "2017-01-29T09:50:25+00:00" - }, - { - "name": "sebastian/diff", - "version": "1.4.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/1.4" - }, - "time": "2017-05-22T07:24:03+00:00" - }, - { - "name": "sebastian/environment", - "version": "1.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/1.3" - }, - "time": "2016-08-18T05:49:44+00:00" - }, - { - "name": "sebastian/exporter", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/master" - }, - "time": "2016-06-17T09:04:28+00:00" - }, - { - "name": "sebastian/global-state", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" - }, - "time": "2015-10-12T03:26:01+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" - }, - "time": "2016-10-03T07:41:43+00:00" - }, - { - "name": "sebastian/version", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/1.0.6" - }, - "time": "2015-06-21T13:59:46+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "2.9.2", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "2acf168de78487db620ab4bc524135a13cfe6745" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745", - "reference": "2acf168de78487db620ab4bc524135a13cfe6745", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "bin": [ - "scripts/phpcs", - "scripts/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "classmap": [ - "CodeSniffer.php", - "CodeSniffer/CLI.php", - "CodeSniffer/Exception.php", - "CodeSniffer/File.php", - "CodeSniffer/Fixer.php", - "CodeSniffer/Report.php", - "CodeSniffer/Reporting.php", - "CodeSniffer/Sniff.php", - "CodeSniffer/Tokens.php", - "CodeSniffer/Reports/", - "CodeSniffer/Tokenizers/", - "CodeSniffer/DocGenerators/", - "CodeSniffer/Standards/AbstractPatternSniff.php", - "CodeSniffer/Standards/AbstractScopeSniff.php", - "CodeSniffer/Standards/AbstractVariableSniff.php", - "CodeSniffer/Standards/IncorrectPatternException.php", - "CodeSniffer/Standards/Generic/Sniffs/", - "CodeSniffer/Standards/MySource/Sniffs/", - "CodeSniffer/Standards/PEAR/Sniffs/", - "CodeSniffer/Standards/PSR1/Sniffs/", - "CodeSniffer/Standards/PSR2/Sniffs/", - "CodeSniffer/Standards/Squiz/Sniffs/", - "CodeSniffer/Standards/Zend/Sniffs/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2018-11-07T22:31:41+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/yaml", - "version": "v3.4.47", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "88289caa3c166321883f67fe5130188ebbb47094" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", - "reference": "88289caa3c166321883f67fe5130188ebbb47094", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/console": "<3.4" - }, - "require-dev": { - "symfony/console": "~3.4|~4.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v3.4.47" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-24T10:57:07+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.9.1", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozart/assert/issues", - "source": "https://github.com/webmozart/assert/tree/master" - }, - "time": "2020-07-08T17:02:28+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "restler/framework": 5 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.6.0", - "ext-curl": "*" - }, - "platform-dev": [], - "plugin-api-version": "2.0.0" -} diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index d4a9b725524..204988c5442 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -111,6 +111,10 @@ with // DOL CHANGE If we keep this, the image is not visible on pages after the first one. //var_dump($file.' '.(!@TCPDF_STATIC::file_exists($file))); //return false; + $tfile = str_replace(' ', '%20', $file); + if (@TCPDF_STATIC::file_exists($tfile)) { + $file = $tfile; + } } * Replace in tcpdf.php diff --git a/dev/examples/zapier/package.json b/dev/examples/zapier/package.json index a9d519dec69..8852928771f 100644 --- a/dev/examples/zapier/package.json +++ b/dev/examples/zapier/package.json @@ -15,7 +15,7 @@ "npm": ">=5.6.0" }, "dependencies": { - "zapier-platform-core": "11.0.1" + "zapier-platform-core": "11.3.1" }, "devDependencies": { "mocha": "^5.2.0", diff --git a/dev/resources/iso-normes/QR code for invoices.txt b/dev/resources/iso-normes/QR code for invoices.txt index a55c9569297..f03351f453f 100644 --- a/dev/resources/iso-normes/QR code for invoices.txt +++ b/dev/resources/iso-normes/QR code for invoices.txt @@ -8,6 +8,10 @@ https://en.wikipedia.org/wiki/EPC_QR_code#Generators -* For ZATCA QR Code format (Saudi Arabia) ------------------------------------------ +* For ZATCA QR Code format (Saudi Arabia). Used when INVOICE_ADD_ZATCA_QR_CODE is set +------------------------------------------------------------------------------------- https://www.pwc.com/m1/en/services/tax/me-tax-legal-news/2021/saudi-arabia-guide-to-develop-compliant-qr-code-for-simplified-einvoices.html + +https://www.tecklenborgh.com/post/ksa-zatca-publishes-guide-on-how-to-develop-a-fatoora-compliant-qr-code + +Method to encode/decode ZATCA string is available in test/phpunit/BarcodeTest.php diff --git a/dev/resources/iso-normes/currencies_iso-4217.txt b/dev/resources/iso-normes/currencies_iso-4217.txt index bc392b72e9c..e24faa4283e 100644 --- a/dev/resources/iso-normes/currencies_iso-4217.txt +++ b/dev/resources/iso-normes/currencies_iso-4217.txt @@ -1,8 +1,12 @@ # File of all ISO-4217 currencies codes -# http://en.wikipedia.org/wiki/ISO_4217 -# http://fx.sauder.ubc.ca/currency_table.html for symbols for 2 letter code # -# Code,Name,Nb decimals +# https://en.wikipedia.org/wiki/ISO_4217 +# https://en.wikipedia.org/wiki/Currency_symbol for symbols for 2 letter code +# + + +# Code, Currency Name, Nb decimals + AED,UAE Dirham,2 AFN,Afghanistan Afghani,2 ALL,Albanian Lek,2 diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index 8cef3a05cf4..03cd41a43a9 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -24,7 +24,7 @@ /** * \file htdocs/accountancy/admin/export.php * \ingroup Accountancy (Double entries) - * \brief Setup page to configure accounting expert module + * \brief Setup page to configure accounting export module */ require '../../main.inc.php'; diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 8a66acee0d9..5b645796a32 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -663,7 +663,7 @@ if ($action == 'create') { // Also, it is not possible to use a value that is not in the list. // Also, the label is not automatically filled when a value is selected. if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { - print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1); + print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1, 'maxwidth250', '', 'subledger_label'); } else { print 'subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'">'; } @@ -746,7 +746,7 @@ if ($action == 'create') { // Also, it is not possible to use a value that is not in the list. // Also, the label is not automatically filled when a value is selected. if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { - print $formaccounting->select_auxaccount('', 'subledger_account', 1); + print $formaccounting->select_auxaccount('', 'subledger_account', 1, 'maxwidth250', '', 'subledger_label'); } else { print ''; } diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 67f521806cb..a760a550bef 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -190,7 +190,7 @@ $arrayfields = array( 't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0), 't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), - 't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), + 't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1), ); if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { @@ -678,19 +678,28 @@ $formconfirm = ''; if ($action == 'export_file') { $form_question = array(); + // If 1 or not set, we check by default. + $checked = (!isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE)); $form_question['notifiedexportdate'] = array( 'name' => 'notifiedexportdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedExportDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'), + 'value' => $checked, ); + + $form_question['separator'] = array('name'=>'separator', 'type'=>'separator'); + + // If 0 or not set, we NOT check by default. + $checked = (isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE)); $form_question['notifiedvalidationdate'] = array( 'name' => 'notifiedvalidationdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedValidationDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) ? 'false' : 'true'), + 'value' => $checked, ); + $form_question['separator2'] = array('name'=>'separator2', 'type'=>'separator'); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600); } @@ -823,7 +832,7 @@ if (!empty($arrayfields['t.piece_num']['checked'])) { // Code journal if (!empty($arrayfields['t.code_journal']['checked'])) { print ''; - print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'maxwidth150'); + print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'small maxwidth150'); print ''; } // Date document @@ -845,10 +854,10 @@ if (!empty($arrayfields['t.doc_ref']['checked'])) { if (!empty($arrayfields['t.numero_compte']['checked'])) { print ''; print '
'; - print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200', 'account'); + print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth150', 'account'); print '
'; print '
'; - print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200', 'account'); + print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth150', 'account'); print '
'; print ''; } @@ -1125,24 +1134,25 @@ while ($i < min($num, $limit)) { // Other type } - print ''; - - print ''; - // Picto + Ref - print '
'; - + $labeltoshow = ''; + $labeltoshowalt = ''; if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') { - print $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); - print $documentlink; + $labeltoshow .= $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); + $labeltoshow .= $documentlink; + $labeltoshowalt .= $objectstatic->ref; } elseif ($line->doc_type == 'bank') { - print $objectstatic->getNomUrl(1); + $labeltoshow .= $objectstatic->getNomUrl(1); + $labeltoshowalt .= $objectstatic->ref; $bank_ref = strstr($line->doc_ref, '-'); - print " " . $bank_ref; + $labeltoshow .= " " . $bank_ref; + $labeltoshowalt .= " " . $bank_ref; } else { - print $line->doc_ref; + $labeltoshow .= $line->doc_ref; + $labeltoshowalt .= $line->doc_ref; } - print '
'; + print ''; + print $labeltoshow; print "\n"; if (!$i) { $totalarray['nbfield']++; @@ -1167,7 +1177,7 @@ while ($i < min($num, $limit)) { // Label operation if (!empty($arrayfields['t.label_operation']['checked'])) { - print ''.$line->label_operation.''; + print ''.dol_escape_htmltag($line->label_operation).''; if (!$i) { $totalarray['nbfield']++; } @@ -1228,7 +1238,7 @@ while ($i < min($num, $limit)) { // Exported operation date if (!empty($arrayfields['t.date_export']['checked'])) { - print ''.dol_print_date($line->date_export, 'dayhour').''; + print ''.dol_print_date($line->date_export, 'dayhour').''; if (!$i) { $totalarray['nbfield']++; } @@ -1236,7 +1246,7 @@ while ($i < min($num, $limit)) { // Validated operation date if (!empty($arrayfields['t.date_validated']['checked'])) { - print ''.dol_print_date($line->date_validation, 'dayhour').''; + print ''.dol_print_date($line->date_validation, 'dayhour').''; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php deleted file mode 100644 index a563b653ac1..00000000000 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php +++ /dev/null @@ -1,325 +0,0 @@ - - * Copyright (C) 2005 Laurent Destailleur - * Copyright (C) 2013 Olivier Geffroy - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2019 Alexandre Spangaro - * Copyright (C) 2018-2020 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * \file htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php - * \ingroup accountancy - * \brief Tab to manage customer lettering - */ -require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; -require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - -// Load translation files required by the page -$langs->loadLangs(array("compta", "accountancy")); - -$action = GETPOST('action', 'aZ09'); -$massaction = GETPOST('massaction', 'alpha'); -$show_files = GETPOST('show_files', 'int'); -$confirm = GETPOST('confirm', 'alpha'); -$toselect = GETPOST('toselect', 'array'); -// $socid = GETPOST('socid', 'int') ?GETPOST('socid', 'int') : GETPOST('id', 'int'); -// Security check -$socid = GETPOSTINT("socid"); -// if ($user->socid) $socid=$user->socid; - -$limit = GETPOSTISSET('limit') ? GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST('sortfield', 'aZ09comma'); -$sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page == - 1) { - $page = 0; -} // If $page is not defined, or '' or -1 -$offset = $limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; -if ($sortorder == "") { - $sortorder = "ASC"; -} -if ($sortfield == "") { - $sortfield = "bk.doc_date"; -} - -/* -$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); -$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); -//$search_doc_type = GETPOST("search_doc_type", 'alpha'); -$search_doc_ref = GETPOST("search_doc_ref", 'alpha'); -*/ - -$lettering = GETPOST('lettering', 'alpha'); -if (!empty($lettering)) { - $action = $lettering; -} - -/* -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers -{ - $search_date_start = ''; - $search_date_end = ''; - //$search_doc_type = ''; - $search_doc_ref = ''; -} -*/ - -$lettering = new Lettering($db); -$object = new Societe($db); -$object->id = $socid; -$result = $object->fetch($socid); -if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); -} - -if (empty($conf->accounting->enabled)) { - accessforbidden(); -} -if ($user->socid > 0) { - accessforbidden(); -} -if (empty($user->rights->accounting->mouvements->lire)) { - accessforbidden(); -} - - -/* - * Action - */ - -if ($action == 'lettering') { - $result = $lettering->updateLettering($toselect); - - if ($result < 0) { - setEventMessages('', $lettering->errors, 'errors'); - $error++; - } -} - -/* -if ($action == 'autolettrage') { - - $result = $lettering->letteringThirdparty($socid); - - if ($result < 0) { - setEventMessages('', $lettering->errors, 'errors'); - $error++; - } -} -*/ - -/* - * View - */ - -$form = new Form($db); -$formaccounting = new FormAccounting($db); - -$title = $object->name." - ".$langs->trans('TabLetteringCustomer'); -$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner'; -llxHeader('', $title, $help_url); - -$head = societe_prepare_head($object); - -dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error'); - -print dol_get_fiche_head($head, 'lettering_customer', $langs->trans("ThirdParty"), 0, 'company'); - -$linkback = ''.$langs->trans("BackToList").''; - -dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom'); - -print dol_get_fiche_end(); - -$sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, "; -$sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, "; -$sql .= " bk.credit, bk.montant, bk.sens, bk.code_journal, bk.piece_num, bk.lettering_code"; -$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as bk"; -$sql .= " WHERE (bk.subledger_account = '".$db->escape($object->code_compta)."' AND bk.numero_compte = '".$db->escape($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER)."' )"; - -/* -if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) { - $sql .= " AND ( bk.doc_date BETWEEN '" . $db->idate($search_date_start) . "' AND '" . $db->idate($search_date_end) . "' )"; -} -*/ - -$sql .= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')'; -$sql .= $db->order($sortfield, $sortorder); - -$debit = 0; -$credit = 0; -$solde = 0; -// Count total nb of records and calc total sum -$nbtotalofrecords = ''; -$resql = $db->query($sql); -if (!$resql) { - dol_print_error($db); - exit(); -} -$nbtotalofrecords = $db->num_rows($resql); - -while ($obj = $db->fetch_object($resql)) { - $debit += $obj->debit; - $credit += $obj->credit; - - $solde += ($obj->credit - $obj->debit); -} - -$sql .= $db->plimit($limit + 1, $offset); - -dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG); -$resql = $db->query($sql); -if (!$resql) { - dol_print_error($db); - exit(); -} - -$param = ''; -$param .= "&socid=".urlencode($socid); - -$num = $db->num_rows($resql); - -dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG); -if ($resql) { - $i = 0; - - $param = "&socid=".$socid; - print '
'; - print ''; - print ''; - - $letteringbutton = ''; - - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); - - print '
'; - print ''."\n"; - - /* - print ''; - //print ''; - - // Date - print ''; - - // Piece - print ''; - print ''; - print ''; - print ''; - */ - - print ''; - //print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("", "", "", '', '', "", $sortfield, $sortorder, 'maxwidthsearch center '); - print "\n"; - - $solde = 0; - $tmp = ''; - - while ($obj = $db->fetch_object($resql)) { - if ($tmp != $obj->lettering_code || empty($tmp)) { - $tmp = $obj->lettering_code; - } - /*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/ $solde += ($obj->credit - $obj->debit); - - print ''; - - //print '' . "\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - // Journal - $accountingjournal = new AccountingJournal($db); - $result = $accountingjournal->fetch('', $obj->code_journal); - $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal); - print ''; - - if (empty($obj->lettering_code) && empty($obj->date_validated)) { - print ''; - print ''."\n"; - } else { - print ''; - print ''; - } - - print "\n"; - } - - print ''; - print ''."\n"; - print ''; - print ''; - print ''; - print "\n"; - - print ''; - print ''."\n"; - print ''; - print ''; - print ''; - print "\n"; - - print "
'; - print '
'; - print $langs->trans('From') . ' '; - print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1); - print '
'; - print '
'; - print $langs->trans('to') . ' '; - print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1); - print '
'; - print '
 '; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
' . $obj->doc_type . ''.dol_print_date($db->jdate($obj->doc_date), 'day').''.$obj->doc_ref.''.$obj->label_compte.''.price($obj->debit).''.price($obj->credit).''.price(round($solde, 2)).''.$journaltoshow.''; - print img_edit(); - print ''.$obj->lettering_code.'
'.$langs->trans("Total").':'.price($debit).''.price($credit).'
'.$langs->trans("Balancing").': '.price($credit - $debit).'
"; - - print '
'."\n"; - print $letteringbutton; - print '
'; - - print ""; - $db->free($resql); -} else { - dol_print_error($db); -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php deleted file mode 100644 index 5c315bee9fc..00000000000 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php +++ /dev/null @@ -1,322 +0,0 @@ - - * Copyright (C) 2005 Laurent Destailleur - * Copyright (C) 2013 Olivier Geffroy - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2019 Alexandre Spangaro - * Copyright (C) 2018-2020 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php - * \ingroup Accountancy (Double entries) - * \brief Tab to setup lettering - */ -require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; -require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - -// Load translation files required by the page -$langs->loadLangs(array("compta", "accountancy")); - -$action = GETPOST('action', 'aZ09'); -$massaction = GETPOST('massaction', 'alpha'); -$show_files = GETPOST('show_files', 'int'); -$confirm = GETPOST('confirm', 'alpha'); -$toselect = GETPOST('toselect', 'array'); -// $socid = GETPOST('socid', 'int') ? ((int) GETPOST('socid', 'int')) : ((int) GETPOST('id', 'int')); -// Security check -$socid = GETPOSTINT("socid"); -// if ($user->socid) $socid=$user->socid; - - -$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST('sortfield', 'aZ09comma'); -$sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page == - 1) { - $page = 0; -} // If $page is not defined, or '' or -1 -$offset = $limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; -if ($sortorder == "") { - $sortorder = "ASC"; -} -if ($sortfield == "") { - $sortfield = "bk.doc_date"; -} - -/* -$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); -$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); -//$search_doc_type = GETPOST("search_doc_type",'alpha'); -$search_doc_ref = GETPOST("search_doc_ref",'alpha'); -*/ - -$lettering = GETPOST('lettering', 'alpha'); -if (!empty($lettering)) { - $action = $lettering; -} - -/* -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers -{ - $search_date_start = ''; - $search_date_end = ''; - //$search_doc_type=''; - $search_doc_ref=''; -} -*/ - -$lettering = new Lettering($db); -$object = new Societe($db); -$object->id = $socid; -$result = $object->fetch($socid); -if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); -} - -if (empty($conf->accounting->enabled)) { - accessforbidden(); -} -if ($user->socid > 0) { - accessforbidden(); -} -if (empty($user->rights->accounting->mouvements->lire)) { - accessforbidden(); -} - - -/* - * Action - */ - -if ($action == 'lettering') { - $result = $lettering->updateLettering($toselect); - - if ($result < 0) { - setEventMessages('', $lettering->errors, 'errors'); - $error++; - } -} - -/* -if ($action == 'autolettrage') { - - $result = $lettering->letteringThirdparty($socid); - - if ($result < 0) { - setEventMessages('', $lettering->errors, 'errors'); - $error++; - } -} -*/ - -/* - * View - */ - -$form = new Form($db); -$formaccounting = new FormAccounting($db); - -$title = $object->name." - ".$langs->trans('TabLetteringSupplier'); -$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner'; -llxHeader('', $title, $help_url); - -$head = societe_prepare_head($object); - -dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error'); - -print dol_get_fiche_head($head, 'lettering_supplier', $langs->trans("ThirdParty"), 0, 'company'); - -$linkback = ''.$langs->trans("BackToList").''; - -dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom'); - -print dol_get_fiche_end(); - -$sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, "; -$sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, "; -$sql .= " bk.credit, bk.montant, bk.sens, bk.code_journal, bk.piece_num, bk.lettering_code, bk.date_validated "; -$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as bk"; -$sql .= " WHERE (bk.subledger_account = '".$db->escape($object->code_compta_fournisseur)."' AND bk.numero_compte = '".$db->escape($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER)."' )"; -if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) { - $sql .= " AND (bk.doc_date BETWEEN '".$db->idate($search_date_start)."' AND '".$db->idate($search_date_end)."' )"; -} -$sql .= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')'; -$sql .= $db->order($sortfield, $sortorder); - -$debit = 0; -$credit = 0; -$solde = 0; -// Count total nb of records and calc total sum -$nbtotalofrecords = ''; -$resql = $db->query($sql); -if (!$resql) { - dol_print_error($db); - exit; -} -$nbtotalofrecords = $db->num_rows($resql); - -while ($obj = $db->fetch_object($resql)) { - $debit += $obj->debit; - $credit += $obj->credit; - - $solde += ($obj->credit - $obj->debit); -} - -$sql .= $db->plimit($limit + 1, $offset); - -dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG); -$resql = $db->query($sql); -if (!$resql) { - dol_print_error($db); - exit; -} - -$param = ''; -$param .= "&socid=".urlencode($socid); - -$num = $db->num_rows($resql); - -dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG); -$resql = $db->query($sql); -if ($resql) { - $num = $db->num_rows($resql); - $i = 0; - - $param = "&socid=".$socid; - print '
'; - print ''; - print ''; - - $letteringbutton = ''; - - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); - - print '
'; - print ''."\n"; - - /* - print ''; - //print ''; - - // Date - print ''; - - // Piece - print ''; - print ''; - print ''; - print ''; - */ - - print ''; - //print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("", "", "", '', '', "", $sortfield, $sortorder, 'maxwidthsearch center '); - print "\n"; - - $solde = 0; - $tmp = ''; - while ($obj = $db->fetch_object($resql)) { - if ($tmp != $obj->lettering_code || empty($tmp)) { - $tmp = $obj->lettering_code; - } - /*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/ $solde += ($obj->credit - $obj->debit); - - print ''; - - //print '' . "\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - // Journal - $accountingjournal = new AccountingJournal($db); - $result = $accountingjournal->fetch('', $obj->code_journal); - $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal); - print ''; - - if (empty($obj->lettering_code) && empty($obj->date_validated)) { - print ''; - print ''."\n"; - } else { - print ''; - print ''; - } - - print "\n"; - } - - print ''; - print ''."\n"; - print ''; - print ''; - print ''; - print "\n"; - - print ''; - print ''."\n"; - print ''; - print ''; - print ''; - print "\n"; - - print "
'; - print '
'; - print $langs->trans('From') . ' '; - print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1); - print '
'; - print '
'; - print $langs->trans('to') . ' '; - print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1); - print '
'; - print '
 '; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
' . $obj->doc_type . ''.dol_print_date($db->jdate($obj->doc_date), 'day').''.$obj->doc_ref.''.$obj->label_compte.''.price($obj->debit).''.price($obj->credit).''.price(round($solde, 2)).''.$journaltoshow.''; - print img_edit(); - print ''.$obj->lettering_code.'
'.$langs->trans("Total").':'.price($debit).''.price($credit).'
'.$langs->trans("Balancing").': '.price($credit - $debit).'
"; - - print '
'."\n"; - print $letteringbutton; - print '
'; - - print ""; - $db->free($resql); -} else { - dol_print_error($db); -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 0d0d013a69f..3c30200c130 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -64,6 +64,10 @@ class AccountancyExport public static $EXPORT_TYPE_FEC = 1000; public static $EXPORT_TYPE_FEC2 = 1010; + /** + * @var DoliDB Database handler + */ + public $db; /** * @var string[] Error codes (or messages) diff --git a/htdocs/accountancy/class/accountancyimport.class.php b/htdocs/accountancy/class/accountancyimport.class.php index ea88534b6ed..5f4d76bc4c5 100644 --- a/htdocs/accountancy/class/accountancyimport.class.php +++ b/htdocs/accountancy/class/accountancyimport.class.php @@ -29,7 +29,7 @@ /** * \file htdocs/accountancy/class/accountancyimport.class.php * \ingroup Accountancy (Double entries) - * \brief Class accountancy import + * \brief Class with methods for accountancy import */ @@ -39,63 +39,104 @@ */ class AccountancyImport { + /** + * @var DoliDB Database handler + */ + public $db; + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Clean amount + * + * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... + * @param array $listfields Fields list to add + * @param int $record_key Record key + * @return mixed Value + */ + public function cleanAmount(&$arrayrecord, $listfields, $record_key) + { + $value_trim = trim($arrayrecord[$record_key]['val']); + return floatval($value_trim); + } + + /** + * Clean value with trim + * + * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... + * @param array $listfields Fields list to add + * @param int $record_key Record key + * @return mixed Value + */ + public function cleanValue(&$arrayrecord, $listfields, $record_key) + { + return trim($arrayrecord[$record_key]['val']); + } + /** * Compute amount * * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... - * @param string $fieldname Field name with alias * @param array $listfields Fields list to add - * @param array $listvalues Values list to add - * @return int <0 if KO, >0 if OK + * @param int $record_key Record key + * @return mixed Value */ - public function computeAmount(&$arrayrecord, $fieldname, &$listfields, &$listvalues) + public function computeAmount(&$arrayrecord, $listfields, $record_key) { - $fieldArr = explode('.', $fieldname); - if (count($fieldArr) > 0) { - $fieldname = $fieldArr[1]; + // get fields indexes + $field_index_list = array_flip($listfields); + if (isset($field_index_list['debit']) && isset($field_index_list['credit'])) { + $debit_index = $field_index_list['debit']; + $credit_index = $field_index_list['credit']; + + $debit = floatval($arrayrecord[$debit_index]['val']); + $credit = floatval($arrayrecord[$credit_index]['val']); + if (!empty($debit)) { + $amount = $debit; + } else { + $amount = $credit; + } + + return "'" . $this->db->escape(abs($amount)) . "'"; } - $debit = floatval(trim($arrayrecord[11]['val'])); - $credit = floatval(trim($arrayrecord[12]['val'])); - if (!empty($debit)) { - $amount = $debit; - } else { - $amount = $credit; - } - - $listfields[] = $fieldname; - $listvalues[] = "'" . abs($amount) . "'"; - - return 1; + return "''"; } /** - * Compute sens + * Compute direction * * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... - * @param string $fieldname Field name with alias * @param array $listfields Fields list to add - * @param array $listvalues Values list to add - * @return int <0 if KO, >0 if OK + * @param int $record_key Record key + * @return mixed Value */ - public function computeDirection(&$arrayrecord, $fieldname, &$listfields, &$listvalues) + public function computeDirection(&$arrayrecord, $listfields, $record_key) { - $fieldArr = explode('.', $fieldname); - if (count($fieldArr) > 0) { - $fieldname = $fieldArr[1]; + $field_index_list = array_flip($listfields); + if (isset($field_index_list['debit'])) { + $debit_index = $field_index_list['debit']; + + $debit = floatval($arrayrecord[$debit_index]['val']); + if (!empty($debit)) { + $sens = 'D'; + } else { + $sens = 'C'; + } + + return "'" . $this->db->escape($sens) . "'"; } - $debit = floatval(trim($arrayrecord[11]['val'])); - if (!empty($debit)) { - $sens = 'D'; - } else { - $sens = 'C'; - } - - $listfields[] = $fieldname; - $listvalues[] = "'" . $sens . "'"; - - return 1; + return "''"; } } diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 24e42c367aa..d805838566f 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2017-2022 OpenDSI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -81,6 +81,24 @@ class AccountingJournal extends CommonObject */ public $lines; + /** + * @var array Accounting account cached + */ + static public $accounting_account_cached = array(); + + /** + * @var array Nature mapping + */ + static public $nature_maps = array( + 1 => 'variousoperations', + 2 => 'sells', + 3 => 'purchases', + 4 => 'bank', + 5 => 'expensereports', + 8 => 'inventories', + 9 => 'hasnew', + ); + /** * Constructor * @@ -345,4 +363,680 @@ class AccountingJournal extends CommonObject } } } + + + /** + * Get journal data + * + * @param User $user User who get infos + * @param string $type Type data returned ('view', 'bookkeeping', 'csv') + * @param int $date_start Filter 'start date' + * @param int $date_end Filter 'end date' + * @param string $in_bookkeeping Filter 'in bookkeeping' ('already', 'notyet') + * @return array|int <0 if KO, >0 if OK + */ + public function getData(User $user, $type = 'view', $date_start = null, $date_end = null, $in_bookkeeping = 'notyet') + { + global $hookmanager; + + // Clean parameters + if (empty($type)) $type = 'view'; + if (empty($in_bookkeeping)) $in_bookkeeping = 'notyet'; + + // Hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $data = array(); + + $hookmanager->initHooks(array('accountingjournaldao')); + $parameters = array('data' => &$data, 'user' => $user, 'type' => $type, 'date_start' => $date_start, 'date_end' => $date_end, 'in_bookkeeping' => $in_bookkeeping); + $reshook = $hookmanager->executeHooks('getData', $parameters, $this); // Note that $action and $object may have been + if ($reshook < 0) { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + return -1; + } elseif (empty($reshook)) { + switch ($this->nature) { + case 1: // Various Journal + $data = $this->getAssetData($user, $type, $date_start, $date_end, $in_bookkeeping); + break; + // case 2: // Sells Journal + // case 3: // Purchases Journal + // case 4: // Bank Journal + // case 5: // Expense reports Journal + // case 8: // Inventory Journal + // case 9: // hasnew Journal + } + } + + return $data; + } + + /** + * Get asset data for various journal + * + * @param User $user User who get infos + * @param string $type Type data returned ('view', 'bookkeeping', 'csv') + * @param int $date_start Filter 'start date' + * @param int $date_end Filter 'end date' + * @param string $in_bookkeeping Filter 'in bookkeeping' ('already', 'notyet') + * @return array|int <0 if KO, >0 if OK + */ + public function getAssetData(User $user, $type = 'view', $date_start = null, $date_end = null, $in_bookkeeping = 'notyet') + { + global $conf, $langs; + + if (empty($conf->asset->enabled)) { + return array(); + } + + require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + + $langs->loadLangs(array("assets")); + + // Clean parameters + if (empty($type)) $type = 'view'; + if (empty($in_bookkeeping)) $in_bookkeeping = 'notyet'; + + $sql = ""; + if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') { + $sql .= "WITH in_accounting_bookkeeping(fk_docdet) AS ("; + $sql .= " SELECT DISTINCT fk_docdet"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE doc_type = 'asset'"; + $sql .= ")"; + } + $sql .= "SELECT ad.fk_asset AS rowid, a.ref AS asset_ref, a.label AS asset_label, a.acquisition_value_ht AS asset_acquisition_value_ht"; + $sql .= ", a.disposal_date AS asset_disposal_date, a.disposal_amount_ht AS asset_disposal_amount_ht, a.disposal_subject_to_vat AS asset_disposal_subject_to_vat"; + $sql .= ", ad.rowid AS depreciation_id, ad.depreciation_mode, ad.ref AS depreciation_ref, ad.depreciation_date, ad.depreciation_ht, ad.accountancy_code_debit, ad.accountancy_code_credit"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation as ad"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "asset as a ON a.rowid = ad.fk_asset"; + if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') { + $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid"; + } + $sql .= " WHERE a.entity IN (" . getEntity('asset', 0) . ')'; // We don't share object for accountancy, we use source object sharing + $sql .= " AND ad.ref != ''"; // not reversal lines + if ($date_start && $date_end) { + $sql .= " AND ad.depreciation_date >= '" . $this->db->idate($date_start) . "' AND ad.depreciation_date <= '" . $this->db->idate($date_end) . "'"; + } + // Define begin binding date + if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) { + $sql .= " AND ad.depreciation_date >= '" . $this->db->idate($conf->global->ACCOUNTING_DATE_START_BINDING) . "'"; + } + // Already in bookkeeping or not + if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') { + $sql .= " AND iab.fk_docdet IS" . ($in_bookkeeping == 'already' ? " NOT" : "") . " NULL"; + } + $sql .= " ORDER BY ad.depreciation_date"; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $this->db->lasterror(); + return -1; + } + + $pre_data = array( + 'elements' => array(), + ); + while ($obj = $this->db->fetch_object($resql)) { + if (!isset($pre_data['elements'][$obj->rowid])) { + $pre_data['elements'][$obj->rowid] = array( + 'ref' => $obj->asset_ref, + 'label' => $obj->asset_label, + 'acquisition_value_ht' => $obj->asset_acquisition_value_ht, + 'depreciation' => array(), + ); + + // Disposal infos + if (isset($obj->asset_disposal_date)) { + $pre_data['elements'][$obj->rowid]['disposal'] = array( + 'date' => $this->db->jdate($obj->asset_disposal_date), + 'amount' => $obj->asset_disposal_amount_ht, + 'subject_to_vat' => !empty($obj->asset_disposal_subject_to_vat), + ); + } + } + + $compta_debit = empty($obj->accountancy_code_debit) ? 'NotDefined' : $obj->accountancy_code_debit; + $compta_credit = empty($obj->accountancy_code_credit) ? 'NotDefined' : $obj->accountancy_code_credit; + + $pre_data['elements'][$obj->rowid]['depreciation'][$obj->depreciation_id] = array( + 'date' => $this->db->jdate($obj->depreciation_date), + 'ref' => $obj->depreciation_ref, + 'lines' => array( + $compta_debit => -$obj->depreciation_ht, + $compta_credit => $obj->depreciation_ht, + ), + ); + } + + $disposal_ref = $langs->transnoentitiesnoconv('AssetDisposal'); + $journal = $this->code; + $journal_label = $this->label; + $journal_label_formatted = $langs->transnoentities($journal_label); + $now = dol_now(); + + $element_static = new Asset($this->db); + + $journal_data = array(); + foreach ($pre_data['elements'] as $pre_data_id => $pre_data_info) { + $element_static->id = $pre_data_id; + $element_static->ref = (string) $pre_data_info["ref"]; + $element_static->label = (string) $pre_data_info["label"]; + $element_static->acquisition_value_ht = $pre_data_info["acquisition_value_ht"]; + $element_link = $element_static->getNomUrl(1, 'with_label'); + + $element_name_formatted_0 = dol_trunc($element_static->label, 16); + $element_name_formatted_1 = utf8_decode(dol_trunc($element_static->label, 32)); + $element_name_formatted_2 = utf8_decode(dol_trunc($element_static->label, 16)); + $label_operation = $element_static->getNomUrl(0, 'label', 16); + + $element = array( + 'ref' => dol_trunc($element_static->ref, 16, 'right', 'UTF-8', 1), + 'error' => $pre_data_info['error'], + 'blocks' => array(), + ); + + // Depreciation lines + //-------------------- + foreach ($pre_data_info['depreciation'] as $depreciation_id => $line) { + $depreciation_ref = $line["ref"]; + $depreciation_date = $line["date"]; + $depreciation_date_formatted = dol_print_date($depreciation_date, 'day'); + + // lines + $blocks = array(); + foreach ($line['lines'] as $account => $mt) { + $account_infos = $this->getAccountingAccountInfos($account); + + if ($type == 'view') { + $account_to_show = length_accounta($account); + if (($account_to_show == "") || $account_to_show == 'NotDefined') { + $account_to_show = '' . $langs->trans("AssetInAccountNotDefined") . ''; + } + + $blocks[] = array( + 'date' => $depreciation_date_formatted, + 'piece' => $element_link, + 'account_accounting' => $account_to_show, + 'subledger_account' => '', + 'label_operation' => $label_operation . ' - ' . $depreciation_ref, + 'debit' => $mt < 0 ? price(-$mt) : '', + 'credit' => $mt >= 0 ? price($mt) : '', + ); + } elseif ($type == 'bookkeeping') { + if ($account_infos['found']) { + $blocks[] = array( + 'doc_date' => $depreciation_date, + 'date_lim_reglement' => '', + 'doc_ref' => $element_static->ref, + 'date_creation' => $now, + 'doc_type' => 'asset', + 'fk_doc' => $element_static->id, + 'fk_docdet' => $depreciation_id, // Useless, can be several lines that are source of this record to add + 'thirdparty_code' => '', + 'subledger_account' => '', + 'subledger_label' => '', + 'numero_compte' => $account, + 'label_compte' => $account_infos['label'], + 'label_operation' => $element_name_formatted_0 . ' - ' . $depreciation_ref, + 'montant' => $mt, + 'sens' => $mt < 0 ? 'D' : 'C', + 'debit' => $mt < 0 ? -$mt : 0, + 'credit' => $mt >= 0 ? $mt : 0, + 'code_journal' => $journal, + 'journal_label' => $journal_label_formatted, + 'piece_num' => '', + 'import_key' => '', + 'fk_user_author' => $user->id, + 'entity' => $conf->entity, + ); + } + } else { // $type == 'csv' + $blocks[] = array( + $depreciation_date, // Date + $element_static->ref, // Piece + $account_infos['code_formatted_1'], // AccountAccounting + $element_name_formatted_0 . ' - ' . $depreciation_ref, // LabelOperation + $mt < 0 ? price(-$mt) : '', // Debit + $mt >= 0 ? price($mt) : '', // Credit + ); + } + } + $element['blocks'][] = $blocks; + } + + // Disposal line + //-------------------- + if (!empty($pre_data_info['disposal'])) { + $disposal_date = $pre_data_info['disposal']['date']; + + if ((!($date_start && $date_end) || ($date_start <= $disposal_date && $disposal_date <= $date_end)) && + (empty($conf->global->ACCOUNTING_DATE_START_BINDING) || $conf->global->ACCOUNTING_DATE_START_BINDING <= $disposal_date) + ) { + $disposal_amount = $pre_data_info['disposal']['amount']; + $disposal_subject_to_vat = $pre_data_info['disposal']['subject_to_vat']; + $disposal_date_formatted = dol_print_date($disposal_date, 'day'); + $disposal_vat = $conf->global->ASSET_DISPOSAL_VAT > 0 ? $conf->global->ASSET_DISPOSAL_VAT : 20; + + // Get accountancy codes + //--------------------------- + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + $accountancy_codes = new AssetAccountancyCodes($this->db); + $result = $accountancy_codes->fetchAccountancyCodes($element_static->id); + if ($result < 0) { + $element['error'] = $accountancy_codes->errorsToString(); + } else { + // Get last depreciation cumulative amount + $element_static->fetchDepreciationLines(); + foreach ($element_static->depreciation_lines as $mode_key => $depreciation_lines) { + $accountancy_codes_list = $accountancy_codes->accountancy_codes[$mode_key]; + + if (!isset($accountancy_codes_list['value_asset_sold'])) { + continue; + } + + $accountancy_code_value_asset_sold = empty($accountancy_codes_list['value_asset_sold']) ? 'NotDefined' : $accountancy_codes_list['value_asset_sold']; + $accountancy_code_depreciation_asset = empty($accountancy_codes_list['depreciation_asset']) ? 'NotDefined' : $accountancy_codes_list['depreciation_asset']; + $accountancy_code_asset = empty($accountancy_codes_list['asset']) ? 'NotDefined' : $accountancy_codes_list['asset']; + $accountancy_code_receivable_on_assignment = empty($accountancy_codes_list['receivable_on_assignment']) ? 'NotDefined' : $accountancy_codes_list['receivable_on_assignment']; + $accountancy_code_vat_collected = empty($accountancy_codes_list['vat_collected']) ? 'NotDefined' : $accountancy_codes_list['vat_collected']; + $accountancy_code_proceeds_from_sales = empty($accountancy_codes_list['proceeds_from_sales']) ? 'NotDefined' : $accountancy_codes_list['proceeds_from_sales']; + + $last_cumulative_amount_ht = 0; + $depreciated_ids = array_keys($pre_data_info['depreciation']); + foreach ($depreciation_lines as $line) { + $last_cumulative_amount_ht = $line['cumulative_depreciation_ht']; + if (!in_array($line['id'], $depreciated_ids) && empty($line['bookkeeping']) && !empty($line['ref'])) { + break; + } + } + + $lines = array(); + $lines[0][$accountancy_code_value_asset_sold] = -($element_static->acquisition_value_ht - $last_cumulative_amount_ht); + $lines[0][$accountancy_code_depreciation_asset] = -$last_cumulative_amount_ht; + $lines[0][$accountancy_code_asset] = $element_static->acquisition_value_ht; + + $disposal_amount_vat = $disposal_subject_to_vat ? (double) price2num($disposal_amount * $disposal_vat / 100, 'MT') : 0; + $lines[1][$accountancy_code_receivable_on_assignment] = -($disposal_amount + $disposal_amount_vat); + if ($disposal_subject_to_vat) $lines[1][$accountancy_code_vat_collected] = $disposal_amount_vat; + $lines[1][$accountancy_code_proceeds_from_sales] = $disposal_amount; + + foreach ($lines as $lines_block) { + $blocks = array(); + foreach ($lines_block as $account => $mt) { + $account_infos = $this->getAccountingAccountInfos($account); + + if ($type == 'view') { + $account_to_show = length_accounta($account); + if (($account_to_show == "") || $account_to_show == 'NotDefined') { + $account_to_show = '' . $langs->trans("AssetInAccountNotDefined") . ''; + } + + $blocks[] = array( + 'date' => $disposal_date_formatted, + 'piece' => $element_link, + 'account_accounting' => $account_to_show, + 'subledger_account' => '', + 'label_operation' => $label_operation . ' - ' . $disposal_ref, + 'debit' => $mt < 0 ? price(-$mt) : '', + 'credit' => $mt >= 0 ? price($mt) : '', + ); + } elseif ($type == 'bookkeeping') { + if ($account_infos['found']) { + $blocks[] = array( + 'doc_date' => $disposal_date, + 'date_lim_reglement' => '', + 'doc_ref' => $element_static->ref, + 'date_creation' => $now, + 'doc_type' => 'asset', + 'fk_doc' => $element_static->id, + 'fk_docdet' => 0, // Useless, can be several lines that are source of this record to add + 'thirdparty_code' => '', + 'subledger_account' => '', + 'subledger_label' => '', + 'numero_compte' => $account, + 'label_compte' => $account_infos['label'], + 'label_operation' => $element_name_formatted_0 . ' - ' . $disposal_ref, + 'montant' => $mt, + 'sens' => $mt < 0 ? 'D' : 'C', + 'debit' => $mt < 0 ? -$mt : 0, + 'credit' => $mt >= 0 ? $mt : 0, + 'code_journal' => $journal, + 'journal_label' => $journal_label_formatted, + 'piece_num' => '', + 'import_key' => '', + 'fk_user_author' => $user->id, + 'entity' => $conf->entity, + ); + } + } else { // $type == 'csv' + $blocks[] = array( + $disposal_date, // Date + $element_static->ref, // Piece + $account_infos['code_formatted_1'], // AccountAccounting + $element_name_formatted_0 . ' - ' . $disposal_ref, // LabelOperation + $mt < 0 ? price(-$mt) : '', // Debit + $mt >= 0 ? price($mt) : '', // Credit + ); + } + } + $element['blocks'][] = $blocks; + } + } + } + } + } + + $journal_data[$pre_data_id] = $element; + } + unset($pre_data); + + return $journal_data; + } + + /** + * Write bookkeeping + * + * @param User $user User who write in the bookkeeping + * @param array $journal_data Journal data to write in the bookkeeping + * $journal_data = array( + * id_element => array( + * 'ref' => 'ref', + * 'error' => '', + * 'blocks' => array( + * pos_block => array( + * num_line => array( + * 'doc_date' => '', + * 'date_lim_reglement' => '', + * 'doc_ref' => '', + * 'date_creation' => '', + * 'doc_type' => '', + * 'fk_doc' => '', + * 'fk_docdet' => '', + * 'thirdparty_code' => '', + * 'subledger_account' => '', + * 'subledger_label' => '', + * 'numero_compte' => '', + * 'label_compte' => '', + * 'label_operation' => '', + * 'montant' => '', + * 'sens' => '', + * 'debit' => '', + * 'credit' => '', + * 'code_journal' => '', + * 'journal_label' => '', + * 'piece_num' => '', + * 'import_key' => '', + * 'fk_user_author' => '', + * 'entity' => '', + * ), + * ), + * ), + * ), + * ); + * @param int $max_nb_errors Nb error authorized before stop the process + * @return int <0 if KO, >0 if OK + */ + public function writeIntoBookkeeping(User $user, &$journal_data = array(), $max_nb_errors = 10) + { + global $conf, $langs, $hookmanager; + require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php'; + + // Hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $error = 0; + + $hookmanager->initHooks(array('accountingjournaldao')); + $parameters = array('journal_data' => &$journal_data); + $reshook = $hookmanager->executeHooks('writeBookkeeping', $parameters, $this); // Note that $action and $object may have been + if ($reshook < 0) { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + return -1; + } elseif (empty($reshook)) { + // Clean parameters + $journal_data = is_array($journal_data) ? $journal_data : array(); + + foreach ($journal_data as $element_id => $element) { + $error_for_line = 0; + $total_credit = 0; + $total_debit = 0; + + $this->db->begin(); + + if ($element['error'] == 'somelinesarenotbound') { + $error++; + $error_for_line++; + $this->errors[] = $langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $element['ref']); + } + + if (!$error_for_line) { + foreach ($element['blocks'] as $lines) { + foreach ($lines as $line) { + $bookkeeping = new BookKeeping($this->db); + $bookkeeping->doc_date = $line['doc_date']; + $bookkeeping->date_lim_reglement = $line['date_lim_reglement']; + $bookkeeping->doc_ref = $line['doc_ref']; + $bookkeeping->date_creation = $line['date_creation']; // not used + $bookkeeping->doc_type = $line['doc_type']; + $bookkeeping->fk_doc = $line['fk_doc']; + $bookkeeping->fk_docdet = $line['fk_docdet']; + $bookkeeping->thirdparty_code = $line['thirdparty_code']; + $bookkeeping->subledger_account = $line['subledger_account']; + $bookkeeping->subledger_label = $line['subledger_label']; + $bookkeeping->numero_compte = $line['numero_compte']; + $bookkeeping->label_compte = $line['label_compte']; + $bookkeeping->label_operation = $line['label_operation']; + $bookkeeping->montant = $line['montant']; + $bookkeeping->sens = $line['sens']; + $bookkeeping->debit = $line['debit']; + $bookkeeping->credit = $line['credit']; + $bookkeeping->code_journal = $line['code_journal']; + $bookkeeping->journal_label = $line['journal_label']; + $bookkeeping->piece_num = $line['piece_num']; + $bookkeeping->import_key = $line['import_key']; + $bookkeeping->fk_user_author = $user->id; + $bookkeeping->entity = $conf->entity; + + $total_debit += $bookkeeping->debit; + $total_credit += $bookkeeping->credit; + + $result = $bookkeeping->create($user); + if ($result < 0) { + if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists + $error++; + $error_for_line++; + $journal_data[$element_id]['error'] = 'alreadyjournalized'; + } else { + $error++; + $error_for_line++; + $journal_data[$element_id]['error'] = 'other'; + $this->errors[] = $bookkeeping->errorsToString(); + } + } + // + // if (!$error_for_line && !empty($conf->asset->enabled) && $this->nature == 1 && $bookkeeping->fk_doc > 0) { + // // Set last cumulative depreciation + // require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; + // $asset = new Asset($this->db); + // $result = $asset->setLastCumulativeDepreciation($bookkeeping->fk_doc); + // if ($result < 0) { + // $error++; + // $error_for_line++; + // $journal_data[$element_id]['error'] = 'other'; + // $this->errors[] = $asset->errorsToString(); + // } + // } + } + + if ($error_for_line) { + break; + } + } + } + + // Protection against a bug on lines before + if (!$error_for_line && (price2num($total_debit, 'MT') != price2num($total_credit, 'MT'))) { + $error++; + $error_for_line++; + $journal_data[$element_id]['error'] = 'amountsnotbalanced'; + $this->errors[] = 'Try to insert a non balanced transaction in book for ' . $element['blocks'] . '. Canceled. Surely a bug.'; + } + + if (!$error_for_line) { + $this->db->commit(); + } else { + $this->db->rollback(); + + if ($error >= $max_nb_errors) { + $this->errors[] = $langs->trans("ErrorTooManyErrorsProcessStopped"); + break; // Break in the foreach + } + } + } + } + + return $error ? -$error : 1; + } + + /** + * Export journal CSV + * ISO and not UTF8 ! + * + * @param array $journal_data Journal data to write in the bookkeeping + * $journal_data = array( + * id_element => array( + * 'continue' => false, + * 'blocks' => array( + * pos_block => array( + * num_line => array( + * data to write in the CSV line + * ), + * ), + * ), + * ), + * ); + * @param int $search_date_end Search date end + * @param string $sep CSV separator + * @return int|string <0 if KO, >0 if OK + */ + public function exportCsv(&$journal_data = array(), $search_date_end = 0, $sep = '') + { + global $conf, $langs, $hookmanager; + + if (empty($sep)) $sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV; + $out = ''; + + // Hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $hookmanager->initHooks(array('accountingjournaldao')); + $parameters = array('journal_data' => &$journal_data, 'search_date_end' => &$search_date_end, 'sep' => &$sep, 'out' => &$out); + $reshook = $hookmanager->executeHooks('exportCsv', $parameters, $this); // Note that $action and $object may have been + if ($reshook < 0) { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + return -1; + } elseif (empty($reshook)) { + // Clean parameters + $journal_data = is_array($journal_data) ? $journal_data : array(); + + // CSV header line + $header = array(); + if ($this->nature == 4) { + $header = array( + $langs->transnoentitiesnoconv("BankId"), + $langs->transnoentitiesnoconv("Date"), + $langs->transnoentitiesnoconv("PaymentMode"), + $langs->transnoentitiesnoconv("AccountAccounting"), + $langs->transnoentitiesnoconv("LedgerAccount"), + $langs->transnoentitiesnoconv("SubledgerAccount"), + $langs->transnoentitiesnoconv("Label"), + $langs->transnoentitiesnoconv("Debit"), + $langs->transnoentitiesnoconv("Credit"), + $langs->transnoentitiesnoconv("Journal"), + $langs->transnoentitiesnoconv("Note"), + ); + } elseif ($this->nature == 5) { + $header = array( + $langs->transnoentitiesnoconv("Date"), + $langs->transnoentitiesnoconv("Piece"), + $langs->transnoentitiesnoconv("AccountAccounting"), + $langs->transnoentitiesnoconv("LabelOperation"), + $langs->transnoentitiesnoconv("Debit"), + $langs->transnoentitiesnoconv("Credit"), + ); + } elseif ($this->nature == 1) { + $header = array( + $langs->transnoentitiesnoconv("Date"), + $langs->transnoentitiesnoconv("Piece"), + $langs->transnoentitiesnoconv("AccountAccounting"), + $langs->transnoentitiesnoconv("LabelOperation"), + $langs->transnoentitiesnoconv("Debit"), + $langs->transnoentitiesnoconv("Credit"), + ); + } + + if (!empty($header)) $out .= '"' . implode('"' . $sep . '"', $header) . '"' . "\n"; + foreach ($journal_data as $element_id => $element) { + foreach ($element['blocks'] as $lines) { + foreach ($lines as $line) { + $out .= '"' . implode('"' . $sep . '"', $line) . '"' . "\n"; + } + } + } + } + + return $out; + } + + /** + * Get accounting account infos + * + * @param string $account Accounting account number + * @return array Accounting account infos + */ + public function getAccountingAccountInfos($account) + { + if (!isset(self::$accounting_account_cached[$account])) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; + $accountingaccount = new AccountingAccount($this->db); + $result = $accountingaccount->fetch(null, $account, true); + if ($result > 0) { + self::$accounting_account_cached[$account] = array( + 'found' => true, + 'label' => $accountingaccount->label, + 'code_formatted_1' => length_accounta(html_entity_decode($account)), + 'label_formatted_1' => utf8_decode(dol_trunc($accountingaccount->label, 32)), + 'label_formatted_2' => dol_trunc($accountingaccount->label, 32), + ); + } else { + self::$accounting_account_cached[$account] = array( + 'found' => false, + 'label' => '', + 'code_formatted_1' => length_accounta(html_entity_decode($account)), + 'label_formatted_1' => '', + 'label_formatted_2' => '', + ); + } + } + + return self::$accounting_account_cached[$account]; + } } diff --git a/htdocs/accountancy/closure/index.php b/htdocs/accountancy/closure/index.php index 6b578bcab71..f02eda61bf6 100644 --- a/htdocs/accountancy/closure/index.php +++ b/htdocs/accountancy/closure/index.php @@ -13,7 +13,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * */ /** diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index 931b5e6420c..4a8080ab8b4 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -68,7 +68,7 @@ $search_tvaintra = GETPOST('search_tvaintra', 'alpha'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +$page = GETPOSTISSET('pageplusonPour le détail de la facture ref…e') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page < 0) { $page = 0; } @@ -137,9 +137,9 @@ if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->acco if (!$error) { $db->begin(); - $sql1 = "UPDATE ".MAIN_DB_PREFIX."facturedet as l"; - $sql1 .= " SET l.fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0'); - $sql1 .= ' WHERE l.rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')'; + $sql1 = "UPDATE ".MAIN_DB_PREFIX."facturedet"; + $sql1 .= " SET fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0'); + $sql1 .= ' WHERE rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')'; dol_syslog('accountancy/customer/lines.php::changeaccount sql= '.$sql1); $resql1 = $db->query($sql1); @@ -496,8 +496,8 @@ if ($result) { } print ''; - print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); + print ''; + $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); print ''; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 80b7bdf2217..bc6713f0846 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -637,7 +637,7 @@ if ($result) { // Description print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $facture_static_det->desc); print ''; diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index ff7b9295693..005783ed7a8 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -405,7 +405,7 @@ if ($result) { // Fees description -- Can be null print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments); print ''; diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index 908159cbe1c..033f1164dc7 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -147,7 +147,7 @@ if (empty($reshook)) { $search_tvaintra = ''; } -// Mass actions + // Mass actions $objectclass = 'ExpenseReport'; $objectlabel = 'ExpenseReport'; $permissiontoread = $user->rights->expensereport->read; @@ -481,7 +481,7 @@ if ($result) { // Fees description -- Can be null print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments); print ''; diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php index 925ab8c9ae3..18277eb6751 100644 --- a/htdocs/accountancy/index.php +++ b/htdocs/accountancy/index.php @@ -117,77 +117,79 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S print '
'; // hideobject is to start hidden print "
\n"; print ''.$langs->trans("AccountancyAreaDescIntro")."
\n"; - print "
\n"; print "
\n"; + if (!empty($user->rights->accounting->chartofaccount)) { + print "
\n"; print "
\n"; - print load_fiche_titre(' '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."\n"; - print '
'; - print "
\n"; + print load_fiche_titre(' '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."\n"; + print '
'; + print "
\n"; - // STEPS - $step++; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '{s}'); - $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("AccountingJournals").'', $s); - print $s; - print "
\n"; - $step++; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '{s}'); - $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Pcg_version").'', $s); - print $s; - print "
\n"; - $step++; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '{s}'); - $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Chartofaccounts").'', $s); - print $s; - print "
\n"; - - print "
\n"; - print $langs->trans("AccountancyAreaDescActionOnceBis"); - print "
\n"; - print "
\n"; - - $step++; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '{s}'); - $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuDefaultAccounts").'', $s); - print $s; - print "
\n"; - - $step++; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '{s}')."\n"; - $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuBankAccounts").'', $s); - print $s; - print "
\n"; - - $step++; - $textlink = ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuVatAccounts").''; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescVat", $step, '{s}'); - $s = str_replace('{s}', $textlink, $s); - print $s; - print "
\n"; - if (!empty($conf->tax->enabled)) { - $textlink = ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuTaxAccounts").''; + // STEPS $step++; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, '{s}'); + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '{s}'); + $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("AccountingJournals").'', $s); + print $s; + print "
\n"; + $step++; + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '{s}'); + $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Pcg_version").'', $s); + print $s; + print "
\n"; + $step++; + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '{s}'); + $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Chartofaccounts").'', $s); + print $s; + print "
\n"; + + print "
\n"; + print $langs->trans("AccountancyAreaDescActionOnceBis"); + print "
\n"; + print "
\n"; + + $step++; + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '{s}'); + $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuDefaultAccounts").'', $s); + print $s; + print "
\n"; + + $step++; + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '{s}')."\n"; + $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuBankAccounts").'', $s); + print $s; + print "
\n"; + + $step++; + $textlink = ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuVatAccounts").''; + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescVat", $step, '{s}'); $s = str_replace('{s}', $textlink, $s); print $s; print "
\n"; - } - if (!empty($conf->expensereport->enabled)) { + + if (!empty($conf->tax->enabled)) { + $textlink = ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuTaxAccounts").''; + $step++; + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, '{s}'); + $s = str_replace('{s}', $textlink, $s); + print $s; + print "
\n"; + } + if (!empty($conf->expensereport->enabled)) { // TODO Move this in the default account page because this is only one accounting account per purpose, not several. + $step++; + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '{s}'); + $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'', $s); + print $s; + print "
\n"; + } + $step++; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '{s}'); - $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'', $s); + $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '{s}'); + $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("ProductsBinding").'', $s); print $s; print "
\n"; + + print '
'; } - $step++; - $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '{s}'); - $s = str_replace('{s}', ''.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("ProductsBinding").'', $s); - print $s; - print "
\n"; - - - print '
'; - // Step A - E print "
\n"; diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 884c56ee6f2..7a5ccd79b21 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -412,8 +412,13 @@ if ($action == 'writebookkeeping') { $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add $bookkeeping->thirdparty_code = $companystatic->code_client; - $bookkeeping->subledger_account = ''; - $bookkeeping->subledger_label = ''; + if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) { + $bookkeeping->subledger_account = $tabcompany[$key]['code_compta']; + $bookkeeping->subledger_label = $tabcompany[$key]['name']; + } else { + $bookkeeping->subledger_account = ''; + $bookkeeping->subledger_label = ''; + } $bookkeeping->numero_compte = $k; $bookkeeping->label_compte = $label_account; @@ -886,6 +891,13 @@ if (empty($action) || $action == 'view') { print ""; // Subledger account print ""; + if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) { + if (($accountoshow == "") || $accountoshow == 'NotDefined') { + print ''.$langs->trans("ThirdpartyAccountNotDefined").''; + } else { + print length_accounta($tabcompany[$key]['code_compta']); + } + } print ''; $companystatic->id = $tabcompany[$key]['id']; $companystatic->name = $tabcompany[$key]['name']; diff --git a/htdocs/accountancy/journal/variousjournal.php b/htdocs/accountancy/journal/variousjournal.php new file mode 100644 index 00000000000..0d95ff61763 --- /dev/null +++ b/htdocs/accountancy/journal/variousjournal.php @@ -0,0 +1,313 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/accountancy/journal/variousjournal.php + * \ingroup Accountancy (Double entries) + * \brief Page of a journal + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("banks", "accountancy", "compta", "other", "errors")); + +$id_journal = GETPOST('id_journal', 'int'); +$action = GETPOST('action', 'aZ09'); + +$date_startmonth = GETPOST('date_startmonth'); +$date_startday = GETPOST('date_startday'); +$date_startyear = GETPOST('date_startyear'); +$date_endmonth = GETPOST('date_endmonth'); +$date_endday = GETPOST('date_endday'); +$date_endyear = GETPOST('date_endyear'); +$in_bookkeeping = GETPOST('in_bookkeeping'); +if ($in_bookkeeping == '') { + $in_bookkeeping = 'notyet'; +} + +// Security check +if (empty($conf->accounting->enabled)) { + accessforbidden(); +} +if ($user->socid > 0) { + accessforbidden(); +} +if (empty($user->rights->accounting->mouvements->lire)) { + accessforbidden(); +} + +// Get information of journal +$object = new AccountingJournal($db); +$result = $object->fetch($id_journal); +if ($result > 0) { + $id_journal = $object->id; +} elseif ($result < 0) { + dol_print_error('', $object->error, $object->errors); +} elseif ($result == 0) { + accessforbidden($langs->trans('ErrorRecordNotFound')); +} + +$hookmanager->initHooks(array('globaljournal', $object->nature_text . 'journal')); +$parameters = array(); + +$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); +$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); + +if (empty($date_startmonth) || empty($date_endmonth)) { + // Period by default on transfer + $dates = getDefaultDatesForTransfer(); + $date_start = $dates['date_start']; + $date_end = $dates['date_end']; + $pastmonthyear = $dates['pastmonthyear']; + $pastmonth = $dates['pastmonth']; +} + +if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form + $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false); + $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); +} + +$data_type = 'view'; +if ($action == 'writebookkeeping') $data_type = 'bookkeeping'; +if ($action == 'exportcsv') $data_type = 'csv'; +$journal_data = $object->getData($user, $data_type, $date_start, $date_end, $in_bookkeeping); +if (!is_array($journal_data)) { + setEventMessages($object->error, $object->errors, 'errors'); +} + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', $parameters, $user, $action); // Note that $action and $object may have been modified by some hooks + +$reload = false; + +// Bookkeeping Write +if ($action == 'writebookkeeping') { + $error = 0; + + $result = $object->writeIntoBookkeeping($user, $journal_data); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $error = abs($result); + } + + $nb_elements = count($journal_data); + if (empty($error) && $nb_elements > 0) { + setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs'); + } elseif ($nb_elements == $error) { + setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings'); + } else { + setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings'); + } + + $reload = true; +} elseif ($action == 'exportcsv') { + // Export CSV + $result = $object->exportCsv($journal_data, $date_end); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $reload = true; + } else { + $filename = 'journal'; + $type_export = 'journal'; + + require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php'; + + print $result; + + $db->close(); + exit(); + } +} + +// Must reload data, so we make a redirect +if ($reload) { + $param = 'id_journal=' . $id_journal; + $param .= '&date_startday=' . $date_startday; + $param .= '&date_startmonth=' . $date_startmonth; + $param .= '&date_startyear=' . $date_startyear; + $param .= '&date_endday=' . $date_endday; + $param .= '&date_endmonth=' . $date_endmonth; + $param .= '&date_endyear=' . $date_endyear; + $param .= '&in_bookkeeping=' . $in_bookkeeping; + header("Location: " . $_SERVER['PHP_SELF'] . ($param ? '?' . $param : '')); + exit; +} + + +/* + * View + */ + +$form = new Form($db); + +if ($object->nature == 2) { + $title = $langs->trans("SellsJournal"); + $some_mandatory_steps_of_setup_were_not_done = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "" || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1'; + $account_accounting_not_defined = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "" || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1'; +} elseif ($object->nature == 3) { + $title = $langs->trans("PurchasesJournal"); + $some_mandatory_steps_of_setup_were_not_done = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "" || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1'; + $account_accounting_not_defined = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "" || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1'; +} elseif ($object->nature == 4) { + $title = $langs->trans("FinanceJournal"); + $some_mandatory_steps_of_setup_were_not_done = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "" || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1' + || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "" || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1' + || empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1'; + $account_accounting_not_defined = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "" || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1' + || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "" || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1'; +} elseif ($object->nature == 5) { + $title = $langs->trans("ExpenseReportsJournal"); + $some_mandatory_steps_of_setup_were_not_done = empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1'; + $account_accounting_not_defined = empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1'; +} else { + $title = $object->getLibType(); + $some_mandatory_steps_of_setup_were_not_done = false; + $account_accounting_not_defined = false; +} + + +$nom = $title . ' | ' . $object->getNomUrl(0, 1, 1, '', 1); +$nomlink = ''; +$periodlink = ''; +$exportlink = ''; +$builddate = dol_now(); +$description = $langs->trans("DescJournalOnlyBindedVisible") . '
'; +if ($object->nature == 2 || $object->nature == 3) { + if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $description .= $langs->trans("DepositsAreNotIncluded"); + } else { + $description .= $langs->trans("DepositsAreIncluded"); + } +} + +$listofchoices = array('notyet' => $langs->trans("NotYetInGeneralLedger"), 'already' => $langs->trans("AlreadyInGeneralLedger")); +$period = $form->selectDate($date_start ? $date_start : -1, 'date_start', 0, 0, 0, '', 1, 0) . ' - ' . $form->selectDate($date_end ? $date_end : -1, 'date_end', 0, 0, 0, '', 1, 0); +$period .= ' - ' . $langs->trans("JournalizationInLedgerStatus") . ' ' . $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); + +$varlink = 'id_journal=' . $id_journal; + +llxHeader('', $title); + +journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink); + +if ($object->nature == 4) { // Bank journal + // Test that setup is complete (we are in accounting, so test on entity is always on $conf->entity only, no sharing allowed) + $sql = "SELECT COUNT(rowid) as nb"; + $sql .= " FROM " . MAIN_DB_PREFIX . "bank_account"; + $sql .= " WHERE entity = " . (int) $conf->entity; + $sql .= " AND fk_accountancy_journal IS NULL"; + $sql .= " AND clos=0"; + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj->nb > 0) { + print '
' . img_warning() . ' ' . $langs->trans("TheJournalCodeIsNotDefinedOnSomeBankAccount"); + print ' : ' . $langs->trans("AccountancyAreaDescBank", 9, '' . $langs->transnoentitiesnoconv("MenuAccountancy") . '-' . $langs->transnoentitiesnoconv("Setup") . "-" . $langs->transnoentitiesnoconv("BankAccounts") . ''); + } + } else dol_print_error($db); +} + +// Button to write into Ledger +if ($some_mandatory_steps_of_setup_were_not_done) { + print '
' . img_warning() . ' ' . $langs->trans("SomeMandatoryStepsOfSetupWereNotDone"); + print ' : ' . $langs->trans("AccountancyAreaDescMisc", 4, '' . $langs->transnoentitiesnoconv("MenuAccountancy") . '-' . $langs->transnoentitiesnoconv("Setup") . "-" . $langs->transnoentitiesnoconv("MenuDefaultAccounts") . ''); + print '
'; +} +print '
'; +if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') { + print ''; +} +if ($account_accounting_not_defined) { + print ''; +} else { + if ($in_bookkeeping == 'notyet') { + print ''; + } else { + print '' . $langs->trans("WriteBookKeeping") . ''; + } +} +print '
'; + +// TODO Avoid using js. We can use a direct link with $param +print ' + '; + +$object_label = $langs->trans("ObjectsRef"); +if ($object->nature == 2 || $object->nature == 3) $object_label = $langs->trans("InvoiceRef"); +if ($object->nature == 5) $object_label = $langs->trans("ExpenseReportRef"); + +/* + * Show result array + */ +print '
'; + +print '
'; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +if ($object->nature == 4) print ''; // bank +print ''; +print ''; +print "\n"; + +foreach ($journal_data as $element_id => $element) { + foreach ($element['blocks'] as $lines) { + foreach ($lines as $line) { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ($object->nature == 4) print ''; + print ''; + print ''; + print ''; + } + } +} + +print '
' . $langs->trans("Date") . '' . $langs->trans("Piece") . ' (' . $object_label . ')' . $langs->trans("AccountAccounting") . '' . $langs->trans("SubledgerAccount") . '' . $langs->trans("LabelOperation") . '' . $langs->trans("PaymentMode") . '' . $langs->trans("Debit") . '' . $langs->trans("Credit") . '
' . $line['date'] . '' . $line['piece'] . '' . $line['account_accounting'] . '' . $line['subledger_account'] . '' . $line['label_operation'] . '' . $line['payment_mode'] . '' . $line['debit'] . '' . $line['credit'] . '
'; +print '
'; + +llxFooter(); + +$db->close(); diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index 9f769ae13b4..914c355c838 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -1,9 +1,9 @@ - * Copyright (C) 2013-2021 Alexandre Spangaro - * Copyright (C) 2014-2015 Ari Elbaz (elarifr) - * Copyright (C) 2013-2016 Florian Henry - * Copyright (C) 2014 Juanjo Menent +/* Copyright (C) 2013-2016 Olivier Geffroy + * Copyright (C) 2013-2022 Alexandre Spangaro + * Copyright (C) 2014-2015 Ari Elbaz (elarifr) + * Copyright (C) 2013-2016 Florian Henry + * Copyright (C) 2014 Juanjo Menent * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -49,6 +49,7 @@ $search_societe = GETPOST('search_societe', 'alpha'); $search_lineid = GETPOST('search_lineid', 'int'); $search_ref = GETPOST('search_ref', 'alpha'); $search_invoice = GETPOST('search_invoice', 'alpha'); +$search_ref_supplier = GETPOST('search_ref_supplier', 'alpha'); $search_label = GETPOST('search_label', 'alpha'); $search_desc = GETPOST('search_desc', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); @@ -112,6 +113,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_lineid = ''; $search_ref = ''; $search_invoice = ''; + $search_ref_supplier = ''; $search_label = ''; $search_desc = ''; $search_amount = ''; @@ -140,9 +142,9 @@ if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->acco if (!$error) { $db->begin(); - $sql1 = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det as l"; - $sql1 .= " SET l.fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0'); - $sql1 .= ' WHERE l.rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')'; + $sql1 = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det"; + $sql1 .= " SET fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0'); + $sql1 .= ' WHERE rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')'; dol_syslog('accountancy/supplier/lines.php::changeaccount sql= '.$sql1); $resql1 = $db->query($sql1); @@ -236,6 +238,9 @@ if ($search_lineid) { if (strlen(trim($search_invoice))) { $sql .= natural_search("f.ref", $search_invoice); } +if (strlen(trim($search_ref_supplier))) { + $sql .= natural_search("f.ref_supplier", $search_ref_supplier); +} if (strlen(trim($search_label))) { $sql .= natural_search("f.libelle", $search_label); } @@ -328,6 +333,9 @@ if ($result) { if ($search_ref) { $param .= "&search_ref=".urlencode($search_ref); } + if ($search_ref_supplier) { + $param .= '&search_ref_supplier='.urlencode($search_ref_supplier); + } if ($search_label) { $param .= "&search_label=".urlencode($search_label); } @@ -392,6 +400,7 @@ if ($result) { print ''; print ''; print ''; + print ''; print ''; print ''; print '
'; @@ -420,6 +429,7 @@ if ($result) { print ''; print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("RefSupplier", $_SERVER["PHP_SELF"], "f.ref_supplier", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); @@ -446,6 +456,9 @@ if ($result) { $facturefournisseur_static->ref = $objp->ref; $facturefournisseur_static->id = $objp->facid; + $facturefournisseur_static->type = $objp->ftype; + $facturefournisseur_static->ref_supplier = $objp->ref_supplier; + $facturefournisseur_static->label = $objp->invoice_label; $thirdpartystatic->id = $objp->socid; $thirdpartystatic->name = $objp->name; @@ -465,8 +478,8 @@ if ($result) { $productstatic->status = $objp->tosell; $productstatic->status_buy = $objp->tobuy; $productstatic->accountancy_code_buy = $objp->accountancy_code_buy; - $productstatic->accountancy_code_buy_intra = $objp->accountancy_code_sell_buy; - $productstatic->accountancy_code_buy_export = $objp->accountancy_code_sell_buy; + $productstatic->accountancy_code_buy_intra = $objp->accountancy_code_sell_buy_intra; + $productstatic->accountancy_code_buy_export = $objp->accountancy_code_sell_buy_export; $accountingaccountstatic->rowid = $objp->fk_compte; $accountingaccountstatic->label = $objp->label_account; @@ -481,7 +494,13 @@ if ($result) { // Ref Invoice print ''.$facturefournisseur_static->getNomUrl(1).''; - print ''; + // Ref supplier invoice + print ''; + print $objp->ref_supplier; + print ''; + + // Supplier invoice label + print ''; print $objp->invoice_label; print ''; @@ -501,8 +520,8 @@ if ($result) { } print ''; - print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); + print ''; + $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); print ''; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 24d0ed08a0a..914c6fa1633 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -1,10 +1,10 @@ - * Copyright (C) 2013-2021 Alexandre Spangaro - * Copyright (C) 2014-2015 Ari Elbaz (elarifr) - * Copyright (C) 2013-2021 Florian Henry - * Copyright (C) 2014 Juanjo Menent s - * Copyright (C) 2016 Laurent Destailleur +/* Copyright (C) 2013-2014 Olivier Geffroy + * Copyright (C) 2013-2022 Alexandre Spangaro + * Copyright (C) 2014-2015 Ari Elbaz (elarifr) + * Copyright (C) 2013-2014 Florian Henry + * Copyright (C) 2014 Juanjo Menent s + * Copyright (C) 2016 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,6 +55,7 @@ $mesCasesCochees = GETPOST('toselect', 'array'); $search_societe = GETPOST('search_societe', 'alpha'); $search_lineid = GETPOST('search_lineid', 'int'); $search_ref = GETPOST('search_ref', 'alpha'); +$search_ref_supplier = GETPOST('search_ref_supplier', 'alpha'); $search_invoice = GETPOST('search_invoice', 'alpha'); $search_label = GETPOST('search_label', 'alpha'); $search_desc = GETPOST('search_desc', 'alpha'); @@ -137,6 +138,7 @@ if (empty($reshook)) { $search_societe = ''; $search_lineid = ''; $search_ref = ''; + $search_ref_supplier = ''; $search_invoice = ''; $search_label = ''; $search_desc = ''; @@ -290,6 +292,9 @@ if (strlen(trim($search_invoice))) { if (strlen(trim($search_ref))) { $sql .= natural_search("p.ref", $search_ref); } +if (strlen(trim($search_ref_supplier))) { + $sql .= natural_search("f.ref_supplier", $search_ref_supplier); +} if (strlen(trim($search_label))) { $sql .= natural_search(array("p.label", "f.libelle"), $search_label); } @@ -413,6 +418,9 @@ if ($result) { if ($search_ref) { $param .= '&search_ref='.urlencode($search_ref); } + if ($search_ref_supplier) { + $param .= '&search_ref_supplier='.urlencode($search_ref_supplier); + } if ($search_label) { $param .= '&search_label='.urlencode($search_label); } @@ -469,7 +477,8 @@ if ($result) { print ''; print ''; print ''; - //print ''; + print ''; + print ''; print ''; print '
'; print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); @@ -499,7 +508,8 @@ if ($result) { print ''; print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("RefSupplier", $_SERVER["PHP_SELF"], "f.ref_supplier", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); //print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); @@ -566,6 +576,7 @@ if ($result) { $facturefourn_static->ref = $objp->ref; $facturefourn_static->id = $objp->facid; $facturefourn_static->type = $objp->ftype; + $facturefourn_static->ref_supplier = $objp->ref_supplier; $facturefourn_static->label = $objp->invoice_label; $facturefourn_static->date = $db->jdate($objp->datef); @@ -625,15 +636,21 @@ if ($result) { // Ref Invoice print ''.$facturefourn_static->getNomUrl(1).''; - /*print ''; + // Ref supplier invoice + print ''; + print $objp->ref_supplier; + print ''; + + // Supplier invoice label + print ''; print $objp->invoice_label; print ''; - */ + // Date print ''.dol_print_date($facturefourn_static->date, 'day').''; // Ref Product - print ''; + print ''; if ($product_static->id > 0) { print $product_static->getNomUrl(1); } @@ -644,7 +661,7 @@ if ($result) { // Description print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($facturefourn_static_det->desc)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($facturefourn_static_det->desc, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $facturefourn_static_det->desc); print ''; diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index caf2bbe61d6..5bdb99330f6 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1719,8 +1719,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''.$langs->trans("MemberNature").''.$object->getmorphylib().''; print ''; - print ''; - // Company print ''.$langs->trans("Company").''.dol_escape_htmltag($object->company).''; @@ -1737,9 +1735,9 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if ($user->admin) { print ''; } - print 'trans("Hidden").''; + print ''.$langs->trans("Hidden").''; } - if ((!empty($object->pass) || !empty($object->pass_crypted)) && empty($object->user_id)) { + if (!empty($object->pass_indatabase) && empty($object->user_id)) { // Show warning only for old password still in clear (does not happen anymore) $langs->load("errors"); $htmltext = $langs->trans("WarningPasswordSetWithNoAccount"); print ' '.$form->textwithpicto('', $htmltext, 1, 'warning'); @@ -1778,7 +1776,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print '
'; print '
'; - print ''; + print '
'; // Tags / Categories if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { @@ -1853,18 +1851,6 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } print ''; - // VCard - /* - print ''; - */ - print "
'; - print $langs->trans("VCard").''; - print ''; - print img_picto($langs->trans("Download").' vcard', 'vcard.png', 'class="paddingrightonly"'); - print $langs->trans("Download"); - print img_picto($langs->trans("Download").' vcard', 'download', 'class="paddingleft"'); - print ''; - print '
\n"; print "
\n"; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index dbe882d2cd1..39b6eaa97d0 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -659,8 +659,7 @@ class Adherent extends CommonObject $nbrowsaffected = 0; $error = 0; - dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=". - $this->email); + dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email); // Clean parameters $this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname); @@ -693,7 +692,9 @@ class Adherent extends CommonObject $sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman' $sql .= ", login = ".($this->login ? "'".$this->db->escape($this->login)."'" : "null"); $sql .= ", societe = ".($this->company ? "'".$this->db->escape($this->company)."'" : ($this->societe ? "'".$this->db->escape($this->societe)."'" : "null")); - $sql .= ", fk_soc = ".($this->socid > 0 ? $this->db->escape($this->socid) : "null"); + if ($this->socid) { + $sql .= ", fk_soc = ".($this->socid > 0 ? $this->db->escape($this->socid) : "null"); // Must be modified only when creating from a third-party + } $sql .= ", address = ".($this->address ? "'".$this->db->escape($this->address)."'" : "null"); $sql .= ", zip = ".($this->zip ? "'".$this->db->escape($this->zip)."'" : "null"); $sql .= ", town = ".($this->town ? "'".$this->db->escape($this->town)."'" : "null"); @@ -713,9 +714,6 @@ class Adherent extends CommonObject $sql .= ", fk_adherent_type = ".$this->db->escape($this->typeid); $sql .= ", morphy = '".$this->db->escape($this->morphy)."'"; $sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null"); - if ($this->socid) { - $sql .= ", fk_soc = '".$this->db->escape($this->socid)."'"; // Must be modified only when creating from a third-party - } if ($this->datefin) { $sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription } @@ -1536,9 +1534,9 @@ class Adherent extends CommonObject * * @param int $date Date of effect of subscription * @param double $amount Amount of subscription (0 accepted for some members) - * @param int $accountid Id bank account - * @param string $operation Type of payment (if Id bank account provided). Example: 'CB', ... - * @param string $label Label operation (if Id bank account provided) + * @param int $accountid Id bank account. NOT USED. + * @param string $operation Code of payment mode (if Id bank account provided). Example: 'CB', ... NOT USED. + * @param string $label Label operation (if Id bank account provided). * @param string $num_chq Numero cheque (if Id bank account provided) * @param string $emetteur_nom Name of cheque writer * @param string $emetteur_banque Name of bank of cheque diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 18a91efaacd..cafc9338ae8 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -271,7 +271,7 @@ class AdherentType extends CommonObject $result = $this->db->query($sql); if ($result) { // Call trigger - $result = $this->call_trigger('ADHERENT_TYPE_DEL_MULTILANGS', $user); + $result = $this->call_trigger('MEMBER_TYPE_DEL_MULTILANGS', $user); if ($result < 0) { $this->error = $this->db->lasterror(); dol_syslog(get_class($this).'::delMultiLangs error='.$this->error, LOG_ERR); diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index 6fad266ea36..d30e851b9a2 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -358,7 +358,7 @@ class Members extends DolibarrApi if ($member->update(DolibarrApiAccess::$user) >= 0) { return $this->get($id); } else { - throw new RestException(500, $member->error); + throw new RestException(500, 'Error when updating member: '.$member->error); } } diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index be8f22f3c45..d95de755166 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -204,7 +204,7 @@ class MembersTypes extends DolibarrApi if ($membertype->update(DolibarrApiAccess::$user) >= 0) { return $this->get($id); } else { - throw new RestException(500, $membertype->error); + throw new RestException(500, 'Error when updating member type: '.$membertype->error); } } diff --git a/htdocs/adherents/class/api_subscriptions.class.php b/htdocs/adherents/class/api_subscriptions.class.php index 55b93df7663..f969017146b 100644 --- a/htdocs/adherents/class/api_subscriptions.class.php +++ b/htdocs/adherents/class/api_subscriptions.class.php @@ -159,7 +159,7 @@ class Subscriptions extends DolibarrApi $subscription->$field = $value; } if ($subscription->create(DolibarrApiAccess::$user) < 0) { - throw new RestException(500, 'Error when creating subscription', array_merge(array($subscription->error), $subscription->errors)); + throw new RestException(500, 'Error when creating contribution', array_merge(array($subscription->error), $subscription->errors)); } return $subscription->id; } @@ -193,7 +193,7 @@ class Subscriptions extends DolibarrApi if ($subscription->update(DolibarrApiAccess::$user) > 0) { return $this->get($id); } else { - throw new RestException(500, $subscription->error); + throw new RestException(500, 'Error when updating contribution: '.$subscription->error); } } diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index 885c8981d93..9aef78174de 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -358,7 +358,7 @@ class Subscription extends CommonObject $result = $member->update_end_date($user); if ($this->fk_bank > 0 && is_object($accountline) && $accountline->id > 0) { // If we found bank account line (this means this->fk_bank defined) - $result = $accountline->delete($user); // Return false if refused because line is conciliated + $result = $accountline->delete($user); // Return false if refused because line is reconciled if ($result > 0) { $this->db->commit(); return 1; diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php index 8b59c0d3ca4..2b0c295afbd 100644 --- a/htdocs/adherents/index.php +++ b/htdocs/adherents/index.php @@ -177,8 +177,8 @@ if ($conf->use_javascript_ajax) { $i = 0; foreach ($AdherentType as $key => $adhtype) { $dataval['draft'][] = array($i, isset($MembersToValidate[$key]) ? $MembersToValidate[$key] : 0); - $dataval['notuptodate'][] = array($i, isset($MembersValidated[$key]) ? $MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) : 0); $dataval['uptodate'][] = array($i, isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0); + $dataval['notuptodate'][] = array($i, isset($MembersValidated[$key]) ? $MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) : 0); $dataval['excluded'][] = array($i, isset($MembersExcluded[$key]) ? $MembersExcluded[$key] : 0); $dataval['resiliated'][] = array($i, isset($MembersResiliated[$key]) ? $MembersResiliated[$key] : 0); @@ -191,18 +191,18 @@ if ($conf->use_javascript_ajax) { } $total = $SumToValidate + $SumValidated + $SumUpToDate + $SumExcluded + $SumResiliated; $dataseries = array(); - $dataseries[] = array($langs->transnoentitiesnoconv("OutOfDate"), round($SumValidated)); + $dataseries[] = array($langs->transnoentitiesnoconv("MembersStatusToValid"), round($SumToValidate)); // Draft, not yet validated $dataseries[] = array($langs->transnoentitiesnoconv("UpToDate"), round($SumUpToDate)); + $dataseries[] = array($langs->transnoentitiesnoconv("OutOfDate"), round($SumValidated)); $dataseries[] = array($langs->transnoentitiesnoconv("MembersStatusExcluded"), round($SumExcluded)); $dataseries[] = array($langs->transnoentitiesnoconv("MembersStatusResiliated"), round($SumResiliated)); - $dataseries[] = array($langs->transnoentitiesnoconv("MembersStatusToValid"), round($SumToValidate)); include DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->SetDataColor(array($badgeStatus1, $badgeStatus4, '-'.$badgeStatus8, $badgeStatus6, '-'.$badgeStatus0)); + $dolgraph->SetDataColor(array('-'.$badgeStatus0, $badgeStatus4, '-'.$badgeStatus1, '-'.$badgeStatus8, $badgeStatus6)); $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 322c08bd77c..e58def3f481 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -307,7 +307,7 @@ $memberstatic = new Adherent($db); $now = dol_now(); -if (!empty($search_categ) || !empty($catid)) { +if ((!empty($search_categ) && $search_categ > 0) || !empty($catid)) { $sql = "SELECT DISTINCT"; } else { $sql = "SELECT"; @@ -336,7 +336,7 @@ $sql .= " FROM ".MAIN_DB_PREFIX."adherent as d"; if (!empty($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (d.rowid = ef.fk_object)"; } -if (!empty($search_categ) || !empty($catid)) { +if ((!empty($search_categ) && $search_categ > 0) || !empty($catid)) { // We need this table joined to the select in order to filter by categ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_member as cm ON d.rowid = cm.fk_member"; } @@ -505,7 +505,7 @@ if (GETPOSTISSET("search_status")) { if ($search_type > 0) { $membertype = new AdherentType($db); - $result = $membertype->fetch(GETPOST("type", 'int')); + $result = $membertype->fetch($search_type); $titre .= " (".$membertype->label.")"; } @@ -540,7 +540,7 @@ if ($search_login) { if ($search_email) { $param .= "&search_email=".urlencode($search_email); } -if ($search_categ) { +if ($search_categ > 0 || $search_categ == -2) { $param .= "&search_categ=".urlencode($search_categ); } if ($search_company) { @@ -573,7 +573,7 @@ if ($search_phone_mobile != '') { if ($search_filter && $search_filter != '-1') { $param .= "&search_filter=".urlencode($search_filter); } -if ($search_status != "" && $search_status != Adherent::STATUS_DRAFT) { +if ($search_status != "" && $search_status != -3) { $param .= "&search_status=".urlencode($search_status); } if ($search_type > 0) { @@ -767,7 +767,7 @@ if (!empty($arrayfields['d.email']['checked'])) { } // End of subscription date if (!empty($arrayfields['d.datefin']['checked'])) { - print ''; + print ''; $selectarray = array('-1'=>'', 'withoutsubscription'=>$langs->trans("WithoutSubscription"), 'uptodate'=>$langs->trans("UpToDate"), 'outofdate'=>$langs->trans("OutOfDate")); print $form->selectarray('search_filter', $selectarray, $search_filter); print ''; @@ -858,7 +858,7 @@ if (!empty($arrayfields['state.nom']['checked'])) { print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['country.code_iso']['checked'])) { - print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, '', $sortfield, $sortorder, 'center '); } if (!empty($arrayfields['d.phone']['checked'])) { print_liste_field_titre($arrayfields['d.phone']['label'], $_SERVER["PHP_SELF"], 'd.phone', '', $param, '', $sortfield, $sortorder); @@ -873,7 +873,7 @@ if (!empty($arrayfields['d.email']['checked'])) { print_liste_field_titre($arrayfields['d.email']['label'], $_SERVER["PHP_SELF"], 'd.email', '', $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['d.datefin']['checked'])) { - print_liste_field_titre($arrayfields['d.datefin']['label'], $_SERVER["PHP_SELF"], 'd.datefin', '', $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['d.datefin']['label'], $_SERVER["PHP_SELF"], 'd.datefin', '', $param, '', $sortfield, $sortorder, 'center '); } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; @@ -1110,16 +1110,14 @@ while ($i < min($num, $limit)) { // End of subscription date $datefin = $db->jdate($obj->datefin); if (!empty($arrayfields['d.datefin']['checked'])) { + print ''; if ($datefin) { - print ''; print dol_print_date($datefin, 'day'); if ($memberstatic->hasDelay()) { $textlate = ' ('.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24) >= 0 ? '+' : '').ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24).' '.$langs->trans("days").')'; print " ".img_warning($langs->trans("SubscriptionLate").$textlate); } - print ''; } else { - print ''; if (!empty($obj->subscription)) { print $langs->trans("SubscriptionNotReceived"); if ($obj->statut > 0) { @@ -1128,8 +1126,8 @@ while ($i < min($num, $limit)) { } else { print ' '; } - print ''; } + print ''; } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 5f578869e6e..7dccaa90eda 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -501,7 +501,7 @@ if ($rowid > 0) { // Login if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) { - print ''.$langs->trans("Login").' / '.$langs->trans("Id").''.$object->login.' '; + print ''.$langs->trans("Login").' / '.$langs->trans("Id").''.dol_escape_htmltag($object->login).''; } // Type @@ -512,25 +512,24 @@ if ($rowid > 0) { print ''; // Company - print ''.$langs->trans("Company").''.$object->company.''; + print ''.$langs->trans("Company").''.dol_escape_htmltag($object->company).''; // Civility - print ''.$langs->trans("UserTitle").''.$object->getCivilityLabel().' '; + print ''.$langs->trans("UserTitle").''.$object->getCivilityLabel().''; print ''; // Password if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) { - print ''.$langs->trans("Password").''.preg_replace('/./i', '*', $object->pass); + print ''.$langs->trans("Password").''; if ($object->pass) { print preg_replace('/./i', '*', $object->pass); } else { if ($user->admin) { - print $langs->trans("Crypted").': '.$object->pass_indatabase_crypted; - } else { - print $langs->trans("Hidden"); + print ''; } + print ''.$langs->trans("Hidden").''; } - if ((!empty($object->pass) || !empty($object->pass_crypted)) && empty($object->user_id)) { + if (!empty($object->pass_indatabase) && empty($object->user_id)) { // Show warning only for old password still in clear (does not happen anymore) $langs->load("errors"); $htmltext = $langs->trans("WarningPasswordSetWithNoAccount"); print ' '.$form->textwithpicto('', $htmltext, 1, 'warning'); @@ -546,15 +545,17 @@ if ($rowid > 0) { print " ".img_warning($langs->trans("Late")); } } else { - if (!$adht->subscription) { + if ($object->need_subscription == 0) { + print $langs->trans("SubscriptionNotNeeded"); + } elseif (!$adht->subscription) { print $langs->trans("SubscriptionNotRecorded"); - if ($object->statut > 0) { - print " ".img_warning($langs->trans("Late")); // Display a delay picto only if it is not a draft and is not canceled + if (Adherent::STATUS_VALIDATED == $object->statut) { + print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft, not excluded and not resiliated } } else { print $langs->trans("SubscriptionNotReceived"); - if ($object->statut > 0) { - print " ".img_warning($langs->trans("Late")); // Display a delay picto only if it is not a draft and is not canceled + if (Adherent::STATUS_VALIDATED == $object->statut) { + print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft, not excluded and not resiliated } } } @@ -563,18 +564,13 @@ if ($rowid > 0) { print ''; print '
'; - print '
'; + print '
'; print '
'; + print ''; - // Birthday - print ''; - - // Public - print ''; - - // Categories + // Tags / Categories if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { print ''; print ''; } + // Birth Date + print ''; + + // Public + print ''; + // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; @@ -663,8 +665,6 @@ if ($rowid > 0) { print dol_get_fiche_end(); - print ''; - /* * Action bar diff --git a/htdocs/adherents/tpl/linkedobjectblock.tpl.php b/htdocs/adherents/tpl/linkedobjectblock.tpl.php index 3acb14a4cdb..5928b706a8e 100644 --- a/htdocs/adherents/tpl/linkedobjectblock.tpl.php +++ b/htdocs/adherents/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -echo "\n"; +echo "\n"; global $user; diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 76dd0617cee..bcd6c99afbf 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -125,6 +125,7 @@ if ($action == 'add' && $user->rights->adherent->configurer) { $object->duration_value = $duration_value; $object->duration_unit = $duration_unit; $object->note = trim($comment); + $object->note_public = trim($comment); $object->mail_valid = trim($mail_valid); $object->vote = (int) $vote; @@ -176,6 +177,7 @@ if ($action == 'update' && $user->rights->adherent->configurer) { $object->duration_value = $duration_value; $object->duration_unit = $duration_unit; $object->note = trim($comment); + $object->note_public = trim($comment); $object->mail_valid = trim($mail_valid); $object->vote = (boolean) trim($vote); @@ -358,7 +360,7 @@ if ($action == 'create') { print ''; print ''; // Morphy @@ -375,7 +377,7 @@ if ($action == 'create') { print ''; print ''; print ''; @@ -783,7 +785,7 @@ if ($rowid > 0) { print ''; print ''; // Morphy diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 25495e2de43..c3cb92dba8d 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -369,7 +369,7 @@ $form = new Form($db); $formother = new FormOther($db); $formcompany = new FormCompany($db); -$countrynotdefined = ''.$langs->trans("ErrorSetACountryFirst").' ('.$langs->trans("SeeAbove").')'; +$countrynotdefined = ''.$langs->trans("ErrorSetACountryFirst").' ('.$langs->trans("SeeAbove").')'; print load_fiche_titre($langs->trans("CompanyFoundation"), '', 'title_setup'); @@ -410,10 +410,10 @@ print ''."\n"; // Zip -print ''."\n"; -print ''."\n"; // Country diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 4de4c682483..cd8ab4c1836 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -8,11 +8,11 @@ * Copyright (C) 2011 Remy Younes * Copyright (C) 2012-2015 Marcos García * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2011-2021 Alexandre Spangaro + * Copyright (C) 2011-2022 Alexandre Spangaro * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud * Copyright (C) 2019-2020 Frédéric France - * Copyright (C) 2020 Open-Dsi + * Copyright (C) 2020-2022 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -94,13 +94,13 @@ if (!GETPOSTISSET('search_country_id') && $search_country_id == '' && ($id == 2 $search_code = GETPOST('search_code', 'alpha'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('admin')); +$hookmanager->initHooks(array('admin', 'dictionaryadmin')); // This page is a generic page to edit dictionaries // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder = array(9, 15, 30, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 6, 24, 0, 29, 0, 33, 34, 32, 28, 17, 35, 36, 0, 10, 23, 12, 13, 7, 0, 14, 0, 22, 20, 18, 21, 41, 0, 37, 42, 0, 43, 0, 25, 0); +$taborder = array(9, 15, 30, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 6, 24, 0, 29, 0, 33, 34, 32, 28, 17, 35, 36, 0, 10, 23, 12, 13, 7, 0, 14, 0, 22, 20, 18, 21, 41, 0, 37, 42, 0, 43, 0, 25, 0, 44, 0); // Name of SQL tables of dictionaries $tabname = array(); @@ -147,6 +147,7 @@ $tabname[40] = MAIN_DB_PREFIX."c_stcommcontact"; $tabname[41] = MAIN_DB_PREFIX."c_transport_mode"; $tabname[42] = MAIN_DB_PREFIX."c_product_nature"; $tabname[43] = MAIN_DB_PREFIX."c_productbatch_qcstatus"; +$tabname[44] = MAIN_DB_PREFIX."c_asset_disposal_type"; // Dictionary labels $tablib = array(); @@ -193,13 +194,14 @@ $tablib[40] = "DictionaryProspectContactStatus"; $tablib[41] = "DictionaryTransportMode"; $tablib[42] = "DictionaryProductNature"; $tablib[43] = "DictionaryBatchStatus"; +$tablib[44] = "DictionaryAssetDisposalType"; // Requests to extract data $tabsql = array(); $tabsql[1] = "SELECT f.rowid as rowid, f.code, f.libelle, c.code as country_code, c.label as country, f.active FROM ".MAIN_DB_PREFIX."c_forme_juridique as f, ".MAIN_DB_PREFIX."c_country as c WHERE f.fk_pays=c.rowid"; $tabsql[2] = "SELECT d.rowid as rowid, d.code_departement as code, d.nom as libelle, d.fk_region as region_id, r.nom as region, c.code as country_code, c.label as country, d.active FROM ".MAIN_DB_PREFIX."c_departements as d, ".MAIN_DB_PREFIX."c_regions as r, ".MAIN_DB_PREFIX."c_country as c WHERE d.fk_region=r.code_region and r.fk_pays=c.rowid and r.active=1 and c.active=1"; $tabsql[3] = "SELECT r.rowid as rowid, r.code_region as state_code, r.nom as libelle, r.fk_pays as country_id, c.code as country_code, c.label as country, r.active FROM ".MAIN_DB_PREFIX."c_regions as r, ".MAIN_DB_PREFIX."c_country as c WHERE r.fk_pays=c.rowid and c.active=1"; -$tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite FROM ".MAIN_DB_PREFIX."c_country AS c"; +$tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite, c.eec FROM ".MAIN_DB_PREFIX."c_country AS c"; $tabsql[5] = "SELECT c.rowid as rowid, c.code as code, c.label, c.active FROM ".MAIN_DB_PREFIX."c_civility AS c"; $tabsql[6] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.type, a.active, a.module, a.color, a.position FROM ".MAIN_DB_PREFIX."c_actioncomm AS a"; $tabsql[7] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.accountancy_code as accountancy_code, c.code as country_code, c.label as country, a.fk_pays as country_id, a.active FROM ".MAIN_DB_PREFIX."c_chargesociales AS a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_pays=c.rowid and c.active=1"; @@ -216,7 +218,7 @@ $tabsql[17] = "SELECT id as rowid, code, label, accountancy_code, active FR $tabsql[18] = "SELECT rowid as rowid, code, libelle, tracking, active FROM ".MAIN_DB_PREFIX."c_shipment_mode"; $tabsql[19] = "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_effectif"; $tabsql[20] = "SELECT rowid as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_input_method"; -$tabsql[21] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.position FROM ".MAIN_DB_PREFIX."c_availability AS c"; +$tabsql[21] = "SELECT c.rowid as rowid, c.code, c.label, c.type_duration, c.qty, c.active, c.position FROM ".MAIN_DB_PREFIX."c_availability AS c"; $tabsql[22] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_input_reason"; $tabsql[23] = "SELECT t.rowid as rowid, t.taux, t.revenuestamp_type, c.label as country, c.code as country_code, t.fk_pays as country_id, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_revenuestamp as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[24] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_type_resource"; @@ -239,6 +241,7 @@ $tabsql[40] = "SELECT id as rowid, code, libelle, picto, active FROM ".MAIN $tabsql[41] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_transport_mode"; $tabsql[42] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_product_nature"; $tabsql[43] = "SELECT rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_productbatch_qcstatus"; +$tabsql[44] = "SELECT rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_asset_disposal_type"; // Criteria to sort dictionaries $tabsqlsort = array(); @@ -262,7 +265,7 @@ $tabsqlsort[17] = "code ASC"; $tabsqlsort[18] = "code ASC, libelle ASC"; $tabsqlsort[19] = "id ASC"; $tabsqlsort[20] = "code ASC, libelle ASC"; -$tabsqlsort[21] = "code ASC, label ASC, position ASC"; +$tabsqlsort[21] = "code ASC, label ASC, position ASC, type_duration ASC, qty ASC"; $tabsqlsort[22] = "code ASC, label ASC"; $tabsqlsort[23] = "country ASC, taux ASC"; $tabsqlsort[24] = "code ASC, label ASC"; @@ -285,6 +288,7 @@ $tabsqlsort[40] = "code ASC"; $tabsqlsort[41] = "code ASC"; $tabsqlsort[42] = "code ASC"; $tabsqlsort[43] = "code ASC"; +$tabsqlsort[44] = "code ASC"; // Field names in select result for dictionary display $tabfield = array(); @@ -308,7 +312,7 @@ $tabfield[17] = "code,label,accountancy_code"; $tabfield[18] = "code,libelle,tracking"; $tabfield[19] = "code,libelle"; $tabfield[20] = "code,libelle"; -$tabfield[21] = "code,label,position"; +$tabfield[21] = "code,label,qty,type_duration,position"; $tabfield[22] = "code,label"; $tabfield[23] = "country_id,country,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[24] = "code,label"; @@ -331,6 +335,7 @@ $tabfield[40] = "code,libelle,picto"; $tabfield[41] = "code,label"; $tabfield[42] = "code,label"; $tabfield[43] = "code,label"; +$tabfield[44] = "code,label"; // Edit field names for editing a record $tabfieldvalue = array(); @@ -354,7 +359,7 @@ $tabfieldvalue[17] = "code,label,accountancy_code"; $tabfieldvalue[18] = "code,libelle,tracking"; $tabfieldvalue[19] = "code,libelle"; $tabfieldvalue[20] = "code,libelle"; -$tabfieldvalue[21] = "code,label,position"; +$tabfieldvalue[21] = "code,label,qty,type_duration,position"; $tabfieldvalue[22] = "code,label"; $tabfieldvalue[23] = "country,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[24] = "code,label"; @@ -377,6 +382,7 @@ $tabfieldvalue[40] = "code,libelle,picto"; $tabfieldvalue[41] = "code,label"; $tabfieldvalue[42] = "code,label"; $tabfieldvalue[43] = "code,label"; +$tabfieldvalue[44] = "code,label"; // Field names in the table for inserting a record $tabfieldinsert = array(); @@ -400,7 +406,7 @@ $tabfieldinsert[17] = "code,label,accountancy_code"; $tabfieldinsert[18] = "code,libelle,tracking"; $tabfieldinsert[19] = "code,libelle"; $tabfieldinsert[20] = "code,libelle"; -$tabfieldinsert[21] = "code,label,position"; +$tabfieldinsert[21] = "code,label,qty,type_duration,position"; $tabfieldinsert[22] = "code,label"; $tabfieldinsert[23] = "fk_pays,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[24] = "code,label"; @@ -424,6 +430,7 @@ $tabfieldinsert[40] = "code,libelle,picto"; $tabfieldinsert[41] = "code,label"; $tabfieldinsert[42] = "code,label"; $tabfieldinsert[43] = "code,label"; +$tabfieldinsert[44] = "code,label"; // Rowid name of field depending if field is autoincrement on or off.. // Use "" if id field is "rowid" and has autoincrement on @@ -472,6 +479,7 @@ $tabrowid[40] = "id"; $tabrowid[41] = ""; $tabrowid[42] = "rowid"; $tabrowid[43] = "rowid"; +$tabrowid[44] = "rowid"; // Condition to show dictionary in setup page $tabcond = array(); @@ -518,6 +526,7 @@ $tabcond[40] = (!empty($conf->societe->enabled) && !empty($conf->global->THIRDPA $tabcond[41] = !empty($conf->intracommreport->enabled); $tabcond[42] = !empty($conf->product->enabled); $tabcond[43] = !empty($conf->product->enabled) && !empty($conf->productbatch->enabled) && $conf->global->MAIN_FEATURES_LEVEL >= 2; +$tabcond[44] = !empty($conf->asset->enabled); // List of help for fields $tabhelp = array(); @@ -557,13 +566,14 @@ $tabhelp[33] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[34] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[35] = array(); $tabhelp[36] = array('range_ik'=>$langs->trans('PrevRangeToThisRange')); -$tabhelp[37] = array('code'=>$langs->trans("EnterAnyCode"), 'unit_type' => $langs->trans('MeasuringUnitTypeDesc'), 'scale' => $langs->trans('MeasuringScaleDesc')); +$tabhelp[37] = array('code'=>$langs->trans("EnterAnyCode"), 'unit_type' => $langs->trans('Measuringtype_durationDesc'), 'scale' => $langs->trans('MeasuringScaleDesc')); $tabhelp[38] = array('code'=>$langs->trans("EnterAnyCode"), 'url' => $langs->trans('UrlSocialNetworksDesc'), 'icon' => $langs->trans('FafaIconSocialNetworksDesc')); $tabhelp[39] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[40] = array('code'=>$langs->trans("EnterAnyCode"), 'picto'=>$langs->trans("PictoHelp")); $tabhelp[41] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[42] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[43] = array('code'=>$langs->trans("EnterAnyCode")); +$tabhelp[44] = array('code'=>$langs->trans("EnterAnyCode")); // Table to store complete informations (will replace all other table). Key is table name. $tabcomplete = array( @@ -609,6 +619,7 @@ $tabcomplete = array( 'c_stcommcontact'=>array('picto'=>'company'), 'c_product_nature'=>array('picto'=>'product'), 'c_productbatch_qcstatus'=>array('picto'=>'lot'), + 'c_asset_disposal_type'=>array('picto'=>'asset'), ); @@ -658,8 +669,8 @@ if ($id == 11) { asort($elementList); $sourceList = array( - 'internal' => $langs->trans('Internal'), - 'external' => $langs->trans('External') + 'internal' => $langs->trans('Internal'), + 'external' => $langs->trans('External') ); } @@ -683,406 +694,470 @@ if ($id == 10) { * Actions */ +$parameters = array( + 'id' =>$id, + 'rowid' =>$rowid, + 'code' =>$code, + 'confirm' =>$confirm, + 'entity' =>$entity, + 'taborder' =>$taborder, + 'tabname' =>$tabname, + 'tablib' =>$tablib, + 'tabsql' =>$tabsql, + 'tabsqlsort' =>$tabsqlsort, + 'tabfield' =>$tabfield, + 'tabfieldvalue' =>$tabfieldvalue, + 'tabfieldinsert'=>$tabfieldinsert, + 'tabrowid' =>$tabrowid, + 'tabcond' =>$tabcond, + 'tabhelp' =>$tabhelp, + 'tabcomplete' =>$tabcomplete +); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha')) { $search_country_id = ''; $search_code = ''; } -// Actions add or modify an entry into a dictionary -if (GETPOST('actionadd') || GETPOST('actionmodify')) { - $listfield = explode(',', str_replace(' ', '', $tabfield[$id])); - $listfieldinsert = explode(',', $tabfieldinsert[$id]); - $listfieldmodify = explode(',', $tabfieldinsert[$id]); - $listfieldvalue = explode(',', $tabfieldvalue[$id]); +if (empty($reshook)) { + // Actions add or modify an entry into a dictionary + if (GETPOST('actionadd') || GETPOST('actionmodify')) { + $listfield = explode(',', str_replace(' ', '', $tabfield[$id])); + $listfieldinsert = explode(',', $tabfieldinsert[$id]); + $listfieldmodify = explode(',', $tabfieldinsert[$id]); + $listfieldvalue = explode(',', $tabfieldvalue[$id]); - // Check that all mandatory fields are filled - $ok = 1; - foreach ($listfield as $f => $value) { - // Discard check of mandatory fields for country for some tables - if ($value == 'country_id' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryVAT', 'DictionaryRegion', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp', 'DictionaryAccountancysystem', 'DictionaryAccountancyCategory'))) { - continue; // For some pages, country is not mandatory + // Check that all mandatory fields are filled + $ok = 1; + foreach ($listfield as $f => $value) { + // Discard check of mandatory fields for country for some tables + if ($value == 'country_id' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryVAT', 'DictionaryRegion', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp', 'DictionaryAccountancysystem', 'DictionaryAccountancyCategory'))) { + continue; // For some pages, country is not mandatory + } + if ($value == 'country' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryCanton', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp'))) { + continue; // For some pages, country is not mandatory + } + // Discard check of mandatory fiedls for other fields + if ($value == 'localtax1' && !GETPOST('localtax1_type')) { + continue; + } + if ($value == 'localtax2' && !GETPOST('localtax2_type')) { + continue; + } + if ($value == 'color' && !GETPOST('color')) { + continue; + } + if ($value == 'formula' && !GETPOST('formula')) { + continue; + } + if ($value == 'dayrule' && !GETPOST('dayrule')) { + continue; + } + if ($value == 'sortorder') { + continue; // For a column name 'sortorder', we use the field name 'position' + } + if ((!GETPOSTISSET($value) || GETPOST($value) == '') + && (!in_array($value, array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking', 'picto')) // Fields that are not mandatory + && ($id != 10 || ($value != 'code' && $value != 'note')) // Field code and note is not mandatory for dictionary table 10 + ) + ) { + $ok = 0; + $fieldnamekey = $value; + // We take translate key of field + if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) { + $fieldnamekey = 'Label'; + } + if ($fieldnamekey == 'libelle_facture') { + $fieldnamekey = 'LabelOnDocuments'; + } + if ($fieldnamekey == 'nbjour') { + $fieldnamekey = 'NbOfDays'; + } + if ($fieldnamekey == 'decalage') { + $fieldnamekey = 'Offset'; + } + if ($fieldnamekey == 'module') { + $fieldnamekey = 'Module'; + } + if ($fieldnamekey == 'code') { + $fieldnamekey = 'Code'; + } + if ($fieldnamekey == 'note') { + $fieldnamekey = 'Note'; + } + if ($fieldnamekey == 'taux') { + $fieldnamekey = 'Rate'; + } + if ($fieldnamekey == 'type') { + $fieldnamekey = 'Type'; + } + if ($fieldnamekey == 'position') { + $fieldnamekey = 'Position'; + } + if ($fieldnamekey == 'unicode') { + $fieldnamekey = 'Unicode'; + } + if ($fieldnamekey == 'deductible') { + $fieldnamekey = 'Deductible'; + } + if ($fieldnamekey == 'sortorder') { + $fieldnamekey = 'SortOrder'; + } + if ($fieldnamekey == 'category_type') { + $fieldnamekey = 'Calculated'; + } + if ($fieldnamekey == 'revenuestamp_type') { + $fieldnamekey = 'TypeOfRevenueStamp'; + } + if ($fieldnamekey == 'use_default') { + $fieldnamekey = 'UseByDefault'; + } + + setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); + } } - if ($value == 'country' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryCanton', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp'))) { - continue; // For some pages, country is not mandatory - } - // Discard check of mandatory fiedls for other fields - if ($value == 'localtax1' && !GETPOST('localtax1_type')) { - continue; - } - if ($value == 'localtax2' && !GETPOST('localtax2_type')) { - continue; - } - if ($value == 'color' && !GETPOST('color')) { - continue; - } - if ($value == 'formula' && !GETPOST('formula')) { - continue; - } - if ($value == 'dayrule' && !GETPOST('dayrule')) { - continue; - } - if ($value == 'sortorder') { - continue; // For a column name 'sortorder', we use the field name 'position' - } - if ((!GETPOSTISSET($value) || GETPOST($value) == '') - && (!in_array($value, array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking', 'picto')) // Fields that are not mandatory - && ($id != 10 || ($value != 'code' && $value != 'note')) // Field code and note is not mandatory for dictionary table 10 - ) - ) { + // Other checks + if (GETPOST('actionadd') && $tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && GETPOSTISSET("type") && in_array(GETPOST("type"), array('system', 'systemauto'))) { $ok = 0; - $fieldnamekey = $value; - // We take translate key of field - if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) { - $fieldnamekey = 'Label'; - } - if ($fieldnamekey == 'libelle_facture') { - $fieldnamekey = 'LabelOnDocuments'; - } - if ($fieldnamekey == 'nbjour') { - $fieldnamekey = 'NbOfDays'; - } - if ($fieldnamekey == 'decalage') { - $fieldnamekey = 'Offset'; - } - if ($fieldnamekey == 'module') { - $fieldnamekey = 'Module'; - } - if ($fieldnamekey == 'code') { - $fieldnamekey = 'Code'; - } - if ($fieldnamekey == 'note') { - $fieldnamekey = 'Note'; - } - if ($fieldnamekey == 'taux') { - $fieldnamekey = 'Rate'; - } - if ($fieldnamekey == 'type') { - $fieldnamekey = 'Type'; - } - if ($fieldnamekey == 'position') { - $fieldnamekey = 'Position'; - } - if ($fieldnamekey == 'unicode') { - $fieldnamekey = 'Unicode'; - } - if ($fieldnamekey == 'deductible') { - $fieldnamekey = 'Deductible'; - } - if ($fieldnamekey == 'sortorder') { - $fieldnamekey = 'SortOrder'; - } - if ($fieldnamekey == 'category_type') { - $fieldnamekey = 'Calculated'; - } - if ($fieldnamekey == 'revenuestamp_type') { - $fieldnamekey = 'TypeOfRevenueStamp'; - } - if ($fieldnamekey == 'use_default') { - $fieldnamekey = 'UseByDefault'; - } - - setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); + setEventMessages($langs->transnoentities('ErrorReservedTypeSystemSystemAuto'), null, 'errors'); } - } - // Other checks - if (GETPOST('actionadd') && $tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && GETPOSTISSET("type") && in_array(GETPOST("type"), array('system', 'systemauto'))) { - $ok = 0; - setEventMessages($langs->transnoentities('ErrorReservedTypeSystemSystemAuto'), null, 'errors'); - } - if (GETPOSTISSET("code")) { - if (GETPOST("code") == '0') { + if (GETPOSTISSET("code")) { + if (GETPOST("code") == '0') { + $ok = 0; + setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); + } + } + if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) { + if (in_array($tablib[$id], array('DictionaryCompanyType', 'DictionaryHolidayTypes'))) { // Field country is no mandatory for such dictionaries + $_POST["country"] = ''; + } else { + $ok = 0; + setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Country")), null, 'errors'); + } + } + if (($id == 3 || $id == 42) && !is_numeric(GETPOST("code"))) { $ok = 0; - setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); + setEventMessages($langs->transnoentities("ErrorFieldMustBeANumeric", $langs->transnoentities("Code")), null, 'errors'); } - } - if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) { - if (in_array($tablib[$id], array('DictionaryCompanyType', 'DictionaryHolidayTypes'))) { // Field country is no mandatory for such dictionaries - $_POST["country"] = ''; - } else { - $ok = 0; - setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Country")), null, 'errors'); + + // Clean some parameters + if ((GETPOST("localtax1_type") || (GETPOST('localtax1_type') == '0')) && !GETPOST("localtax1")) { + $_POST["localtax1"] = '0'; // If empty, we force to 0 + } + if ((GETPOST("localtax2_type") || (GETPOST('localtax2_type') == '0')) && !GETPOST("localtax2")) { + $_POST["localtax2"] = '0'; // If empty, we force to 0 + } + if (GETPOST("accountancy_code") <= 0) { + $_POST["accountancy_code"] = ''; // If empty, we force to null + } + if (GETPOST("accountancy_code_sell") <= 0) { + $_POST["accountancy_code_sell"] = ''; // If empty, we force to null + } + if (GETPOST("accountancy_code_buy") <= 0) { + $_POST["accountancy_code_buy"] = ''; // If empty, we force to null + } + if ($id == 10 && GETPOSTISSET("code")) { // Spaces are not allowed into code for tax dictionary + $_POST["code"] = preg_replace('/[^a-zA-Z0-9\-\+]/', '', GETPOST("code")); } - } - if (($id == 3 || $id == 42) && !is_numeric(GETPOST("code"))) { - $ok = 0; - setEventMessages($langs->transnoentities("ErrorFieldMustBeANumeric", $langs->transnoentities("Code")), null, 'errors'); - } - // Clean some parameters - if ((GETPOST("localtax1_type") || (GETPOST('localtax1_type') == '0')) && !GETPOST("localtax1")) { - $_POST["localtax1"] = '0'; // If empty, we force to 0 - } - if ((GETPOST("localtax2_type") || (GETPOST('localtax2_type') == '0')) && !GETPOST("localtax2")) { - $_POST["localtax2"] = '0'; // If empty, we force to 0 - } - if (GETPOST("accountancy_code") <= 0) { - $_POST["accountancy_code"] = ''; // If empty, we force to null - } - if (GETPOST("accountancy_code_sell") <= 0) { - $_POST["accountancy_code_sell"] = ''; // If empty, we force to null - } - if (GETPOST("accountancy_code_buy") <= 0) { - $_POST["accountancy_code_buy"] = ''; // If empty, we force to null - } - if ($id == 10 && GETPOSTISSET("code")) { // Spaces are not allowed into code for tax dictionary - $_POST["code"] = preg_replace('/[^a-zA-Z0-9\-\+]/', '', GETPOST("code")); - } + // If check ok and action add, add the line + if ($ok && GETPOST('actionadd')) { + if ($tabrowid[$id]) { + // Get free id for insert + $newid = 0; + $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; + $result = $db->query($sql); + if ($result) { + $obj = $db->fetch_object($result); + $newid = ($obj->newid + 1); + } else { + dol_print_error($db); + } + } - // If check ok and action add, add the line - if ($ok && GETPOST('actionadd')) { - if ($tabrowid[$id]) { - // Get free id for insert - $newid = 0; - $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; - $result = $db->query($sql); - if ($result) { - $obj = $db->fetch_object($result); - $newid = ($obj->newid + 1); + // Add new entry + $sql = "INSERT INTO ".$tabname[$id]." ("; + // List of fields + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) { + $sql .= $tabrowid[$id].","; + } + $sql .= $tabfieldinsert[$id]; + $sql .= ",active)"; + $sql .= " VALUES("; + + // List of values + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) { + $sql .= $newid.","; + } + $i = 0; + foreach ($listfieldinsert as $f => $value) { + $keycode = $listfieldvalue[$i]; + if (empty($keycode)) { + $keycode = $value; + } + + if ($value == 'price' || preg_match('/^amount/i', $value)) { + $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); + } elseif ($value == 'taux' || $value == 'localtax1') { + $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z + } elseif ($value == 'entity') { + $_POST[$keycode] = getEntity($tabname[$id]); + } + + if ($i) { + $sql .= ","; + } + + if ($keycode == 'sortorder') { // For column name 'sortorder', we use the field name 'position' + $sql .= (int) GETPOST('position', 'int'); + } elseif (GETPOST($keycode) == '' && !($keycode == 'code' && $id == 10)) { + $sql .= "null"; // For vat, we want/accept code = '' + } elseif ($keycode == 'content') { + $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; + } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { + $sql .= (int) GETPOST($keycode, 'int'); + } else { + $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + } + + $i++; + } + $sql .= ",1)"; + + dol_syslog("actionadd", LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) { // Add is ok + setEventMessages($langs->transnoentities("RecordCreatedSuccessfully"), null, 'mesgs'); + + // Clean $_POST array, we keep only id of dictionary + if ($id == 10 && GETPOST('country', 'int') > 0) { + $search_country_id = GETPOST('country', 'int'); + } + $_POST = array('id'=>$id); } else { - dol_print_error($db); + if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); + } else { + dol_print_error($db); + } } } - // Add new entry - $sql = "INSERT INTO ".$tabname[$id]." ("; - // List of fields - if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) { - $sql .= $tabrowid[$id].","; - } - $sql .= $tabfieldinsert[$id]; - $sql .= ",active)"; - $sql .= " VALUES("; - - // List of values - if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) { - $sql .= $newid.","; - } - $i = 0; - foreach ($listfieldinsert as $f => $value) { - $keycode = $listfieldvalue[$i]; - if (empty($keycode)) { - $keycode = $value; - } - - if ($value == 'price' || preg_match('/^amount/i', $value)) { - $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); - } elseif ($value == 'taux' || $value == 'localtax1') { - $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z - } elseif ($value == 'entity') { - $_POST[$keycode] = getEntity($tabname[$id]); - } - - if ($i) { - $sql .= ","; - } - - if ($keycode == 'sortorder') { // For column name 'sortorder', we use the field name 'position' - $sql .= (int) GETPOST('position', 'int'); - } elseif (GETPOST($keycode) == '' && !($keycode == 'code' && $id == 10)) { - $sql .= "null"; // For vat, we want/accept code = '' - } elseif ($keycode == 'content') { - $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { - $sql .= (int) GETPOST($keycode, 'int'); + // If verif ok and action modify, modify the line + if ($ok && GETPOST('actionmodify')) { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; } else { - $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + $rowidcol = "rowid"; } - $i++; - } - $sql .= ",1)"; - - dol_syslog("actionadd", LOG_DEBUG); - $resql = $db->query($sql); - if ($resql) { // Add is ok - setEventMessages($langs->transnoentities("RecordCreatedSuccessfully"), null, 'mesgs'); - - // Clean $_POST array, we keep only id of dictionary - if ($id == 10 && GETPOST('country', 'int') > 0) { - $search_country_id = GETPOST('country', 'int'); + // Modify entry + $sql = "UPDATE ".$tabname[$id]." SET "; + // Modifie valeur des champs + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) { + $sql .= $tabrowid[$id]."="; + $sql .= "'".$db->escape($rowid)."', "; } - $_POST = array('id'=>$id); - } else { - if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); + $i = 0; + foreach ($listfieldmodify as $field) { + $keycode = $listfieldvalue[$i]; + if (empty($keycode)) { + $keycode = $field; + } + + if ($field == 'price' || preg_match('/^amount/i', $field)) { + $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); + } elseif ($field == 'taux' || $field == 'localtax1') { + $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z + } elseif ($field == 'entity') { + $_POST[$keycode] = getEntity($tabname[$id]); + } + + if ($i) { + $sql .= ","; + } + $sql .= $field."="; + if ($listfieldvalue[$i] == 'sortorder') { // For column name 'sortorder', we use the field name 'position' + $sql .= (int) GETPOST('position', 'int'); + } elseif (GETPOST($keycode) == '' && !($keycode == 'code' && $id == 10)) { + $sql .= "null"; // For vat, we want/accept code = '' + } elseif ($keycode == 'content') { + $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; + } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { + $sql .= (int) GETPOST($keycode, 'int'); + } else { + $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + } + + $i++; + } + if (in_array($rowidcol, array('code', 'code_iso'))) { + $sql .= " WHERE ".$rowidcol." = '".$db->escape($rowid)."'"; } else { - dol_print_error($db); + $sql .= " WHERE ".$rowidcol." = ".((int) $rowid); + } + if (in_array('entity', $listfieldmodify)) { + $sql .= " AND entity = ".((int) getEntity($tabname[$id], 0)); + } + + dol_syslog("actionmodify", LOG_DEBUG); + //print $sql; + $resql = $db->query($sql); + if (!$resql) { + setEventMessages($db->error(), null, 'errors'); } } + //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition } - // If verif ok and action modify, modify the line - if ($ok && GETPOST('actionmodify')) { + if (GETPOST('actioncancel')) { + //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition + } + + if ($action == 'confirm_delete' && $confirm == 'yes') { // delete if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } else { $rowidcol = "rowid"; } - // Modify entry - $sql = "UPDATE ".$tabname[$id]." SET "; - // Modifie valeur des champs - if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) { - $sql .= $tabrowid[$id]."="; - $sql .= "'".$db->escape($rowid)."', "; - } - $i = 0; - foreach ($listfieldmodify as $field) { - $keycode = $listfieldvalue[$i]; - if (empty($keycode)) { - $keycode = $field; - } + $sql = "DELETE FROM ".$tabname[$id]." WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - if ($field == 'price' || preg_match('/^amount/i', $field)) { - $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); - } elseif ($field == 'taux' || $field == 'localtax1') { - $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z - } elseif ($field == 'entity') { - $_POST[$keycode] = getEntity($tabname[$id]); - } - - if ($i) { - $sql .= ","; - } - $sql .= $field."="; - if ($listfieldvalue[$i] == 'sortorder') { // For column name 'sortorder', we use the field name 'position' - $sql .= (int) GETPOST('position', 'int'); - } elseif (GETPOST($keycode) == '' && !($keycode == 'code' && $id == 10)) { - $sql .= "null"; // For vat, we want/accept code = '' - } elseif ($keycode == 'content') { - $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { - $sql .= (int) GETPOST($keycode, 'int'); + dol_syslog("delete", LOG_DEBUG); + $result = $db->query($sql); + if (!$result) { + if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') { + setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); } else { - $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + dol_print_error($db); } - - $i++; - } - if (in_array($rowidcol, array('code', 'code_iso'))) { - $sql .= " WHERE ".$rowidcol." = '".$db->escape($rowid)."'"; - } else { - $sql .= " WHERE ".$rowidcol." = ".((int) $rowid); - } - if (in_array('entity', $listfieldmodify)) { - $sql .= " AND entity = ".((int) getEntity($tabname[$id], 0)); - } - - dol_syslog("actionmodify", LOG_DEBUG); - //print $sql; - $resql = $db->query($sql); - if (!$resql) { - setEventMessages($db->error(), null, 'errors'); } } - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition -} -if (GETPOST('actioncancel')) { - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition -} + // activate + if ($action == $acts[0]) { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } -if ($action == 'confirm_delete' && $confirm == 'yes') { // delete - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } } - $sql = "DELETE FROM ".$tabname[$id]." WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - - dol_syslog("delete", LOG_DEBUG); - $result = $db->query($sql); - if (!$result) { - if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') { - setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); + // disable + if ($action == $acts[1]) { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } + } + + // favorite + if ($action == 'activate_favorite') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } + } + + // disable favorite + if ($action == 'disable_favorite') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } + } + + // Is in EEC - Activate + if ($action == 'activate_eec') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } + } + + // Is in EEC - Disable + if ($action == 'disable_eec') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { dol_print_error($db); } } } - -// activate -if ($action == $acts[0]) { - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; - } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } - - $result = $db->query($sql); - if (!$result) { - dol_print_error($db); - } -} - -// disable -if ($action == $acts[1]) { - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; - } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } - - $result = $db->query($sql); - if (!$result) { - dol_print_error($db); - } -} - -// favorite -if ($action == 'activate_favorite') { - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; - } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } - - $result = $db->query($sql); - if (!$result) { - dol_print_error($db); - } -} - -// disable favorite -if ($action == 'disable_favorite') { - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; - } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } - - $result = $db->query($sql); - if (!$result) { - dol_print_error($db); - } -} - - /* * View */ @@ -1416,6 +1491,9 @@ if ($id) { if ($value == 'block_if_negative') { $valuetoshow = $langs->trans('BlockHolidayIfNegative'); } + if ($value == 'type_duration') { + $valuetoshow = $langs->trans('Unit'); + } if ($id == 2) { // Special case for state page if ($value == 'region_id') { @@ -1441,6 +1519,7 @@ if ($id) { if ($id == 4) { $tdsoffields .= ''; + $tdsoffields .= ''; } $tdsoffields .= ''; + print ''; } print ''; + print ''; } print ''; print ''; + print ''; @@ -2387,6 +2484,10 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; + } elseif ($value == 'type_duration') { + print ''; } else { $fieldValue = isset($obj->{$value}) ? $obj->{$value}: ''; diff --git a/htdocs/admin/dolistore/ajax/image.php b/htdocs/admin/dolistore/ajax/image.php index af844edaa68..e601da43e06 100644 --- a/htdocs/admin/dolistore/ajax/image.php +++ b/htdocs/admin/dolistore/ajax/image.php @@ -1,7 +1,7 @@ . * Copyright (C) 2008-2011 Laurent Destailleur - * Copyright (C) 2020 Frédéric France + * Copyright (C) 2020 Frédéric France * * This program is free software; you can redistribute it and/or modifyion 2.0 (the "License"); * it under the terms of the GNU General Public License as published bypliance with the License. @@ -17,9 +17,6 @@ * or see https://www.gnu.org/ */ -if (!defined('REQUIRE_JQUERY_BLOCKUI')) { - define('REQUIRE_JQUERY_BLOCKUI', 1); -} if (!defined('NOTOKENRENEWAL')) { define('NOTOKENRENEWAL', 1); } diff --git a/htdocs/admin/dolistore/css/dolistore.css b/htdocs/admin/dolistore/css/dolistore.css index 3d8f163caf2..c3a8b6ca7ce 100644 --- a/htdocs/admin/dolistore/css/dolistore.css +++ b/htdocs/admin/dolistore/css/dolistore.css @@ -67,9 +67,6 @@ div.divsearchfield { .tree li:last-child:after{ display: none } -.blockUI { - cursor: auto!important; -} .newAppParent{ position: relative; overflow: hidden; diff --git a/htdocs/admin/emailcollector_list.php b/htdocs/admin/emailcollector_list.php index af137a1ecdb..9e93dd78b86 100644 --- a/htdocs/admin/emailcollector_list.php +++ b/htdocs/admin/emailcollector_list.php @@ -109,11 +109,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = dol_eval($val['visible'], 1); + $visible = dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'] ); } diff --git a/htdocs/admin/eventorganization.php b/htdocs/admin/eventorganization.php index 904d10bff67..254f7d3c8d4 100644 --- a/htdocs/admin/eventorganization.php +++ b/htdocs/admin/eventorganization.php @@ -220,8 +220,9 @@ if ($action == 'edit') { foreach ($arrayofparameters as $constname => $val) { if ($val['enabled']==1) { $setupnotempty++; - print '
'.$langs->trans("DateOfBirth").''.dol_print_date($object->birth, 'day').'
'.$langs->trans("Public").''.yn($object->public).'
'.$langs->trans("Categories").''; @@ -582,6 +578,12 @@ if ($rowid > 0) { print '
'.$langs->trans("DateOfBirth").''.dol_print_date($object->birth, 'day').'
'.$langs->trans("Public").''.yn($object->public).'
'.$langs->trans("Label").'
'.$langs->trans("Status").''; - print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'), '1'=>$langs->trans('InActivity')), 1); + print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'), '1'=>$langs->trans('InActivity')), 1, 0, 0, 0, '', 0, 0, 0, '', 'minwidth100'); print '
'.$langs->trans("Amount").''; - print ''; + print ''; print '
'.$langs->trans("VoteAllowed").''; @@ -389,12 +391,12 @@ if ($action == 'create') { print '
'.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('comment', $object->note, '', 200, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); + $doleditor = new DolEditor('comment', (GETPOSTISSET('comment') ? GETPOST('comment', 'restricthtml') : $object->note_public), '', 200, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); $doleditor->Create(); print '
'.$langs->trans("WelcomeEMail").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('mail_valid', $object->mail_valid, '', 250, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); + $doleditor = new DolEditor('mail_valid', GETPOSTISSET('mail_valid') ? GETPOST('mail_valid') : $object->mail_valid, '', 250, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); $doleditor->Create(); print '
'.$langs->trans("Label").'
'.$langs->trans("Status").''; - print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'), '1'=>$langs->trans('InActivity')), $object->status); + print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'), '1'=>$langs->trans('InActivity')), $object->status, 0, 0, 0, '', 0, 0, 0, '', 'minwidth100'); print '
'; +print '
'; print '
'; +print '
'; print '
'; $tdsoffields .= ''; @@ -1485,6 +1564,7 @@ if ($id) { if ($id == 4) { print ''; if ($action != 'edit') { @@ -1558,6 +1638,7 @@ if ($id) { } if ($id == 4) { print ''; @@ -1581,10 +1662,10 @@ if ($id) { // Determines the name of the field in relation to the possible names // in data dictionaries - $showfield = 1; // By defaut + $showfield = 1; // By default $cssprefix = ''; $sortable = 1; - $valuetoshow = ucfirst($value); // By defaut + $valuetoshow = ucfirst($value); // By default $valuetoshow = $langs->trans($valuetoshow); // try to translate // Special cases @@ -1765,6 +1846,9 @@ if ($id) { if ($value == 'block_if_negative') { $valuetoshow = $langs->trans('BlockHolidayIfNegative'); } + if ($value == 'type_duration') { + $valuetoshow = $langs->trans('Unit'); + } if ($value == 'region_id' || $value == 'country_id') { $showfield = 0; @@ -1783,8 +1867,9 @@ if ($id) { print getTitleFieldOfList($newvaluetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $value : ''), ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, $cssprefix); } } - // Favorite - Only activated on country dictionary + // Favorite & EEC - Only activated on country dictionary if ($id == 4) { + print getTitleFieldOfList($langs->trans("InEEC"), 0, $_SERVER["PHP_SELF"], "eec", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder, '', 0, $langs->trans("CountryIsInEEC")); print getTitleFieldOfList($langs->trans("Favorite"), 0, $_SERVER["PHP_SELF"], "favorite", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); } @@ -2001,6 +2086,9 @@ if ($id) { $valuetoshow = $langs->trans($obj->{$value}); } elseif ($value == 'block_if_negative') { $valuetoshow = yn($obj->{$value}); + } elseif ($value == 'type_duration') { + $TDurationTypes = array('y'=>$langs->trans('Years'), 'm'=>$langs->trans('Month'), 'w'=>$langs->trans('Weeks'), 'd'=>$langs->trans('Days'), 'h'=>$langs->trans('Hours'), 'i'=>$langs->trans('Minutes')); + $valuetoshow =$TDurationTypes[$obj->{$value}]; } $class .= ($class ? ' ' : '').'tddict'; if ($value == 'note' && $id == 10) { @@ -2078,10 +2166,19 @@ if ($id) { } $url .= '&'; - // Favorite + // Favorite & EEC // Only activated on country dictionary if ($id == 4) { print ''; + // Is in EEC + if ($iserasable) { + print ''.$actl[$obj->eec].''; + } else { + print $langs->trans("AlwaysActive"); + } + print ''; + // Favorite if ($iserasable) { print ''.$actl[$obj->favorite].''; } else { @@ -2348,10 +2445,10 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') } elseif ($value == 'unit') { print ''; $units = array( - 'mm' => $langs->trans('SizeUnitmm'), - 'cm' => $langs->trans('SizeUnitcm'), - 'point' => $langs->trans('SizeUnitpoint'), - 'inch' => $langs->trans('SizeUnitinch') + 'mm' => $langs->trans('SizeUnitmm'), + 'cm' => $langs->trans('SizeUnitcm'), + 'point' => $langs->trans('SizeUnitpoint'), + 'inch' => $langs->trans('SizeUnitinch') ); print $form->selectarray('unit', $units, (!empty($obj->{$value}) ? $obj->{$value}:''), 0, 0, 0); print ''; print $form->selectyesno("block_if_negative", (!empty($obj->{$value}) ? $obj->{$value}:''), 1); print ''; + print $form->selectTypeDuration('', $obj->{$value}, array('i','h')); + print '
'; + print '
aa'; $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); + $tooltiphelp .= (($langs->trans($constname . 'Tooltip2') && $langs->trans($constname . 'Tooltip2') != $constname . 'Tooltip2') ? '

'."\n".$langs->trans($constname . 'Tooltip2') : ''); print ''.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).''; print '
'; @@ -314,6 +315,7 @@ if ($action == 'edit') { $setupnotempty++; print '
'; $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); + $tooltiphelp .= (($langs->trans($constname . 'Tooltip2') && $langs->trans($constname . 'Tooltip2') != $constname . 'Tooltip2') ? '

'."\n".$langs->trans($constname . 'Tooltip2') : ''); print $form->textwithpicto($langs->trans($constname), $tooltiphelp); print '
'; diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php index 77fb8f24f82..1146232dca3 100644 --- a/htdocs/admin/expensereport_rules.php +++ b/htdocs/admin/expensereport_rules.php @@ -38,169 +38,178 @@ if (!$user->admin) { accessforbidden(); } -//Init error -$error = false; -$message = false; +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('admin', 'dictionaryadmin','expensereport_rules')); -$action = GETPOST('action', 'aZ09'); -$id = GETPOST('id', 'int'); -$apply_to = GETPOST('apply_to'); -$fk_user = GETPOST('fk_user', 'int'); -$fk_usergroup = GETPOST('fk_usergroup', 'int'); - -$fk_c_type_fees = GETPOST('fk_c_type_fees'); -$code_expense_rules_type = GETPOST('code_expense_rules_type'); -$dates = dol_mktime(12, 0, 0, GETPOST('startmonth'), GETPOST('startday'), GETPOST('startyear')); -$datee = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear')); -$amount = GETPOST('amount'); - -$object = new ExpenseReportRule($db); -if (!empty($id)) { - $result = $object->fetch($id); - if ($result < 0) { - dol_print_error('', $object->error, $object->errors); - } +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } -// TODO do action -if ($action == 'save') { - $error = 0; +if (empty($reshook)) { + //Init error + $error = false; + $message = false; - // check parameters - if (empty($apply_to)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportApplyTo")), null, 'errors'); - } - if (empty($fk_c_type_fees)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDomain")), null, 'errors'); - } - if (empty($code_expense_rules_type)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitOn")), null, 'errors'); - } - if (empty($dates)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateStart")), null, 'errors'); - } - if (empty($datee)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateEnd")), null, 'errors'); - } - if (empty($amount)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitAmount")), null, 'errors'); - } + $action = GETPOST('action', 'aZ09'); + $id = GETPOST('id', 'int'); - if (empty($error)) { - $object->setValues($_POST); + $apply_to = GETPOST('apply_to'); + $fk_user = GETPOST('fk_user', 'int'); + $fk_usergroup = GETPOST('fk_usergroup', 'int'); - if ($apply_to == 'U') { - $object->fk_user = (int) $fk_user; - $object->fk_usergroup = 0; - $object->is_for_all = 0; - } elseif ($apply_to == 'G') { - $object->fk_usergroup = (int) $fk_usergroup; - $object->fk_user = 0; - $object->is_for_all = 0; - } elseif ($apply_to == 'A') { - $object->is_for_all = 1; - $object->fk_user = 0; - $object->fk_usergroup = 0; + $fk_c_type_fees = GETPOST('fk_c_type_fees'); + $code_expense_rules_type = GETPOST('code_expense_rules_type'); + $dates = dol_mktime(12, 0, 0, GETPOST('startmonth'), GETPOST('startday'), GETPOST('startyear')); + $datee = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear')); + $amount = GETPOST('amount'); + + $object = new ExpenseReportRule($db); + if (!empty($id)) { + $result = $object->fetch($id); + if ($result < 0) { + dol_print_error('', $object->error, $object->errors); + } + } + // TODO do action + if ($action == 'save') { + $error = 0; + + // check parameters + if (empty($apply_to)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportApplyTo")), null, 'errors'); + } + if (empty($fk_c_type_fees)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDomain")), null, 'errors'); + } + if (empty($code_expense_rules_type)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitOn")), null, 'errors'); + } + if (empty($dates)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateStart")), null, 'errors'); + } + if (empty($datee)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateEnd")), null, 'errors'); + } + if (empty($amount)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitAmount")), null, 'errors'); } - $object->dates = $dates; - $object->datee = $datee; + if (empty($error)) { + $object->setValues($_POST); - $object->entity = $conf->entity; + if ($apply_to == 'U') { + $object->fk_user = (int) $fk_user; + $object->fk_usergroup = 0; + $object->is_for_all = 0; + } elseif ($apply_to == 'G') { + $object->fk_usergroup = (int) $fk_usergroup; + $object->fk_user = 0; + $object->is_for_all = 0; + } elseif ($apply_to == 'A') { + $object->is_for_all = 1; + $object->fk_user = 0; + $object->fk_usergroup = 0; + } - $res = $object->create($user); - if ($res > 0) { - setEventMessages($langs->trans('ExpenseReportRuleSave'), null); - } else { + $object->dates = $dates; + $object->datee = $datee; + + $object->entity = $conf->entity; + + $res = $object->create($user); + if ($res > 0) { + setEventMessages($langs->trans('ExpenseReportRuleSave'), null); + } else { + dol_print_error($object->db); + } + + header('Location: ' . $_SERVER['PHP_SELF']); + exit; + } + } elseif ($action == 'delete') { + // TODO add confirm + $res = $object->delete($user); + + if ($res < 0) { dol_print_error($object->db); } - header('Location: '.$_SERVER['PHP_SELF']); + header('Location: ' . $_SERVER['PHP_SELF']); exit; } -} elseif ($action == 'delete') { - // TODO add confirm - $res = $object->delete($user); - if ($res < 0) { - dol_print_error($object->db); - } + $rules = $object->getAllRule(); - header('Location: '.$_SERVER['PHP_SELF']); - exit; + $tab_apply = array( + 'A' => $langs->trans('All'), + 'G' => $langs->trans('Group'), + 'U' => $langs->trans('User') + ); + $tab_rules_type = array( + 'EX_DAY' => $langs->trans('Day'), + 'EX_MON' => $langs->trans('Month'), + 'EX_YEA' => $langs->trans('Year'), + 'EX_EXP' => $langs->trans('OnExpense') + ); } + /* + * View + */ -$rules = $object->getAllRule(); + llxHeader('', $langs->trans("ExpenseReportsSetup")); -$tab_apply = array( - 'A' => $langs->trans('All'), - 'G' => $langs->trans('Group'), - 'U' => $langs->trans('User') -); -$tab_rules_type = array( - 'EX_DAY' => $langs->trans('Day'), - 'EX_MON' => $langs->trans('Month'), - 'EX_YEA' => $langs->trans('Year'), - 'EX_EXP' => $langs->trans('OnExpense') -); + $form = new Form($db); + $linkback = '' . $langs->trans("BackToModuleList") . ''; + print load_fiche_titre($langs->trans("ExpenseReportsSetup"), $linkback, 'title_setup'); -/* - * View - */ + $head = expensereport_admin_prepare_head(); + print dol_get_fiche_head($head, 'expenserules', $langs->trans("ExpenseReportsRules"), -1, 'trip'); -llxHeader('', $langs->trans("ExpenseReportsSetup")); - -$form = new Form($db); - -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ExpenseReportsSetup"), $linkback, 'title_setup'); - -$head = expensereport_admin_prepare_head(); -print dol_get_fiche_head($head, 'expenserules', $langs->trans("ExpenseReportsRules"), -1, 'trip'); - -echo ''.$langs->trans('ExpenseReportRulesDesc').''; -print '

'; + echo '' . $langs->trans('ExpenseReportRulesDesc') . ''; + print '

'; if ($action != 'edit') { - echo '
'; - echo ''; + echo ''; + echo ''; echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo ''; echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo '
'.$langs->trans('ExpenseReportApplyTo').''.$langs->trans('Type').''.$langs->trans('ExpenseReportLimitOn').''.$langs->trans('ExpenseReportDateStart').''.$langs->trans('ExpenseReportDateEnd').''.$langs->trans('ExpenseReportLimitAmount').''.$langs->trans('ExpenseReportRestrictive').'
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . ' 
'; - echo '
'.$form->selectarray('apply_to', $tab_apply, '', 0).'
'; - echo '
'.$form->select_dolusers('', 'fk_user').'
'; - echo '
'.$form->select_dolgroups('', 'fk_usergroup').'
'; + echo '
' . $form->selectarray('apply_to', $tab_apply, '', 0) . '
'; + echo '
' . $form->select_dolusers('', 'fk_user') . '
'; + echo '
' . $form->select_dolgroups('', 'fk_usergroup') . '
'; echo '
'.$form->selectExpense('', 'fk_c_type_fees', 0, 1, 1).''.$form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0).''.$form->selectDate(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0).''.$form->selectDate(strtotime(date('Y-m-t', dol_now())), 'end', '', '', 0, '', 1, 0).' '.$conf->currency.''.$form->selectyesno('restrictive', 0, 1).'' . $form->selectExpense('', 'fk_c_type_fees', 0, 1, 1) . '' . $form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0) . '' . $form->selectDate(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0) . ' ' . $conf->currency . '' . $form->selectyesno('restrictive', 0, 1) . '
'; @@ -208,60 +217,60 @@ if ($action != 'edit') { } -echo ''; -echo ''; + echo ''; + echo ''; if ($action == 'edit') { - echo ''; + echo ''; echo ''; } -echo ''; + echo '
'; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; foreach ($rules as $rule) { - echo ''; + echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; @@ -328,10 +337,10 @@ foreach ($rules as $rule) { } -echo '
'.$langs->trans('ExpenseReportApplyTo').''.$langs->trans('Type').''.$langs->trans('ExpenseReportLimitOn').''.$langs->trans('ExpenseReportDateStart').''.$langs->trans('ExpenseReportDateEnd').''.$langs->trans('ExpenseReportLimitAmount').''.$langs->trans('ExpenseReportRestrictive').' 
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . ' 
'; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { $selected = ($object->is_for_all > 0) ? 'A' : ($object->fk_usergroup > 0 ? 'G' : 'U'); - echo '
'.$form->selectarray('apply_to', $tab_apply, $selected, 0).'
'; - echo '
'.$form->select_dolusers($object->fk_user, 'fk_user').'
'; - echo '
'.$form->select_dolgroups($object->fk_usergroup, 'fk_usergroup').'
'; + echo '
' . $form->selectarray('apply_to', $tab_apply, $selected, 0) . '
'; + echo '
' . $form->select_dolusers($object->fk_user, 'fk_user') . '
'; + echo '
' . $form->select_dolgroups($object->fk_usergroup, 'fk_usergroup') . '
'; } else { if ($rule->is_for_all > 0) { echo $tab_apply['A']; } elseif ($rule->fk_usergroup > 0) { - echo $tab_apply['G'].' ('.$rule->getGroupLabel().')'; + echo $tab_apply['G'] . ' (' . $rule->getGroupLabel() . ')'; } elseif ($rule->fk_user > 0) { - echo $tab_apply['U'].' ('.$rule->getUserName().')'; + echo $tab_apply['U'] . ' (' . $rule->getUserName() . ')'; } } echo '
'; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectExpense($object->fk_c_type_fees, 'fk_c_type_fees', 0, 1, 1); } else { if ($rule->fk_c_type_fees == -1) { echo $langs->trans('AllExpenseReport'); } else { - $key = getDictionaryValue(MAIN_DB_PREFIX.'c_type_fees', 'code', $rule->fk_c_type_fees, false, 'id'); + $key = getDictionaryValue(MAIN_DB_PREFIX . 'c_type_fees', 'code', $rule->fk_c_type_fees, false, 'id'); if ($key && $key != $langs->trans($key)) { echo $langs->trans($key); } else { - $value = getDictionaryValue(MAIN_DB_PREFIX.'c_type_fees', 'label', $rule->fk_c_type_fees, false, 'id'); + $value = getDictionaryValue(MAIN_DB_PREFIX . 'c_type_fees', 'label', $rule->fk_c_type_fees, false, 'id'); echo $langs->trans($value ? $value : 'Undefined'); // TODO check to return trans of 'code' } } @@ -269,7 +278,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectarray('code_expense_rules_type', $tab_rules_type, $object->code_expense_rules_type, 0); } else { @@ -278,7 +287,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { print $form->selectDate(strtotime(date('Y-m-d', $object->dates)), 'start', '', '', 0, '', 1, 0); } else { @@ -287,7 +296,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { print $form->selectDate(strtotime(date('Y-m-d', $object->datee)), 'end', '', '', 0, '', 1, 0); } else { @@ -296,16 +305,16 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { - echo ''.$conf->currency; + echo '' . $conf->currency; } else { echo price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency); } echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectyesno('restrictive', $object->restrictive, 1); } else { @@ -316,11 +325,11 @@ foreach ($rules as $rule) { echo ''; if ($object->id != $rule->id) { - echo ''.img_edit().' '; - echo ''.img_delete().''; + echo '' . img_edit() . ' '; + echo '' . img_delete() . ''; } else { - echo ' '; - echo ''.$langs->trans("Cancel").''; + echo ' '; + echo '' . $langs->trans("Cancel") . ''; } echo '
'; -echo '
'; + echo '
'; + echo ''; -echo ''; + print dol_get_fiche_end(); // End of page diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index 9eec54b03a7..599aac27c3f 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -225,6 +225,12 @@ if ($action == 'updateMask') { setEventMessages($langs->trans("Error"), null, 'errors'); } } +} elseif ($action == 'set_INVOICE_CHECK_POSTERIOR_DATE') { + $check_posterior_date = GETPOST('INVOICE_CHECK_POSTERIOR_DATE', 'int'); + $res = dolibarr_set_const($db, 'INVOICE_CHECK_POSTERIOR_DATE', $check_posterior_date, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } } @@ -761,6 +767,25 @@ print '\n"; print ''; + +print ''.$langs->trans("InvoiceCheckPosteriorDate"). ' ' ; +print $form->textwithpicto('', $langs->trans("InvoiceCheckPosteriorDateHelp"), 1, 'help') . ''; +print ''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('INVOICE_CHECK_POSTERIOR_DATE'); +} else { + print '
'; + print ''; + print ''; + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("INVOICE_CHECK_POSTERIOR_DATE", $arrval, $conf->global->INVOICE_CHECK_POSTERIOR_DATE); + print ''; + print ''; + print ''; + print '
'; +} +print ''; + print ''; print '
'; diff --git a/htdocs/admin/fckeditor.php b/htdocs/admin/fckeditor.php index 51247ac0b35..140cd7fcfdf 100644 --- a/htdocs/admin/fckeditor.php +++ b/htdocs/admin/fckeditor.php @@ -110,7 +110,8 @@ if (GETPOST('save', 'alpha')) { $fckeditor_skin = GETPOST('fckeditor_skin', 'alpha'); if (!empty($fckeditor_skin)) { - if (!dolibarr_set_const($db, 'FCKEDITOR_SKIN', $fckeditor_skin, 'chaine', 0, '', $conf->entity)) { + $result = dolibarr_set_const($db, 'FCKEDITOR_SKIN', $fckeditor_skin, 'chaine', 0, '', $conf->entity); + if ($result <= 0) { $error++; } } else { @@ -119,7 +120,8 @@ if (GETPOST('save', 'alpha')) { $fckeditor_test = GETPOST('formtestfield', 'restricthtml'); if (!empty($fckeditor_test)) { - if (!dolibarr_set_const($db, 'FCKEDITOR_TEST', $fckeditor_test, 'chaine', 0, '', $conf->entity)) { + $result = dolibarr_set_const($db, 'FCKEDITOR_TEST', $fckeditor_test, 'chaine', 0, '', $conf->entity); + if ($result <= 0) { $error++; } } else { @@ -129,7 +131,7 @@ if (GETPOST('save', 'alpha')) { if (!$error) { setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } else { - setEventMessages($langs->trans("Error"), null, 'errors'); + setEventMessages($langs->trans("Error").' '.$db->lasterror(), null, 'errors'); } } diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index fc8e24b9322..f065760f62d 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -46,11 +46,12 @@ if ($action == 'test' || $action == 'send') { $substitutionarrayfortest = array( '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT, + '__CHECK_READ__' => (!empty($object) && is_object($object) && is_object($object->thirdparty)) ? '' : '', + '__USER_LOGIN__' => $user->login, + '__USER_EMAIL__' => $user->email, + '__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), // Done into actions_sendmails '__ID__' => 'RecipientIdRecord', //'__EMAIL__' => 'RecipientEMail', // Done into actions_sendmails - '__CHECK_READ__' => (!empty($object) && is_object($object) && is_object($object->thirdparty)) ? '' : '', - '__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), // Done into actions_sendmails - '__LOGIN__' => 'RecipientLogin', '__LASTNAME__' => 'RecipientLastname', '__FIRSTNAME__' => 'RecipientFirstname', '__ADDRESS__'=> 'RecipientAddress', @@ -662,7 +663,7 @@ if ($action == 'edit') { print ''.$langs->trans("MAIN_MAIL_EMAIL_DKIM_ENABLED").''; if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('swiftmailer'))) { if (function_exists('openssl_open')) { - print yn($conf->global->MAIN_MAIL_EMAIL_DKIM_ENABLED); + print yn(getDolGlobalInt('MAIN_MAIL_EMAIL_DKIM_ENABLED')); } else { print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')'; } @@ -762,9 +763,18 @@ if ($action == 'edit') { print ''.$langs->trans("MAIN_MAIL_AUTOCOPY_TO").''; print ''; if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) { - print $conf->global->MAIN_MAIL_AUTOCOPY_TO; - if (!isValidEmail($conf->global->MAIN_MAIL_AUTOCOPY_TO)) { - print img_warning($langs->trans("ErrorBadEMail")); + $listofemail = explode(',', $conf->global->MAIN_MAIL_AUTOCOPY_TO); + $i = 0; + foreach ($listofemail as $key => $val) { + if ($i) { + print ', '; + } + $val = trim($val); + print $val; + if (!isValidEmail($val, 0, 1)) { + print img_warning($langs->trans("ErrorBadEMail", $val)); + } + $i++; } } else { print ' '; @@ -887,7 +897,6 @@ if ($action == 'edit') { } setEventMessages($errormsg, null, 'errors'); - print $errormsg; } print '
'; } diff --git a/htdocs/admin/mails_emailing.php b/htdocs/admin/mails_emailing.php index 6b1aa3334b5..40af4c4ae2a 100644 --- a/htdocs/admin/mails_emailing.php +++ b/htdocs/admin/mails_emailing.php @@ -31,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $langs->loadLangs(array('companies', 'products', 'admin', 'mails', 'other', 'errors')); $action = GETPOST('action', 'aZ09'); -$cancel = GETPOST('cancel', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); if (!$user->admin) { accessforbidden(); @@ -40,17 +40,22 @@ if (!$user->admin) { $usersignature = $user->signature; // For action = test or send, we ensure that content is not html, even for signature, because this we want a test with NO html. if ($action == 'test' || $action == 'send') { - $usersignature = dol_string_nohtmltag($usersignature); + $usersignature = dol_string_nohtmltag($usersignature, 2); } $substitutionarrayfortest = array( -'__LOGIN__' => $user->login, -'__ID__' => 'TESTIdRecord', -'__EMAIL__' => 'TESTEMail', -'__LASTNAME__' => 'TESTLastname', -'__FIRSTNAME__' => 'TESTFirstname', -'__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), -//'__PERSONALIZED__' => 'TESTPersonalized' // Hiden because not used yet + '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT, + '__ID__' => 'RecipientIdRecord', + //'__EMAIL__' => 'RecipientEMail', // Done into actions_sendmails + '__CHECK_READ__' => (!empty($object) && is_object($object) && is_object($object->thirdparty)) ? '' : '', + '__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), // Done into actions_sendmails + '__LOGIN__' => $user->login, + '__LASTNAME__' => 'RecipientLastname', + '__FIRSTNAME__' => 'RecipientFirstname', + '__ADDRESS__'=> 'RecipientAddress', + '__ZIP__'=> 'RecipientZip', + '__TOWN_'=> 'RecipientTown', + '__COUNTRY__'=> 'RecipientCountry' ); complete_substitutions_array($substitutionarrayfortest, $langs); @@ -86,10 +91,10 @@ $trackid = (($action == 'testhtml') ? "testhtml" : "test"); $sendcontext = 'emailing'; // Force to use dedicated context of setup for emailing include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; -if ($action == 'presend' && GETPOST('trackid') == 'test') { +if ($action == 'presend' && GETPOST('trackid', 'alphanohtml') == 'test') { $action = 'test'; } -if ($action == 'presend' && GETPOST('trackid') == 'testhtml') { +if ($action == 'presend' && GETPOST('trackid', 'alphanohtml') == 'testhtml') { $action = 'testhtml'; } @@ -271,12 +276,15 @@ if ($action == 'edit') { // Host server - print ''; + print ''; if (!$conf->use_javascript_ajax && $linuxlike && $conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail') { + print ''; print $langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike"); print ''; - print $langs->trans("SeeLocalSendMailSetup"); + print ''.$langs->trans("SeeLocalSendMailSetup").''; + print ''; } else { + print ''; $mainserver = (!empty($conf->global->MAIN_MAIL_SMTP_SERVER_EMAILING) ? $conf->global->MAIN_MAIL_SMTP_SERVER_EMAILING : ''); $smtpserver = ini_get('SMTP') ?ini_get('SMTP') : $langs->transnoentities("Undefined"); if ($linuxlike) { @@ -287,17 +295,19 @@ if ($action == 'edit') { print ''; // SuperAdministrator access only if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity)) { - print ''; + print ''; print ''; - print ''.$langs->trans("SeeLocalSendMailSetup").''; + print ''.$langs->trans("SeeLocalSendMailSetup").''; + print ' '.$langs->trans("SeeLinkToOnlineDocumentation").''; } else { $text = !empty($mainserver) ? $mainserver : $smtpserver; $htmltext = $langs->trans("ContactSuperAdminForChange"); print $form->textwithpicto($text, $htmltext, 1, 'superadmin'); print ''; } + print ''; } - print ''; + print ''; // Port @@ -305,7 +315,7 @@ if ($action == 'edit') { if (!$conf->use_javascript_ajax && $linuxlike && $conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail') { print $langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike"); print ''; - print $langs->trans("SeeLocalSendMailSetup"); + print ''.$langs->trans("SeeLocalSendMailSetup").''; } else { $mainport = (!empty($conf->global->MAIN_MAIL_SMTP_PORT_EMAILING) ? $conf->global->MAIN_MAIL_SMTP_PORT_EMAILING : ''); $smtpport = ini_get('smtp_port') ?ini_get('smtp_port') : $langs->transnoentities("Undefined"); @@ -319,7 +329,7 @@ if ($action == 'edit') { if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity)) { print ''; print ''; - print ''.$langs->trans("SeeLocalSendMailSetup").''; + print ''.$langs->trans("SeeLocalSendMailSetup").''; } else { $text = (!empty($mainport) ? $mainport : $smtpport); $htmltext = $langs->trans("ContactSuperAdminForChange"); @@ -360,7 +370,6 @@ if ($action == 'edit') { } // TLS - print ''.$langs->trans("MAIN_MAIL_EMAIL_TLS").''; if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) { if (function_exists('openssl_open')) { @@ -374,7 +383,6 @@ if ($action == 'edit') { print ''; // STARTTLS - print ''.$langs->trans("MAIN_MAIL_EMAIL_STARTTLS").''; if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) { if (function_exists('openssl_open')) { @@ -388,7 +396,6 @@ if ($action == 'edit') { print ''; // SMTP_ALLOW_SELF_SIGNED_EMAILING - print ''.$langs->trans("MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED").''; if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) { if (function_exists('openssl_open')) { @@ -414,6 +421,7 @@ if ($action == 'edit') { print ''.$langs->trans("EMailsDesc")."
\n"; print "

\n"; + print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print ''; print ''; @@ -460,7 +468,7 @@ if ($action == 'edit') { print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')'; } } else { - print yn(0).' ('.$langs->trans("NotSupported").')'; + print ''.yn(0).' ('.$langs->trans("NotSupported").')'; } print ''; @@ -492,6 +500,7 @@ if ($action == 'edit') { } print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print '
'; print dol_get_fiche_end(); @@ -543,6 +552,7 @@ if ($action == 'edit') { // Run the test to connect if ($action == 'testconnect') { + print '
'; print load_fiche_titre($langs->trans("DoTestServerAvailability")); include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; @@ -573,16 +583,18 @@ if ($action == 'edit') { // Cree l'objet formulaire mail include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); + $formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test"); $formmail->fromname = (GETPOSTISSET('fromname') ? GETPOST('fromname', 'restricthtml') : $conf->global->MAIN_MAIL_EMAIL_FROM); $formmail->frommail = (GETPOSTISSET('frommail') ? GETPOST('frommail', 'restricthtml') : $conf->global->MAIN_MAIL_EMAIL_FROM); - $formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test"); + $formmail->fromid = $user->id; + $formmail->fromalsorobot = 1; $formmail->withfromreadonly = 0; $formmail->withsubstit = 0; $formmail->withfrom = 1; $formmail->witherrorsto = 1; - $formmail->withto = (!GETPOST('sendto') ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); - $formmail->withtocc = (!GETPOST(['sendtocc']) ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty - $formmail->withtoccc = (!GETPOST(['sendtoccc']) ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withto = (GETPOSTISSET('sendto') ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); + $formmail->withtocc = (GETPOSTISSET(['sendtocc']) ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withtoccc = (GETPOSTISSET(['sendtoccc']) ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty $formmail->withtopic = (GETPOSTISSET('subject') ? GETPOST('subject') : $langs->trans("Test")); $formmail->withtopicreadonly = 0; $formmail->withfile = 2; @@ -601,7 +613,7 @@ if ($action == 'edit') { $formmail->param["returnurl"] = $_SERVER["PHP_SELF"]; // Init list of files - if (GETPOST("mode") == 'init') { + if (GETPOST("mode", "aZ09") == 'init') { $formmail->clear_attached_files(); } diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 476f15459cb..e308d27b2b2 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -205,7 +205,7 @@ if (!empty($conf->expedition->enabled)) { $elementList['shipping_send'] = img_picto('', 'dolly', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToSendShipment')); } if (!empty($conf->reception->enabled)) { - $elementList['reception_send'] = img_picto('', 'dolly', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToSendReception')); + $elementList['reception_send'] = img_picto('', 'dollyrevert', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToSendReception')); } if (!empty($conf->ficheinter->enabled)) { $elementList['fichinter_send'] = img_picto('', 'intervention', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToSendIntervention')); @@ -769,7 +769,7 @@ if ($action == 'add') { if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) { $okforextended = false; } - $doleditor = new DolEditor($tmpfieldlist, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 180, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_4, '90%'); + $doleditor = new DolEditor($tmpfieldlist, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 180, 'dolibarr_mailings', 'In', 0, true, $okforextended, ROWS_4, '90%'); print $doleditor->Create(1); } print ''; @@ -1000,7 +1000,7 @@ if ($resql) { if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) { $okforextended = false; } - $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 500, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%'); + $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 500, 'dolibarr_mailings', 'In', 0, true, $okforextended, ROWS_6, '90%'); print $doleditor->Create(1); } if ($tmpfieldlist == 'content_lines') { @@ -1034,7 +1034,7 @@ if ($resql) { continue; // It means this is a type of template not into elementList (may be because enabled condition of this type is false because module is not enabled) } // Test on 'enabled' - if (!dol_eval($obj->enabled, 1)) { + if (!dol_eval($obj->enabled, 1, 1, '1')) { $i++; continue; // Email template not qualified } @@ -1152,6 +1152,7 @@ if ($resql) { //else print ''.img_delete().''; // Some dictionary can be edited by other profile than admin } print ''; + print "\n"; } diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index b3c3e5066c2..bf4ac3f8979 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -464,7 +464,7 @@ if ($action == 'create') { } print ''; print ''.$langs->trans('DetailMenuIdParent'); - print ', '.$langs->trans("Example").': fk_mainmenu=abc&fk_leftmenu=def'; + print ', '.$langs->trans("Example").': fk_mainmenu=abc&fk_leftmenu=def'; print ''; // Niveau @@ -496,7 +496,7 @@ if ($action == 'create') { print ''.$langs->trans('Enabled').''; print ''.$langs->trans('DetailEnabled'); if (!empty($menu->enabled)) { - print ' ('.$langs->trans("ConditionIsCurrently").': '.yn(dol_eval($menu->enabled, 1)).')'; + print ' ('.$langs->trans("ConditionIsCurrently").': '.yn(dol_eval($menu->enabled, 1, 1, '1')).')'; } print ''; @@ -504,7 +504,7 @@ if ($action == 'create') { print ''.$langs->trans('Rights').''; print ''.$langs->trans('DetailRight'); if (!empty($menu->perms)) { - print ' ('.$langs->trans("ConditionIsCurrently").': '.yn(dol_eval($menu->perms, 1)).')'; + print ' ('.$langs->trans("ConditionIsCurrently").': '.yn(dol_eval($menu->perms, 1, 1, '1')).')'; } print ''; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 4ad384233d8..8ed6615965b 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -481,9 +481,9 @@ $deschelp = ''; if ($mode == 'common' || $mode == 'commonkanban') { $desc = $langs->trans("ModulesDesc", '{picto}'); $desc .= ' '.$langs->trans("ModulesDesc2", '{picto2}'); - $desc = str_replace('{picto}', img_picto('', 'switch_off'), $desc); - $desc = str_replace('{picto2}', img_picto('', 'setup'), $desc); - if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled + $desc = str_replace('{picto}', img_picto('', 'switch_off', 'class="size15x"'), $desc); + $desc = str_replace('{picto2}', img_picto('', 'setup', 'class="size15x"'), $desc); + if (!count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled $deschelp = '
'.$desc."

\n"; } } diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index b622ef192ce..c91af2fcc36 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -332,8 +332,8 @@ foreach ($TCurrency as &$currency) { print ''; print '1 '.$conf->currency.' = '; print ' '.$currency->code.' '; - print ' '; - print ''; + print ' '; + print ''; print ''; print ''; } diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index db79a1503c9..38245b5e204 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -1,9 +1,10 @@ * Copyright (C) 2005-2015 Laurent Destailleur - * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2015 Bahfir Abbes * Copyright (C) 2020 Thibault FOUCART + * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -268,6 +269,8 @@ foreach ($listofnotifiedevents as $notifiedevent) { $label = $langs->trans("Notify_".$notifiedevent['code']); //!=$langs->trans("Notify_".$notifiedevent['code'])?$langs->trans("Notify_".$notifiedevent['code']):$notifiedevent['label']; $elementLabel = $langs->trans(ucfirst($notifiedevent['elementtype'])); + $model = $notifiedevent['elementtype']; + if ($notifiedevent['elementtype'] == 'order_supplier') { $elementLabel = $langs->trans('SupplierOrder'); } elseif ($notifiedevent['elementtype'] == 'propal') { diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index 6384c561967..3bc745a1101 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -198,6 +198,37 @@ if ($action == 'updateMask') { // par appel methode canBeActivated dolibarr_set_const($db, "PROPALE_ADDON", $value, 'chaine', 0, '', $conf->entity); +} elseif (preg_match('/set_(.*)/', $action, $reg)) { + $code = $reg[1]; + $value = (GETPOST($code) ? GETPOST($code) : 1); + + $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + if ($error) { + setEventMessages($langs->trans('Error'), null, 'errors'); + } else { + setEventMessages($langs->trans('SetupSaved'), null, 'mesgs'); + header("Location: " . $_SERVER["PHP_SELF"]); + exit(); + } +} elseif (preg_match('/del_(.*)/', $action, $reg)) { + $code = $reg[1]; + $res = dolibarr_del_const($db, $code, $conf->entity); + + if (!($res > 0)) { + $error++; + } + + if ($error) { + setEventMessages($langs->trans('Error'), null, 'errors'); + } else { + setEventMessages($langs->trans('SetupSaved'), null, 'mesgs'); + header("Location: " . $_SERVER["PHP_SELF"]); + exit(); + } } @@ -593,6 +624,28 @@ print ''; +print ''; +print ''; +print '' . $langs->trans('DefaultPuttingPricesUpToDate').''; +print ''; +print ''; +if (!empty($conf->use_javascript_ajax)) { + print ajax_constantonoff('PROPOSAL_CLONE_UPDATE_PRICES', array(), $conf->entity, 0, 0, 1, 0); +} else { + if (empty($conf->global->PROPOSAL_CLONE_UPDATE_PRICES)) { + print '' . img_picto($langs->trans('Disabled'), 'switch_off') . ''; + } else { + print '' . img_picto($langs->trans('Enabled'), 'switch_on') . ''; + } +} +print ''; +print ''; +print ''; +*/ + /* print '
'; print ''; diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index a2758304527..cb625dbe039 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -304,7 +304,15 @@ if ($mode == 'config' && $user->admin) { print ''; print ''.$langs->trans("Name").''; print ''.$langs->trans("Type").''; - print ''.$langs->trans("Profile").''; + print ''; + $htmltext = $langs->trans("PROFILE_DEFAULT").' = '.$langs->trans("PROFILE_DEFAULT_HELP").'
'; + $htmltext .= $langs->trans("PROFILE_SIMPLE").' = '.$langs->trans("PROFILE_SIMPLE_HELP").'
'; + $htmltext .= $langs->trans("PROFILE_EPOSTEP").' = '.$langs->trans("PROFILE_EPOSTEP_HELP").'
'; + $htmltext .= $langs->trans("PROFILE_P822D").' = '.$langs->trans("PROFILE_P822D_HELP").'
'; + $htmltext .= $langs->trans("PROFILE_STAR").' = '.$langs->trans("PROFILE_STAR_HELP").'
'; + + print $form->textwithpicto($langs->trans("Profile"), $htmltext); + print ''; print ''.$langs->trans("Parameters").''; print ''; print "\n"; @@ -386,17 +394,6 @@ if ($mode == 'config' && $user->admin) { print ''; print '
'; - - - print load_fiche_titre($langs->trans("ReceiptPrinterProfileDesc"), '', '')."\n"; - - print ''."\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print '
'.$langs->trans("PROFILE_DEFAULT").':'.$langs->trans("PROFILE_DEFAULT_HELP").'
'.$langs->trans("PROFILE_SIMPLE").':'.$langs->trans("PROFILE_SIMPLE_HELP").'
'.$langs->trans("PROFILE_EPOSTEP").':'.$langs->trans("PROFILE_EPOSTEP_HELP").'
'.$langs->trans("PROFILE_P822D").':'.$langs->trans("PROFILE_P822D_HELP").'
'.$langs->trans("PROFILE_STAR").':'.$langs->trans("PROFILE_STAR_HELP").'
'; } // mode = template diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php index 82df4bed430..67c6914f1cf 100644 --- a/htdocs/admin/security_file.php +++ b/htdocs/admin/security_file.php @@ -36,6 +36,14 @@ if (!$user->admin) { } $action = GETPOST('action', 'aZ09'); +$sortfield = GETPOST('sortfield', 'aZ09'); +$sortorder = GETPOST('sortorder', 'aZ09'); +if (empty($sortfield)) { + $sortfield = 'date'; +} +if (empty($sortorder)) { + $sortorder = 'desc'; +} $upload_dir = $conf->admin->dir_temp; @@ -73,8 +81,6 @@ if ($action == 'updateform') { } else { setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile', 'alpha')), null, 'errors'); } - Header('Location: '.$_SERVER["PHP_SELF"]); - exit; } @@ -190,7 +196,7 @@ $formfile = new FormFile($db); $formfile->form_attach_new_file($_SERVER['PHP_SELF'], $langs->trans("FormToTestFileUploadForm"), 0, 0, 1, 50, '', '', 1, '', 0); // List of document -$filearray = dol_dir_list($upload_dir, "files", 0, '', '', 'name', SORT_ASC, 1); +$filearray = dol_dir_list($upload_dir, "files", 0, '', '', $sortfield, $sortorder == 'desc' ? SORT_DESC : SORT_ASC, 1); $formfile->list_of_documents($filearray, null, 'admin_temp', ''); // End of page diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index c48acebe140..8a480ea49ca 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -266,10 +266,20 @@ print '
'; print '$dolibarr_main_restrict_ip: '; if (empty($dolibarr_main_restrict_ip)) { - print ''.$langs->trans("None").''; + print $langs->trans("None"); //print ' ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("IPsOfUsers")).')'; +} else { + print $dolibarr_main_restrict_ip; } +print '
'; +print '$dolibarr_main_restrict_os_commands: '; +if (empty($dolibarr_main_restrict_os_commands)) { + print $langs->trans("None"); +} else { + print $dolibarr_main_restrict_os_commands; +} +print ' ('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore').')'; print '
'; if (empty($conf->global->SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF)) { @@ -406,7 +416,7 @@ print '

'; print '
'; -print load_fiche_titre($langs->trans("OtherSetup").' ('.$langs->trans("Experimental").')', '', 'folder'); +print load_fiche_titre($langs->trans("OtherSetup"), '', 'folder'); //print ''.$langs->trans("PasswordEncryption").': '; @@ -439,19 +449,24 @@ print '
'; print 'MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE = '.(empty($conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE).'   ('.$langs->trans("Recommended").': 1)
'; print '
'; +print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.(empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN).'   ('.$langs->trans("Recommended").': 2)'."
"; +print '
'; + +print '
'; +print '
'; + + +print load_fiche_titre($langs->trans("OtherSetup").' ('.$langs->trans("Experimental").')', '', 'folder'); + print 'MAIN_RESTRICTHTML_ONLY_VALID_HTML = '.(empty($conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 1)' : $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML)."
"; print '
'; print 'MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = '.(empty($conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 1)' : $conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES)."
"; print '
'; -print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.(empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 2)' : $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)."
"; -print '
'; - print 'MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL = '.(empty($conf->global->MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)' : $conf->global->MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL)."
"; print '
'; - print 'MAIN_EXEC_USE_POPEN = '; if (empty($conf->global->MAIN_EXEC_USE_POPEN)) { print ''.$langs->trans("Undefined").''; diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index c36f6ae1d1b..ebf4187eabf 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -26,6 +26,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; require_once DOL_DOCUMENT_ROOT."/ticket/class/ticket.class.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/ticket.lib.php"; +require_once DOL_DOCUMENT_ROOT."/core/class/html.formcategory.class.php"; // Load translation files required by the page $langs->loadLangs(array("admin", "ticket")); @@ -157,6 +158,14 @@ if ($action == 'setvarworkflow') { } } +if ($action == 'setvarworkflowother' || $action == 'setvarworkflow') { + $param_ticket_product_category = GETPOST('product_category_id', 'int'); + $res = dolibarr_set_const($db, 'TICKET_PRODUCT_CATEGORY', $param_ticket_product_category, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } +} + if ($action == 'setvarother') { $param_must_exists = GETPOST('TICKET_EMAIL_MUST_EXISTS', 'alpha'); $res = dolibarr_set_const($db, 'TICKET_EMAIL_MUST_EXISTS', $param_must_exists, 'chaine', 0, '', $conf->entity); @@ -203,6 +212,12 @@ if ($action == 'setvarother') { if (!($res > 0)) { $error++; } + + $param_auto_notify_close = GETPOST('TICKET_NOTIFY_AT_CLOSING', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_NOTIFY_AT_CLOSING', $param_auto_notify_close, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } } @@ -213,7 +228,7 @@ if ($action == 'setvarother') { $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); -$form = new Form($db); +$formcategory = new FormCategory($db); $help_url = "FR:Module_Ticket"; $page_name = "TicketSetup"; @@ -320,7 +335,7 @@ foreach ($dirmodels as $reldir) { } print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $formcategory->textwithpicto('', $htmltooltip, 1, 0); print ''; print ''; @@ -458,7 +473,7 @@ foreach ($dirmodels as $reldir) { print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $formcategory->textwithpicto('', $htmltooltip, 1, 0); print ''; // Preview @@ -483,8 +498,7 @@ foreach ($dirmodels as $reldir) { print ''; print '

'; - -if (!$conf->use_javascript_ajax) { +if (empty($conf->use_javascript_ajax)) { print ''; print ''; print ''; @@ -506,11 +520,11 @@ if ($conf->use_javascript_ajax) { print ajax_constantonoff('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND", $arrval, $conf->global->TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND); + print $formcategory->selectarray("TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND", $arrval, $conf->global->TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND); } print ''; print ''; -print $form->textwithpicto('', $langs->trans("TicketsAutoReadTicketHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketsAutoReadTicketHelp"), 1, 'help'); print ''; print ''; @@ -522,17 +536,47 @@ if ($conf->use_javascript_ajax) { print ajax_constantonoff('TICKET_AUTO_ASSIGN_USER_CREATE'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_AUTO_ASSIGN_USER_CREATE", $arrval, $conf->global->TICKET_AUTO_ASSIGN_USER_CREATE); + print $formcategory->selectarray("TICKET_AUTO_ASSIGN_USER_CREATE", $arrval, $conf->global->TICKET_AUTO_ASSIGN_USER_CREATE); } print ''; print ''; -print $form->textwithpicto('', $langs->trans("TicketsAutoAssignTicketHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketsAutoAssignTicketHelp"), 1, 'help'); print ''; print ''; -if (!$conf->use_javascript_ajax) { - print ''; +// Auto notify contacts when closing the ticket +print ''.$langs->trans("TicketsAutoNotifyClose").''; +print ''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_NOTIFY_AT_CLOSING'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $formcategory->selectarray("TICKET_NOTIFY_AT_CLOSING", $arrval, $conf->global->TICKET_NOTIFY_AT_CLOSING); } +print ''; +print ''; +print $formcategory->textwithpicto('', $langs->trans("TicketsAutoNotifyCloseHelp"), 1, 'help'); +print ''; +print ''; + +// Choose which product category is used for tickets +if ($conf->use_javascript_ajax) { + print '
'; + print ''; + print ''; +} + +print ''.$langs->trans("TicketChooseProductCategory").''; +print ''; +$formcategory->selectProductCategory($conf->global->TICKET_PRODUCT_CATEGORY, 'product_category_id'); +if ($conf->use_javascript_ajax) { + print ajax_combobox('select_'.$htmlname); +} +print ''; +print ''; +print $formcategory->textwithpicto('', $langs->trans("TicketChooseProductCategoryHelp"), 1, 'help'); +print ''; +print ''; // Define wanted maximum time elapsed before answers to tickets print ''; @@ -545,7 +589,7 @@ print ' '; print ''; -print $form->textwithpicto('', $langs->trans("TicketsDelayBeforeFirstAnswerHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketsDelayBeforeFirstAnswerHelp"), 1, 'help'); print ''; print ''; @@ -556,14 +600,18 @@ print ' '; print ''; -print $form->textwithpicto('', $langs->trans("TicketsDelayBetweenAnswersHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketsDelayBetweenAnswersHelp"), 1, 'help'); print ''; print ''; -print '
'; - print '
'; +print '
'; +print ''; +print '
'; + +print ''; + // Admin var of module print load_fiche_titre($langs->trans("Notification"), '', ''); @@ -591,7 +639,7 @@ print ''.$langs->trans("TicketEmailNotificationFrom").'< print ''; print ''; print ''; -print $form->textwithpicto('', $langs->trans("TicketEmailNotificationFromHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketEmailNotificationFromHelp"), 1, 'help'); print ''; print ''; @@ -600,7 +648,7 @@ print ''.$langs->trans("TicketEmailNotificationTo").' (' print ''; print ''; print ''; -print $form->textwithpicto('', $langs->trans("TicketEmailNotificationToHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketEmailNotificationToHelp"), 1, 'help'); print ''; print ''; @@ -612,11 +660,11 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { print ajax_constantonoff('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS", $arrval, $conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS); + print $formcategory->selectarray("TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS", $arrval, $conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS); } print ''; print ''; - print $form->textwithpicto('', $langs->trans("TicketsEmailAlsoSendToMainAddressHelp"), 1, 'help'); + print $formcategory->textwithpicto('', $langs->trans("TicketsEmailAlsoSendToMainAddressHelp"), 1, 'help'); print ''; print ''; } @@ -630,7 +678,7 @@ $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_INTRO', $mail_intro, '100%', 120 $doleditor->Create(); print ''; print ''; -print $form->textwithpicto('', $langs->trans("TicketMessageMailIntroHelpAdmin"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketMessageMailIntroHelpAdmin"), 1, 'help'); print ''; // Texte de signature @@ -642,12 +690,12 @@ $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_SIGNATURE', $mail_signature, '10 $doleditor->Create(); print ''; print ''; -print $form->textwithpicto('', $langs->trans("TicketMessageMailSignatureHelpAdmin"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketMessageMailSignatureHelpAdmin"), 1, 'help'); print ''; print ''; -print $form->buttonsSaveCancel("Save", ''); +print $formcategory->buttonsSaveCancel("Save", ''); print ''; diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php index 818141e5cde..88a7db9b1d7 100644 --- a/htdocs/admin/ticket_public.php +++ b/htdocs/admin/ticket_public.php @@ -327,33 +327,6 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTextHelpMessageHelpAdmin"), 1, 'help'); print ''; - // Activate email creation to user - print ''.$langs->trans("TicketsDisableCustomerEmail").''; - print ''; - if ($conf->use_javascript_ajax) { - print ajax_constantonoff('TICKET_DISABLE_CUSTOMER_MAILS'); - } else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_DISABLE_CUSTOMER_MAILS", $arrval, $conf->global->TICKET_DISABLE_CUSTOMER_MAILS); - } - print ''; - print ''; - print $form->textwithpicto('', $langs->trans("TicketsDisableEmailHelp"), 1, 'help'); - print ''; - print ''; - - // Texte de création d'un ticket - $mail_mesg_new = $conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->trans('TicketNewEmailBody'); - print ''.$langs->trans("TicketNewEmailBodyLabel").''; - print ''; - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_NEW', $mail_mesg_new, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70); - $doleditor->Create(); - print ''; - print ''; - print $form->textwithpicto('', $langs->trans("TicketNewEmailBodyHelp"), 1, 'help'); - print ''; - // Url public interface $url_interface = $conf->global->TICKET_URL_PUBLIC_INTERFACE; print ''.$langs->trans("TicketUrlPublicInterfaceLabelAdmin").''; @@ -364,8 +337,45 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->textwithpicto('', $langs->trans("TicketUrlPublicInterfaceHelpAdmin"), 1, 'help'); print ''; + print ''; + + print '

'; + + print_fiche_titre($langs->trans("Emails")); + + print '
'; + print ''; + + // Activate email creation to user + print ''; + print ''; + print ''; + + // Text of email after creatio of a ticket + $mail_mesg_new = $conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->trans('TicketNewEmailBody'); + print ''; + print ''; + // Activate email notification when a new message is added - print ''; + print ''; print ''; - print ''; print ''; // Send notification when a new message is added to a email if a user is not assigned to the ticket - print ''; print ''; - print ''; + print ''; print '
'; + print $form->textwithpicto($langs->trans("TicketsDisableCustomerEmail"), $langs->trans("TicketsDisableEmailHelp"), 1, 'help'); + print ''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_DISABLE_CUSTOMER_MAILS'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("TICKET_DISABLE_CUSTOMER_MAILS", $arrval, $conf->global->TICKET_DISABLE_CUSTOMER_MAILS); + } + print '
'; + print $form->textwithpicto($langs->trans("TicketNewEmailBodyLabel"), $langs->trans("TicketNewEmailBodyHelp"), 1, 'help'); + print ''; + print ''; + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_NEW', $mail_mesg_new, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70); + $doleditor->Create(); + print '
'.$langs->trans("TicketsPublicNotificationNewMessage").'
'; + print $form->textwithpicto($langs->trans("TicketsPublicNotificationNewMessage"), $langs->trans("TicketsPublicNotificationNewMessageHelp"), 1, 'help'); + print ''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED'); @@ -374,19 +384,15 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->selectarray("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED", $arrval, $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED); } print ''; - print $form->textwithpicto('', $langs->trans("TicketsPublicNotificationNewMessageHelp"), 1, 'help'); - print '
'.$langs->trans("TicketPublicNotificationNewMessageDefaultEmail").''; + print '
'; + print $form->textwithpicto($langs->trans("TicketPublicNotificationNewMessageDefaultEmail"), $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help'); print ''; print ''; - print $form->textwithpicto('', $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help'); - print '
'; print '
'; diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 6ed3bd00863..36136aeef24 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -214,10 +214,6 @@ if (in_array($type, array('mysql', 'mysqli'))) { print '
'; print '
'.$langs->trans("ExportOptions").''; - print '
'; - print ''; - print ''; - print '
'; if (!empty($conf->global->MYSQL_OLD_OPTION_DISABLE_FK)) { print '
'; @@ -239,14 +235,35 @@ if (in_array($type, array('mysql', 'mysqli'))) { print ''; print ''; print ''; - print '
'; + print '

'; - print ''; + print '
'; + print ''; + print ''; + print '
'; + + print ''; print ''; print '
'; + $execmethod = 0; + if (!empty($conf->global->MAIN_EXEC_USE_POPEN)) { + $execmethod = $conf->global->MAIN_EXEC_USE_POPEN; + } + if (empty($execmethod)) { + $execmethod = 1; + } + if ($execmethod == 1) { + // If we use the "exec" method for shell, we ask if we need to use the alternative low memory exec mode. + print ''; + print ''; + print '
'; + } + print ''; diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index 36be1f273ff..bc627cc14f0 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -137,7 +137,8 @@ $dirtocompress = basename($fulldirtocompress); if ($compression == 'zip') { $file .= '.zip'; - $excludefiles = '/(\.back|\.old|\.log|\.pdf_preview-.*\.png|[\/\\\]temp[\/\\\]|documents[\/\\\]admin[\/\\\]documents[\/\\\])/i'; + + $excludefiles = '/(\.back|\.old|\.log|\.pdf_preview-.*\.png|[\/\\\]temp[\/\\\]|[\/\\\]admin[\/\\\]documents[\/\\\])/i'; //var_dump($fulldirtocompress); //var_dump($outputdir."/".$file);exit; @@ -173,7 +174,7 @@ if ($compression == 'zip') { // We also exclude '/temp/' dir and 'documents/admin/documents' // We make escapement here and call executeCLI without escapement because we don't want to have the '*.log' escaped. - $cmd = "tar -cf ".escapeshellcmd($outputdir."/".$file)." --exclude-vcs --exclude-caches-all --exclude='temp' --exclude='*.log' --exclude='*.pdf_preview-*.png' --exclude='documents/admin/documents' -C '".escapeshellcmd(dol_sanitizePathName($dirtoswitch))."' '".escapeshellcmd(dol_sanitizeFileName($dirtocompress))."'"; + $cmd = "tar -cf '".escapeshellcmd($outputdir."/".$file)."' --exclude-vcs --exclude-caches-all --exclude='temp' --exclude='*.log' --exclude='*.pdf_preview-*.png' --exclude='documents/admin/documents' -C '".escapeshellcmd(dol_sanitizePathName($dirtoswitch))."' '".escapeshellcmd(dol_sanitizeFileName($dirtocompress))."'"; $result = $utils->executeCLI($cmd, $outputfile, 0, null, 1); diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index a58c3378ecd..a68f49e36e3 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -71,6 +71,12 @@ $workflowcodes = array( 'enabled'=>(!empty($conf->commande->enabled) && !empty($conf->facture->enabled)), 'picto'=>'bill' ), + 'WORKFLOW_TICKET_CREATE_INTERVENTION' => array ( + 'family'=>'create', + 'position'=>25, + 'enabled'=>(!empty($conf->ticket->enabled) && !empty($conf->ficheinter->enabled)), + 'picto'=>'ticket' + ), 'separator1'=>array('family'=>'separator', 'position'=>25, 'title'=>''), @@ -161,7 +167,21 @@ $workflowcodes = array( 'position' => 90, 'enabled' => ! empty($conf->expedition->enabled) && ! empty($conf->facture->enabled), 'picto' => 'shipment' - ) + ), + + // Automatic link ticket -> contract + 'WORKFLOW_TICKET_LINK_CONTRACT' => array( + 'family' => 'link_ticket', + 'position' => 75, + 'enabled' => ! empty($conf->ticket->enabled) && ! empty($conf->contract->enabled), + 'picto' => 'ticket' + ), + 'WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS' => array( + 'family' => 'link_ticket', + 'position' => 76, + 'enabled' => ! empty($conf->ticket->enabled) && ! empty($conf->contract->enabled), + 'picto' => 'ticket' + ), ); if (!empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts['workflow'])) { @@ -237,6 +257,11 @@ foreach ($workflowcodes as $key => $params) { if ($reg[1] == 'shipping') { $header .= ' - '.$langs->trans('Shipment'); } + } elseif (preg_match('/link_(.*)/', $params['family'], $reg)) { + $header = $langs->trans("AutomaticLinking"); + if ($reg[1] == 'ticket') { + $header .= ' - '.$langs->trans('Ticket'); + } } else { $header = $langs->trans("Description"); } diff --git a/htdocs/api/README.md b/htdocs/api/README.md index 7ab85cc26bb..1af112920ce 100644 --- a/htdocs/api/README.md +++ b/htdocs/api/README.md @@ -41,7 +41,7 @@ https://**yourdolibarr.tld**/mydolibarr/api/index.php/otherservice?DOLAPIKEY=**a Develop an API -------------- -The API uses Lucarast Restler framework. Please check documentation https://www.luracast.com/products/restler and examples http://help.luracast.com/restler/examples/ +The API uses Lucarast Restler framework. Please check documentation https://www.luracast.com/products/restler and examples https://restler3.luracast.com/examples/index.html Github contains also useful information : https://github.com/Luracast/Restler diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 28dbef6887e..da49e4cbba7 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -126,7 +126,7 @@ class Documents extends DolibarrApi * @param string $langcode Language code like 'en_US', 'fr_FR', 'es_ES', ... (If not set, use the default language). * @return array List of documents * - * @throws RestException 500 + * @throws RestException 500 System error * @throws RestException 501 * @throws RestException 400 * @throws RestException 401 @@ -249,7 +249,7 @@ class Documents extends DolibarrApi * @throws RestException 400 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @url GET / */ @@ -546,7 +546,7 @@ class Documents extends DolibarrApi * @throws RestException 400 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @url POST /upload */ diff --git a/htdocs/api/index.php b/htdocs/api/index.php index d5bc7e273e2..c66573e8022 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -158,6 +158,25 @@ if (!empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $ $api = new DolibarrApi($db, '', $refreshcache); //var_dump($api->r->apiVersionMap); +// If MAIN_API_DEBUG is set to 1, we save logs into file "dolibarr_api.log" +if (!empty($conf->global->MAIN_API_DEBUG)) { + $r = $api->r; + $r->onCall(function () use ($r) { + // Don't log Luracast Restler Explorer recources calls + //if (!preg_match('/^explorer/', $r->url)) { + // 'method' => $api->r->requestMethod, + // 'url' => $api->r->url, + // 'route' => $api->r->apiMethodInfo->className.'::'.$api->r->apiMethodInfo->methodName, + // 'version' => $api->r->getRequestedApiVersion(), + // 'data' => $api->r->getRequestData(), + //dol_syslog("Debug API input ".var_export($r, true), LOG_DEBUG, 0, '_api'); + dol_syslog("Debug API url ".var_export($r->url, true), LOG_DEBUG, 0, '_api'); + dol_syslog("Debug API input ".var_export($r->getRequestData(), true), LOG_DEBUG, 0, '_api'); + //} + }); +} + + // Enable the Restler API Explorer. // See https://github.com/Luracast/Restler-API-Explorer for more info. $api->r->addAPIClass('Luracast\\Restler\\Explorer'); diff --git a/htdocs/asset/accountancy_codes.php b/htdocs/asset/accountancy_codes.php new file mode 100644 index 00000000000..431b4ba7c68 --- /dev/null +++ b/htdocs/asset/accountancy_codes.php @@ -0,0 +1,189 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/accountancy_code.php + * \ingroup asset + * \brief Card with accountancy code on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Asset($db); +$assetaccountancycodes = new AssetAccountancyCodes($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetaccountancycodes', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); + +$result = $assetaccountancycodes->fetchAccountancyCodes($object->id); +if ($result < 0) { + setEventMessages($assetaccountancycodes->error, $assetaccountancycodes->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/asset/accountancy_codes.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } + + if ($action == "update") { + $assetaccountancycodes->setAccountancyCodesFromPost(); + + $result = $assetaccountancycodes->updateAccountancyCodes($user, $object->id); + if ($result < 0) { + setEventMessages($assetaccountancycodes->error, $assetaccountancycodes->errors, 'errors'); + $action = 'edit'; + } else { + setEventMessage($langs->trans('RecordSaved')); + header("Location: " . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('Asset'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetPrepareHead($object); + print dol_get_fiche_head($head, 'accountancy_codes', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
'; + $morehtmlref .= '
'; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
'; + print '
'; + print '
'; + + if ($action == 'edit') { + print '
'; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + include DOL_DOCUMENT_ROOT . '/asset/tpl/accountancy_codes_edit.tpl.php'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print '
'; + } else { + include DOL_DOCUMENT_ROOT . '/asset/tpl/accountancy_codes_view.tpl.php'; + } + + print dol_get_fiche_end(); + + if ($action != 'edit') { + print '
' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT/* && !empty($object->enabled_modes)*/) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + } + print '
' . "\n"; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/admin/assets_type_extrafields.php b/htdocs/asset/admin/asset_extrafields.php similarity index 56% rename from htdocs/asset/admin/assets_type_extrafields.php rename to htdocs/asset/admin/asset_extrafields.php index 165361f7f57..a84d3bc2016 100644 --- a/htdocs/asset/admin/assets_type_extrafields.php +++ b/htdocs/asset/admin/asset_extrafields.php @@ -1,5 +1,11 @@ +/* Copyright (C) 2001-2002 Rodolphe Quiedeville + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2018 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,20 +19,20 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * or see https://www.gnu.org/ */ /** - * \file htdocs/asset/admin/assets_type_extrafields.php - * \ingroup asset - * \brief Page to setup extra fields type of assets + * \file htdocs/asset/admin/asset_extrafields.php + * \ingroup asset + * \brief Page to setup extra fields of asset */ + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; // Load translation files required by the page -$langs->loadLangs(array('assets', 'admin')); +$langs->loadLangs(array("assets", "admin", "companies")); $extrafields = new ExtraFields($db); $form = new Form($db); @@ -40,7 +46,7 @@ foreach ($tmptype2label as $key => $val) { $action = GETPOST('action', 'aZ09'); $attrname = GETPOST('attrname', 'alpha'); -$elementtype = 'adherent_type'; //Must be the $table_element of the class that manage extrafield +$elementtype = 'asset'; //Must be the $table_element of the class that manage extrafield if (!$user->admin) { accessforbidden(); @@ -59,38 +65,47 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ -$textobject = $langs->transnoentitiesnoconv("AssetsTypes"); +$help_url = ''; +$page_name = "AssetSetup"; +$textobject = $langs->transnoentitiesnoconv("Assets"); -llxHeader('', $langs->trans("AssetsSetup")); - -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("AssetsSetup"), $linkback, 'title_setup'); +llxHeader('', $langs->trans("AssetSetup"), $help_url); -$head = asset_admin_prepare_head(); +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); -print dol_get_fiche_head($head, 'attributes_type', $langs->trans("Assets"), -1, 'generic'); + +$head = assetAdminPrepareHead(); + +print dol_get_fiche_head($head, 'asset_extrafields', $langs->trans($page_name), -1, 'asset'); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; print dol_get_fiche_end(); + // Buttons if ($action != 'create' && $action != 'edit') { print '"; } -// Creation of an optional field + +/* + * Creation of an optional field + */ if ($action == 'create') { - print "
"; + print '
'; print load_fiche_titre($langs->trans('NewAttribute')); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; } -// Edition of an optional field +/* + * Edition of an optional field + */ if ($action == 'edit' && !empty($attrname)) { print "
"; print load_fiche_titre($langs->trans("FieldEdition", $attrname)); diff --git a/htdocs/asset/admin/assets_extrafields.php b/htdocs/asset/admin/assetmodel_extrafields.php similarity index 54% rename from htdocs/asset/admin/assets_extrafields.php rename to htdocs/asset/admin/assetmodel_extrafields.php index 9a68f99fe06..387c43df635 100644 --- a/htdocs/asset/admin/assets_extrafields.php +++ b/htdocs/asset/admin/assetmodel_extrafields.php @@ -1,6 +1,11 @@ - * Copyright (C) 2018 Alexandre Spangaro +/* Copyright (C) 2001-2002 Rodolphe Quiedeville + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2018 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,9 +22,9 @@ */ /** - * \file htdocs/asset/admin/assets_extrafields.php + * \file htdocs/asset/admin/assetmodel_extrafields.php * \ingroup asset - * \brief Page to setup extra fields of assets + * \brief Page to setup extra fields of asset model */ require '../../main.inc.php'; @@ -41,7 +46,7 @@ foreach ($tmptype2label as $key => $val) { $action = GETPOST('action', 'aZ09'); $attrname = GETPOST('attrname', 'alpha'); -$elementtype = 'don'; //Must be the $table_element of the class that manage extrafield +$elementtype = 'asset_model'; //Must be the $table_element of the class that manage extrafield if (!$user->admin) { accessforbidden(); @@ -60,17 +65,20 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ -$textobject = $langs->transnoentitiesnoconv("Assets"); +$help_url = ''; +$page_name = "AssetSetup"; +$textobject = $langs->transnoentitiesnoconv("AssetModels"); -llxHeader('', $langs->trans("AssetsSetup")); - -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("AssetsSetup"), $linkback, 'title_setup'); +llxHeader('', $langs->trans("AssetSetup"), $help_url); -$head = asset_admin_prepare_head(); +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); -print dol_get_fiche_head($head, 'attributes', $langs->trans("Assets"), -1, 'generic'); + +$head = assetAdminPrepareHead(); + +print dol_get_fiche_head($head, 'assetmodel_extrafields', $langs->trans($page_name), -1, 'asset'); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; @@ -80,29 +88,24 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } -/* ************************************************************************** */ -/* */ -/* Create optional field */ -/* */ -/* ************************************************************************** */ - +/* + * Creation of an optional field + */ if ($action == 'create') { - print "
"; + print '
'; print load_fiche_titre($langs->trans('NewAttribute')); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; } -/* ************************************************************************** */ -/* */ -/* Edit optional field */ -/* */ -/* ************************************************************************** */ +/* + * Edition of an optional field + */ if ($action == 'edit' && !empty($attrname)) { print "
"; print load_fiche_titre($langs->trans("FieldEdition", $attrname)); diff --git a/htdocs/asset/admin/setup.php b/htdocs/asset/admin/setup.php index a90c2b479c4..afa4777de3d 100644 --- a/htdocs/asset/admin/setup.php +++ b/htdocs/asset/admin/setup.php @@ -18,8 +18,8 @@ /** * \file htdocs/asset/admin/setup.php - * \ingroup assets - * \brief Assets setup page. + * \ingroup asset + * \brief Asset setup page. */ require '../../main.inc.php'; @@ -40,30 +40,421 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); -$arrayofparameters = array('FIXEDASSETS_MYPARAM1'=>array('css'=>'minwidth200'), 'FIXEDASSETS_MYPARAM2'=>array('css'=>'minwidth500')); +$value = GETPOST('value', 'alpha'); +$label = GETPOST('label', 'alpha'); +$scandir = GETPOST('scan_dir', 'alpha'); +$type = 'asset'; + +$arrayofparameters = array( + 'ASSET_ACCOUNTANCY_CATEGORY'=>array('type'=>'accountancy_category', 'enabled'=>1), + 'ASSET_DEPRECIATION_DURATION_PER_YEAR'=>array('type'=>'string', 'css'=>'minwidth200', 'enabled'=>1), + //'ASSET_MYPARAM2'=>array('type'=>'textarea','enabled'=>1), + //'ASSET_MYPARAM3'=>array('type'=>'category:'.Categorie::TYPE_CUSTOMER, 'enabled'=>1), + //'ASSET_MYPARAM4'=>array('type'=>'emailtemplate:thirdparty', 'enabled'=>1), + //'ASSET_MYPARAM5'=>array('type'=>'yesno', 'enabled'=>1), + //'ASSET_MYPARAM5'=>array('type'=>'thirdparty_type', 'enabled'=>1), + //'ASSET_MYPARAM6'=>array('type'=>'securekey', 'enabled'=>1), + //'ASSET_MYPARAM7'=>array('type'=>'product', 'enabled'=>1), +); + +$error = 0; +$setupnotempty = 0; + +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); /* * Actions */ -include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +if ((float) DOL_VERSION >= 6) { + include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +} + +if ($action == 'updateMask') { + $maskconstorder = GETPOST('maskconstorder', 'alpha'); + $maskorder = GETPOST('maskorder', 'alpha'); + + if ($maskconstorder) { + $res = dolibarr_set_const($db, $maskconstorder, $maskorder, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + } + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} elseif ($action == 'specimen') { + $modele = GETPOST('module', 'alpha'); + $tmpobjectkey = GETPOST('object'); + + $tmpobject = new $tmpobjectkey($db); + $tmpobject->initAsSpecimen(); + + // Search template files + $file = ''; $classname = ''; $filefound = 0; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $file = dol_buildpath($reldir."core/modules/asset/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0); + if (file_exists($file)) { + $filefound = 1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($tmpobject, $langs) > 0) { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); + return; + } else { + setEventMessages($module->error, null, 'errors'); + dol_syslog($module->error, LOG_ERR); + } + } else { + setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} elseif ($action == 'setmod') { + // TODO Check if numbering module chosen can be activated by calling method canBeActivated + $tmpobjectkey = GETPOST('object'); + if (!empty($tmpobjectkey)) { + $constforval = 'ASSET_'.strtoupper($tmpobjectkey)."_ADDON"; + dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity); + } +} elseif ($action == 'set') { + // Activate a model + $ret = addDocumentModel($value, $type, $label, $scandir); +} elseif ($action == 'del') { + $ret = delDocumentModel($value, $type); + if ($ret > 0) { + $tmpobjectkey = GETPOST('object'); + if (!empty($tmpobjectkey)) { + $constforval = 'ASSET_'.strtoupper($tmpobjectkey).'_ADDON_PDF'; + if ($conf->global->$constforval == "$value") { + dolibarr_del_const($db, $constforval, $conf->entity); + } + } + } +} elseif ($action == 'setdoc') { + // Set or unset default model + $tmpobjectkey = GETPOST('object'); + if (!empty($tmpobjectkey)) { + $constforval = 'ASSET_'.strtoupper($tmpobjectkey).'_ADDON_PDF'; + if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity)) { + // The constant that was read before the new set + // We therefore requires a variable to have a coherent view + $conf->global->$constforval = $value; + } + + // We disable/enable the document template (into llx_document_model table) + $ret = delDocumentModel($value, $type); + if ($ret > 0) { + $ret = addDocumentModel($value, $type, $label, $scandir); + } + } +} elseif ($action == 'unsetdoc') { + $tmpobjectkey = GETPOST('object'); + if (!empty($tmpobjectkey)) { + $constforval = 'ASSET_'.strtoupper($tmpobjectkey).'_ADDON_PDF'; + dolibarr_del_const($db, $constforval, $conf->entity); + } +} + /* * View */ -llxHeader('', $langs->trans("AssetsSetup")); +$form = new Form($db); -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("AssetsSetup"), $linkback, 'title_setup'); +$help_url = ''; +$page_name = "AssetSetup"; + +llxHeader('', $langs->trans($page_name), $help_url); + +// Subheader +$linkback = ''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); + +// Configuration header +$head = assetAdminPrepareHead(); +print dol_get_fiche_head($head, 'settings', $langs->trans($page_name), -1, "asset"); + +// Setup page goes here +echo ''.$langs->trans("AssetSetupPage").''; -$head = asset_admin_prepare_head(); +$moduledir = 'asset'; +$myTmpObjects = array(); +$myTmpObjects['Asset'] = array('includerefgeneration'=>1, 'includedocgeneration'=>0); -print dol_get_fiche_head($head, 'settings', $langs->trans("Assets"), -1, 'generic'); +foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { + if ($myTmpObjectKey == 'MyObject') { + continue; + } + if ($myTmpObjectArray['includerefgeneration']) { + /* + * Orders Numbering model + */ + $setupnotempty++; + + print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', ''); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/".$moduledir); + + if (is_dir($dir)) { + $handle = opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') { + $file = substr($file, 0, dol_strlen($file) - 4); + + require_once $dir.'/'.$file.'.php'; + + $module = new $file($db); + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) { + continue; + } + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) { + continue; + } + + if ($module->isEnabled()) { + dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php'); + + print ''; + + // Show example of numbering model + print ''."\n"; + + print ''; + + $mytmpinstance = new $myTmpObjectKey($db); + $mytmpinstance->initAsSpecimen(); + + // Info + $htmltooltip = ''; + $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; + + $nextval = $module->getNextValue($mytmpinstance); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip .= ''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') { + $nextval = $langs->trans($nextval); + } + $htmltooltip .= $nextval.'
'; + } else { + $htmltooltip .= $langs->trans($module->error).'
'; + } + } + + print ''; + + print "\n"; + } + } + } + closedir($handle); + } + } + } + print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; + print $module->info(); + print ''; + $tmp = $module->getExample(); + if (preg_match('/^Error/', $tmp)) { + $langs->load("errors"); + print '
'.$langs->trans($tmp).'
'; + } elseif ($tmp == 'NotConfigured') { + print $langs->trans($tmp); + } else { + print $tmp; + } + print '
'; + $constforvar = 'ASSET_'.strtoupper($myTmpObjectKey).'_ADDON'; + if ($conf->global->$constforvar == $file) { + print img_picto($langs->trans("Activated"), 'switch_on'); + } else { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print '

\n"; + } + + if ($myTmpObjectArray['includedocgeneration']) { + /* + * Document templates generators + */ + $setupnotempty++; + $type = strtolower($myTmpObjectKey); + + print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', ''); + + // Load array def with activated templates + $def = array(); + $sql = "SELECT nom"; + $sql .= " FROM ".MAIN_DB_PREFIX."document_model"; + $sql .= " WHERE type = '".$db->escape($type)."'"; + $sql .= " AND entity = ".$conf->entity; + $resql = $db->query($sql); + if ($resql) { + $i = 0; + $num_rows = $db->num_rows($resql); + while ($i < $num_rows) { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } + } else { + dol_print_error($db); + } + + print "\n"; + print "\n"; + print ''; + print ''; + print '\n"; + print '\n"; + print ''; + print ''; + print "\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) { + foreach (array('', '/doc') as $valdir) { + $realpath = $reldir."core/modules/".$moduledir.$valdir; + $dir = dol_buildpath($realpath); + + if (is_dir($dir)) { + $handle = opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + $filelist[] = $file; + } + closedir($handle); + arsort($filelist); + + foreach ($filelist as $file) { + if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) { + if (file_exists($dir.'/'.$file)) { + $name = substr($file, 4, dol_strlen($file) - 16); + $classname = substr($file, 0, dol_strlen($file) - 12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified = 1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) { + $modulequalified = 0; + } + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) { + $modulequalified = 0; + } + + if ($modulequalified) { + print ''; + + // Active + if (in_array($name, $def)) { + print ''; + } else { + print '"; + } + + // Default + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip .= '
'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); + if ($module->type == 'pdf') { + $htmltooltip .= '
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip .= '
'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file; + + $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); + $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } + } + + print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name) ? $name : $module->name); + print "\n"; + if (method_exists($module, 'info')) { + print $module->info($langs); + } else { + print $module->description; + } + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"), 'switch_on'); + print ''; + print ''."\n"; + print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print "'; + $constforvar = 'ASSET_'.strtoupper($myTmpObjectKey).'_ADDON'; + if ($conf->global->$constforvar == $name) { + //print img_picto($langs->trans("Default"), 'on'); + // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset + print 'scandir).'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; + } else { + print 'scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print ''; + if ($module->type == 'pdf') { + print ''.img_object($langs->trans("Preview"), 'pdf').''; + } else { + print img_object($langs->trans("PreviewNotAvailable"), 'generic'); + } + print '
'; + } +} if ($action == 'edit') { print '
'; @@ -73,37 +464,221 @@ if ($action == 'edit') { print ''; print ''; - foreach ($arrayofparameters as $key => $val) { - print ''; - } + foreach ($arrayofparameters as $constname => $val) { + if ($val['enabled']==1) { + $setupnotempty++; + print ''; + } + } print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print $form->textwithpicto($langs->trans($key), $langs->trans($key.'Tooltip')); - print '
'; + $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); + print ''.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).''; + print ''; + if ($val['type'] == 'textarea') { + print '\n"; + } elseif ($val['type']== 'html') { + require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; + $doleditor = new DolEditor($constname, $conf->global->{$constname}, '', 160, 'dolibarr_notes', '', false, false, $conf->fckeditor->enabled, ROWS_5, '90%'); + $doleditor->Create(); + } elseif ($val['type'] == 'yesno') { + print $form->selectyesno($constname, $conf->global->{$constname}, 1); + } elseif (preg_match('/emailtemplate:/', $val['type'])) { + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $tmp = explode(':', $val['type']); + $nboftemplates = $formmail->fetchAllEMailTemplate($tmp[1], $user, null, 1); // We set lang=null to get in priority record with no lang + //$arraydefaultmessage = $formmail->getEMailTemplate($db, $tmp[1], $user, null, 0, 1, ''); + $arrayofmessagename = array(); + if (is_array($formmail->lines_model)) { + foreach ($formmail->lines_model as $modelmail) { + //var_dump($modelmail); + $moreonlabel = ''; + if (!empty($arrayofmessagename[$modelmail->label])) { + $moreonlabel = ' (' . $langs->trans("SeveralLangugeVariatFound") . ')'; + } + // The 'label' is the key that is unique if we exclude the language + $arrayofmessagename[$modelmail->id] = $langs->trans(preg_replace('/\(|\)/', '', $modelmail->label)) . $moreonlabel; + } + } + print $form->selectarray($constname, $arrayofmessagename, $conf->global->{$constname}, 'None', 0, 0, '', 0, 0, 0, '', '', 1); + } elseif (preg_match('/category:/', $val['type'])) { + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + $formother = new FormOther($db); + + $tmp = explode(':', $val['type']); + print img_picto('', 'category', 'class="pictofixedwidth"'); + print $formother->select_categories($tmp[1], $conf->global->{$constname}, $constname, 0, $langs->trans('CustomersProspectsCategoriesShort')); + } elseif (preg_match('/thirdparty_type/', $val['type'])) { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; + $formcompany = new FormCompany($db); + print $formcompany->selectProspectCustomerType($conf->global->{$constname}, $constname); + } elseif ($val['type'] == 'securekey') { + print ''; + if (!empty($conf->use_javascript_ajax)) { + print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token'.$constname.'" class="linkobject"'); + } + if (!empty($conf->use_javascript_ajax)) { + print "\n".''; + } + } elseif ($val['type'] == 'product') { + if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { + $selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname); + $form->select_produits($selected, $constname, '', 0); + } + } elseif ($val['type'] == 'accountancy_code') { + $selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname); + if (!empty($conf->accounting->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; + $formaccounting = new FormAccounting($db); + print $formaccounting->select_account($selected, $constname, 1, null, 1, 1, 'minwidth150 maxwidth300', 1); + } else { + print ''; + } + } elseif ($val['type'] == 'accountancy_category') { + $selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname); + if (!empty($conf->accounting->enabled)) { + print ''; + // autosuggest from existing account types if found + print ''; + require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountancysystem.class.php'; + $accountsystem = new AccountancySystem($db); + $accountsystem->fetch($conf->global->CHARTOFACCOUNTS); + $sql = 'SELECT DISTINCT pcg_type FROM ' . MAIN_DB_PREFIX . 'accounting_account'; + $sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'"; + $sql .= ' AND entity in ('.getEntity('accounting_account', 0).')'; // Always limit to current entity. No sharing in accountancy. + $sql .= ' LIMIT 50000'; // just as a sanity check + $resql = $db->query($sql); + if ($resql) { + while ($obj = $db->fetch_object($resql)) { + print ''; + } else { + print ''; + } + } else { + print ''; + } + print '
'; - print $form->buttonsSaveCancel("Save", ''); + print '
'; + print ''; + print '
'; print '
'; print '
'; } else { - print ''; - print ''; + if (!empty($arrayofparameters)) { + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print ''; - foreach ($arrayofparameters as $key => $val) { - print ''; + foreach ($arrayofparameters as $constname => $val) { + if ($val['enabled']==1) { + $setupnotempty++; + print ''; + } + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print $form->textwithpicto($langs->trans($key), $langs->trans($key.'Tooltip')); - print ''.$conf->global->$key.'
'; + $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); + print $form->textwithpicto($langs->trans($constname), $tooltiphelp); + print ''; + + if ($val['type'] == 'textarea') { + print dol_nl2br($conf->global->{$constname}); + } elseif ($val['type']== 'html') { + print $conf->global->{$constname}; + } elseif ($val['type'] == 'yesno') { + print ajax_constantonoff($constname); + } elseif (preg_match('/emailtemplate:/', $val['type'])) { + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $tmp = explode(':', $val['type']); + + $template = $formmail->getEMailTemplate($db, $tmp[1], $user, $langs, $conf->global->{$constname}); + if ($template<0) { + setEventMessages(null, $formmail->errors, 'errors'); + } + print $langs->trans($template->label); + } elseif (preg_match('/category:/', $val['type'])) { + $c = new Categorie($db); + $result = $c->fetch($conf->global->{$constname}); + if ($result < 0) { + setEventMessages(null, $c->errors, 'errors'); + } elseif ($result > 0 ) { + $ways = $c->print_all_ways(' >> ', 'none', 0, 1); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text + $toprint = array(); + foreach ($ways as $way) { + $toprint[] = '
  • color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . $way . '
  • '; + } + print '
      ' . implode(' ', $toprint) . '
    '; + } + } elseif (preg_match('/thirdparty_type/', $val['type'])) { + if ($conf->global->{$constname}==2) { + print $langs->trans("Prospect"); + } elseif ($conf->global->{$constname}==3) { + print $langs->trans("ProspectCustomer"); + } elseif ($conf->global->{$constname}==1) { + print $langs->trans("Customer"); + } elseif ($conf->global->{$constname}==0) { + print $langs->trans("NorProspectNorCustomer"); + } + } elseif ($val['type'] == 'product') { + $product = new Product($db); + $resprod = $product->fetch($conf->global->{$constname}); + if ($resprod > 0) { + print $product->ref; + } elseif ($resprod < 0) { + setEventMessages(null, $object->errors, "errors"); + } + } elseif ($val['type'] == 'accountancy_code') { + if (!empty($conf->accounting->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('', $conf->global->{$constname}, 1); + + print $accountingaccount->getNomUrl(0, 1, 1, '', 1); + } else { + print $conf->global->{$constname}; + } + } else { + print $conf->global->{$constname}; + } + print '
    '; + + print '
    '; + print ''.$langs->trans("Modify").''; + print '
    '; + } else { + print '
    '.$langs->trans("NothingToSetup"); } - - print ''; - - print '
    '; - print ''.$langs->trans("Modify").''; - print '
    '; } +if (empty($setupnotempty)) { + print '
    '.$langs->trans("NothingToSetup"); +} + +// Page end print dol_get_fiche_end(); -// End of page llxFooter(); $db->close(); diff --git a/htdocs/asset/agenda.php b/htdocs/asset/agenda.php new file mode 100644 index 00000000000..49a0c215701 --- /dev/null +++ b/htdocs/asset/agenda.php @@ -0,0 +1,215 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/agenda.php + * \ingroup asset + * \brief Tab of events on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +if (GETPOST('actioncode', 'array')) { + $actioncode = GETPOST('actioncode', 'array', 3); + if (!count($actioncode)) { + $actioncode = '0'; + } +} else { + $actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); +} +$search_agenda_label = GETPOST('search_agenda_label'); + +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page == -1) { + $page = 0; +} // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortfield) { + $sortfield = 'a.datep,a.id'; +} +if (!$sortorder) { + $sortorder = 'DESC,DESC'; +} + +// Initialize technical objects +$object = new Asset($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetagenda', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity]."/".$object->id; +} + +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); + + +/* + * Actions + */ + +$parameters = array('id'=>$id); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + // Cancel + if (GETPOST('cancel', 'alpha') && !empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + + // Purge search criteria + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers + $actioncode = ''; + $search_agenda_label = ''; + } +} + + + +/* + * View + */ + +$form = new Form($db); + +if ($object->id > 0) { + $title = $langs->trans("Agenda"); + //if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title; + $help_url = 'EN:Module_Agenda_En'; + llxHeader('', $title, $help_url); + + if (!empty($conf->notification->enabled)) { + $langs->load("mails"); + } + $head = assetPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + + $object->info($object->id); + dol_print_object_info($object, 1); + + print '
    '; + + print dol_get_fiche_end(); + + + // Actions buttons + + $objthirdparty = $object; + $objcon = new stdClass(); + + $out = '&origin=' . urlencode($object->element . '@' . $object->module) . '&originid=' . urlencode($object->id); + $urlbacktopage = $_SERVER['PHP_SELF'] . '?id=' . $object->id; + $out .= '&backtopage=' . urlencode($urlbacktopage); + $permok = $user->rights->agenda->myactions->create; + if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) { + //$out.='trans("AddAnAction"),'filenew'); + //$out.=""; + } + + + print '
    '; + + if (!empty($conf->agenda->enabled)) { + if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) { + print '' . $langs->trans("AddAction") . ''; + } else { + print '' . $langs->trans("AddAction") . ''; + } + } + + print '
    '; + + if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { + $param = '&id=' . $object->id . '&socid=' . $socid; + if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage=' . urlencode($contextpage); + } + if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit=' . urlencode($limit); + } + + + print load_fiche_titre($langs->trans("ActionsOnAsset"), '', ''); + + // List of all actions + $filters = array(); + $filters['search_agenda_label'] = $search_agenda_label; + + // TODO Replace this with same code than into list.php + show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, $object->module); + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/card.php b/htdocs/asset/card.php index 35c0ffcff88..c516866b7d0 100644 --- a/htdocs/asset/card.php +++ b/htdocs/asset/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2018 Alexandre Spangaro +/* Copyright (C) 2017 Laurent Destailleur + * Copyright (C) 2018 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page -$langs->loadLangs(array("asset")); +$langs->loadLangs(array("assets", "other")); // Get parameters $id = GETPOST('id', 'int'); @@ -68,12 +68,6 @@ if (empty($action) && empty($id) && empty($ref)) { // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. -// Security check -if (!empty($user->socid)) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'asset', $id); - $permissiontoread = $user->rights->asset->read; $permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php $permissiontodelete = $user->rights->asset->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); @@ -81,7 +75,13 @@ $permissionnote = $user->rights->asset->write; // Used by the include of actions $permissiondellink = $user->rights->asset->write; // Used by the include of actions_dellink.inc.php $upload_dir = $conf->asset->multidir_output[isset($object->entity) ? $object->entity : 1]; -$error = 0; +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); /* @@ -95,6 +95,8 @@ if ($reshook < 0) { } if (empty($reshook)) { + $error = 0; + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; if (empty($backtopage) || ($cancel && empty($id))) { @@ -107,6 +109,27 @@ if (empty($reshook)) { } } + $object->oldcopy = dol_clone($object); + $triggermodname = 'ASSET_MODIFY'; // Name of trigger action code to execute when we modify record + + // Action dispose object + if ($action == 'confirm_disposal' && $confirm == 'yes' && $permissiontoadd) { + $object->disposal_date = dol_mktime(12, 0, 0, GETPOST('disposal_datemonth', 'int'), GETPOST('disposal_dateday', 'int'), GETPOST('disposal_dateyear', 'int')); // for date without hour, we use gmt + $object->disposal_amount_ht = GETPOST('disposal_amount', 'int'); + $object->fk_disposal_type = GETPOST('fk_disposal_type', 'int'); + $disposal_invoice_id = GETPOST('disposal_invoice_id', 'int'); + $object->disposal_depreciated = ((GETPOST('disposal_depreciated') == '1' || GETPOST('disposal_depreciated') == 'on') ? 1 : 0); + $object->disposal_subject_to_vat = ((GETPOST('disposal_subject_to_vat') == '1' || GETPOST('disposal_subject_to_vat') == 'on') ? 1 : 0); + + $result = $object->dispose($user, $disposal_invoice_id); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } + $action = ''; + } elseif ($action == "add") { + $object->supplier_invoice_id = GETPOST('supplier_invoice_id', 'int'); + } + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php'; @@ -122,13 +145,6 @@ if (empty($reshook)) { // Action to build doc include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - if ($action == 'set_thirdparty' && $permissiontoadd) { - $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'MYOBJECT_MODIFY'); - } - if ($action == 'classin' && $permissiontoadd) { - $object->setProject(GETPOST('projectid', 'int')); - } - // Actions to send emails $triggersendname = 'ASSET_SENTBYMAIL'; $autocopy = 'MAIN_MAIL_AUTOCOPY_ASSET_TO'; @@ -136,6 +152,7 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; } + /* * View * @@ -150,7 +167,7 @@ llxHeader('', $title, $help_url); // Part to create if ($action == 'create') { - print load_fiche_titre($langs->trans("NewAsset"), '', $object->picto); + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("Asset")), '', 'object_'.$object->picto); print '
    '; print ''; @@ -161,9 +178,16 @@ if ($action == 'create') { if ($backtopageforcancel) { print ''; } + if (GETPOSTISSET('supplier_invoice_id')) { + $object->fields['supplier_invoice_id'] = array('type' => 'integer:FactureFournisseur:fourn/class/fournisseur.facture.class.php:1:entity IN (__SHARED_ENTITIES__)', 'label' => 'SupplierInvoice', 'enabled' => '1', 'noteditable' => '1', 'position' => 280, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'validate' => '1',); + print ''; + } print dol_get_fiche_head(array(), ''); + // Set some default values + //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; + print ''."\n"; // Common attributes @@ -185,12 +209,11 @@ if ($action == 'create') { // Part to edit record if (($id || $ref) && $action == 'edit') { - print load_fiche_titre($langs->trans("Assets")); + print load_fiche_titre($langs->trans("Asset"), '', 'object_'.$object->picto); print ''; print ''; print ''; - print ''; print ''; if ($backtopage) { print ''; @@ -222,18 +245,60 @@ if (($id || $ref) && $action == 'edit') { if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { $res = $object->fetch_optionals(); - $head = asset_prepare_head($object); + $head = assetPrepareHead($object); print dol_get_fiche_head($head, 'card', $langs->trans("Asset"), -1, $object->picto); $formconfirm = ''; // Confirmation to delete if ($action == 'delete') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteAssets'), $langs->trans('ConfirmDeleteAsset'), 'confirm_delete', '', 0, 1); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteAsset'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } elseif ($action == 'disposal') { + // Disposal + $langs->load('bills'); + + $disposal_date = dol_mktime(12, 0, 0, GETPOST('disposal_datemonth', 'int'), GETPOST('disposal_dateday', 'int'), GETPOST('disposal_dateyear', 'int')); // for date without hour, we use gmt + $disposal_amount = GETPOST('disposal_amount', 'int'); + $fk_disposal_type = GETPOST('fk_disposal_type', 'int'); + $disposal_invoice_id = GETPOST('disposal_invoice_id', 'int'); + $disposal_depreciated = GETPOSTISSET('disposal_depreciated') ? GETPOST('disposal_depreciated') : 1; + $disposal_depreciated = !empty($disposal_depreciated) ? 1 : 0; + $disposal_subject_to_vat = GETPOSTISSET('disposal_subject_to_vat') ? GETPOST('disposal_subject_to_vat') : 1; + $disposal_subject_to_vat = !empty($disposal_subject_to_vat) ? 1 : 0; + + $object->fields['fk_disposal_type']['visible'] = 1; + $disposal_type_form = $object->showInputField(null, 'fk_disposal_type', $fk_disposal_type, '', '', '', 0); + $object->fields['fk_disposal_type']['visible'] = -2; + + $object->fields['disposal_invoice_id'] = array('type' => 'integer:Facture:compta/facture/class/facture.class.php::entity IN (__SHARED_ENTITIES__)', 'enabled' => '1', 'notnull' => 1, 'visible' => 1, 'index' => 1, 'validate' => '1',); + $disposal_invoice_form = $object->showInputField(null, 'disposal_invoice_id', $disposal_invoice_id, '', '', '', 0); + unset($object->fields['disposal_invoice_id']); + + // Create an array for form + $formquestion = array( + array('type' => 'date', 'name' => 'disposal_date', 'tdclass' => 'fieldrequired', 'label' => $langs->trans("AssetDisposalDate"), 'value' => $disposal_date), + array('type' => 'text', 'name' => 'disposal_amount', 'tdclass' => 'fieldrequired', 'label' => $langs->trans("AssetDisposalAmount"), 'value' => $disposal_amount), + array('type' => 'other', 'name' => 'fk_disposal_type', 'tdclass' => 'fieldrequired', 'label' => $langs->trans("AssetDisposalType"), 'value' => $disposal_type_form), + array('type' => 'other', 'name' => 'disposal_invoice_id', 'label' => $langs->trans("InvoiceCustomer"), 'value' => $disposal_invoice_form), + array('type' => 'checkbox', 'name' => 'disposal_depreciated', 'label' => $langs->trans("AssetDisposalDepreciated"), 'value' => $disposal_depreciated), + array('type' => 'checkbox', 'name' => 'disposal_subject_to_vat', 'label' => $langs->trans("AssetDisposalSubjectToVat"), 'value' => $disposal_subject_to_vat), + ); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('AssetDisposal'), $langs->trans('AssetConfirmDisposalAsk', $object->ref . ' - ' . $object->label), 'confirm_disposal', $formquestion, 'yes', 1); + } elseif ($action == 'reopen') { + // Re-open + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $langs->trans('AssetConfirmReOpenAsk', $object->ref), 'confirm_reopen', $formquestion, 'yes', 1); } + // Clone confirmation + /* elseif ($action == 'clone') { + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + }*/ // Call Hook formConfirm - $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $formconfirm .= $hookmanager->resPrint; @@ -250,24 +315,19 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
    '; - /* - // Ref bis - $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->asset->creer, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->asset->creer, 'string', '', null, null, '', 1); - // Thirdparty - $morehtmlref.='
    '.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1); - */ $morehtmlref .= '
    '; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + print '
    '; print '
    '; print '
    '; - print '
    '."\n"; + print '
    '."\n"; // Common attributes - //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just after this field + $keyforbreak='date_acquisition'; // We change column just before this field //unset($object->fields['fk_project']); // Hide field already shown in banner //unset($object->fields['fk_soc']); // Hide field already shown in banner include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; @@ -277,69 +337,100 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
    '; print '
    '; + print '
    '; print '
    '; print dol_get_fiche_end(); - - /* - * Buttons - */ - if ($user->socid == 0) { - print '
    '; - + // Buttons for actions + if ($action != 'presend' && $action != 'editline') { + print '
    ' . "\n"; $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } if (empty($reshook)) { - if ($user->rights->asset->write) { - print ''.$langs->trans("Modify").''."\n"; - } else { - print ''.$langs->trans('Modify').''."\n"; + // Send + if (empty($user->socid)) { + print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init&token=' . newToken() . '#formmailbeforetitle'); } - if ($user->rights->asset->delete) { - print ''.$langs->trans('Delete').''."\n"; - } else { - print ''.$langs->trans('Delete').''."\n"; + if ($object->status == $object::STATUS_DRAFT) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); } + + // Clone + //print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=clone&token=' . newToken(), '', false && $permissiontoadd); + + if ($object->status == $object::STATUS_DRAFT) { + print dolGetButtonAction($langs->trans('AssetDisposal'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=disposal&token=' . newToken(), '', $permissiontoadd); + } else { + print dolGetButtonAction($langs->trans('ReOpen'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=reopen&token=' . newToken(), '', $permissiontoadd); + } + + // Delete (need delete permission, or if draft, just need create/modify permission) + print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=delete&token=' . newToken(), '', $permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)); } - print "
    "; + print '
    ' . "\n"; + } + + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; } if ($action != 'presend') { print '
    '; print ''; // ancre - // Documents - $filename = dol_sanitizeFileName($object->ref); - $filedir = $conf->contrat->dir_output."/".dol_sanitizeFileName($object->ref); - $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed = $user->rights->asset->read; // If you can read, you can build the PDF to read content - $delallowed = $user->rights->asset->write; // If you can create/edit, you can remove a file on card + $includedocgeneration = 0; - print $formfile->showdocuments('asset', $filename, $filedir, $urlsource, 0, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang); + // Documents + if ($includedocgeneration) { + $objref = dol_sanitizeFileName($object->ref); + $relativepath = $objref.'/'.$objref.'.pdf'; + $filedir = $conf->asset->dir_output.'/'.$objref; + $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; + $genallowed = $user->rights->asset->read; // If you can read, you can build the PDF to read content + $delallowed = $user->rights->asset->write; // If you can create/edit, you can remove a file on card + print $formfile->showdocuments('asset:Asset', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); + } // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('asset')); $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + print '
    '; $MAXEVENT = 10; - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/asset/info.php?id='.$object->id); + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/asset/agenda.php?id='.$object->id); // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlright); + $somethingshown = $formactions->showactions($object, $object->element, 0, 1, '', $MAXEVENT, '', $morehtmlright); print '
    '; } -} + //Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + // Presend form + $modelmail = 'asset'; + $defaulttopic = 'InformationMessage'; + $diroutput = $conf->asset->dir_output; + $trackid = 'asset'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; +} // End of page llxFooter(); diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php index 916fb376526..19c15839231 100644 --- a/htdocs/asset/class/asset.class.php +++ b/htdocs/asset/class/asset.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2018 Alexandre Spangaro +/* Copyright (C) 2017 Laurent Destailleur + * Copyright (C) 2018 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ /** * \file asset/class/asset.class.php * \ingroup asset - * \brief This file is a CRUD class file for asset (Create/Read/Update/Delete) + * \brief This file is a CRUD class file for Asset (Create/Read/Update/Delete) */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; @@ -30,22 +30,28 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; class Asset extends CommonObject { /** - * @var string ID to identify managed object + * @var string ID of module. + */ + public $module = 'asset'; + + /** + * @var string ID to identify managed object. */ public $element = 'asset'; /** - * @var string Name of table without prefix where object is stored + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. */ public $table_element = 'asset'; /** - * @var int Does module support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int Does this object support multicompany module ? + * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table */ - public $ismultientitymanaged = 0; + public $ismultientitymanaged = 1; /** - * @var int Does asset support extrafields ? 0=No, 1=Yes + * @var int Does object support extrafields ? 0=No, 1=Yes */ public $isextrafieldmanaged = 1; @@ -54,111 +60,124 @@ class Asset extends CommonObject */ public $picto = 'asset'; - - const STATUS_DRAFT = 0; - const STATUS_VALIDATED = 1; - const STATUS_CANCELED = 9; - + const STATUS_DRAFT = 0; // In progress + const STATUS_DISPOSED = 9; // Disposed /** - * 'type' if the field format. + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" * 'label' the translation key. - * 'enabled' is a condition when the field must be managed. - * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only. Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. * 'index' if we want an index in database. * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). - * 'position' is the sort order of field. * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. - * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). - * 'help' is a string visible as a tooltip on field + * 'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage) + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' + * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar' + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. * 'comment' is not used. You can store here any text of your choice. It is not used by application. - * 'default' is a default value for creation (can still be replaced by the global setup of default values) - * 'showoncombobox' if field must be shown into the label of combobox + * 'validate' is 1 if need to validate with $this->validateField() + * 'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value) + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. */ /** * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. */ - public $fields = array( - 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>-1, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), - 'ref' => array('type'=>'varchar(10)', 'label'=>'Ref', 'visible'=>1, 'enabled'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'showoncombobox'=>1), - 'entity' => array('type'=>'integer', 'label'=>'Entity', 'visible'=>0, 'enabled'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1, 'searchall'=>1), - 'fk_asset_type' => array('type'=>'integer:AssetType:asset/class/asset_type.class.php', 'label'=>'AssetsType', 'visible'=>1, 'enabled'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'searchall'=>1), - 'amount_ht' => array('type'=>'double(24,8)', 'label'=>'AmountHTShort', 'visible'=>1, 'enabled'=>1, 'position'=>40, 'notnull'=>-1, 'isameasure'=>'1', 'help'=>"Help text",), - 'amount_vat' => array('type'=>'double(24,8)', 'label'=>'AmountVAT', 'visible'=>1, 'enabled'=>1, 'position'=>41, 'notnull'=>-1, 'isameasure'=>'1', 'help'=>"Help text",), - 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>90, 'notnull'=>-1,), - 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'visible'=>-1, 'enabled'=>1, 'position'=>91, 'notnull'=>-1,), - 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'visible'=>-1, 'enabled'=>1, 'position'=>92, 'notnull'=>-1,), - 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>-2, 'enabled'=>1, 'position'=>500, 'notnull'=>1,), - 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'visible'=>-2, 'enabled'=>1, 'position'=>501, 'notnull'=>1,), - 'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'visible'=>-2, 'enabled'=>1, 'position'=>510, 'notnull'=>1,), - 'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'visible'=>-2, 'enabled'=>1, 'position'=>511, 'notnull'=>-1,), - 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'visible'=>-2, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1,), - 'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Active', '9'=>'Cancel')), + public $fields=array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'noteditable'=>'0', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'validate'=>'1', 'comment'=>"Reference of object"), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'showoncombobox'=>'2', 'validate'=>'1',), + 'fk_asset_model' => array('type'=>'integer:AssetModel:asset/class/assetmodel.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'AssetModel', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'index'=>1, 'validate'=>'1',), + 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>0, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp', 'validate'=>'1',), + 'acquisition_type' => array('type'=>'smallint', 'label'=>'AssetAcquisitionType', 'enabled'=>'1', 'position'=>60, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('0'=>'AssetAcquisitionTypeNew', '1'=>'AssetAcquisitionTypeOccasion'), 'validate'=>'1',), + 'asset_type' => array('type'=>'smallint', 'label'=>'AssetType', 'enabled'=>'1', 'position'=>70, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('0'=>'AssetTypeIntangible', '1'=>'AssetTypeTangible', '2'=>'AssetTypeInProgress', '3'=>'AssetTypeFinancial'), 'validate'=>'1',), + 'not_depreciated' => array('type'=>'boolean', 'label'=>'AssetNotDepreciated', 'enabled'=>'1', 'position'=>80, 'notnull'=>0, 'default'=>'0', 'visible'=>1, 'validate'=>'1',), + 'date_acquisition' => array('type'=>'date', 'label'=>'AssetDateAcquisition', 'enabled'=>'1', 'position'=>90, 'notnull'=>1, 'visible'=>1,), + 'date_start' => array('type'=>'date', 'label'=>'AssetDateStart', 'enabled'=>'1', 'position'=>100, 'notnull'=>0, 'visible'=>-1,), + 'acquisition_value_ht' => array('type'=>'price', 'label'=>'AssetAcquisitionValueHT', 'enabled'=>'1', 'position'=>110, 'notnull'=>1, 'visible'=>1, 'isameasure'=>'1', 'validate'=>'1',), + 'recovered_vat' => array('type'=>'price', 'label'=>'AssetRecoveredVAT', 'enabled'=>'1', 'position'=>120, 'notnull'=>0, 'visible'=>1, 'isameasure'=>'1', 'validate'=>'1',), + 'reversal_date' => array('type'=>'date', 'label'=>'AssetReversalDate', 'enabled'=>'1', 'position'=>130, 'notnull'=>0, 'visible'=>1,), + 'reversal_amount_ht' => array('type'=>'price', 'label'=>'AssetReversalAmountHT', 'enabled'=>'1', 'position'=>140, 'notnull'=>0, 'visible'=>1, 'isameasure'=>'1', 'validate'=>'1',), + 'disposal_date' => array('type'=>'date', 'label'=>'AssetDisposalDate', 'enabled'=>'1', 'position'=>200, 'notnull'=>0, 'visible'=>-2,), + 'disposal_amount_ht' => array('type'=>'price', 'label'=>'AssetDisposalAmount', 'enabled'=>'1', 'position'=>210, 'notnull'=>0, 'visible'=>-2, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'fk_disposal_type' => array('type'=>'sellist:c_asset_disposal_type:label:rowid::active=1', 'label'=>'AssetDisposalType', 'enabled'=>'1', 'position'=>220, 'notnull'=>0, 'visible'=>-2, 'index'=>1, 'validate'=>'1',), + 'disposal_depreciated' => array('type'=>'boolean', 'label'=>'AssetDisposalDepreciated', 'enabled'=>'1', 'position'=>230, 'notnull'=>0, 'default'=>'0', 'visible'=>-2, 'validate'=>'1',), + 'disposal_subject_to_vat' => array('type'=>'boolean', 'label'=>'AssetDisposalSubjectToVat', 'enabled'=>'1', 'position'=>240, 'notnull'=>0, 'default'=>'0', 'visible'=>-2, 'validate'=>'1',), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>300, 'notnull'=>0, 'visible'=>0, 'validate'=>'1',), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>301, 'notnull'=>0, 'visible'=>0, 'validate'=>'1',), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>'1', 'position'=>600, 'notnull'=>0, 'visible'=>0,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'default'=>'0', 'visible'=>2, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '9'=>'Canceled'), 'validate'=>'1',), ); - - /** - * @var int ID - */ public $rowid; - - /** - * @var string Ref - */ public $ref; - - /** - * @var int Entity - */ - public $entity; - - /** - * @var string Asset label - */ public $label; - - public $amount; - - /** - * @var int Thirdparty ID - */ - public $fk_soc; - - /** - * @var string description - */ - public $description; - - /** - * @var integer|string date_creation - */ + public $fk_asset_model; + public $reversal_amount_ht; + public $acquisition_value_ht; + public $recovered_vat; + public $reversal_date; + public $date_acquisition; + public $date_start; + public $qty; + public $acquisition_type; + public $asset_type; + public $not_depreciated; + public $disposal_date; + public $disposal_amount_ht; + public $fk_disposal_type; + public $disposal_depreciated; + public $disposal_subject_to_vat; + public $note_public; + public $note_private; public $date_creation; - - public $tms; - - /** - * @var int ID - */ public $fk_user_creat; - - /** - * @var int ID - */ public $fk_user_modif; - - /** - * @var string import key - */ + public $last_main_doc; public $import_key; - - /** - * @var int Status - */ + public $model_pdf; public $status; + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + // public $fk_element = 'fk_asset'; + // /** + // * @var array List of child tables. To test if we can delete object. + // */ + // protected $childtables = array(); + // /** + // * @var array List of child tables. To know object to delete on cascade. + // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + // */ + // protected $childtablesoncascade = array('asset_assetdet'); + + /** + * @var AssetDepreciationOptions Used for computed fields of depreciation options class. + */ + public $asset_depreciation_options; + /** + * @var array List of depreciation lines for each mode (sort by depreciation date). + */ + public $depreciation_lines = array(); /** * Constructor @@ -167,16 +186,34 @@ class Asset extends CommonObject */ public function __construct(DoliDB $db) { - global $conf; + global $conf, $langs; $this->db = $db; - if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) { + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) { $this->fields['rowid']['visible'] = 0; } - if (empty($conf->multicompany->enabled)) { + if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) { $this->fields['entity']['enabled'] = 0; } + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) { + if (isset($val['enabled']) && empty($val['enabled'])) { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) { + foreach ($this->fields as $key => $val) { + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + foreach ($val['arrayofkeyval'] as $key2 => $val2) { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } } /** @@ -188,11 +225,27 @@ class Asset extends CommonObject */ public function create(User $user, $notrigger = false) { - return $this->createCommon($user, $notrigger); + if (!isset($this->date_start) || $this->date_start === "") $this->date_start = $this->date_acquisition; + + $this->db->begin(); + + $result = $result_create = $this->createCommon($user, $notrigger); + if ($result > 0 && $this->fk_asset_model > 0) $result = $this->setDataFromAssetModel($user, $notrigger); + if ($result > 0) { + if ($this->supplier_invoice_id > 0) $this->add_object_linked('invoice_supplier', $this->supplier_invoice_id); + } + + if ($result < 0) { + $this->db->rollback(); + } else { + $this->db->commit(); + } + + return $result > 0 ? $result_create : $result; } /** - * Clone and object into another one + * Clone an object into another one * * @param User $user User that creates * @param int $fromid Id of object to clone @@ -200,45 +253,95 @@ class Asset extends CommonObject */ public function createFromClone(User $user, $fromid) { - global $hookmanager, $langs; + global $langs, $extrafields; $error = 0; dol_syslog(__METHOD__, LOG_DEBUG); - $object = new self($this->db); - - $this->db->begin(); - - // Load source object - $object->fetchCommon($fromid); - // Reset some properties - unset($object->id); - unset($object->fk_user_creat); - unset($object->import_key); - - // Clear fields - $object->ref = "copy_of_".$object->ref; - $object->title = $langs->trans("CopyOf")." ".$object->title; - - // Create clone - $object->context['createfromclone'] = 'createfromclone'; - $result = $object->createCommon($user); - if ($result < 0) { - $error++; - $this->error = $object->error; - $this->errors = $object->errors; - } - - unset($object->context['createfromclone']); - - // End - if (!$error) { - $this->db->commit(); - return $object; - } else { - $this->db->rollback(); - return -1; - } + // $object = new self($this->db); + // + // $this->db->begin(); + // + // // Load source object + // $result = $object->fetchCommon($fromid); + // if ($result > 0 && !empty($object->table_element_line)) { + // $object->fetchLines(); + // } + // + // // get lines so they will be clone + // //foreach($this->lines as $line) + // // $line->fetch_optionals(); + // + // // Reset some properties + // unset($object->id); + // unset($object->fk_user_creat); + // unset($object->import_key); + // + // // Clear fields + // if (property_exists($object, 'ref')) { + // $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; + // } + // if (property_exists($object, 'label')) { + // $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + // } + // if (property_exists($object, 'status')) { + // $object->status = self::STATUS_DRAFT; + // } + // if (property_exists($object, 'date_creation')) { + // $object->date_creation = dol_now(); + // } + // if (property_exists($object, 'date_modification')) { + // $object->date_modification = null; + // } + // // ... + // // Clear extrafields that are unique + // if (is_array($object->array_options) && count($object->array_options) > 0) { + // $extrafields->fetch_name_optionals_label($this->table_element); + // foreach ($object->array_options as $key => $option) { + // $shortkey = preg_replace('/options_/', '', $key); + // if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { + // //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; + // unset($object->array_options[$key]); + // } + // } + // } + // + // // Create clone + // $object->context['createfromclone'] = 'createfromclone'; + // $result = $object->createCommon($user); + // if ($result < 0) { + // $error++; + // $this->error = $object->error; + // $this->errors = $object->errors; + // } + // + // if (!$error) { + // // copy internal contacts + // if ($this->copy_linked_contact($object, 'internal') < 0) { + // $error++; + // } + // } + // + // if (!$error) { + // // copy external contacts if same company + // if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) { + // if ($this->copy_linked_contact($object, 'external') < 0) { + // $error++; + // } + // } + // } + // + // unset($object->context['createfromclone']); + // + // // End + // if (!$error) { + // $this->db->commit(); + // return $object; + // } else { + // $this->db->rollback(); + // return -1; + // } + return -1; } /** @@ -251,7 +354,21 @@ class Asset extends CommonObject public function fetch($id, $ref = null) { $result = $this->fetchCommon($id, $ref); - //if ($result > 0 && ! empty($this->table_element_line)) $this->fetchLines(); + if ($result > 0) { + if (!empty($this->table_element_line)) $this->fetchLines(); + + $res = $this->hasDepreciationLinesInBookkeeping(); + if ($res < 0) { + return -1; + } elseif ($res > 0) { + $this->fields['date_acquisition']['noteditable'] = '1'; + $this->fields['date_start']['noteditable'] = '1'; + $this->fields['acquisition_value_ht']['noteditable'] = '1'; + $this->fields['recovered_vat']['noteditable'] = '1'; + $this->fields['reversal_date']['noteditable'] = '1'; + $this->fields['reversal_amount_ht']['noteditable'] = '1'; + } + } return $result; } @@ -260,14 +377,93 @@ class Asset extends CommonObject * * @return int <0 if KO, 0 if not found, >0 if OK */ - /*public function fetchLines() + public function fetchLines() { - $this->lines=array(); + $this->lines = array(); - // Load lines with object AssetsLine + return 1; + } - return count($this->lines)?1:0; - }*/ + + /** + * Load list of objects in memory from the database. + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit limit + * @param int $offset Offset + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) + * @param string $filtermode Filter mode (AND or OR) + * @return array|int int <0 if KO, array of pages if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $records = array(); + + $sql = "SELECT "; + $sql .= $this->getFieldList('t'); + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) { + $sql .= " WHERE t.entity IN (".getEntity($this->table_element).")"; + } else { + $sql .= " WHERE 1 = 1"; + } + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid') { + $sqlwhere[] = $key." = ".((int) $value); + } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) { + $sqlwhere[] = $key." = '".$this->db->idate($value)."'"; + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } elseif (strpos($value, '%') === false) { + $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")"; + } else { + $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'"; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")"; + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= $this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < ($limit ? min($limit, $num) : $num)) { + $obj = $this->db->fetch_object($resql); + + $record = new self($this->db); + $record->setVarsFromFetchObj($obj); + + $records[$record->id] = $record; + + $i++; + } + $this->db->free($resql); + + return $records; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } /** * Update object into database @@ -278,7 +474,32 @@ class Asset extends CommonObject */ public function update(User $user, $notrigger = false) { - return $this->updateCommon($user, $notrigger); + if (!isset($this->date_start) || $this->date_start === "") $this->date_start = $this->date_acquisition; + + $this->db->begin(); + + $result = $this->updateCommon($user, $notrigger); + if ($result > 0 && $this->fk_asset_model > 0 && $this->fk_asset_model != $this->oldcopy->fk_asset_model) { + $result = $this->setDataFromAssetModel($user, $notrigger); + } + if ($result > 0 && ( + $this->date_start != $this->oldcopy->date_start || + $this->acquisition_value_ht != $this->oldcopy->acquisition_value_ht || + $this->reversal_date != $this->oldcopy->reversal_date || + $this->reversal_amount_ht != $this->oldcopy->reversal_amount_ht || + ($this->fk_asset_model > 0 && $this->fk_asset_model != $this->oldcopy->fk_asset_model) + ) + ) { + $result = $this->calculationDepreciation(); + } + + if ($result < 0) { + $this->db->rollback(); + } else { + $this->db->commit(); + } + + return $result; } /** @@ -291,19 +512,758 @@ class Asset extends CommonObject public function delete(User $user, $notrigger = false) { return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + /** + * Set asset model + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function setDataFromAssetModel(User $user, $notrigger = false) + { + global $langs; + $langs->load('assets'); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + $this->fk_asset_model = $this->fk_asset_model > 0 ? $this->fk_asset_model : 0; + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if (empty($this->fk_asset_model)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetModel") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $this->db->begin(); + + // Get depreciation options + //--------------------------- + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + $options_model = new AssetDepreciationOptions($this->db); + $result = $options_model->fetchDeprecationOptions(0, $this->fk_asset_model); + if ($result < 0) { + $this->error = $options_model->error; + $this->errors = $options_model->errors; + $error++; + } elseif ($result > 0) { + $options = new AssetDepreciationOptions($this->db); + $result = $options->fetchDeprecationOptions($this->id); + if ($result < 0) { + $this->error = $options->error; + $this->errors = $options->errors; + $error++; + } + + if (!$error) { + foreach ($options_model->deprecation_options as $mode_key => $fields) { + foreach ($fields as $field_key => $value) { + $options->deprecation_options[$mode_key][$field_key] = $value; + } + } + + $result = $options->updateDeprecationOptions($user, $this->id, 0, $notrigger); + if ($result < 0) { + $this->error = $options->error; + $this->errors = $options->errors; + $error++; + } + } + } + + // Get accountancy codes + //--------------------------- + if (!$error) { + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + $accountancy_codes_model = new AssetAccountancyCodes($this->db); + $result = $accountancy_codes_model->fetchAccountancyCodes(0, $this->fk_asset_model); + if ($result < 0) { + $this->error = $accountancy_codes_model->error; + $this->errors = $accountancy_codes_model->errors; + $error++; + } elseif ($result > 0) { + $accountancy_codes = new AssetAccountancyCodes($this->db); + $result = $accountancy_codes->fetchAccountancyCodes($this->id); + if ($result < 0) { + $this->error = $accountancy_codes->error; + $this->errors = $accountancy_codes->errors; + $error++; + } + + if (!$error) { + foreach ($accountancy_codes_model->accountancy_codes as $mode_key => $fields) { + foreach ($fields as $field_key => $value) { + $accountancy_codes->accountancy_codes[$mode_key][$field_key] = $value; + } + } + + $result = $accountancy_codes->updateAccountancyCodes($user, $this->id, 0, $notrigger); + if ($result < 0) { + $this->error = $accountancy_codes->error; + $this->errors = $accountancy_codes->errors; + $error++; + } + } + } + } + + if ($error) { + $this->db->rollback(); + return -1; + } else { + $this->db->commit(); + return 1; + } + } + + /** + * Fetch depreciation lines for each mode in $this->depreciation_lines (sort by depreciation date) + * + * @return int <0 if KO, Id of created object if OK + */ + public function fetchDepreciationLines() + { + global $langs; + $langs->load('assets'); + $this->depreciation_lines = array(); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS ("; + $sql .= " SELECT DISTINCT fk_docdet"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE doc_type = 'asset'"; + $sql .= ")"; + $sql .= "SELECT ad.rowid, ad.depreciation_mode, ad.ref, ad.depreciation_date, ad.depreciation_ht, ad.cumulative_depreciation_ht"; + $sql .= ", " . $this->db->ifsql('iab.fk_docdet IS NOT NULL', 1, 0) . " AS bookkeeping"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad"; + $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid"; + $sql .= " WHERE ad.fk_asset = " . (int) $this->id; + $sql .= " ORDER BY ad.depreciation_date ASC"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror(); + return -1; + } + + while ($obj = $this->db->fetch_object($resql)) { + if (!isset($this->depreciation_lines[$obj->depreciation_mode])) $this->depreciation_lines[$obj->depreciation_mode] = array(); + $this->depreciation_lines[$obj->depreciation_mode][] = array( + 'id' => $obj->rowid, + 'ref' => $obj->ref, + 'depreciation_date' => $this->db->jdate($obj->depreciation_date), + 'depreciation_ht' => $obj->depreciation_ht, + 'cumulative_depreciation_ht' => $obj->cumulative_depreciation_ht, + 'bookkeeping' => $obj->bookkeeping, + ); + } + + return 1; + } + + /** + * If has depreciation lines in bookkeeping + * + * @return int <0 if KO, 0 if NO, 1 if Yes + */ + public function hasDepreciationLinesInBookkeeping() + { + global $langs; + $langs->load('assets'); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS ("; + $sql .= " SELECT DISTINCT fk_docdet"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE doc_type = 'asset'"; + $sql .= ")"; + $sql .= "SELECT COUNT(*) AS has_bookkeeping"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad"; + $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid"; + $sql .= " WHERE ad.fk_asset = " . (int) $this->id; + $sql .= " AND iab.fk_docdet IS NOT NULL"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror(); + return -1; + } + + if ($obj = $this->db->fetch_object($resql)) { + return $obj->has_bookkeeping > 0 ? 1 : 0; + } + + return 0; + } + + /** + * Add depreciation line for a mode + * + * @param string $mode Depreciation mode (economic, accelerated_depreciation, ...) + * @param string $ref Ref line + * @param int $depreciation_date Depreciation date + * @param double $depreciation_ht Depreciation amount HT + * @param double $cumulative_depreciation_ht Depreciation cumulative amount HT + * @param string $accountancy_code_debit Accountancy code Debit + * @param string $accountancy_code_credit Accountancy code Credit + * @return int <0 if KO, Id of created line if OK + */ + public function addDepreciationLine($mode, $ref, $depreciation_date, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_debit, $accountancy_code_credit) + { + global $langs; + $langs->load('assets'); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + $mode = strtolower(trim($mode)); + $ref = trim($ref); + $accountancy_code_debit = trim($accountancy_code_debit); + $accountancy_code_credit = trim($accountancy_code_credit); + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "asset_depreciation(fk_asset, depreciation_mode, ref, depreciation_date, depreciation_ht, cumulative_depreciation_ht, accountancy_code_debit, accountancy_code_credit)"; + $sql .= " VALUES ( "; + $sql .= " " . (int) $this->id; + $sql .= ", '" . $this->db->escape($mode) . "'"; + $sql .= ", '" . $this->db->escape($ref) . "'"; + $sql .= ", '" . $this->db->idate($depreciation_date) . "'"; + $sql .= ", " . (double) $depreciation_ht; + $sql .= ", " . (double) $cumulative_depreciation_ht; + $sql .= ", '" . $this->db->escape($accountancy_code_debit) . "'"; + $sql .= ", '" . $this->db->escape($accountancy_code_credit) . "'"; + $sql .= ")"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorAddDepreciationLine') . ': ' . $this->db->lasterror(); + return -1; + } + + return 1; + } + + /** + * Calculation depreciation lines (reversal and future) for each mode + * + * @return int <0 if KO, Id of created object if OK + */ + public function calculationDepreciation() + { + global $conf, $langs; + $langs->load('assets'); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + // Get depreciation options + //--------------------------- + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + $options = new AssetDepreciationOptions($this->db); + $result = $options->fetchDeprecationOptions($this->id); + if ($result < 0) { + $this->error = $options->error; + $this->errors = $options->errors; + return -1; + } + + // Get accountancy codes + //--------------------------- + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + $accountancy_codes = new AssetAccountancyCodes($this->db); + $result = $accountancy_codes->fetchAccountancyCodes($this->id); + if ($result < 0) { + $this->error = $accountancy_codes->error; + $this->errors = $accountancy_codes->errors; + return -1; + } + + $this->db->begin(); + + // Delete old lines + $modes = array(); + foreach ($options->deprecation_options as $mode_key => $fields) { + $modes[$mode_key] = $this->db->escape($mode_key); + } + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "asset_depreciation"; + $sql .= " WHERE fk_asset = " . (int) $this->id; + $sql .= " AND depreciation_mode NOT IN ('" . $this->db->sanitize(implode("', '", $modes)) . "')"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror(); + $error++; + } + + if (!$error) { + // Get fiscal period + require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; + $dates = getDefaultDatesForTransfer(); + $init_fiscal_period_start = $dates['date_start']; + $init_fiscal_period_end = $dates['date_end']; + if (empty($init_fiscal_period_start) || empty($init_fiscal_period_end)) { + $pastmonthyear = $dates['pastmonthyear']; + $pastmonth = $dates['pastmonth']; + $init_fiscal_period_start = dol_get_first_day($pastmonthyear, $pastmonth, false); + $init_fiscal_period_end = dol_get_last_day($pastmonthyear, $pastmonth, false); + } + + foreach ($options->deprecation_options as $mode_key => $fields) { + // Get last depreciation lines save in bookkeeping + //----------------------------------------------------- + $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS ("; + $sql .= " SELECT fk_docdet"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE doc_type = 'asset'"; + $sql .= ")"; + $sql .= "SELECT ad.depreciation_date, ad.cumulative_depreciation_ht"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad"; + $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid"; + $sql .= " WHERE ad.fk_asset = " . (int) $this->id; + $sql .= " AND ad.depreciation_mode = '" . $this->db->escape($mode_key) . "'"; + $sql .= " AND iab.fk_docdet IS NOT NULL"; + $sql .= " ORDER BY ad.depreciation_date DESC"; + $sql .= " LIMIT 1"; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorFetchMaxDepreciationDateForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + break; + } + $last_depreciation_date = ''; + $last_cumulative_depreciation_ht = $this->reversal_amount_ht; + if ($obj = $this->db->fetch_object($resql)) { + $last_depreciation_date = $this->db->jdate($obj->depreciation_date); + $last_cumulative_depreciation_ht = $obj->cumulative_depreciation_ht; + } + + // Set last cumulative depreciation + $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table']; + $sql .= " SET total_amount_last_depreciation_ht = " . (empty($last_cumulative_depreciation_ht) ? 0 : $last_cumulative_depreciation_ht); + $sql .= " WHERE fk_asset = " . (int) $this->id; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror(); + $error++; + break; + } + + // Delete old lines + $sql = "DELETE " . MAIN_DB_PREFIX . "asset_depreciation FROM " . MAIN_DB_PREFIX . "asset_depreciation"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab ON ab.doc_type = 'asset' AND ab.fk_docdet = " . MAIN_DB_PREFIX . "asset_depreciation.rowid"; + $sql .= " WHERE " . MAIN_DB_PREFIX . "asset_depreciation.fk_asset = " . (int) $this->id; + $sql .= " AND " . MAIN_DB_PREFIX . "asset_depreciation.depreciation_mode = '" . $this->db->escape($mode_key) . "'"; + $sql .= " AND ab.fk_docdet IS NULL"; + if ($last_depreciation_date !== "") $sql .= " AND " . MAIN_DB_PREFIX . "asset_depreciation.ref != ''"; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror(); + $error++; + break; + } + + // Get depreciation period + $depreciation_date_start = $this->date_start > $this->date_acquisition ? $this->date_start : $this->date_acquisition; + $depreciation_date_end = dol_time_plus_duree($depreciation_date_start, $fields['duration'], $fields['duration_type'] == 1 ? 'm' : ($fields['duration_type'] == 2 ? 'd' : 'y')); + $depreciation_amount = $fields['amount_base_depreciation_ht']; + if ($fields['duration_type'] == 2) { // Daily + $fiscal_period_start = $depreciation_date_start; + $fiscal_period_end = $depreciation_date_start; + } elseif ($fields['duration_type'] == 1) { // Monthly + $date_temp = dol_getdate($depreciation_date_start); + $fiscal_period_start = dol_get_first_day($date_temp['year'], $date_temp['mon'], false); + $fiscal_period_end = dol_get_last_day($date_temp['year'], $date_temp['mon'], false); + } else { // Annually + $fiscal_period_start = $init_fiscal_period_start; + $fiscal_period_end = $init_fiscal_period_end; + } + $cumulative_depreciation_ht = $last_cumulative_depreciation_ht; + $depreciation_period_amount = $depreciation_amount - $this->reversal_amount_ht; + $start_date = $depreciation_date_start; + $disposal_date = isset($this->disposal_date) && $this->disposal_date !== "" ? $this->disposal_date : ""; + $finish_date = $disposal_date !== "" ? $disposal_date : $depreciation_date_end; + $accountancy_code_depreciation_debit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_debit']; + $accountancy_code_depreciation_debit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_debit_key]; + $accountancy_code_depreciation_credit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_credit']; + $accountancy_code_credit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_credit_key]; + + // Reversal depreciation line + //----------------------------------------------------- + if ($last_depreciation_date === "" && ($depreciation_date_start < $fiscal_period_start || is_numeric($this->reversal_date))) { + if (is_numeric($this->reversal_date)) { + if ($this->reversal_date < $fiscal_period_start) { + $this->errors[] = $langs->trans('AssetErrorReversalDateNotGreaterThanCurrentBeginFiscalDateForMode', $mode_key); + $error++; + break; + } + + if (empty($this->reversal_amount_ht)) { + $this->errors[] = $langs->trans('AssetErrorReversalAmountNotProvidedForMode', $mode_key); + $error++; + break; + } + + $start_date = $this->reversal_date; + $result = $this->addDepreciationLine($mode_key, '', $start_date, $this->reversal_amount_ht, $this->reversal_amount_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit); + if ($result < 0) { + $error++; + break; + } + } else { + $this->errors[] = $langs->trans('AssetErrorReversalDateNotProvidedForMode', $mode_key); + $error++; + break; + } + } + + // futures depreciation lines + //----------------------------------------------------- + $nb_days_in_year = !empty($conf->global->ASSET_DEPRECIATION_DURATION_PER_YEAR) ? $conf->global->ASSET_DEPRECIATION_DURATION_PER_YEAR : 365; + $nb_days_in_month = !empty($conf->global->ASSET_DEPRECIATION_DURATION_PER_MONTH) ? $conf->global->ASSET_DEPRECIATION_DURATION_PER_MONTH : 30; + $period_amount = (double) price2num($depreciation_period_amount / $fields['duration'], 'MT'); + $first_period_found = false; + $first_period_date = isset($begin_period) && $begin_period > $fiscal_period_start ? $begin_period : $fiscal_period_start; + + $ref_date_format = "%Y" . ($fields['duration_type'] == 1 || $fields['duration_type'] == 2 ? '-%m' : '') . ($fields['duration_type'] == 2 ? '-%d' : ''); + + // Loop security + $idx_loop = 0; + $max_loop = $fields['duration'] + 2; + do { + // Loop security + $idx_loop++; + if ($idx_loop > $max_loop) break; + + if ($last_depreciation_date < $fiscal_period_end && ($first_period_date <= $start_date || $first_period_found)) { + // Disposal not depreciated + if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end && empty($this->disposal_depreciated)) { + break; + } + + $first_period_found = true; + + $period_begin = dol_print_date($fiscal_period_start, $ref_date_format); + $period_end = dol_print_date($fiscal_period_end, $ref_date_format); + $ref = $period_begin . ($period_begin != $period_end ? ' - ' . $period_end : ''); + if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end) { + $ref .= ' - ' . $langs->transnoentitiesnoconv('AssetDisposal'); + } + + $begin_date = $fiscal_period_start < $start_date && $start_date <= $fiscal_period_end ? $start_date : $fiscal_period_start; + $end_date = $fiscal_period_start < $finish_date && $finish_date <= $fiscal_period_end ? $finish_date : $fiscal_period_end; + if ($fields['duration_type'] == 2) { // Daily + $depreciation_ht = $period_amount; + } elseif ($fields['duration_type'] == 1) { // Monthly + $nb_days = min($nb_days_in_month, num_between_day($begin_date, $end_date, 1)); + if ($nb_days >= 28) { + $date_temp = dol_getdate($begin_date); + if ($date_temp['mon'] == 2) { + $nb_days = 30; + } + } + $depreciation_ht = (double) price2num($period_amount * $nb_days / $nb_days_in_month, 'MT'); + } else { // Annually + $nb_days = min($nb_days_in_year, num_between_day($begin_date, $end_date, 1)); + $depreciation_ht = (double) price2num($period_amount * $nb_days / $nb_days_in_year, 'MT'); + } + + if ($fiscal_period_start <= $depreciation_date_end && $depreciation_date_end <= $fiscal_period_end) { // last period + $depreciation_ht = (double) price2num($depreciation_amount - $cumulative_depreciation_ht, 'MT'); + $cumulative_depreciation_ht = $depreciation_amount; + } else { + $cumulative_depreciation_ht += $depreciation_ht; + } + + $result = $this->addDepreciationLine($mode_key, $ref, $fiscal_period_end, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit); + if ($result < 0) { + $error++; + break; + } + } + + // Next fiscal period (+1 day/month/year) + $fiscal_period_start = dol_time_plus_duree($fiscal_period_end, 1, 'd'); + if ($fields['duration_type'] == 2) { // Daily + $fiscal_period_end = $fiscal_period_start; + } elseif ($fields['duration_type'] == 1) { // Monthly + $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'm'), -1, 'd'); + } else { // Annually + $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'y'), -1, 'd'); + } + $last_period_date = $disposal_date !== "" && $disposal_date < $depreciation_date_end ? $disposal_date : $depreciation_date_end; + } while ($fiscal_period_start < $last_period_date); + + if ($error) { + break; + } + } + } + + if ($error) { + $this->db->rollback(); + return -1; + } else { + $this->db->commit(); + return 1; + } + } + + /** + * Set last cumulative depreciation for each mode + * + * @param int $asset_depreciation_id Asset depreciation line ID + * @return int <0 if KO, >0 if OK + */ + public function setLastCumulativeDepreciation($asset_depreciation_id) + { + global $langs; + $langs->load('assets'); + + // Clean parameters + $asset_depreciation_id = $asset_depreciation_id > 0 ? $asset_depreciation_id : 0; + + // Check parameters + $error = 0; + if (empty($asset_depreciation_id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetDepreciation") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $this->db->begin(); + + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + $options = new AssetDepreciationOptions($this->db); + + // Get last depreciation lines save in bookkeeping + //----------------------------------------------------- + $sql = "SELECT fk_asset, depreciation_mode, cumulative_depreciation_ht"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation"; + $sql .= " WHERE rowid = " . (int) $asset_depreciation_id; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorFetchCumulativeDepreciation') . ': ' . $this->db->lasterror(); + $error++; + } else { + if ($obj = $this->db->fetch_object($resql)) { + $mode_key = $obj->depreciation_mode; + if (!empty($options->deprecation_options_fields[$mode_key])) { + $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table']; + $sql .= " SET total_amount_last_depreciation_ht = " . $obj->cumulative_depreciation_ht; + $sql .= " WHERE fk_asset = " . (int) $obj->fk_asset; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror(); + $error++; + } + } + } + } + + if ($error) { + $this->db->rollback(); + return -1; + } else { + $this->db->commit(); + return 1; + } + } + + /** + * Set dispose status + * + * @param User $user Object user that dispose + * @param int $disposal_invoice_id Disposal invoice ID + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function dispose($user, $disposal_invoice_id, $notrigger = 0) + { + global $conf, $langs; + + // Protection + if ($this->status != self::STATUS_DRAFT || $this->status == self::STATUS_DISPOSED) { + return 0; + } + + $this->db->begin(); + + $required_fields = array('disposal_date', 'disposal_date', 'fk_disposal_type'); + foreach ($required_fields as $field) { + $this->fields[$field]['notnull'] = 1; + } + $result = $this->update($user, 1); + foreach ($required_fields as $field) { + $this->fields[$field]['notnull'] = 0; + } + if ($result > 0) { + if ($disposal_invoice_id > 0) $this->add_object_linked('facture', $disposal_invoice_id); + $result = $this->setStatusCommon($user, self::STATUS_DISPOSED, $notrigger, 'ASSET_DISPOSED'); + } + if ($result > 0) $result = $this->calculationDepreciation(); + + if ($result < 0) { + $this->db->rollback(); + } else { + $this->db->commit(); + } + + // Define output language + if ($result > 0 && empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + if (method_exists($this, 'generateDocument')) { + global $hidedetails, $hidedesc, $hideref; + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $newlang = $this->thirdparty->default_lang; + } + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model = $this->model_pdf; + $ret = $this->fetch($this->id); // Reload to get new records + + $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + + return $result; + } + + /** + * Set back to validated status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function reopen($user, $notrigger = 0) + { + global $conf, $langs; + + // Protection + if ($this->status != self::STATUS_DISPOSED || $this->status == self::STATUS_DRAFT) { + return 0; + } + + + $this->db->begin(); + + $this->disposal_date = null; + $this->disposal_amount_ht = null; + $this->fk_disposal_type = null; + $this->disposal_depreciated = null; + $this->disposal_subject_to_vat = null; + $result = $this->update($user, 1); + if ($result > 0) { + $this->deleteObjectLinked(null, 'facture'); + $result = $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'ASSET_REOPEN'); + } + if ($result > 0) $result = $this->calculationDepreciation(); + + if ($result < 0) { + $this->db->rollback(); + } else { + $this->db->commit(); + } + + // Define output language + if ($result > 0 && empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + if (method_exists($this, 'generateDocument')) { + global $hidedetails, $hidedesc, $hideref; + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $newlang = $this->thirdparty->default_lang; + } + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model = $this->model_pdf; + $ret = $this->fetch($this->id); // Reload to get new records + + $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + + return $result; } /** * Return a link to the object card (with optionaly the picto) * - * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) - * @param string $option On what the link point to ('nolink', ...) - * @param int $notooltip 1=Disable tooltip - * @param string $morecss Add more css on link - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string String with URL + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $maxlen Max length of name + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) + public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) { global $db, $conf, $langs, $hookmanager; global $dolibarr_main_authentication, $dolibarr_main_demo; @@ -338,7 +1298,7 @@ class Asset extends CommonObject $linkclose = ''; if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $label = $langs->trans("ShowAssets"); + $label = $langs->trans("ShowAsset"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; @@ -347,19 +1307,59 @@ class Asset extends CommonObject $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } - $linkstart = ''; - $linkend = ''; + if ($option == 'nolink') { + $linkend = ''; + } else { + $linkend = ''; + } $result .= $linkstart; - if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + + if (empty($this->showphoto_on_popup)) { + if ($withpicto) { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } else { + if ($withpicto) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + list($class, $module) = explode('@', $this->picto); + $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); + if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { + $result .= '
    No photo
    '; + } else { + $result .= '
    No photo
    '; + } + + $result .= '
    '; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } } + if ($withpicto != 2) { - $result .= $this->ref; + $name = $this->ref; + if ($option == 'label') $name = $this->label; + elseif ($option == 'with_label') $name .= ' - ' . $this->label; + $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name); } + $result .= $linkend; //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + global $action; $hookmanager->initHooks(array($this->element . 'dao')); $parameters = array('id'=>$this->id, 'getnomurl' => &$result); @@ -373,10 +1373,21 @@ class Asset extends CommonObject } /** - * Retourne le libelle du status d'un user (actif, inactif) + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLabelStatus($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function getLibStatut($mode = 0) { @@ -387,43 +1398,43 @@ class Asset extends CommonObject /** * Return the status * - * @param int $status Id status - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto - * @return string Label of status + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ - public static function LibStatut($status, $mode = 0) + public function LibStatut($status, $mode = 0) { // phpcs:enable - global $langs; - - $langs->load("contracts"); - $labelStatus = array(); - $labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Disabled'); - $labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); - $labelStatusShort = array(); - $labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Disabled'); - $labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); - - $statusType = 'status0'; - if ($status == self::STATUS_VALIDATED) { - $statusType = 'status4'; + if (empty($this->labelStatus) || empty($this->labelStatusShort)) { + global $langs; + //$langs->load("asset@asset"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInProgress'); + $this->labelStatus[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInProgress'); + $this->labelStatusShort[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed'); } - return dolGetStatus($labelStatus[$status], $labelStatusShort[$status], '', $statusType, $mode); + $statusType = 'status4'; + if ($status == self::STATUS_DISPOSED) { + $statusType = 'status6'; + } + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); } /** - * Load info into asset object + * Load the info information in the object * - * @param int $id Id of order + * @param int $id Id of object * @return void */ public function info($id) { - $sql = 'SELECT rowid, date_creation as datec, tms as datem,'; - $sql .= ' fk_user_creat, fk_user_modif'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; - $sql .= ' WHERE t.rowid = '.((int) $id); + $sql = "SELECT rowid, date_creation as datec, tms as datem,"; + $sql .= " fk_user_creat, fk_user_modif"; + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + $sql .= " WHERE t.rowid = ".((int) $id); + $result = $this->db->query($sql); if ($result) { if ($this->db->num_rows($result)) { @@ -466,25 +1477,116 @@ class Asset extends CommonObject */ public function initAsSpecimen() { + // Set here init that are not commonf fields + // $this->property1 = ... + // $this->property2 = ... + $this->initAsSpecimenCommon(); } + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + return $this->lines; + } /** - * Action executed by scheduler - * CAN BE A CRON TASK + * Returns the reference to the following non used object depending on the active numbering module. * - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + * @return string Object free reference */ - public function doScheduledJob() + public function getNextNumRef() { - global $conf, $langs; + global $langs, $conf; + $langs->load("asset@asset"); - $this->output = ''; - $this->error = ''; + if (empty($conf->global->ASSET_ASSET_ADDON)) { + $conf->global->ASSET_ASSET_ADDON = 'mod_asset_standard'; + } - dol_syslog(__METHOD__, LOG_DEBUG); + if (!empty($conf->global->ASSET_ASSET_ADDON)) { + $mybool = false; - return 0; + $file = $conf->global->ASSET_ASSET_ADDON.".php"; + $classname = $conf->global->ASSET_ASSET_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/asset/"); + + // Load file with numbering class (if found) + $mybool |= @include_once $dir.$file; + } + + if ($mybool === false) { + dol_print_error('', "Failed to include file ".$file); + return ''; + } + + if (class_exists($classname)) { + $obj = new $classname(); + $numref = $obj->getNextValue($this); + + if ($numref != '' && $numref != '-1') { + return $numref; + } else { + $this->error = $obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } else { + print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; + return ""; + } + } else { + print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); + return ""; + } } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param null|array $moreparams Array to provide more information + * @return int 0 if KO, 1 if OK + */ + // public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) + // { + // global $conf, $langs; + // + // $result = 0; + // $includedocgeneration = 1; + // + // $langs->load("asset@asset"); + // + // if (!dol_strlen($modele)) { + // $modele = 'standard_asset'; + // + // if (!empty($this->model_pdf)) { + // $modele = $this->model_pdf; + // } elseif (!empty($conf->global->ASSET_ADDON_PDF)) { + // $modele = $conf->global->ASSET_ADDON_PDF; + // } + // } + // + // $modelpath = "core/modules/asset/doc/"; + // + // if ($includedocgeneration && !empty($modele)) { + // $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + // } + // + // return $result; + // } } diff --git a/htdocs/asset/class/asset_type.class.php b/htdocs/asset/class/asset_type.class.php deleted file mode 100644 index be8643e3f20..00000000000 --- a/htdocs/asset/class/asset_type.class.php +++ /dev/null @@ -1,445 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/asset/class/asset_type.class.php - * \ingroup asset - * \brief File of class to manage asset types - */ - -require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; - - -/** - * Class to manage asset type - */ -class AssetType extends CommonObject -{ - /** - * @var string Name of table without prefix where object is stored - */ - public $table_element = 'asset_type'; - - /** - * @var string ID to identify managed object - */ - public $element = 'asset_type'; - - /** - * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png - */ - public $picto = 'asset'; - - /** - * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - * @var int - */ - public $ismultientitymanaged = 1; - - /** - * @var string Asset type label - */ - public $label; - - /** @var string Accountancy code asset */ - public $accountancy_code_asset; - - /** @var string Accountancy code depreciation asset */ - public $accountancy_code_depreciation_asset; - - /** @var string Accountancy code depreciation expense */ - public $accountancy_code_depreciation_expense; - - /** @var string Public note */ - public $note; - - /** @var array Array of asset */ - public $asset = array(); - - public $fields = array( - 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), - 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>15, 'index'=>1), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), - 'label' =>array('type'=>'varchar(50)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25, 'showoncombobox'=>1), - 'accountancy_code_asset' =>array('type'=>'varchar(32)', 'label'=>'Accountancy code asset', 'enabled'=>1, 'visible'=>-1, 'position'=>30), - 'accountancy_code_depreciation_asset' =>array('type'=>'varchar(32)', 'label'=>'Accountancy code depreciation asset', 'enabled'=>1, 'visible'=>-1, 'position'=>35), - 'accountancy_code_depreciation_expense' =>array('type'=>'varchar(32)', 'label'=>'Accountancy code depreciation expense', 'enabled'=>1, 'visible'=>-1, 'position'=>40), - 'note' =>array('type'=>'mediumtext', 'label'=>'Note', 'enabled'=>1, 'visible'=>-1, 'position'=>45), - ); - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - $this->db = $db; - } - - - /** - * Fonction qui permet de creer le type d'immobilisation - * - * @param User $user User making creation - * @param int $notrigger 1=do not execute triggers, 0 otherwise - * @return int >0 if OK, < 0 if KO - */ - public function create($user, $notrigger = 0) - { - global $conf; - - $error = 0; - - $this->label = trim($this->label); - $this->accountancy_code_asset = trim($this->accountancy_code_asset); - $this->accountancy_code_depreciation_asset = trim($this->accountancy_code_depreciation_asset); - $this->accountancy_code_depreciation_expense = trim($this->accountancy_code_depreciation_expense); - - $this->db->begin(); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."asset_type ("; - $sql .= "label"; - $sql .= ", accountancy_code_asset"; - $sql .= ", accountancy_code_depreciation_asset"; - $sql .= ", accountancy_code_depreciation_expense"; - $sql .= ", note"; - $sql .= ", entity"; - $sql .= ") VALUES ("; - $sql .= "'".$this->db->escape($this->label)."'"; - $sql .= ", '".$this->db->escape($this->accountancy_code_asset)."'"; - $sql .= ", '".$this->db->escape($this->accountancy_code_depreciation_asset)."'"; - $sql .= ", '".$this->db->escape($this->accountancy_code_depreciation_expense)."'"; - $sql .= ", '".$this->db->escape($this->note)."'"; - $sql .= ", ".((int) $conf->entity); - $sql .= ")"; - - dol_syslog("Asset_type::create", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."asset_type"); - - $result = $this->update($user, 1); - if ($result < 0) { - $this->db->rollback(); - return -3; - } - - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('ASSET_TYPE_CREATE', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } - - if (!$error) { - $this->db->commit(); - return $this->id; - } else { - dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } else { - $this->error = $this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Met a jour en base donnees du type - * - * @param User $user Object user making change - * @param int $notrigger 1=do not execute triggers, 0 otherwise - * @return int >0 if OK, < 0 if KO - */ - public function update($user, $notrigger = 0) - { - global $conf, $hookmanager; - - $error = 0; - - $this->label = trim($this->label); - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."asset_type "; - $sql .= "SET "; - $sql .= "label = '".$this->db->escape($this->label)."',"; - $sql .= "accountancy_code_asset = '".$this->db->escape($this->accountancy_code_asset)."',"; - $sql .= "accountancy_code_depreciation_asset = '".$this->db->escape($this->accountancy_code_depreciation_asset)."',"; - $sql .= "accountancy_code_depreciation_expense = '".$this->db->escape($this->accountancy_code_depreciation_expense)."',"; - $sql .= "note = '".$this->db->escape($this->note)."'"; - $sql .= " WHERE rowid = ".((int) $this->id); - - $result = $this->db->query($sql); - if ($result) { - $action = 'update'; - - // Actions on extra fields - if (!$error) { - $result = $this->insertExtraFields(); - if ($result < 0) { - $error++; - } - } - - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('ASSET_TYPE_MODIFY', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } - - if (!$error) { - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); - return -$error; - } - } else { - $this->error = $this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Fonction qui permet de supprimer le status de l'adherent - * - * @return int >0 if OK, 0 if not found, < 0 if KO - */ - public function delete() - { - global $user; - - $error = 0; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."asset_type"; - $sql .= " WHERE rowid = ".((int) $this->id); - - $resql = $this->db->query($sql); - if ($resql) { - // Call trigger - $result = $this->call_trigger('ASSET_TYPE_DELETE', $user); - if ($result < 0) { - $error++; $this->db->rollback(); return -2; - } - // End call triggers - - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - $this->error = $this->db->lasterror(); - return -1; - } - } - - /** - * Fonction qui permet de recuperer le status de l'immobilisation - * - * @param int $rowid Id of member type to load - * @return int <0 if KO, >0 if OK - */ - public function fetch($rowid) - { - $sql = "SELECT d.rowid, d.label as label, d.accountancy_code_asset, d.accountancy_code_depreciation_asset, d.accountancy_code_depreciation_expense, d.note"; - $sql .= " FROM ".MAIN_DB_PREFIX."asset_type as d"; - $sql .= " WHERE d.rowid = ".(int) $rowid; - - dol_syslog("Asset_type::fetch", LOG_DEBUG); - - $resql = $this->db->query($sql); - if ($resql) { - if ($this->db->num_rows($resql)) { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->rowid; - $this->ref = $obj->rowid; - $this->label = $obj->label; - $this->accountancy_code_asset = $obj->accountancy_code_asset; - $this->accountancy_code_depreciation_asset = $obj->accountancy_code_depreciation_asset; - $this->accountancy_code_depreciation_expense = $obj->accountancy_code_depreciation_expense; - $this->note = $obj->note; - } - - return 1; - } else { - $this->error = $this->db->lasterror(); - return -1; - } - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return list of asset's type - * - * @return array List of types of members - */ - public function liste_array() - { - // phpcs:enable - global $conf, $langs; - - $assettypes = array(); - - $sql = "SELECT rowid, label as label"; - $sql .= " FROM ".MAIN_DB_PREFIX."asset_type"; - $sql .= " WHERE entity IN (".getEntity('asset_type').")"; - - $resql = $this->db->query($sql); - if ($resql) { - $nump = $this->db->num_rows($resql); - - if ($nump) { - $i = 0; - while ($i < $nump) { - $obj = $this->db->fetch_object($resql); - - $assettypes[$obj->rowid] = $langs->trans($obj->label); - $i++; - } - } - } else { - print $this->db->error(); - } - return $assettypes; - } - - /** - * Return array of Asset objects for asset type this->id (or all if this->id not defined) - * - * @param string $excludefilter Filter string to exclude. This parameter must not be provided by input of users - * @param int $mode 0=Return array of asset instance - * 1=Return array of asset instance without extra data - * 2=Return array of asset id only - * @return mixed Array of asset or -1 on error - */ - public function listAssetForAssetType($excludefilter = '', $mode = 0) - { - global $conf, $user; - - $ret = array(); - - $sql = "SELECT a.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX."asset as a"; - $sql .= " WHERE a.entity IN (".getEntity('asset').")"; - $sql .= " AND a.fk_asset_type = ".((int) $this->id); - if (!empty($excludefilter)) { - $sql .= ' AND ('.$excludefilter.')'; - } - - dol_syslog(get_class($this)."::listAssetsForGroup", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { - if (!array_key_exists($obj->rowid, $ret)) { - if ($mode < 2) { - $assetstatic = new Asset($this->db); - $assetstatic->fetch($obj->rowid); - $ret[$obj->rowid] = $assetstatic; - } else { - $ret[$obj->rowid] = $obj->rowid; - } - } - } - - $this->db->free($resql); - - $this->asset = $ret; - - return $ret; - } else { - $this->error = $this->db->lasterror(); - return -1; - } - } - - /** - * Return clicable name (with picto eventually) - * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param int $maxlen length max label - * @param int $notooltip 1=Disable tooltip - * @return string String with URL - */ - public function getNomUrl($withpicto = 0, $maxlen = 0, $notooltip = 0) - { - global $langs; - - $result = ''; - $label = $langs->trans("ShowTypeCard", $this->label); - - $linkstart = ''; - $linkend = ''; - - $result .= $linkstart; - if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); - } - if ($withpicto != 2) { - $result .= ($maxlen ?dol_trunc($this->label, $maxlen) : $this->label); - } - $result .= $linkend; - - return $result; - } - - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void - */ - public function initAsSpecimen() - { - global $conf, $user, $langs; - - // Initialize parameters - $this->id = 0; - $this->ref = 'ATSPEC'; - $this->specimen = 1; - - $this->label = 'ASSET TYPE SPECIMEN'; - $this->note = 'This is a note'; - - // Assets of this asset type is just me - $this->asset = array( - $user->id => $user - ); - } - - /** - * getLibStatut - * - * @return string Return status of a type of asset - */ - public function getLibStatut() - { - return ''; - } -} diff --git a/htdocs/asset/class/assetaccountancycodes.class.php b/htdocs/asset/class/assetaccountancycodes.class.php new file mode 100644 index 00000000000..720dd1e745d --- /dev/null +++ b/htdocs/asset/class/assetaccountancycodes.class.php @@ -0,0 +1,279 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file asset/class/assetaccountancycodes.class.php + * \ingroup asset + * \brief This file is a class file for AssetAccountancyCodes + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; + +/** + * Class for AssetAccountancyCodes + */ +class AssetAccountancyCodes extends CommonObject +{ + /** + * @var array Array with all accountancy codes info by mode. + * Note : 'economic' mode is mandatory and is the primary accountancy codes + * 'depreciation_asset' and 'depreciation_expense' is mandatory and is used for write depreciation in bookkeeping + */ + public $accountancy_codes_fields = array( + 'economic' => array( + 'label' => 'AssetAccountancyCodeDepreciationEconomic', + 'table' => 'asset_accountancy_codes_economic', + 'depreciation_debit' => 'depreciation_asset', + 'depreciation_credit' => 'depreciation_expense', + 'fields' => array( + 'asset' => array('label' => 'AssetAccountancyCodeAsset'), + 'depreciation_asset' => array('label' => 'AssetAccountancyCodeDepreciationAsset'), + 'depreciation_expense' => array('label' => 'AssetAccountancyCodeDepreciationExpense'), + 'value_asset_sold' => array('label' => 'AssetAccountancyCodeValueAssetSold'), + 'receivable_on_assignment' => array('label' => 'AssetAccountancyCodeReceivableOnAssignment'), + 'proceeds_from_sales' => array('label' => 'AssetAccountancyCodeProceedsFromSales'), + 'vat_collected' => array('label' => 'AssetAccountancyCodeVatCollected'), + 'vat_deductible' => array('label' => 'AssetAccountancyCodeVatDeductible'), + ), + ), + 'accelerated_depreciation' => array( + 'label' => 'AssetAccountancyCodeDepreciationAcceleratedDepreciation', + 'table' => 'asset_accountancy_codes_fiscal', + 'depreciation_debit' => 'accelerated_depreciation', + 'depreciation_credit' => 'endowment_accelerated_depreciation', + 'fields' => array( + 'accelerated_depreciation' => array('label' => 'AssetAccountancyCodeAcceleratedDepreciation'), + 'endowment_accelerated_depreciation' => array('label' => 'AssetAccountancyCodeEndowmentAcceleratedDepreciation'), + 'provision_accelerated_depreciation' => array('label' => 'AssetAccountancyCodeProvisionAcceleratedDepreciation'), + ), + ), + ); + + /** + * @var array Array with all accountancy codes by mode. + */ + public $accountancy_codes = array(); + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Fill accountancy_codes property of object (using for data sent by forms) + * + * @return array Array of values + */ + public function setAccountancyCodesFromPost() + { + $this->accountancy_codes = array(); + foreach ($this->accountancy_codes_fields as $mode_key => $mode_info) { + $this->accountancy_codes[$mode_key] = array(); + foreach ($mode_info['fields'] as $field_key => $field_info) { + $accountancy_code = GETPOST($mode_key . '_' . $field_key, 'aZ09'); + if (empty($accountancy_code) || $accountancy_code == '-1') $accountancy_code = ''; + $this->accountancy_codes[$mode_key][$field_key] = $accountancy_code; + } + } + } + + /** + * Load accountancy codes of a asset or a asset model + * + * @param int $asset_id Asset ID to set + * @param int $asset_model_id Asset model ID to set + * @return int <0 if KO, >0 if OK + */ + public function fetchAccountancyCodes($asset_id = 0, $asset_model_id = 0) + { + global $langs, $hookmanager; + dol_syslog(__METHOD__ . " asset_id=$asset_id, asset_model_id=$asset_model_id"); + + $error = 0; + $this->errors = array(); + $this->accountancy_codes = array(); + + // Clean parameters + $asset_id = $asset_id > 0 ? $asset_id : 0; + $asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0; + + if (!is_object($hookmanager)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $hookmanager->initHooks(array('assetaccountancycodesdao')); + $parameters = array('asset_id' => $asset_id, 'asset_model_id' => $asset_model_id); + $reshook = $hookmanager->executeHooks('fetchAccountancyCodes', $parameters, $this); // Note that $action and $object may have been modified by some hooks + if (!empty($reshook)) { + return $reshook; + } + + // Check parameters + if (empty($asset_id) && empty($asset_model_id)) { + $this->errors[] = $langs->trans('AssetErrorAssetOrAssetModelIDNotProvide'); + $error++; + } + if ($error) { + dol_syslog(__METHOD__ . " Error check parameters: " . $this->errorsToString(), LOG_ERR); + return -1; + } + + $accountancy_codes = array(); + foreach ($this->accountancy_codes_fields as $mode_key => $mode_info) { + $sql = "SELECT " . implode(',', array_keys($mode_info['fields'])); + $sql .= " FROM " . MAIN_DB_PREFIX . $mode_info['table']; + $sql .= " WHERE " . ($asset_id > 0 ? " fk_asset = " . (int) $asset_id : " fk_asset_model = " . (int) $asset_model_id); + + $resql = $this->db->query($sql); + if ($resql) { + if ($obj = $this->db->fetch_object($resql)) { + $accountancy_codes[$mode_key] = array(); + foreach ($mode_info['fields'] as $field_key => $field_info) { + $accountancy_codes[$mode_key][$field_key] = $obj->$field_key; + } + } + } else { + $this->errors[] = $langs->trans('AssetErrorFetchAccountancyCodesForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + } + } + + if ($error) { + dol_syslog(__METHOD__ . " Error fetch accountancy codes: " . $this->errorsToString(), LOG_ERR); + return -1; + } else { + $this->accountancy_codes = $accountancy_codes; + return 1; + } + } + + /** + * Update accountancy codes of a asset or a asset model + * + * @param User $user User making update + * @param int $asset_id Asset ID to set + * @param int $asset_model_id Asset model ID to set + * @param int $notrigger 1=disable trigger UPDATE (when called by create) + * @return int <0 if KO, >0 if OK + */ + public function updateAccountancyCodes($user, $asset_id = 0, $asset_model_id = 0, $notrigger = 0) + { + global $langs, $hookmanager; + dol_syslog(__METHOD__ . " user_id={$user->id}, asset_id=$asset_id, asset_model_id=$asset_model_id, notrigger=$notrigger"); + + $error = 0; + $this->errors = array(); + + // Clean parameters + $asset_id = $asset_id > 0 ? $asset_id : 0; + $asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0; + + if (!is_object($hookmanager)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $hookmanager->initHooks(array('assetaccountancycodesdao')); + $parameters = array('user' => $user, 'asset_id' => $asset_id, 'asset_model_id' => $asset_model_id); + $reshook = $hookmanager->executeHooks('updateAccountancyCodes', $parameters, $this); // Note that $action and $object may have been modified by some hooks + if (!empty($reshook)) { + return $reshook; + } + + // Check parameters + if (empty($asset_id) && empty($asset_model_id)) { + $this->errors[] = $langs->trans('AssetErrorAssetOrAssetModelIDNotProvide'); + $error++; + } + if ($error) { + dol_syslog(__METHOD__ . " Error check parameters: " . $this->errorsToString(), LOG_ERR); + return -1; + } + + $this->db->begin(); + $now = dol_now(); + + foreach ($this->accountancy_codes_fields as $mode_key => $mode_info) { + // Delete old accountancy codes + $sql = "DELETE FROM " . MAIN_DB_PREFIX . $mode_info['table']; + $sql .= " WHERE " . ($asset_id > 0 ? " fk_asset = " . (int) $asset_id : " fk_asset_model = " . (int) $asset_model_id); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorDeleteAccountancyCodesForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + } + + if (!$error && !empty($this->accountancy_codes[$mode_key])) { + // Insert accountancy codes + $sql = "INSERT INTO " . MAIN_DB_PREFIX . $mode_info['table'] . "("; + $sql .= $asset_id > 0 ? "fk_asset," : "fk_asset_model,"; + $sql .= implode(',', array_keys($mode_info['fields'])); + $sql .= ", tms, fk_user_modif"; + $sql .= ") VALUES("; + $sql .= $asset_id > 0 ? $asset_id : $asset_model_id; + foreach ($mode_info['fields'] as $field_key => $field_info) { + $sql .= ', ' . (empty($this->accountancy_codes[$mode_key][$field_key]) ? 'NULL' : "'" . $this->db->escape($this->accountancy_codes[$mode_key][$field_key]) . "'"); + } + $sql .= ", '" . $this->db->idate($now) . "'"; + $sql .= ", " . $user->id; + $sql .= ")"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorInsertAccountancyCodesForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + } + } + } + + if (!$error && $asset_id > 0) { + // Calculation of depreciation lines (reversal and future) + require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; + $asset = new Asset($this->db); + $result = $asset->fetch($asset_id); + if ($result > 0) $result = $asset->calculationDepreciation(); + if ($result < 0) { + $this->errors[] = $langs->trans('AssetErrorCalculationDepreciationLines'); + $this->errors[] = $asset->errorsToString(); + $error++; + } + } + + if (!$error && !$notrigger) { + // Call trigger + $result = $this->call_trigger('ASSET_ACCOUNTANCY_CODES_MODIFY', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + if (!$error) { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } +} diff --git a/htdocs/asset/class/assetdepreciationoptions.class.php b/htdocs/asset/class/assetdepreciationoptions.class.php new file mode 100644 index 00000000000..ce2ddd73c08 --- /dev/null +++ b/htdocs/asset/class/assetdepreciationoptions.class.php @@ -0,0 +1,546 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file asset/class/assetdepreciationoptions.class.php + * \ingroup asset + * \brief This file is a class file for AssetDepreciationOptions + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; + +/** + * Class for AssetDepreciationOptions + */ +class AssetDepreciationOptions extends CommonObject +{ + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = ''; + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage) + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' + * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar' + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * 'validate' is 1 if need to validate with $this->validateField() + * 'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value) + * 'enabled_field' if the mode block or a field is enabled if another field equal a value (="mode_key:field_key:value") + * 'only_on_asset' is 1 if only a field on a asset + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields = array(); + + /** + * @var array Array with all deprecation options info by mode. + * Note : economic mode is mandatory and is the primary options + */ + public $deprecation_options_fields = array( + 'economic' => array( + 'label' => 'AssetDepreciationOptionEconomic', + 'table' => 'asset_depreciation_options_economic', + 'fields' => array( + 'depreciation_type' => array('type'=>'smallint', 'label'=>'AssetDepreciationOptionDepreciationType', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'arrayofkeyval'=>array('0'=>'AssetDepreciationOptionDepreciationTypeLinear', '1'=>'AssetDepreciationOptionDepreciationTypeDegressive', '2'=>'AssetDepreciationOptionDepreciationTypeExceptional'), 'validate'=>'1',), + 'degressive_coefficient' => array('type'=>'double(24,8)', 'label'=>'AssetDepreciationOptionDegressiveRate', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1','enabled_field' => 'economic:depreciation_type:1'), + 'duration' => array('type'=>'integer', 'label'=>'AssetDepreciationOptionDuration', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'duration_type' => array('type'=>'smallint', 'label'=>'AssetDepreciationOptionDurationType', 'enabled'=>'1', 'position'=>40, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'arrayofkeyval'=>array('0'=>'AssetDepreciationOptionDurationTypeAnnual', '1'=>'AssetDepreciationOptionDurationTypeMonthly'/*, '2'=>'AssetDepreciationOptionDurationTypeDaily'*/), 'validate'=>'1',), + 'rate' => array('type'=>'double(24,8)', 'label'=>'AssetDepreciationOptionRate', 'enabled'=>'1', 'position'=>50, 'visible'=>3, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1', 'computed' => '$object->asset_depreciation_options->getRate("economic")',), + 'accelerated_depreciation_option' => array('type'=>'boolean', 'label'=>'AssetDepreciationOptionAcceleratedDepreciation', 'enabled'=>'1', 'position'=>60, 'column_break' => true, 'notnull'=>0, 'default'=>'0', 'visible'=>1, 'validate'=>'1',), + 'amount_base_depreciation_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionAmountBaseDepreciationHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>90, 'notnull'=>0, 'required'=>1, 'visible'=>1, 'default'=>'$object->reversal_amount_ht > 0 ? $object->reversal_amount_ht : $object->acquisition_value_ht', 'isameasure'=>'1', 'validate'=>'1',), + 'amount_base_deductible_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionAmountBaseDeductibleHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>100, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'total_amount_last_depreciation_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionTotalAmountLastDepreciationHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>110, 'noteditable'=> 1, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + ), + ), + 'accelerated_depreciation' => array( + 'label' => 'AssetDepreciationOptionAcceleratedDepreciation', + 'table' => 'asset_depreciation_options_fiscal', + 'enabled_field' => 'economic:accelerated_depreciation_option:1', + 'fields' => array( + 'depreciation_type' => array('type'=>'smallint', 'label'=>'AssetDepreciationOptionDepreciationType', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'arrayofkeyval'=>array('0'=>'AssetDepreciationOptionDepreciationTypeLinear', '1'=>'AssetDepreciationOptionDepreciationTypeDegressive', '2'=>'AssetDepreciationOptionDepreciationTypeExceptional'), 'validate'=>'1',), + 'degressive_coefficient' => array('type'=>'double(24,8)', 'label'=>'AssetDepreciationOptionDegressiveRate', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1','enabled_field' => 'accelerated_depreciation:depreciation_type:1'), + 'duration' => array('type'=>'integer', 'label'=>'AssetDepreciationOptionDuration', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'duration_type' => array('type'=>'smallint', 'label'=>'AssetDepreciationOptionDurationType', 'enabled'=>'1', 'position'=>40, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'arrayofkeyval'=>array('0'=>'AssetDepreciationOptionDurationTypeAnnual', '1'=>'AssetDepreciationOptionDurationTypeMonthly'/*, '2'=>'AssetDepreciationOptionDurationTypeDaily'*/), 'validate'=>'1',), + 'rate' => array('type'=>'double(24,8)', 'label'=>'AssetDepreciationOptionRate', 'enabled'=>'1', 'position'=>50, 'visible'=>3, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1', 'computed' => '$object->asset_depreciation_options->getRate("accelerated_depreciation")',), + 'amount_base_depreciation_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionAmountBaseDepreciationHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>80, 'column_break' => true, 'notnull'=>0, 'required'=>1, 'visible'=>1, 'default'=>'$object->reversal_amount_ht > 0 ? $object->reversal_amount_ht : $object->acquisition_value_ht', 'isameasure'=>'1', 'validate'=>'1',), + 'amount_base_deductible_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionAmountBaseDeductibleHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>90, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'total_amount_last_depreciation_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionTotalAmountLastDepreciationHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>100, 'noteditable'=> 1, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + ), + ), + ); + public $fk_asset; + public $fk_asset_model; + public $tms; + public $fk_user_modif; + + /** + * @var array Array with all deprecation options by mode. + */ + public $deprecation_options = array(); + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $langs; + $this->db = $db; + + // Translate some data of arrayofkeyval + if (is_object($langs)) { + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['fields']) && is_array($mode_info['fields'])) { + foreach ($mode_info['fields'] as $field_key => $field_info) { + if (!empty($field_info['arrayofkeyval']) && is_array($field_info['arrayofkeyval'])) { + foreach ($field_info['arrayofkeyval'] as $key => $val) { + $this->deprecation_options_fields[$mode_key]['fields'][$field_key]['arrayofkeyval'][$key] = $langs->trans($val); + } + } + } + } + } + } + } + + /** + * Set object infos for a mode + * + * @param string $mode Depreciation mode (economic, accelerated_depreciation, ...) + * @param int $class_type Type (0:asset, 1:asset model) + * @param bool $all_field Get all fields + * @return int <0 if KO, >0 if OK + */ + public function setInfosForMode($mode, $class_type = 0, $all_field = false) + { + // Clean parameters + $mode = strtolower(trim($mode)); + + if (!empty($this->deprecation_options_fields[$mode])) { + $this->table_element = $this->deprecation_options_fields[$mode]['table']; + $this->fields = $this->deprecation_options_fields[$mode]['fields']; + foreach ($this->fields as $field_key => $field_info) { + if ((!empty($field_info['computed']) && !$all_field) || (!empty($field_info['only_on_asset']) && !empty($class_type))) { + unset($this->fields[$field_key]); + continue; + } + + // Unset required option (notnull) if field disabled + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($this->deprecation_options[$info[0]][$info[1]] != $info[2] && isset($this->fields[$field_key]['notnull'])) { + unset($this->fields[$field_key]['notnull']); + } + } + // Set value of the field in the object (for createCommon and setDeprecationOptionsFromPost functions) + $this->{$field_key} = $this->deprecation_options[$mode][$field_key]; + } + + $this->fields['rowid'] = array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"); + if (empty($class_type)) { + $this->fields['fk_asset'] = array('type' => 'integer:Asset:asset/class/asset.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label' => 'Asset', 'enabled' => '1', 'position' => 0, 'notnull' => 0, 'visible' => 0, 'index' => 1, 'validate' => '1',); + } else { + $this->fields['fk_asset_model'] = array('type' => 'integer:AssetModel:asset/class/assetmodel.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label' => 'AssetModel', 'enabled' => '1', 'position' => 0, 'notnull' => 0, 'visible' => 0, 'index' => 1, 'validate' => '1',); + } + $this->fields['tms'] = array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => '1', 'position' => 501, 'notnull' => 0, 'visible' => 0,); + $this->fields['fk_user_modif'] = array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => '1', 'position' => 511, 'notnull' => -1, 'visible' => 0,); + } + + return 1; + } + + /** + * Fill deprecation_options property of object (using for data sent by forms) + * + * @param int $class_type Type (0:asset, 1:asset model) + * @return int <0 if KO, >0 if OK + */ + public function setDeprecationOptionsFromPost($class_type = 0) + { + global $conf, $langs; + + $error = 0; + + $deprecation_options = array(); + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + $this->setInfosForMode($mode_key, $class_type); + + foreach ($mode_info['fields'] as $field_key => $field_info) { + if (!empty($field_info['computed'])) { + continue; + } + + $html_name = $mode_key . '_' . $field_key; + if ($field_info['type'] == 'duration') { + if (GETPOST($html_name . 'hour') == '' && GETPOST($html_name . 'min') == '') { + continue; // The field was not submited to be saved + } + } else { + if (!GETPOSTISSET($html_name)) { + continue; // The field was not submited to be saved + } + } + // Ignore special fields + if (in_array($field_key, array('rowid', 'entity', 'import_key'))) { + continue; + } + if (in_array($field_key, array('date_creation', 'tms', 'fk_user_creat', 'fk_user_modif'))) { + if (!in_array(abs($field_info['visible']), array(1, 3))) { + continue; // Only 1 and 3 that are case to create + } + } + + // Set value to insert + if (in_array($field_info['type'], array('text', 'html'))) { + $value = GETPOST($html_name, 'restricthtml'); + } elseif ($field_info['type'] == 'date') { + $value = dol_mktime(12, 0, 0, GETPOST($html_name . 'month', 'int'), GETPOST($html_name . 'day', 'int'), GETPOST($html_name . 'year', 'int')); // for date without hour, we use gmt + } elseif ($field_info['type'] == 'datetime') { + $value = dol_mktime(GETPOST($html_name . 'hour', 'int'), GETPOST($html_name . 'min', 'int'), GETPOST($html_name . 'sec', 'int'), GETPOST($html_name . 'month', 'int'), GETPOST($html_name . 'day', 'int'), GETPOST($html_name . 'year', 'int'), 'tzuserrel'); + } elseif ($field_info['type'] == 'duration') { + $value = 60 * 60 * GETPOST($html_name . 'hour', 'int') + 60 * GETPOST($html_name . 'min', 'int'); + } elseif (preg_match('/^(integer|price|real|double)/', $field_info['type'])) { + $value = price2num(GETPOST($html_name, 'alphanohtml')); // To fix decimal separator according to lang setup + } elseif ($field_info['type'] == 'boolean') { + $value = ((GETPOST($html_name) == '1' || GETPOST($html_name) == 'on') ? 1 : 0); + } elseif ($field_info['type'] == 'reference') { + // todo to check + $tmparraykey = array(); //array_keys($object->param_list); + $value = $tmparraykey[GETPOST($html_name)] . ',' . GETPOST($html_name . '2'); + } else { + if ($field_key == 'lang') { + $value = GETPOST($html_name, 'aZ09') ? GETPOST($html_name, 'aZ09') : ""; + } else { + $value = GETPOST($html_name, 'alphanohtml'); + } + } + if (preg_match('/^integer:/i', $field_info['type']) && $value == '-1') { + $value = ''; // This is an implicit foreign key field + } + if (!empty($field_info['foreignkey']) && $value == '-1') { + $value = ''; // This is an explicit foreign key field + } + + //var_dump($field_key.' '.$value.' '.$field_info['type']); + $field_value = $value; + if ($field_info['notnull'] > 0 && $field_value == '' && !is_null($field_info['default']) && $field_info['default'] == '(PROV)') { + $field_value = '(PROV)'; + } elseif ((!empty($field_info['required']) || $field_info['notnull'] > 0) && $field_value == '' && !empty($field_info['default'])) { + $field_value = dol_eval($field_info['default'], 1); + } + if ($field_info['notnull'] > 0 && $field_value == '' && is_null($field_info['default'])) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv($field_info['label'])), null, 'errors'); + } + $deprecation_options[$mode_key][$field_key] = $field_value; + + // Validation of fields values + if ($conf->global->MAIN_FEATURE_LEVEL >= 2 || !empty($conf->global->MAIN_ACTIVATE_VALIDATION_RESULT)) { + if (!$error && !empty($field_info['validate']) && is_callable(array($this, 'validateField'))) { + if (!$this->validateField($mode_info['fields'], $field_key, $value)) { + $error++; + } + } + } + } + } + // Unset not enabled modes + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($deprecation_options[$info[0]][$info[1]] != $info[2]) { + unset($deprecation_options[$info[0]][$info[1]]); + } + } + } + $this->deprecation_options = $deprecation_options; + + if ($error) { + return -1; + } else { + return 1; + } + } + + /** + * Load deprecation options of a asset or a asset model + * + * @param int $asset_id Asset ID to set + * @param int $asset_model_id Asset model ID to set + * @return int <0 if KO, >0 if OK + */ + public function fetchDeprecationOptions($asset_id = 0, $asset_model_id = 0) + { + global $langs, $hookmanager; + dol_syslog(__METHOD__ . " asset_id=$asset_id, asset_model_id=$asset_model_id"); + + $error = 0; + $this->errors = array(); + $this->deprecation_options = array(); + + // Clean parameters + $asset_id = $asset_id > 0 ? $asset_id : 0; + $asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0; + + if (!is_object($hookmanager)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $hookmanager->initHooks(array('assetdepreciationoptionsdao')); + $parameters = array('asset_id' => $asset_id, 'asset_model_id' => $asset_model_id); + $reshook = $hookmanager->executeHooks('fetchDepreciationOptions', $parameters, $this); // Note that $action and $object may have been modified by some hooks + if (!empty($reshook)) { + return $reshook; + } + + // Check parameters + if (empty($asset_id) && empty($asset_model_id)) { + $this->errors[] = $langs->trans('AssetErrorAssetOrAssetModelIDNotProvide'); + $error++; + } + if ($error) { + dol_syslog(__METHOD__ . " Error check parameters: " . $this->errorsToString(), LOG_ERR); + return -1; + } + + $class_type = $asset_id > 0 ? 0 : 1; + $deprecation_options = array(); + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + $this->setInfosForMode($mode_key, $class_type); + + $result = $this->fetchCommon(0, '', " AND " . ($asset_id > 0 ? " fk_asset = " . (int) $asset_id : " fk_asset_model = " . (int) $asset_model_id)); + if ($result < 0) { + $this->errors = array_merge(array($langs->trans('AssetErrorFetchDepreciationOptionsForMode', $mode_key) . ':'), $this->errors); + $error++; + } elseif ($result > 0) { + foreach ($this->fields as $field_key => $field_info) { + if (in_array($field_key, array('rowid', 'fk_asset', 'fk_asset_model', 'tms', 'fk_user_modif'))) continue; + $deprecation_options[$mode_key][$field_key] = $this->{$field_key}; + } + } + } + // Unset not enabled modes + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($deprecation_options[$info[0]][$info[1]] != $info[2]) { + unset($deprecation_options[$info[0]][$info[1]]); + } + } + } + + if ($error) { + dol_syslog(__METHOD__ . " Error fetch accountancy codes: " . $this->errorsToString(), LOG_ERR); + return -1; + } else { + $this->deprecation_options = $deprecation_options; + return 1; + } + } + + /** + * get general depreciation info for a mode (used in depreciation card) + * + * @param string $mode Depreciation mode (economic, accelerated_depreciation, ...) + * @return array|int <0 if KO otherwise array with general depreciation info + */ + public function getGeneralDepreciationInfoForMode($mode) + { + global $hookmanager; + dol_syslog(__METHOD__ . " mode=$mode"); + + $this->errors = array(); + + // Clean parameters + $mode = strtolower(trim($mode)); + + if (!is_object($hookmanager)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $hookmanager->initHooks(array('assetdepreciationoptionsdao')); + $parameters = array('mode' => $mode); + $reshook = $hookmanager->executeHooks('getGeneralDepreciationInfoForMode', $parameters, $this); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) { + return $reshook; + } elseif ($reshook > 0) { + return $hookmanager->resArray; + } + + $duration_type_list = $this->deprecation_options_fields[$mode]['fields']['duration_type']['arrayofkeyval']; + + return array( + 'base_depreciation_ht' => $this->deprecation_options[$mode]['amount_base_depreciation_ht'], + 'duration' => $this->deprecation_options[$mode]['duration'], + 'duration_type' => $duration_type_list[$this->deprecation_options[$mode]['duration_type']], + 'rate' => $this->getRate($mode), + ); + } + + /** + * Update deprecation options of a asset or a asset model + * + * @param User $user User making update + * @param int $asset_id Asset ID to set + * @param int $asset_model_id Asset model ID to set + * @param int $notrigger 1=disable trigger UPDATE (when called by create) + * @return int <0 if KO, >0 if OK + */ + public function updateDeprecationOptions($user, $asset_id = 0, $asset_model_id = 0, $notrigger = 0) + { + global $langs, $hookmanager; + dol_syslog(__METHOD__ . " user_id={$user->id}, asset_id=$asset_id, asset_model_id=$asset_model_id, notrigger=$notrigger"); + + $error = 0; + $this->errors = array(); + + // Clean parameters + $asset_id = $asset_id > 0 ? $asset_id : 0; + $asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0; + + if (!is_object($hookmanager)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $hookmanager->initHooks(array('assetdepreciationoptionsdao')); + $parameters = array('user' => $user, 'asset_id' => $asset_id, 'asset_model_id' => $asset_model_id); + $reshook = $hookmanager->executeHooks('updateDepreciationOptions', $parameters, $this); // Note that $action and $object may have been modified by some hooks + if (!empty($reshook)) { + return $reshook; + } + + // Check parameters + if (empty($asset_id) && empty($asset_model_id)) { + $this->errors[] = $langs->trans('AssetErrorAssetOrAssetModelIDNotProvide'); + $error++; + } + if ($error) { + dol_syslog(__METHOD__ . " Error check parameters: " . $this->errorsToString(), LOG_ERR); + return -1; + } + + $this->db->begin(); + + if ($asset_id > 0) { + $this->fk_asset = $asset_id; + $class_type = 0; + } else { + $this->fk_asset_model = $asset_model_id; + $class_type = 1; + } + $this->tms = dol_now(); + $this->fk_user_modif = $user->id; + + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + // Delete old accountancy codes + $sql = "DELETE FROM " . MAIN_DB_PREFIX . $mode_info['table']; + $sql .= " WHERE " . ($asset_id > 0 ? " fk_asset = " . (int) $asset_id : " fk_asset_model = " . (int) $asset_model_id); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorDeleteDepreciationOptionsForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + } + + if (!$error && !empty($this->deprecation_options[$mode_key])) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($this->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + + $this->setInfosForMode($mode_key, $class_type); + + $result = $this->createCommon($user, 1); + if ($result < 0) { + $this->errors = array_merge(array($langs->trans('AssetErrorInsertDepreciationOptionsForMode', $mode_key) . ':'), $this->errors); + $error++; + } + } + } + + if (!$error && $this->fk_asset > 0) { + // Calculation of depreciation lines (reversal and future) + require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; + $asset = new Asset($this->db); + $result = $asset->fetch($this->fk_asset); + if ($result > 0) $result = $asset->calculationDepreciation(); + if ($result < 0) { + $this->errors[] = $langs->trans('AssetErrorCalculationDepreciationLines'); + $this->errors[] = $asset->errorsToString(); + $error++; + } + } + + if (!$error && !$notrigger) { + // Call trigger + $result = $this->call_trigger('ASSET_DEPRECIATION_OPTIONS_MODIFY', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + if ($error) { + $this->db->rollback(); + return -1; + } else { + $this->db->commit(); + return 1; + } + } + + /** + * Get rate + * + * @param string $mode Depreciation mode (economic, accelerated_depreciation, ...) + * @return string Rate of the provided mode option + */ + public function getRate($mode) + { + $duration = $this->deprecation_options[$mode]["duration"] > 0 ? $this->deprecation_options[$mode]["duration"] : 0; + $duration_type = $this->deprecation_options[$mode]["duration_type"] > 0 ? $this->deprecation_options[$mode]["duration_type"] : 0; + + return price(price2num($duration > 0 ? (100 * ($duration_type == 1 ? 12 : 1) / $duration) : 0, 2)); + } +} diff --git a/htdocs/asset/class/assetmodel.class.php b/htdocs/asset/class/assetmodel.class.php new file mode 100644 index 00000000000..eae7b5d0fde --- /dev/null +++ b/htdocs/asset/class/assetmodel.class.php @@ -0,0 +1,822 @@ + + * Copyright (C) 2021 Open-Dsi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file class/assetmodel.class.php + * \ingroup asset + * \brief This file is a CRUD class file for AssetModel (Create/Read/Update/Delete) + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class for AssetModel + */ +class AssetModel extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'asset'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'assetmodel'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'asset_model'; + + /** + * @var int Does this object support multicompany module ? + * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table + */ + public $ismultientitymanaged = 1; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for assetmodel. Must be the part after the 'object_' into object_assetmodel.png + */ + public $picto = 'asset'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage) + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' + * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar' + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * 'validate' is 1 if need to validate with $this->validateField() + * 'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value) + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'validate'=>'1'), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'showoncombobox'=>'2', 'validate'=>'1',), + 'asset_type' => array('type'=>'smallint', 'label'=>'AssetType', 'enabled'=>'1', 'position'=>40, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('0'=>'AssetTypeIntangible', '1'=>'AssetTypeTangible', '2'=>'AssetTypeInProgress', '3'=>'AssetTypeFinancial'), 'validate'=>'1',), + 'fk_pays' =>array('type'=>'integer:Ccountry:core/class/ccountry.class.php', 'label'=>'Country', 'enabled'=>1, 'visible'=>1, 'position'=>50), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>300, 'notnull'=>0, 'visible'=>0, 'validate'=>'1',), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>301, 'notnull'=>0, 'visible'=>0, 'validate'=>'1',), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'default'=>'0', 'visible'=>2, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Enabled', '9'=>'Disabled'), 'validate'=>'1',), + ); + public $rowid; + public $ref; + public $label; + public $asset_type; + public $note_public; + public $note_private; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $last_main_doc; + public $import_key; + public $model_pdf; + public $status; + + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + // public $fk_element = 'fk_assetmodel'; + // /** + // * @var array List of child tables. To test if we can delete object. + // */ + // protected $childtables = array(); + // /** + // * @var array List of child tables. To know object to delete on cascade. + // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + // */ + // protected $childtablesoncascade = array('asset_assetmodeldet'); + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $conf, $langs; + + $this->db = $db; + + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) { + $this->fields['rowid']['visible'] = 0; + } + if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) { + $this->fields['entity']['enabled'] = 0; + } + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) { + if (isset($val['enabled']) && empty($val['enabled'])) { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) { + foreach ($this->fields as $key => $val) { + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + foreach ($val['arrayofkeyval'] as $key2 => $val2) { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + $resultcreate = $this->createCommon($user, $notrigger); + + return $resultcreate; + } + + /** + * Clone an object into another one + * + * @param User $user User that creates + * @param int $fromid Id of object to clone + * @return mixed New object created, <0 if KO + */ + public function createFromClone(User $user, $fromid) + { + global $langs, $extrafields; + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $object = new self($this->db); + + $this->db->begin(); + + // Load source object + $result = $object->fetchCommon($fromid); + if ($result > 0 && !empty($object->table_element_line)) { + $object->fetchLines(); + } + + // get lines so they will be clone + //foreach($this->lines as $line) + // $line->fetch_optionals(); + + // Reset some properties + unset($object->id); + unset($object->fk_user_creat); + unset($object->import_key); + + // Clear fields + if (property_exists($object, 'ref')) { + $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; + } + if (property_exists($object, 'label')) { + $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + } + if (property_exists($object, 'status')) { + $object->status = self::STATUS_DRAFT; + } + if (property_exists($object, 'date_creation')) { + $object->date_creation = dol_now(); + } + if (property_exists($object, 'date_modification')) { + $object->date_modification = null; + } + // ... + // Clear extrafields that are unique + if (is_array($object->array_options) && count($object->array_options) > 0) { + $extrafields->fetch_name_optionals_label($this->table_element); + foreach ($object->array_options as $key => $option) { + $shortkey = preg_replace('/options_/', '', $key); + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { + //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; + unset($object->array_options[$key]); + } + } + } + + // Create clone + $object->context['createfromclone'] = 'createfromclone'; + $result = $object->createCommon($user); + if ($result < 0) { + $error++; + $this->error = $object->error; + $this->errors = $object->errors; + } + + if (!$error) { + // copy internal contacts + if ($this->copy_linked_contact($object, 'internal') < 0) { + $error++; + } + } + + if (!$error) { + // copy external contacts if same company + if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) { + if ($this->copy_linked_contact($object, 'external') < 0) { + $error++; + } + } + } + + unset($object->context['createfromclone']); + + // End + if (!$error) { + $this->db->commit(); + return $object; + } else { + $this->db->rollback(); + return -1; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + $result = $this->fetchCommon($id, $ref); + if ($result > 0 && !empty($this->table_element_line)) { + $this->fetchLines(); + } + return $result; + } + + /** + * Load object lines in memory from the database + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetchLines() + { + $this->lines = array(); + + return 1; + } + + + /** + * Load list of objects in memory from the database. + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit limit + * @param int $offset Offset + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) + * @param string $filtermode Filter mode (AND or OR) + * @return array|int int <0 if KO, array of pages if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $records = array(); + + $sql = "SELECT "; + $sql .= $this->getFieldList('t'); + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) { + $sql .= " WHERE t.entity IN (".getEntity($this->table_element).")"; + } else { + $sql .= " WHERE 1 = 1"; + } + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid') { + $sqlwhere[] = $key." = ".((int) $value); + } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) { + $sqlwhere[] = $key." = '".$this->db->idate($value)."'"; + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } elseif (strpos($value, '%') === false) { + $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")"; + } else { + $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'"; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")"; + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= $this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < ($limit ? min($limit, $num) : $num)) { + $obj = $this->db->fetch_object($resql); + + $record = new self($this->db); + $record->setVarsFromFetchObj($obj); + + $records[$record->id] = $record; + + $i++; + } + $this->db->free($resql); + + return $records; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + return $this->updateCommon($user, $notrigger); + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + + /** + * Validate object + * + * @param User $user User making status change + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <=0 if OK, 0=Nothing done, >0 if KO + */ + public function validate($user, $notrigger = 0) + { + global $conf, $langs; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) { + dol_syslog(get_class($this) . "::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + $now = dol_now(); + + $this->db->begin(); + + // Validate + $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " SET status = " . self::STATUS_VALIDATED; + if (!empty($this->fields['date_validation'])) { + $sql .= ", date_validation = '" . $this->db->idate($now) . "'"; + } + if (!empty($this->fields['fk_user_valid'])) { + $sql .= ", fk_user_valid = " . ((int) $user->id); + } + $sql .= " WHERE rowid = " . ((int) $this->id); + + dol_syslog(get_class($this) . "::validate()", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + dol_print_error($this->db); + $this->error = $this->db->lasterror(); + $error++; + } + + if (!$error && !$notrigger) { + // Call trigger + $result = $this->call_trigger('ASSETMODEL_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + // Set new ref and current status + if (!$error) { + $this->status = self::STATUS_VALIDATED; + } + + if (!$error) { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, >0 if OK + */ + public function setDraft($user, $notrigger = 0) + { + // Protection + if ($this->status <= self::STATUS_DRAFT) { + return 0; + } + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'ASSETMODEL_UNVALIDATE'); + } + + /** + * Set cancel status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function cancel($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_VALIDATED) { + return 0; + } + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'ASSETMODEL_CANCEL'); + } + + /** + * Set back to validated status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function reopen($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_CANCELED) { + return 0; + } + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'ASSETMODEL_REOPEN'); + } + + /** + * Return a link to the object card (with optionaly the picto) + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) + { + global $conf, $langs, $hookmanager; + + if (!empty($conf->dol_no_mouse_hover)) { + $notooltip = 1; // Force disable tooltips + } + + $result = ''; + + $label = img_picto('', $this->picto).' '.$langs->trans("AssetModel").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + + $url = dol_buildpath('/asset/model/card.php', 1).'?id='.$this->id; + + if ($option != 'nolink') { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { + $add_save_lastsearch_values = 1; + } + if ($add_save_lastsearch_values) { + $url .= '&save_lastsearch_values=1'; + } + } + + $linkclose = ''; + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $label = $langs->trans("ShowAssetModel"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } + + if ($option == 'nolink') { + $linkstart = ''; + if ($option == 'nolink') { + $linkend = ''; + } else { + $linkend = ''; + } + + $result .= $linkstart; + + if (empty($this->showphoto_on_popup)) { + if ($withpicto) { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } else { + if ($withpicto) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + list($class, $module) = explode('@', $this->picto); + $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); + if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { + $result .= '
    No photo
    '; + } else { + $result .= '
    No photo
    '; + } + + $result .= '
    '; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } + } + + if ($withpicto != 2) { + $result .= $this->ref; + } + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('assetmodeldao')); + $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } + + return $result; + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLabelStatus($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLibStatut($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function LibStatut($status, $mode = 0) + { + // phpcs:enable + if (empty($this->labelStatus) || empty($this->labelStatusShort)) { + global $langs; + //$langs->load("asset@asset"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled'); + } + + $statusType = 'status'.$status; + //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; + if ($status == self::STATUS_CANCELED) { + $statusType = 'status6'; + } + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); + } + + /** + * Load the info information in the object + * + * @param int $id Id of object + * @return void + */ + public function info($id) + { + $sql = "SELECT rowid, date_creation as datec, tms as datem,"; + $sql .= " fk_user_creat, fk_user_modif"; + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + $sql .= " WHERE t.rowid = ".((int) $id); + + $result = $this->db->query($sql); + if ($result) { + if ($this->db->num_rows($result)) { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + + if ($obj->fk_user_valid) { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_cloture); + $this->user_cloture = $cluser; + } + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_validation = $this->db->jdate($obj->datev); + } + + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + // Set here init that are not commonf fields + // $this->property1 = ... + // $this->property2 = ... + + $this->initAsSpecimenCommon(); + } + + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + return $this->lines; + } + + /** + * Action executed by scheduler + * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' + * Use public function doScheduledJob($param1, $param2, ...) to get parameters + * + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function doScheduledJob() + { + global $conf, $langs; + + //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; + + $error = 0; + $this->output = ''; + $this->error = ''; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $now = dol_now(); + + $this->db->begin(); + + // ... + + $this->db->commit(); + + return $error; + } +} diff --git a/htdocs/asset/depreciation.php b/htdocs/asset/depreciation.php new file mode 100644 index 00000000000..8f3547d81fb --- /dev/null +++ b/htdocs/asset/depreciation.php @@ -0,0 +1,199 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/depreciation.php + * \ingroup asset + * \brief Card with depreciation on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Asset($db); +$assetdepreciationoptions = new AssetDepreciationOptions($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetdepreciation', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!empty($object->not_depreciated)) accessforbidden(); + +$object->asset_depreciation_options = &$assetdepreciationoptions; +$result = $assetdepreciationoptions->fetchDeprecationOptions($object->id); +if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); +} +$result = $object->fetchDepreciationLines(); +if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('Asset'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetPrepareHead($object); + print dol_get_fiche_head($head, 'depreciation', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print '
    '; + + print dol_get_fiche_end(); + + $parameters = array(); + $reshook = $hookmanager->executeHooks('listAssetDeprecation', $parameters, $object, $action); + print $hookmanager->resPrint; + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } elseif (empty($reshook)) { + $bookkeeping_icon = ''; + $future_icon = ''; + $now = dol_now(); + + foreach ($assetdepreciationoptions->deprecation_options_fields as $mode_key => $fields) { + $lines = $object->depreciation_lines[$mode_key]; + if (!empty($lines)) { + $mode_info = $assetdepreciationoptions->deprecation_options_fields[$mode_key]; + $depreciation_info = $assetdepreciationoptions->getGeneralDepreciationInfoForMode($mode_key); + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + + // Depreciation general info + //--------------------------------- + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + print ''; + print ''; + print '
    ' . $langs->trans('AssetBaseDepreciationHT') . '' . price($depreciation_info['base_depreciation_ht']) . '
    ' . $langs->trans('AssetDepreciationBeginDate') . '' . dol_print_date($object->date_start > $object->date_acquisition ? $object->date_start : $object->date_acquisition, 'day') . '
    '; + + // We close div and reopen for second column + print '
    '; + print '
    '; + + print '
    '; + print ''; + print ''; + print ''; + print '
    ' . $langs->trans('AssetDepreciationDuration') . '' . $depreciation_info['duration'] . ' ( ' . $depreciation_info['duration_type'] . ' )
    ' . $langs->trans('AssetDepreciationRate') . '' . $depreciation_info['rate'] . '
    '; + print '
    '; + print '
    '; + print '
    '; + + // Depreciation lines + //--------------------------------- + print '
    '; + print '
    '; + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + if (empty($lines)) { + print ''; + } else { + foreach ($lines as $line) { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + } + } + + print '
    ' . $langs->trans("Ref") . '' . $langs->trans("AssetDepreciationDate") . '' . $langs->trans("AssetDepreciationHT") . '' . $langs->trans("AssetCumulativeDepreciationHT") . '' . $langs->trans("AssetResidualHT") . '
    ' . $langs->trans("None") . '
    ' . ($line['bookkeeping'] ? $bookkeeping_icon : ($line['depreciation_date'] > $now ? $future_icon : '')) . '' . (empty($line['ref']) ? $langs->trans('AssetDepreciationReversal') : $line['ref']) . '' . dol_print_date($line['depreciation_date'], 'day') . ''; + print price($line['depreciation_ht']); + print ''; + print price($line['cumulative_depreciation_ht']); + print ''; + print price(price2num($depreciation_info['base_depreciation_ht'] - $line['cumulative_depreciation_ht'], 'MT')); + print '
    '; + print '
    '; + } + } + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/depreciation_options.php b/htdocs/asset/depreciation_options.php new file mode 100644 index 00000000000..ba5719705dc --- /dev/null +++ b/htdocs/asset/depreciation_options.php @@ -0,0 +1,190 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/depreciation_options.php + * \ingroup asset + * \brief Card with depreciation options on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Asset($db); +$assetdepreciationoptions = new AssetDepreciationOptions($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetdepreciationoptions', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!empty($object->not_depreciated)) accessforbidden(); + +$object->asset_depreciation_options = &$assetdepreciationoptions; +$result = $assetdepreciationoptions->fetchDeprecationOptions($object->id); +if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/asset/depreciation_options.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } + + if ($action == "update") { + $result = $assetdepreciationoptions->setDeprecationOptionsFromPost(); + if ($result > 0) $result = $assetdepreciationoptions->updateDeprecationOptions($user, $object->id); + if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); + $action = 'edit'; + } else { + setEventMessage($langs->trans('RecordSaved')); + header("Location: " . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('Asset'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetPrepareHead($object); + print dol_get_fiche_head($head, 'depreciation_options', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print '
    '; + + if ($action == 'edit') { + print ''; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + include DOL_DOCUMENT_ROOT . '/asset/tpl/depreciation_options_edit.tpl.php'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print ''; + } else { + include DOL_DOCUMENT_ROOT . '/asset/tpl/depreciation_options_view.tpl.php'; + } + + print dol_get_fiche_end(); + + if ($action != 'edit') { + print '
    ' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT/* && !empty($object->enabled_modes)*/) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + } + print '
    ' . "\n"; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/disposal.php b/htdocs/asset/disposal.php new file mode 100644 index 00000000000..7fddb92b05f --- /dev/null +++ b/htdocs/asset/disposal.php @@ -0,0 +1,120 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/disposal.php + * \ingroup asset + * \brief Card with disposal info on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Asset($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetdisposal', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity]."/".$object->id; +} + +$permissionnote = $user->rights->asset->write; // Used by the include of actions_setnotes.inc.php +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!isset($object->disposal_date) || $object->disposal_date === "") accessforbidden(); + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('Asset'), $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = assetPrepareHead($object); + + print dol_get_fiche_head($head, 'disposal', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print ''."\n"; + + // Common attributes + $show_fields = array('disposal_date', 'disposal_amount_ht', 'fk_disposal_type', 'disposal_depreciated', 'disposal_subject_to_vat'); + foreach ($object->fields as $field_key => $field_info) { + $object->fields[$field_key]['visible'] = in_array($field_key, $show_fields) ? 1 : 0; + } + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + + print '
    '; + print '
    '; + + print dol_get_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/document.php b/htdocs/asset/document.php index 9d46e9ae0b6..96b222b26c1 100644 --- a/htdocs/asset/document.php +++ b/htdocs/asset/document.php @@ -31,19 +31,18 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page -$langs->loadLangs(array('assets', 'companies', 'other')); +$langs->loadLangs(array('assets', 'companies', 'other', 'mails')); -$id = (GETPOST('id', 'int') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility -$ref = GETPOST('ref', 'alpha'); -$socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST('sortfield', 'aZ09comma'); -$sortorder = GETPOST('sortorder', 'aZ09comma'); +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page == -1) { $page = 0; @@ -58,18 +57,28 @@ if (!$sortfield) { $sortfield = "name"; } +// Initialize technical objects $object = new Asset($db); -if ($object->fetch($id)) { - $upload_dir = $conf->asset->dir_output."/".dol_sanitizeFileName($object->ref); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetdocument', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals + +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object); } -$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php +$permissiontoadd = $user->rights->asset->asset->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result=restrictedArea($user, 'asset', $id, ''); +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); /* @@ -83,60 +92,67 @@ include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; * View */ -$title = $langs->trans('Assets')." - ".$langs->trans('Documents'); - -$help_url = ''; - -llxHeader('', $title, $help_url); - $form = new Form($db); +$title = $langs->trans("Asset").' - '.$langs->trans("Files"); +$help_url = ''; +llxHeader('', $title, $help_url); + +if ($object->id) { + /* + * Show tabs + */ + $head = assetPrepareHead($object); + + print dol_get_fiche_head($head, 'document', $langs->trans("Asset"), -1, $object->picto); -if ($id > 0 || !empty($ref)) { - if ($object->fetch($id, $ref) > 0) { - $upload_dir = $conf->asset->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref); - - $head = asset_prepare_head($object); - print dol_get_fiche_head($head, 'documents', $langs->trans('Asset'), -1, 'accounting'); - - // Build file list - $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1); - $totalsize = 0; - foreach ($filearray as $key => $file) { - $totalsize += $file['size']; - } - - // Asset content - - $linkback = ''.$langs->trans("BackToList").''; - - $morehtmlref = ''; - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0); - - print '
    '; - print '
    '; - - print ''; - - print ''; - print ''; - print "
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("TotalSizeOfAttachedFiles").''.dol_print_size($totalsize, 1, 1).'
    \n"; - - print "
    \n"; - - print dol_get_fiche_end(); - - $modulepart = 'asset'; - $permissiontoadd = $user->rights->asset->write; - $permtoedit = $user->rights->asset->write; - $param = '&id='.$object->id; - include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; - } else { - dol_print_error($db); + // Build file list + $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1); + $totalsize = 0; + foreach ($filearray as $key => $file) { + $totalsize += $file['size']; } + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + + print '
    '; + print ''; + + // Number of files + print ''; + + // Total size + print ''; + + print '
    ' . $langs->trans("NbOfAttachedFiles") . '' . count($filearray) . '
    ' . $langs->trans("TotalSizeOfAttachedFiles") . '' . $totalsize . ' ' . $langs->trans("bytes") . '
    '; + + print '
    '; + + print dol_get_fiche_end(); + + $modulepart = 'asset'; + $permissiontoadd = $user->rights->asset->write; + // $permissiontoadd = 1; + $permtoedit = $user->rights->asset->write; + // $permtoedit = 1; + $param = '&id=' . $object->id; + + //$relativepathwithnofile='asset/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile = dol_sanitizeFileName($object->ref) . '/'; + + include DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php'; } else { - print $langs->trans("ErrorUnknown"); + accessforbidden('', 0, 1); } // End of page diff --git a/htdocs/asset/info.php b/htdocs/asset/info.php deleted file mode 100644 index 7a8f4c20ce2..00000000000 --- a/htdocs/asset/info.php +++ /dev/null @@ -1,93 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/asset/info.php - * \ingroup asset - * \brief Page to show an asset information - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; - -// Load translation files required by the page -$langs->loadLangs(array("asset")); - -$id = GETPOSTINT('id'); -$ref = GETPOST('ref', 'alpha'); -$action = GETPOST('action', 'aZ09'); - -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'asset', $id); - -$object = new Asset($db); -$object->fetch($id); - - -/* - * Actions - */ - -// None - - -/* - * View - */ - -$form = new Form($db); - -$title = $langs->trans('Asset')." - ".$langs->trans('Info'); - -$help_url = ""; - -llxHeader('', $title, $help_url); - -$object->info($id); - -$head = asset_prepare_head($object); - -print dol_get_fiche_head($head, 'info', $langs->trans("Asset"), -1, 'generic'); - -$linkback = ''.$langs->trans("BackToList").''; - -$morehtmlref = '
    '; -$morehtmlref .= '
    '; - -dol_banner_tab($object, 'rowid', $linkback, 1, 'rowid', 'ref', $morehtmlref); - -print '
    '; -print '
    '; - -print '
    '; - -print '
    '; -dol_print_object_info($object); -print '
    '; - -print '
    '; - -print dol_get_fiche_end(); - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php index 1abdabd333e..c475e22fc83 100644 --- a/htdocs/asset/list.php +++ b/htdocs/asset/list.php @@ -31,26 +31,26 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; // Load translation files required by the page -$langs->loadLangs(array("assets")); +$langs->loadLangs(array("assets", "other")); -$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... -$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) -$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? -$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation -$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button -$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list -$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'assetlist'; // To manage different context of search -$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page -$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... +$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) +$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? +$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation +$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button +$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'assetlist'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $id = GETPOST('id', 'int'); // Load variable for pagination -$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action $offset = $limit * $page; @@ -71,33 +71,24 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // Default sort order (if not yet defined by previous GETPOST) if (!$sortfield) { + reset($object->fields); // Reset is required to avoid key() to return null. $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. } if (!$sortorder) { $sortorder = "ASC"; } -// Security check -$socid = 0; -if ($user->socid) { - $socid = $user->socid; -} -if ($user->socid > 0) { - // Protection if external user - //$socid = $user->socid; - accessforbidden(); -} -// Security check -$result = restrictedArea($user, 'asset', $id); - - // Initialize array of search criterias -$search_all = GETPOST("search_all", 'alpha'); +$search_all = GETPOST('search_all', 'alphanohtml'); $search = array(); foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { $search[$key] = GETPOST('search_'.$key, 'alpha'); } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } } // List of fields to search into when doing a "search in all" @@ -108,27 +99,24 @@ foreach ($object->fields as $key => $val) { } } -// Definition of fields for list +// Definition of array of fields for columns $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>($val['enabled'] && ($val['visible'] != 3)), 'position'=>$val['position']); + $visible = (int) dol_eval($val['visible'], 1); + $arrayfields['t.'.$key] = array( + 'label'=>$val['label'], + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' + ); } } // Extra fields -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) { - $arrayfields["ef.".$key] = array( - 'label'=>$extrafields->attributes[$object->table_element]['label'][$key], - 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), - 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], - 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]) - ); - } - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; + $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); @@ -136,13 +124,28 @@ $permissiontoread = $user->rights->asset->read; $permissiontoadd = $user->rights->asset->write; $permissiontodelete = $user->rights->asset->delete; +// Security check +if (empty($conf->asset->enabled)) { + accessforbidden('Module not enabled'); +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$socid = 0; if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + /* * Actions */ if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; @@ -162,8 +165,12 @@ if (empty($reshook)) { if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers foreach ($object->fields as $key => $val) { $search[$key] = ''; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') @@ -188,21 +195,20 @@ $form = new Form($db); $now = dol_now(); -//$help_url="EN:Module_Asset|FR:Module_Asset_FR|ES:Módulo_Asset"; $help_url = ''; $title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("Assets")); +$morejs = array(); +$morecss = array(); // Build and execute select // -------------------------------------------------------------------- $sql = 'SELECT '; -foreach ($object->fields as $key => $val) { - $sql .= "t.".$key.", "; -} +$sql .= $object->getFieldList('t'); // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key." as options_".$key.', ' : ''); + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : ''); } } // Add fields from hooks @@ -211,27 +217,45 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $obje $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { +if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; } +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; if ($object->ismultientitymanaged == 1) { $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; } else { $sql .= " WHERE 1 = 1"; } foreach ($search as $key => $val) { - if ($key == 'status' && $search[$key] == -1) { - continue; - } - $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); - if (strpos($object->fields[$key]['type'], 'integer:') === 0) { - if ($search[$key] == '-1') { - $search[$key] = ''; + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $search[$key] == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND t.".$columnName." >= '".$db->idate($search[$key])."'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; + } + } } - $mode_search = 2; - } - if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); } } if ($search_all) { @@ -246,51 +270,69 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec $sql .= $hookmanager->resPrint; /* If a group by is required -$sql.= " GROUP BY " -foreach($object->fields as $key => $val) -{ +$sql .= " GROUP BY "; +foreach($object->fields as $key => $val) { $sql .= "t.".$key.", "; } // Add fields from extrafields -if (! empty($extrafields->attributes[$object->table_element]['label'])) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); +if (!empty($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); + } } // Add where from hooks -$parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook -$sql.=$hookmanager->resPrint; -$sql=preg_replace('/,\s*$/','', $sql); +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +$sql = preg_replace('/,\s*$/', '', $sql); */ -$sql .= $db->order($sortfield, $sortorder); +// Add HAVING from hooks +/* +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= !empty($hookmanager->resPrint) ? (" HAVING 1=1 " . $hookmanager->resPrint) : ""; +*/ // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + /* This old and fast method to get and count full list returns all record so use a high amount of memory. $resql = $db->query($sql); $nbtotalofrecords = $db->num_rows($resql); + */ + /* The slow method does not consume memory on mysql (not tested on pgsql) */ + /*$resql = $db->query($sql, 0, 'auto', 1); + while ($db->fetch_object($resql)) { + $nbtotalofrecords++; + }*/ + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $resql = $db->query($sqlforcount); + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } -// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set. -if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) { - $num = $nbtotalofrecords; -} else { - if ($limit) { - $sql .= $db->plimit($limit + 1, $offset); - } - $resql = $db->query($sql); - if (!$resql) { - dol_print_error($db); - exit; - } - - $num = $db->num_rows($resql); +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); } +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + + // Direct jump if only one record found if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { $obj = $db->fetch_object($resql); @@ -303,7 +345,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ // Output page // -------------------------------------------------------------------- -llxHeader('', $title, $help_url); +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); $arrayofselected = is_array($toselect) ? $toselect : array(); @@ -317,9 +359,11 @@ if ($limit > 0 && $limit != $conf->liste_limit) { foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { foreach ($search[$key] as $skey) { - $param .= '&search_'.$key.'[]='.urlencode($skey); + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } } - } else { + } elseif ($search[$key] != '') { $param .= '&search_'.$key.'='.urlencode($search[$key]); } } @@ -328,11 +372,17 @@ if ($optioncss != '') { } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( - //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), + //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"), + //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), + //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), ); if ($permissiontodelete) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); @@ -351,24 +401,25 @@ print ''; print ''; print ''; +print ''; print ''; -$newcardbutton = dolGetButtonTitle($langs->trans('NewAsset'), '', 'fa fa-plus-circle', dol_buildpath('/asset/card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/asset/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); // Add code for pre mass action (confirmation or email presend form) -$topicmail = "SendAssetsRef"; +$topicmail = "SendAssetRef"; $modelmail = "asset"; $objecttmp = new Asset($db); $trackid = 'asset'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; -if ($sall) { +if ($search_all) { foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); } - print '
    '.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'
    '; + print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '; } $moreforfilter = ''; @@ -395,31 +446,42 @@ $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfi $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table -print ''."\n"; +print '
    '."\n"; // Fields title search // -------------------------------------------------------------------- print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; } @@ -443,14 +505,14 @@ print ''."\n"; // -------------------------------------------------------------------- print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { @@ -464,13 +526,13 @@ $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$ $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column -print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch ')."\n"; +print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; print ''."\n"; // Detect if we need a fetch on each output line $needToFetchEachLine = 0; -if (is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { +if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) { if (preg_match('/\$object/', $val)) { $needToFetchEachLine++; // There is at least one compute field that use $object @@ -483,6 +545,7 @@ if (is_array($extrafields->attributes[$object->table_element]['computed']) && co // -------------------------------------------------------------------- $i = 0; $totalarray = array(); +$totalarray['nbfield'] = 0; while ($i < ($limit ? min($num, $limit) : $num)) { $obj = $db->fetch_object($resql); if (empty($obj)) { @@ -495,7 +558,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { // Show here line of result print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif ($key == 'status') { @@ -508,14 +571,17 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; } - if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status') { + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } + //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; if ($key == 'status') { print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id, ''); } else { print $object->showOutputField($val, $key, $object->$key, ''); } @@ -545,7 +611,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { print $hookmanager->resPrint; // Action column print ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo "\n"; +} +if (count($linkedObjectBlock) > 1) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo "\n"; +} + +echo "\n"; diff --git a/htdocs/asset/type.php b/htdocs/asset/type.php deleted file mode 100644 index cd802c1c4fd..00000000000 --- a/htdocs/asset/type.php +++ /dev/null @@ -1,608 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/asset/type.php - * \ingroup asset - * \brief Asset's type setup - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; -require_once DOL_DOCUMENT_ROOT.'/asset/class/asset_type.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; -if (!empty($conf->accounting->enabled)) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; -} -if (!empty($conf->accounting->enabled)) { - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -} -if (!empty($conf->accounting->enabled)) { - require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; -} - -// Load translation files required by the page -$langs->load("assets"); - -$rowid = GETPOST('rowid', 'int'); -$action = GETPOST('action', 'aZ09'); -$cancel = GETPOST('cancel', 'alpha'); -$backtopage = GETPOST('backtopage', 'alpha'); - -$type = GETPOST('type', 'alpha'); - -$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST('sortfield', 'aZ09comma'); -$sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page == -1) { - $page = 0; -} // If $page is not defined, or '' or -1 -$offset = $limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; -if (!$sortorder) { - $sortorder = "DESC"; -} -if (!$sortfield) { - $sortfield = "a.label"; -} - -$label = GETPOST("label", "alpha"); -$accountancy_code_asset = GETPOST('accountancy_code_asset', 'string'); -$accountancy_code_depreciation_asset = GETPOST('accountancy_code_depreciation_asset', 'string'); -$accountancy_code_depreciation_expense = GETPOST('accountancy_code_depreciation_expense', 'string'); -$comment = GETPOST('comment', 'string'); - -// Security check -$result = restrictedArea($user, 'asset', $rowid, 'asset_type'); - -$object = new AssetType($db); - -$extrafields = new ExtraFields($db); - -// fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label($object->table_element); - -if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers - $type = ""; - $sall = ""; -} - - -// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('assettypecard', 'globalcard')); - -$permissiontoadd = $user->rights->asset->setup_advance; - - -/* - * Actions - */ - -if ($cancel) { - $action = ''; - - if (!empty($backtopage)) { - header("Location: ".$backtopage); - exit; - } -} - -if ($action == 'add' && $user->rights->asset->write) { - $object->label = trim($label); - $object->accountancy_code_asset = trim($accountancy_code_asset); - $object->accountancy_code_depreciation_asset = trim($accountancy_code_depreciation_asset); - $object->accountancy_code_depreciation_expense = trim($accountancy_code_depreciation_expense); - $object->note = trim($comment); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost(null, $object); - if ($ret < 0) { - $error++; - } - - if (empty($object->label)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); - } else { - $sql = "SELECT label FROM ".MAIN_DB_PREFIX."asset_type WHERE label='".$db->escape($object->label)."'"; - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - } - if ($num) { - $error++; - $langs->load("errors"); - setEventMessages($langs->trans("ErrorLabelAlreadyExists", $login), null, 'errors'); - } - } - - if (!$error) { - $id = $object->create($user); - if ($id > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; - } else { - setEventMessages($object->error, $object->errors, 'errors'); - $action = 'create'; - } - } else { - $action = 'create'; - } -} - -if ($action == 'update' && $user->rights->asset->write) { - $object->fetch($rowid); - - $object->oldcopy = clone $object; - - $object->label = trim($label); - $object->accountancy_code_asset = trim($accountancy_code_asset); - $object->accountancy_code_depreciation_asset = trim($accountancy_code_depreciation_asset); - $object->accountancy_code_depreciation_expense = trim($accountancy_code_depreciation_expense); - $object->note = trim($comment); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET'); - if ($ret < 0) { - $error++; - } - - $ret = $object->update($user); - - if ($ret >= 0 && !count($object->errors)) { - setEventMessages($langs->trans("AssetTypeModified"), null, 'mesgs'); - } else { - setEventMessages($object->error, $object->errors, 'errors'); - } - - header("Location: ".$_SERVER["PHP_SELF"]."?rowid=".$object->id); - exit; -} - -if ($action == 'confirm_delete' && $user->rights->asset->write) { - $object->fetch($rowid); - $res = $object->delete(); - - if ($res > 0) { - setEventMessages($langs->trans("AssetsTypeDeleted"), null, 'mesgs'); - header("Location: ".$_SERVER["PHP_SELF"]); - exit; - } else { - setEventMessages($langs->trans("AssetsTypeCanNotBeDeleted"), null, 'errors'); - $action = ''; - } -} - - -/* - * View - */ - -$form = new Form($db); - -$help_url = ''; - -llxHeader('', $langs->trans("AssetsTypeSetup"), $help_url); - - -// List of asset type -if (!$rowid && $action != 'create' && $action != 'edit') { - //print dol_get_fiche_head(''); - - $sql = "SELECT d.rowid, d.label as label, d.accountancy_code_asset, d.accountancy_code_depreciation_asset, d.accountancy_code_depreciation_expense, d.note"; - $sql .= " FROM ".MAIN_DB_PREFIX."asset_type as d"; - $sql .= " WHERE d.entity IN (".getEntity('asset_type').")"; - - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - $nbtotalofrecords = $num; - - $i = 0; - - $param = ''; - - print '
    '; - if ($optioncss != '') { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $newcardbutton = dolGetButtonTitle($langs->trans('NewAssetType'), '', 'fa fa-plus-circle', dol_buildpath('/asset/type.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); - - print_barre_liste($langs->trans("AssetsTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, $object->picto, 0, $newcardbutton, '', $limit); - - $moreforfilter = ''; - - print '
    '; - print '
    '; if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { - print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); - } elseif (strpos($val['type'], 'integer:') === 0) { - print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth150', 1); - } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) { - print ''; + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
    '; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + } elseif ($key == 'lang') { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); + print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + } else { + print ''; } print '
    '; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined $selected = 0; if (in_array($object->id, $arrayofselected)) { $selected = 1; @@ -605,7 +671,7 @@ if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $n $genallowed = $permissiontoread; $delallowed = $permissiontoadd; - print $formfile->showdocuments('massfilesarea_asset', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, ''); + print $formfile->showdocuments('massfilesarea_asset', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); } // End of page diff --git a/htdocs/asset/model/accountancy_codes.php b/htdocs/asset/model/accountancy_codes.php new file mode 100644 index 00000000000..fd5999b20b0 --- /dev/null +++ b/htdocs/asset/model/accountancy_codes.php @@ -0,0 +1,191 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/model/accountancy_code.php + * \ingroup asset + * \brief Card with accountancy code on Asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new AssetModel($db); +$assetaccountancycodes = new AssetAccountancyCodes($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodelaccountancycodes', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->write))); // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + +$result = $assetaccountancycodes->fetchAccountancyCodes(0, $object->id); +if ($result < 0) { + setEventMessages($assetaccountancycodes->error, $assetaccountancycodes->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/asset/model/accountancy_codes.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } + + if ($action == "update") { + $assetaccountancycodes->setAccountancyCodesFromPost(); + + $result = $assetaccountancycodes->updateAccountancyCodes($user, 0, $object->id); + if ($result < 0) { + setEventMessages($assetaccountancycodes->error, $assetaccountancycodes->errors, 'errors'); + $action = 'edit'; + } else { + setEventMessage($langs->trans('RecordSaved')); + header("Location: " . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('AssetModel'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetModelPrepareHead($object); + print dol_get_fiche_head($head, 'accountancy_codes', $langs->trans("AssetModel"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print '
    '; + + if ($action == 'edit') { + print '
    '; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + include DOL_DOCUMENT_ROOT . '/asset/tpl/accountancy_codes_edit.tpl.php'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print '
    '; + } else { + include DOL_DOCUMENT_ROOT . '/asset/tpl/accountancy_codes_view.tpl.php'; + } + + print dol_get_fiche_end(); + + if ($action != 'edit') { + print '
    ' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT/* && !empty($object->enabled_modes)*/) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + } + print '
    ' . "\n"; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/agenda.php b/htdocs/asset/model/agenda.php new file mode 100644 index 00000000000..cd0365a1418 --- /dev/null +++ b/htdocs/asset/model/agenda.php @@ -0,0 +1,217 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/model/agenda.php + * \ingroup asset + * \brief Tab of events on Asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; +require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +if (GETPOST('actioncode', 'array')) { + $actioncode = GETPOST('actioncode', 'array', 3); + if (!count($actioncode)) { + $actioncode = '0'; + } +} else { + $actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); +} +$search_agenda_label = GETPOST('search_agenda_label'); + +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page == -1) { + $page = 0; +} // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortfield) { + $sortfield = 'a.datep,a.id'; +} +if (!$sortorder) { + $sortorder = 'DESC,DESC'; +} + +// Initialize technical objects +$object = new AssetModel($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodelagenda', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity] . "/model/" . $object->id; +} + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->write))); // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +$parameters = array('id' => $id); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + // Cancel + if (GETPOST('cancel', 'alpha') && !empty($backtopage)) { + header("Location: " . $backtopage); + exit; + } + + // Purge search criteria + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers + $actioncode = ''; + $search_agenda_label = ''; + } +} + + +/* + * View + */ + +$form = new Form($db); + +if ($object->id > 0) { + $title = $langs->trans("Agenda"); + //if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title; + $help_url = 'EN:Module_Agenda_En'; + llxHeader('', $title, $help_url); + + if (!empty($conf->notification->enabled)) { + $langs->load("mails"); + } + $head = assetModelPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("AssetModel"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + + $object->info($object->id); + dol_print_object_info($object, 1); + + print '
    '; + + print dol_get_fiche_end(); + + + // Actions buttons + + $objthirdparty = $object; + $objcon = new stdClass(); + + $out = '&origin=' . urlencode($object->element . '@' . $object->module) . '&originid=' . urlencode($object->id); + $urlbacktopage = $_SERVER['PHP_SELF'] . '?id=' . $object->id; + $out .= '&backtopage=' . urlencode($urlbacktopage); + $permok = $user->rights->agenda->myactions->create; + if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) { + //$out.='trans("AddAnAction"),'filenew'); + //$out.=""; + } + + + print '
    '; + + // if (!empty($conf->agenda->enabled)) { + // if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) { + // print '' . $langs->trans("AddAction") . ''; + // } else { + // print '' . $langs->trans("AddAction") . ''; + // } + // } + + print '
    '; + + // if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { + // $param = '&id=' . $object->id . '&socid=' . $socid; + // if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + // $param .= '&contextpage=' . urlencode($contextpage); + // } + // if ($limit > 0 && $limit != $conf->liste_limit) { + // $param .= '&limit=' . urlencode($limit); + // } + // + // + // print load_fiche_titre($langs->trans("ActionsOnAssetModel"), '', ''); + // + // // List of all actions + // $filters = array(); + // $filters['search_agenda_label'] = $search_agenda_label; + // + // // TODO Replace this with same code than into list.php + // show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, $object->module); + // } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/card.php b/htdocs/asset/model/card.php new file mode 100644 index 00000000000..3e0858da55e --- /dev/null +++ b/htdocs/asset/model/card.php @@ -0,0 +1,330 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/model/card.php + * \ingroup asset + * \brief Page to create/edit/view asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'assetmodelcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); + +// Initialize technical objects +$object = new AssetModel($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodelcard', 'globalcard')); // Note that conf->hooks_modules contains array + +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Initialize array of search criterias +$search_all = GETPOST("search_all", 'alpha'); +$search = array(); +foreach ($object->fields as $key => $val) { + if (GETPOST('search_' . $key, 'alpha')) { + $search[$key] = GETPOST('search_' . $key, 'alpha'); + } +} + +if (empty($action) && empty($id) && empty($ref)) { + $action = 'view'; +} + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->write))); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->delete) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->delete))) || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); +$permissionnote = $permissiontoadd; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $permissiontoadd; // Used by the include of actions_dellink.inc.php +$upload_dir = $conf->asset->multidir_output[isset($object->entity) ? $object->entity : 1]; + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $error = 0; + + $backurlforlist = DOL_URL_ROOT . '/asset/model/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT . '/asset/model/card.php?id=' . ((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + $triggermodname = 'ASSETMODEL_MODIFY'; // Name of trigger action code to execute when we modify record + + if (($action == 'edit' && !($permissiontoadd && $object->status == $object::STATUS_DRAFT)) || + ($action == 'confirm_setdraft' && !($permissiontoadd && $object->status != $object::STATUS_DRAFT)) || + ($action == 'confirm_validate' && !($permissiontoadd && $object->status != $object::STATUS_VALIDATED)) || + ($action == 'confirm_close' && !($permissiontoadd && $object->status != $object::STATUS_CANCELED)) + ) { + $action = ""; + } + + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen + include DOL_DOCUMENT_ROOT . '/core/actions_addupdatedelete.inc.php'; +} + + +/* + * View + * + * Put here all code to build page + */ + +$form = new Form($db); +$formfile = new FormFile($db); + +$title = $langs->trans("AssetModel") . ' - ' . $langs->trans("Card"); +$help_url = ''; +llxHeader('', $title, $help_url); + +// Part to create +if ($action == 'create') { + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("AssetModel")), '', 'object_' . $object->picto); + + print '
    '; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + // Set some default values + //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; + + print '' . "\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_add.tpl.php'; + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_add.tpl.php'; + + print '
    ' . "\n"; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel("Create"); + + print '
    '; + + //dol_set_focus('input[name="ref"]'); +} + +// Part to edit record +if (($id || $ref) && $action == 'edit') { + print load_fiche_titre($langs->trans("AssetModel"), '', 'object_' . $object->picto); + + print '
    '; + print ''; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(); + + print '' . "\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php'; + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php'; + + print '
    '; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print '
    '; +} + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $res = $object->fetch_optionals(); + + $head = assetModelPrepareHead($object); + print dol_get_fiche_head($head, 'card', $langs->trans("AssetModel"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteAssetModel'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } elseif ($action == 'clone') { + // Clone confirmation + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + } + + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; + + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php'; + + // Other attributes. Fields from hook formObjectOptions and Extrafields. + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + + print '
    '; + print '
    '; + print '
    '; + + print '
    '; + + print dol_get_fiche_end(); + + + // Buttons for actions + if ($action != 'editline') { + print '
    ' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + + // Back to draft + if ($object->status != $object::STATUS_DRAFT) { + print dolGetButtonAction($langs->trans('SetToDraft'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=confirm_setdraft&confirm=yes&token=' . newToken(), '', $permissiontoadd); + } + + if ($object->status != $object::STATUS_VALIDATED) { + print dolGetButtonAction($langs->trans('Enable'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=confirm_validate&confirm=yes&token=' . newToken(), '', $permissiontoadd); + } + + if ($object->status != $object::STATUS_CANCELED) { + print dolGetButtonAction($langs->trans('Disable'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_close&confirm=yes&token='.newToken(), '', $permissiontoadd); + } + + // Clone + print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&socid=' . $object->socid . '&action=clone&token=' . newToken(), '', $permissiontoadd); + + // Delete (need delete permission, or if draft, just need create/modify permission) + print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=delete&token=' . newToken(), '', $permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)); + } + print '
    ' . "\n"; + } + + print '
    '; + print ''; // ancre + + print '
    '; + + // $MAXEVENT = 10; + // + // $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT . '/asset/model/agenda.php?id=' . $object->id); + // + // // List of actions on element + // include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + // $formactions = new FormActions($db); + // $somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, 0, 1, '', $MAXEVENT, '', $morehtmlright); + + print '
    '; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/depreciation_options.php b/htdocs/asset/model/depreciation_options.php new file mode 100644 index 00000000000..f5bc751663b --- /dev/null +++ b/htdocs/asset/model/depreciation_options.php @@ -0,0 +1,191 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/model/depreciation_options.php + * \ingroup asset + * \brief Card with depreciation options on Asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new AssetModel($db); +$assetdepreciationoptions = new AssetDepreciationOptions($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodeldeprectationoptions', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->write))); // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + +$object->asset_depreciation_options = &$assetdepreciationoptions; +$result = $assetdepreciationoptions->fetchDeprecationOptions(0, $object->id); +if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/asset/model/depreciation_options.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } + + if ($action == "update") { + $result = $assetdepreciationoptions->setDeprecationOptionsFromPost(1); + if ($result > 0) $result = $assetdepreciationoptions->updateDeprecationOptions($user, 0, $object->id); + if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); + $action = 'edit'; + } else { + setEventMessage($langs->trans('RecordSaved')); + header("Location: " . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('AssetModel'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetModelPrepareHead($object); + print dol_get_fiche_head($head, 'depreciation_options', $langs->trans("AssetModel"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print '
    '; + + if ($action == 'edit') { + print '
    '; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + include DOL_DOCUMENT_ROOT . '/asset/tpl/depreciation_options_edit.tpl.php'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print '
    '; + } else { + include DOL_DOCUMENT_ROOT . '/asset/tpl/depreciation_options_view.tpl.php'; + } + + print dol_get_fiche_end(); + + if ($action != 'edit') { + print '
    ' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT/* && !empty($object->enabled_modes)*/) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + } + print '
    ' . "\n"; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/list.php b/htdocs/asset/model/list.php new file mode 100644 index 00000000000..a6423bb3a73 --- /dev/null +++ b/htdocs/asset/model/list.php @@ -0,0 +1,681 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/model/list.php + * \ingroup asset + * \brief List page for asset model + */ + +// Load Dolibarr environment +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/asset/class/assetmodel.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "other")); + +$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... +$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) +$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? +$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation +$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button +$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'assetmodellist'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') + +$id = GETPOST('id', 'int'); + +// Load variable for pagination +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST('sortfield', 'aZ09comma'); +$sortorder = GETPOST('sortorder', 'aZ09comma'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { + $page = 0; +} // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical objects +$object = new AssetModel($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetmodellist')); // Note that conf->hooks_modules contains array + +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); +//$extrafields->fetch_name_optionals_label($object->table_element_line); + +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Default sort order (if not yet defined by previous GETPOST) +if (!$sortfield) { + reset($object->fields); // Reset is required to avoid key() to return null. + $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. +} +if (!$sortorder) { + $sortorder = "ASC"; +} + +// Initialize array of search criterias +$search_all = GETPOST('search_all', 'alphanohtml'); +$search = array(); +foreach ($object->fields as $key => $val) { + if ($key == 'fk_pays' && !GETPOSTISSET('search_'.$key)) { + $search[$key] = $mysoc->country_id; + } elseif (GETPOST('search_'.$key, 'alpha') !== '') { + $search[$key] = GETPOST('search_'.$key, 'alpha'); + } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } +} + +// List of fields to search into when doing a "search in all" +$fieldstosearchall = array(); +foreach ($object->fields as $key => $val) { + if (!empty($val['searchall'])) { + $fieldstosearchall['t.'.$key] = $val['label']; + } +} + +// Definition of array of fields for columns +$arrayfields = array(); +foreach ($object->fields as $key => $val) { + // If $val['visible']==0, then we never show the field + if (!empty($val['visible'])) { + $visible = (int) dol_eval($val['visible'], 1); + $arrayfields['t.'.$key] = array( + 'label'=>$val['label'], + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' + ); + } +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; + +$object->fields = dol_sort_array($object->fields, 'position'); +$arrayfields = dol_sort_array($arrayfields, 'position'); + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->write))); +$permissiontodelete = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->delete) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->delete))); + +// Security check +if (empty($conf->asset->enabled)) { + accessforbidden('Module not enabled'); +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$socid = 0; if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + + +/* + * Actions + */ + +if (GETPOST('cancel', 'alpha')) { + $action = 'list'; + $massaction = ''; +} +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { + $massaction = ''; +} + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + // Purge search criteria + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers + foreach ($object->fields as $key => $val) { + $search[$key] = ''; + if ($key == 'fk_pays') $search[$key] = $mysoc->country_id; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } + } + $toselect = array(); + $search_array_options = array(); + } + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') + || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) { + $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation + } + + // Mass actions + $objectclass = 'AssetModel'; + $objectlabel = 'AssetModel'; + $uploaddir = $conf->asset->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); + +$help_url = ''; +$title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("AssetModels")); +$morejs = array(); +$morecss = array(); + + +// Build and execute select +// -------------------------------------------------------------------- +$sql = 'SELECT '; +$sql .= $object->getFieldList('t'); +// Add fields from extrafields +if (!empty($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : ''); + } +} +// Add fields from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= preg_replace('/^,/', '', $hookmanager->resPrint); +$sql = preg_replace('/,\s*$/', '', $sql); +$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; +if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; +} +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +if ($object->ismultientitymanaged == 1) { + $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; +} else { + $sql .= " WHERE 1 = 1"; +} +foreach ($search as $key => $val) { + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $search[$key] == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND t.".$columnName." >= '".$db->idate($search[$key])."'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; + } + } + } + } +} +if ($search_all) { + $sql .= natural_search(array_keys($fieldstosearchall), $search_all); +} +//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear); +// Add where from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; + +/* If a group by is required +$sql .= " GROUP BY "; +foreach($object->fields as $key => $val) { + $sql .= "t.".$key.", "; +} +// Add fields from extrafields +if (!empty($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); + } +} +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +$sql = preg_replace('/,\s*$/', '', $sql); +*/ + +// Add HAVING from hooks +/* +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= !empty($hookmanager->resPrint) ? (" HAVING 1=1 " . $hookmanager->resPrint) : ""; +*/ + +// Count total nb of records +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + /* This old and fast method to get and count full list returns all record so use a high amount of memory. + $resql = $db->query($sql); + $nbtotalofrecords = $db->num_rows($resql); + */ + /* The slow method does not consume memory on mysql (not tested on pgsql) */ + /*$resql = $db->query($sql, 0, 'auto', 1); + while ($db->fetch_object($resql)) { + $nbtotalofrecords++; + }*/ + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $resql = $db->query($sqlforcount); + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + $page = 0; + $offset = 0; + } + $db->free($resql); +} + +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} + +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + + +// Direct jump if only one record found +if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { + $obj = $db->fetch_object($resql); + $id = $obj->rowid; + header("Location: ".DOL_URL_ROOT.'/asset/model/card.php?id='.$id); + exit; +} + + +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +$arrayofselected = is_array($toselect) ? $toselect : array(); + +$param = ''; +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage='.urlencode($contextpage); +} +if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.urlencode($limit); +} +foreach ($search as $key => $val) { + if (is_array($search[$key]) && count($search[$key])) { + foreach ($search[$key] as $skey) { + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } + } elseif ($search[$key] != '') { + $param .= '&search_'.$key.'='.urlencode($search[$key]); + } +} +if ($optioncss != '') { + $param .= '&optioncss='.urlencode($optioncss); +} +// Add $param from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; + +// List of mass actions available +$arrayofmassactions = array( + //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"), + //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), + //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), + //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), +); +if ($permissiontodelete) { + $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); +} +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { + $arrayofmassactions = array(); +} +$massactionbutton = $form->selectMassAction('', $arrayofmassactions); + +print '
    '."\n"; +if ($optioncss != '') { + print ''; +} +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/asset/model/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); + +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); + +// Add code for pre mass action (confirmation or email presend form) +$topicmail = "SendAssetModelRef"; +$modelmail = "assetmodel"; +$objecttmp = new AssetModel($db); +$trackid = 'assetmodel'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + +if ($search_all) { + foreach ($fieldstosearchall as $key => $val) { + $fieldstosearchall[$key] = $langs->trans($val); + } + print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '; +} + +$moreforfilter = ''; +/*$moreforfilter.='
    '; +$moreforfilter.= $langs->trans('MyFilter') . ': '; +$moreforfilter.= '
    ';*/ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +if (empty($reshook)) { + $moreforfilter .= $hookmanager->resPrint; +} else { + $moreforfilter = $hookmanager->resPrint; +} + +if (!empty($moreforfilter)) { + print '
    '; + print $moreforfilter; + print '
    '; +} + +$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); + +print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table +print ''."\n"; + + +// Fields title search +// -------------------------------------------------------------------- +print ''; +foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '').'right'; + } + if (!empty($arrayfields['t.'.$key]['checked'])) { + print ''; + } +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + +// Fields from hook +$parameters = array('arrayfields'=>$arrayfields); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +// Action column +print ''; +print ''."\n"; + + +// Fields title label +// -------------------------------------------------------------------- +print ''; +foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '').'right'; + } + if (!empty($arrayfields['t.'.$key]['checked'])) { + print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n"; + } +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; +// Hook fields +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +// Action column +print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +print ''."\n"; + + +// Detect if we need a fetch on each output line +$needToFetchEachLine = 0; +if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { + foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) { + if (preg_match('/\$object/', $val)) { + $needToFetchEachLine++; // There is at least one compute field that use $object + } + } +} + + +// Loop on record +// -------------------------------------------------------------------- +$i = 0; +$totalarray = array(); +$totalarray['nbfield'] = 0; +while ($i < ($limit ? min($num, $limit) : $num)) { + $obj = $db->fetch_object($resql); + if (empty($obj)) { + break; // Should not happen + } + + // Store properties in $object + $object->setVarsFromFetchObj($obj); + + // Show here line of result + print ''; + foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } + + if (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } elseif ($key == 'ref') { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } + + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '').'right'; + } + //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; + + if (!empty($arrayfields['t.'.$key]['checked'])) { + print ''; + if ($key == 'status') { + print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id, ''); + } else { + print $object->showOutputField($val, $key, $object->$key, ''); + } + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; + } + if (!isset($totalarray['val'])) { + $totalarray['val'] = array(); + } + if (!isset($totalarray['val']['t.'.$key])) { + $totalarray['val']['t.'.$key] = 0; + } + $totalarray['val']['t.'.$key] += $object->$key; + } + } + } + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + + print ''."\n"; + + $i++; +} + +// Show total line +include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; + +// If no record found +if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''; +} + + +$db->free($resql); + +$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print '
    '; + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
    '; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + } elseif ($key == 'lang') { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); + print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + } else { + print ''; + } + print '
    '; +$searchpicto = $form->showFilterButtons(); +print $searchpicto; +print '
    '; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '
    '.$langs->trans("NoRecordFound").'
    '."\n"; +print '
    '."\n"; + +print '
    '."\n"; + +if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) { + $hidegeneratedfilelistifempty = 1; + if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) { + $hidegeneratedfilelistifempty = 0; + } + + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; + $formfile = new FormFile($db); + + // Show list of available documents + $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; + $urlsource .= str_replace('&', '&', $param); + + $filedir = $diroutputmassaction; + $genallowed = $permissiontoread; + $delallowed = $permissiontoadd; + + print $formfile->showdocuments('massfilesarea_asset', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/note.php b/htdocs/asset/model/note.php new file mode 100644 index 00000000000..4af8407976f --- /dev/null +++ b/htdocs/asset/model/note.php @@ -0,0 +1,120 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/asset/model/note.php + * \ingroup asset + * \brief Card with notes on Asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new AssetModel($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodelnote', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->write))); // Used by the include of actions_addupdatedelete.inc.php +$permissionnote = $permissiontoadd; // Used by the include of actions_setnotes.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not include_once +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('AssetModel'), $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = assetModelPrepareHead($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("AssetModel"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
    '; + print '
    '; + + + $cssclass = "titlefield"; + include DOL_DOCUMENT_ROOT . '/core/tpl/notes.tpl.php'; + + print '
    '; + + print dol_get_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/note.php b/htdocs/asset/note.php index ebd340e393d..8de86d49bb7 100644 --- a/htdocs/asset/note.php +++ b/htdocs/asset/note.php @@ -27,7 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; // Load translation files required by the page -$langs->loadLangs(array("asset", "companies")); +$langs->loadLangs(array("assets", "companies")); // Get parameters $id = GETPOST('id', 'int'); @@ -40,30 +40,24 @@ $backtopage = GETPOST('backtopage', 'alpha'); $object = new Asset($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; -$hookmanager->initHooks(array('assetnote')); // Note that conf->hooks_modules contains array - +$hookmanager->initHooks(array('assetnote', 'globalcard')); // Note that conf->hooks_modules contains array // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); -// Security check - Protection if external user -//if ($user->socid > 0) accessforbidden(); -//if ($user->socid > 0) $socid = $user->socid; -//$result = restrictedArea($user, 'asset', $id); - // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals if ($id > 0 || !empty($ref)) { $upload_dir = $conf->asset->multidir_output[$object->entity]."/".$object->id; } -// Security check -if (!empty($user->socid)) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'asset', $id); +$permissionnote = $user->rights->asset->write; // Used by the include of actions_setnotes.inc.php +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php -$permissionnote = 1; -//$permissionnote=$user->rights->asset->creer; // Used by the include of actions_setnotes.inc.php +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); /* @@ -78,67 +72,28 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once } + /* * View */ $form = new Form($db); -//$help_url='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; $help_url = ''; -llxHeader('', $langs->trans('Assets'), $help_url); +llxHeader('', $langs->trans('Asset'), $help_url); if ($id > 0 || !empty($ref)) { $object->fetch_thirdparty(); - $head = asset_prepare_head($object); + $head = assetPrepareHead($object); - print dol_get_fiche_head($head, 'note', $langs->trans("Asset"), -1, 'generic'); + print dol_get_fiche_head($head, 'note', $langs->trans("Asset"), -1, $object->picto); // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = '' . $langs->trans("BackToList") . ''; $morehtmlref = '
    '; - /* - // Ref customer - $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); - // Thirdparty - $morehtmlref.='
    '.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1); - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
    '.$langs->trans('Project') . ' '; - if ($user->rights->asset->creer) - { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref.=' : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
    '; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
    '; - } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); - } - } else { - if (! empty($object->fk_project)) { - $proj = new Project($db); - $proj->fetch($object->fk_project); - $morehtmlref.=''; - $morehtmlref.=$proj->ref; - $morehtmlref.=''; - } else { - $morehtmlref.=''; - } - } - }*/ $morehtmlref .= '
    '; @@ -150,7 +105,7 @@ if ($id > 0 || !empty($ref)) { $cssclass = "titlefield"; - include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + include DOL_DOCUMENT_ROOT . '/core/tpl/notes.tpl.php'; print ''; diff --git a/htdocs/asset/tpl/accountancy_codes_edit.tpl.php b/htdocs/asset/tpl/accountancy_codes_edit.tpl.php new file mode 100644 index 00000000000..bbd2b3d797c --- /dev/null +++ b/htdocs/asset/tpl/accountancy_codes_edit.tpl.php @@ -0,0 +1,81 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + +if (!empty($conf->accounting->enabled) && !is_object($formaccounting)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; + $formaccounting = new FormAccounting($db); +} + + +?> + +executeHooks('formAssetAccountancyCodes', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + foreach ($assetaccountancycodes->accountancy_codes_fields as $mode_key => $mode_info) { + //if (empty($object->enabled_modes[$mode_key])) continue; + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print ''; + foreach ($mode_info['fields'] as $field_key => $field_info) { + $html_name = $mode_key . '_' . $field_key; + print ''; + } + print '
    ' . $langs->trans($field_info['label']) . ''; + $accountancy_code = GETPOSTISSET($html_name) ? GETPOST($html_name, 'aZ09') : (!empty($assetaccountancycodes->accountancy_codes[$mode_key][$field_key]) ? $assetaccountancycodes->accountancy_codes[$mode_key][$field_key] : ''); + if (!empty($conf->accounting->enabled)) { + print $formaccounting->select_account($accountancy_code, $html_name, 1, null, 1, 1, 'minwidth150 maxwidth300', 1); + } else { + print ''; + } + print '
    '; + print '
    '; + } +} +?> + diff --git a/htdocs/asset/tpl/accountancy_codes_view.tpl.php b/htdocs/asset/tpl/accountancy_codes_view.tpl.php new file mode 100644 index 00000000000..0d92ad8eb37 --- /dev/null +++ b/htdocs/asset/tpl/accountancy_codes_view.tpl.php @@ -0,0 +1,82 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + + +?> + +executeHooks('formAssetAccountancyCodes', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; + + foreach ($assetaccountancycodes->accountancy_codes_fields as $mode_key => $mode_info) { + //if (empty($object->enabled_modes[$mode_key])) continue; + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print ''; + foreach ($mode_info['fields'] as $field_key => $field_info) { + print ''; + } + print '
    ' . $langs->trans($field_info['label']) . ''; + if (!empty($assetaccountancycodes->accountancy_codes[$mode_key][$field_key])) { + $accountancy_code = $assetaccountancycodes->accountancy_codes[$mode_key][$field_key]; + if (!empty($conf->accounting->enabled)) { + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('', $accountancy_code, 1); + + print $accountingaccount->getNomUrl(0, 1, 1, '', 1); + } else { + print $accountancy_code; + } + } + print '
    '; + print '
    '; + } +} +?> + diff --git a/htdocs/asset/tpl/depreciation_options_edit.tpl.php b/htdocs/asset/tpl/depreciation_options_edit.tpl.php new file mode 100644 index 00000000000..cef22936260 --- /dev/null +++ b/htdocs/asset/tpl/depreciation_options_edit.tpl.php @@ -0,0 +1,228 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + +if (!is_object($formadmin)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); +} + + +?> + +executeHooks('formAssetDeprecationOptions', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $class_type = get_class($object) == 'Asset' ? 0 : 1; + foreach ($assetdepreciationoptions->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + $enabled_field_info[] = array( + 'mode_key' => $info[0], + 'field_key' => $info[1], + 'value' => $info[2], + 'target' => 'block_' . $mode_key, + ); + } + + $assetdepreciationoptions->setInfosForMode($mode_key, $class_type, true); + $prefix_html_name = $mode_key . '_'; + + print '
    '; + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + $mode_info['fields'] = dol_sort_array($mode_info['fields'], 'position'); + foreach ($mode_info['fields'] as $field_key => $field_info) { + // Discard if extrafield is a hidden field on form + if (abs($field_info['visible']) != 1 && abs($field_info['visible']) != 3 && abs($field_info['visible']) != 4) { + continue; + } + if (array_key_exists('enabled', $field_info) && isset($field_info['enabled']) && !verifCond($field_info['enabled'])) { + continue; // We don't want this field + } + if (!empty($field_info['column_break'])) { + print '
    '; + + // We close div and reopen for second column + print '
    '; + print '
    '; + + print '
    '; + print ''; + } + + $html_name = $prefix_html_name . $field_key; + if (!empty($field_info['enabled_field'])) { + $info = explode(':', $field_info['enabled_field']); + $enabled_field_info[] = array( + 'mode_key' => $info[0], + 'field_key' => $info[1], + 'value' => $info[2], + 'target' => 'field_' . $html_name, + ); + } + + $more_class = ''; + if (!empty($field_info['required']) || (isset($field_info['notnull']) && $field_info['notnull'] > 0)) { + $more_class .= ' fieldrequired'; + } + if (preg_match('/^(text|html)/', $val['type'])) { + $more_class .= ' tdtop'; + } + + print ''; + if (!empty($field_info['help'])) { + print $form->textwithpicto($langs->trans($field_info['label']), $langs->trans($field_info['help'])); + } else { + print $langs->trans($field_info['label']); + } + print ''; + print ''; + print ''; + } + print '
    '; + if (!empty($field_info['picto'])) { + print img_picto('', $field_info['picto'], '', false, 0, 0, '', 'pictofixedwidth'); + } + if (in_array($field_info['type'], array('int', 'integer'))) { + $value = GETPOSTISSET($html_name) ?GETPOST($html_name, 'int') : $assetdepreciationoptions->$field_key; + } elseif ($field_info['type'] == 'double') { + $value = GETPOSTISSET($html_name) ? price2num(GETPOST($html_name, 'alphanohtml')) : $assetdepreciationoptions->$field_key; + } elseif (preg_match('/^(text|html)/', $field_info['type'])) { + $tmparray = explode(':', $field_info['type']); + if (!empty($tmparray[1])) { + $check = $tmparray[1]; + } else { + $check = 'restricthtml'; + } + $value = GETPOSTISSET($html_name) ? GETPOST($html_name, $check) : $assetdepreciationoptions->$field_key; + } elseif ($field_info['type'] == 'price') { + $value = GETPOSTISSET($html_name) ? price2num(GETPOST($html_name)) : ($assetdepreciationoptions->$field_key ? price2num($assetdepreciationoptions->$field_key) : (!empty($field_info['default']) ? dol_eval($field_info['default'], 1) : 0)); + } elseif ($field_key == 'lang') { + $value = GETPOSTISSET($html_name) ? GETPOST($html_name, 'aZ09') : $assetdepreciationoptions->lang; + } else { + $value = GETPOSTISSET($html_name) ? GETPOST($html_name, 'alpha') : $assetdepreciationoptions->$field_key; + } + if (!empty($field_info['noteditable'])) { + print $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $prefix_html_name, 0); + } else { + if ($field_key == 'lang') { + print img_picto('', 'language', 'class="pictofixedwidth"'); + print $formadmin->select_language($value, $html_name, 0, null, 1, 0, 0, 'minwidth300', 2); + } else { + print $assetdepreciationoptions->showInputField($field_info, $field_key, $value, '', '', $prefix_html_name, 0); + } + } + print '
    '; + print '
    '; + print '
    '; + print '
    '; + print '
    '; + } +} + +if (!empty($enabled_field_info)) { + $enabled_field_info = json_encode($enabled_field_info); + print << +SCRIPT; +} + +?> + diff --git a/htdocs/asset/tpl/depreciation_options_view.tpl.php b/htdocs/asset/tpl/depreciation_options_view.tpl.php new file mode 100644 index 00000000000..2660fbbaee7 --- /dev/null +++ b/htdocs/asset/tpl/depreciation_options_view.tpl.php @@ -0,0 +1,154 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + + +?> + +executeHooks('formAssetDeprecationOptions', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $class_type = get_class($object) == 'Asset' ? 0 : 1; + foreach ($assetdepreciationoptions->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($assetdepreciationoptions->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + + $assetdepreciationoptions->setInfosForMode($mode_key, $class_type, true); + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + $mode_info['fields'] = dol_sort_array($mode_info['fields'], 'position'); + foreach ($mode_info['fields'] as $field_key => $field_info) { + if (!empty($field_info['enabled_field'])) { + $info = explode(':', $field_info['enabled_field']); + if ($assetdepreciationoptions->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + // Discard if extrafield is a hidden field on form + if (abs($field_info['visible']) != 1 && abs($field_info['visible']) != 3 && abs($field_info['visible']) != 4 && abs($field_info['visible']) != 5) { + continue; + } + if (array_key_exists('enabled', $field_info) && isset($field_info['enabled']) && !verifCond($field_info['enabled'])) { + continue; // We don't want this field + } + if (!empty($field_info['column_break'])) { + print '
    '; + + // We close div and reopen for second column + print '
    '; + print '
    '; + + print '
    '; + print ''; + } + + $key = $mode_key . '_' . $field_key; + $value = $assetdepreciationoptions->deprecation_options[$mode_key][$field_key]; + + print ''; + if (!empty($field_info['help'])) { + print $form->textwithpicto($langs->trans($field_info['label']), $langs->trans($field_info['help'])); + } else { + if (isset($field_info['copytoclipboard']) && $field_info['copytoclipboard'] == 1) { + print showValueWithClipboardCPButton($value, 0, $langs->transnoentitiesnoconv($field_info['label'])); + } else { + print $langs->trans($field_info['label']); + } + } + print ''; + print ''; + print ''; + } + print '
    '; + if (in_array($field_info['type'], array('text', 'html'))) { + print '
    '; + } + if ($field_key == 'lang') { + $langs->load("languages"); + $labellang = ($value ? $langs->trans('Language_' . $value) : ''); + print picto_from_langcode($value, 'class="paddingrightonly saturatemedium opacitylow"'); + print $labellang; + } else { + if (isset($field_info['copytoclipboard']) && $field_info['copytoclipboard'] == 2) { + $out = $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $mode_key . '_', 0); + print showValueWithClipboardCPButton($out, 0, $out); + } else { + print $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $mode_key . '_', 0); + } + } + if (in_array($field_info['type'], array('text', 'html'))) { + print '
    '; + } + print '
    '; + print '
    '; + print '
    '; + print '
    '; + } +} + +?> + diff --git a/htdocs/asset/tpl/depreciation_view.tpl.php b/htdocs/asset/tpl/depreciation_view.tpl.php new file mode 100644 index 00000000000..2660fbbaee7 --- /dev/null +++ b/htdocs/asset/tpl/depreciation_view.tpl.php @@ -0,0 +1,154 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + + +?> + +executeHooks('formAssetDeprecationOptions', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $class_type = get_class($object) == 'Asset' ? 0 : 1; + foreach ($assetdepreciationoptions->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($assetdepreciationoptions->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + + $assetdepreciationoptions->setInfosForMode($mode_key, $class_type, true); + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + $mode_info['fields'] = dol_sort_array($mode_info['fields'], 'position'); + foreach ($mode_info['fields'] as $field_key => $field_info) { + if (!empty($field_info['enabled_field'])) { + $info = explode(':', $field_info['enabled_field']); + if ($assetdepreciationoptions->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + // Discard if extrafield is a hidden field on form + if (abs($field_info['visible']) != 1 && abs($field_info['visible']) != 3 && abs($field_info['visible']) != 4 && abs($field_info['visible']) != 5) { + continue; + } + if (array_key_exists('enabled', $field_info) && isset($field_info['enabled']) && !verifCond($field_info['enabled'])) { + continue; // We don't want this field + } + if (!empty($field_info['column_break'])) { + print '
    '; + + // We close div and reopen for second column + print '
    '; + print '
    '; + + print '
    '; + print ''; + } + + $key = $mode_key . '_' . $field_key; + $value = $assetdepreciationoptions->deprecation_options[$mode_key][$field_key]; + + print ''; + if (!empty($field_info['help'])) { + print $form->textwithpicto($langs->trans($field_info['label']), $langs->trans($field_info['help'])); + } else { + if (isset($field_info['copytoclipboard']) && $field_info['copytoclipboard'] == 1) { + print showValueWithClipboardCPButton($value, 0, $langs->transnoentitiesnoconv($field_info['label'])); + } else { + print $langs->trans($field_info['label']); + } + } + print ''; + print ''; + print ''; + } + print '
    '; + if (in_array($field_info['type'], array('text', 'html'))) { + print '
    '; + } + if ($field_key == 'lang') { + $langs->load("languages"); + $labellang = ($value ? $langs->trans('Language_' . $value) : ''); + print picto_from_langcode($value, 'class="paddingrightonly saturatemedium opacitylow"'); + print $labellang; + } else { + if (isset($field_info['copytoclipboard']) && $field_info['copytoclipboard'] == 2) { + $out = $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $mode_key . '_', 0); + print showValueWithClipboardCPButton($out, 0, $out); + } else { + print $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $mode_key . '_', 0); + } + } + if (in_array($field_info['type'], array('text', 'html'))) { + print '
    '; + } + print '
    '; + print '
    '; + print '
    '; + print '
    '; + } +} + +?> + diff --git a/htdocs/asset/tpl/linkedobjectblock.tpl.php b/htdocs/asset/tpl/linkedobjectblock.tpl.php new file mode 100644 index 00000000000..aef30995432 --- /dev/null +++ b/htdocs/asset/tpl/linkedobjectblock.tpl.php @@ -0,0 +1,81 @@ + + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2014 Marcos García + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Protection to avoid direct call of template +if (empty($conf) || !is_object($conf)) { + print "Error, template page can't be called as URL"; + exit; +} + +print "\n"; + +global $user; +global $noMoreLinkedObjectBlockAfter; + +$langs = $GLOBALS['langs']; +$linkedObjectBlock = $GLOBALS['linkedObjectBlock']; + +// Load translation files required by the page +$langs->load("assets"); + +$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc', 0, 0, 1); + +$total = 0; +$ilink = 0; +foreach ($linkedObjectBlock as $key => $objectlink) { + $ilink++; + + $trclass = 'oddeven'; + if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) { + $trclass .= ' liste_sub_total'; + } + echo '
    '.$langs->trans("Asset"); + if (!empty($showImportButton) && !empty($conf->global->MAIN_ENABLE_IMPORT_LINKED_OBJECT_LINES)) { + print ' '; + echo ''.$objectlink->getNomUrl(1).''.$objectlink->label.''.dol_print_date($objectlink->date_start, 'day').''; + if ($user->rights->asset->read) { + $total = $total + $objectlink->acquisition_value_ht; + echo price($objectlink->acquisition_value_ht); + } + echo ''.$objectlink->getLibStatut(3).''; + echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; + echo '
    '.$langs->trans("Total").''.price($total).'
    '."\n"; - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - - $assettype = new AssetType($db); - - while ($i < $num) { - $objp = $db->fetch_object($result); - - $assettype->id = $objp->rowid; - $assettype->ref = $objp->rowid; - $assettype->label = $objp->rowid; - - print ''; - print ''; - print ''; - - print ''; - - print ''; - - print ''; - - if ($user->rights->asset->write) { - print ''; - } else { - print ''; - } - print ""; - $i++; - } - - // If no record found - if ($num == 0) { - $colspan = 6; - print ''; - } - - print "
    '.$langs->trans("Ref").''.$langs->trans("Label").''.$langs->trans("AccountancyCodeAsset").''.$langs->trans("AccountancyCodeDepreciationAsset").''.$langs->trans("AccountancyCodeDepreciationExpense").' 
    '; - print $assettype->getNomUrl(1); - //'.img_object($langs->trans("ShowType"),'group').' '.$objp->rowid.' - print ''.dol_escape_htmltag($objp->label).''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('', $objp->accountancy_code_asset, 1); - - print $accountingaccount->getNomUrl(0, 1, 1, '', 0); - } else { - print $objp->accountancy_code_asset; - } - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount2 = new AccountingAccount($db); - $accountingaccount2->fetch('', $objp->accountancy_code_depreciation_asset, 1); - - print $accountingaccount2->getNomUrl(0, 1, 1, '', 0); - } else { - print $objp->accountancy_code_depreciation_asset; - } - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount3 = new AccountingAccount($db); - $accountingaccount3->fetch('', $objp->accountancy_code_depreciation_expense, 1); - - print $accountingaccount3->getNomUrl(0, 1, 1, '', 0); - } else { - print $objp->accountancy_code_depreciation_expense; - } - print 'rowid.'">'.img_edit().' 
    '.$langs->trans("NoRecordFound").'
    "; - print '
    '; - - print ''; - } else { - dol_print_error($db); - } -} - - -/* ************************************************************************** */ -/* */ -/* Creation mode */ -/* */ -/* ************************************************************************** */ -if ($action == 'create') { - $object = new AssetType($db); - if (!empty($conf->accounting->enabled)) { - $formaccounting = new FormAccounting($db); - } - - print load_fiche_titre($langs->trans("NewAssetType"), '', $object->picto); - - print '
    '; - print ''; - print ''; - - print dol_get_fiche_head(''); - - print ''; - print ''; - - print ''; - - if (!empty($conf->accounting->enabled)) { - // Accountancy_code_asset - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - } else // For external software - { - // Accountancy_code_asset - print ''; - print ''; - - // Accountancy_code_depreciation_asset - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - } - - print ''; - - // Other attributes - $parameters = array(); - $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook)) { - print $object->showOptionals($extrafields, 'create', $parameters); - } - print ''; - print "
    '.$langs->trans("Label").'
    '.$langs->trans("AccountancyCodeAsset").''; - print $formaccounting->select_account($object->accountancy_code_asset, 'accountancy_code_asset', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeDepreciationAsset").''; - print $formaccounting->select_account($object->accountancy_code_depreciation_asset, 'accountancy_code_depreciation_asset', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeDepreciationExpense").''; - print $formaccounting->select_account($object->accountancy_code_depreciation_expense, 'accountancy_code_depreciation_expense', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeAsset").''; - print '
    '.$langs->trans("AccountancyCodeDepreciationAsset").''; - print '
    '.$langs->trans("AccountancyCodeDepreciationExpense").''; - print '
    '.$langs->trans("Description").''; - print '
    \n"; - - print dol_get_fiche_end(); - - print $form->buttonsSaveCancel("Add"); - - print "
    \n"; -} - -/* ************************************************************************** */ -/* */ -/* View mode */ -/* */ -/* ************************************************************************** */ -if ($rowid > 0) { - if ($action != 'edit') { - $object = new AssetType($db); - $object->fetch($rowid); - $object->fetch_optionals(); - - /* - * Confirmation suppression - */ - if ($action == 'delete') { - print $form->formconfirm($_SERVER['PHP_SELF']."?rowid=".$object->id, $langs->trans("DeleteAnAssetType"), $langs->trans("ConfirmDeleteAssetType", $object->label), "confirm_delete", '', 0, 1); - } - - $head = asset_type_prepare_head($object); - - print dol_get_fiche_head($head, 'card', $langs->trans("AssetType"), -1, 'asset'); - - $linkback = ''.$langs->trans("BackToList").''; - - $morehtmlref = '
    '; - // Ref asset type - $morehtmlref .= $form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->asset->write, 'string', '', 0, 1); - $morehtmlref .= $form->editfieldval("Label", 'label', $object->label, $object, $user->rights->asset->write, 'string', '', null, null, '', 1); - $morehtmlref .= '
    '; - - dol_banner_tab($object, 'rowid', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); - - print '
    '; - print '
    '; - - print ''; - - print ''; - print ''; - print ''; - - print ''; - print ''; - print ''; - - print ''; - print ''; - print ''; - - print '"; - - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; - - print '
    '; - print $langs->trans("AccountancyCodeAsset"); - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('', $object->accountancy_code_asset, 1); - - print $accountingaccount->getNomUrl(0, 1, 1, '', 1); - } else { - print $object->accountancy_code_asset; - } - print '
    '; - print $langs->trans("AccountancyCodeDepreciationAsset"); - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount2 = new AccountingAccount($db); - $accountingaccount2->fetch('', $object->accountancy_code_depreciation_asset, 1); - - print $accountingaccount2->getNomUrl(0, 1, 1, '', 1); - } else { - print $object->accountancy_code_depreciation_asset; - } - print '
    '; - print $langs->trans("AccountancyCodeDepreciationExpense"); - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount3 = new AccountingAccount($db); - $accountingaccount3->fetch('', $object->accountancy_code_depreciation_expense, 1); - - print $accountingaccount3->getNomUrl(0, 1, 1, '', 1); - } else { - print $object->accountancy_code_depreciation_expense; - } - print '
    '.$langs->trans("Description").''; - print nl2br($object->note)."
    '; - print '
    '; - - print dol_get_fiche_end(); - - /* - * Buttons - */ - - print '
    '; - - // Edit - if ($user->rights->asset->write) { - print ''; - } - - // Delete - if ($user->rights->asset->write) { - print ''; - } - - print "
    "; - } - - /* ************************************************************************** */ - /* */ - /* Edition mode */ - /* */ - /* ************************************************************************** */ - - if ($action == 'edit') { - $object = new AssetType($db); - $object->fetch($rowid); - $object->fetch_optionals(); - if (!empty($conf->accounting->enabled)) { - $formaccounting = new FormAccounting($db); - } - - $head = asset_type_prepare_head($object); - - print '
    '; - print ''; - print ''; - print ''; - - print dol_get_fiche_head($head, 'card', $langs->trans("AssetsType"), -1, 'setup'); - - print ''; - - print ''; - - print ''; - - if (!empty($conf->accounting->enabled)) { - // Accountancy_code_asset - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - } else // For external software - { - // Accountancy_code_asset - print ''; - print ''; - - // Accountancy_code_depreciation_asset - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - } - - print ''; - - // Other attributes - $parameters = array(); - $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $act, $action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook)) { - print $object->showOptionals($extrafields, 'edit', $parameters); - } - - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; - - print '
    '.$langs->trans("Ref").''.$object->id.'
    '.$langs->trans("Label").'
    '.$langs->trans("AccountancyCodeAsset").''; - print $formaccounting->select_account($object->accountancy_code_asset, 'accountancy_code_asset', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeDepreciationAsset").''; - print $formaccounting->select_account($object->accountancy_code_depreciation_asset, 'accountancy_code_depreciation_asset', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeDepreciationExpense").''; - print $formaccounting->select_account($object->accountancy_code_depreciation_expense, 'accountancy_code_depreciation_expense', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeAsset").''; - print '
    '.$langs->trans("AccountancyCodeDepreciationAsset").''; - print '
    '.$langs->trans("AccountancyCodeDepreciationExpense").''; - print '
    '.$langs->trans("Description").''; - print '
    '; - - print dol_get_fiche_end(); - - print $form->buttonsSaveCancel(); - - print "
    "; - } -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index f6e40b511f1..96fb68b6e9b 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -519,7 +519,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $keyforbreak = 'duration'; include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; $object->calculateCosts(); - print ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).''; + print ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).''; print ''.$langs->trans("UnitCost").''.price($object->unit_cost).''; // Other attributes diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php index 3cc0dc1753a..48798db9b8f 100644 --- a/htdocs/bom/bom_list.php +++ b/htdocs/bom/bom_list.php @@ -106,7 +106,7 @@ foreach ($object->fields as $key => $val) { $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/bom/bom_net_needs.php b/htdocs/bom/bom_net_needs.php index 4b2d5cdecab..30cd6792c55 100644 --- a/htdocs/bom/bom_net_needs.php +++ b/htdocs/bom/bom_net_needs.php @@ -30,7 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("mrp", "other")); +$langs->loadLangs(array("mrp", "other", "stocks")); // Get parameters $id = GETPOST('id', 'int'); @@ -170,7 +170,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $keyforbreak = 'duration'; include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; - print ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).''; + print ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).''; print ''.$langs->trans("UnitCost").''.price($object->unit_cost).''; // Other attributes @@ -211,9 +211,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").' '; } print ''; - print ''.$langs->trans('Quantity').''; - print ''.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).''; - print ''.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).''; + print ''.$langs->trans('Quantity').''; + print ''.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).''; + print ''.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).''; print ''; if (! empty($TChildBom)) { if ($action == 'treeview') { @@ -227,9 +227,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print img_picto('', 'folder-open'); print ''; print ''; - print ''.$TProduct['qty'].''; - print ''; - print ''; + print ''.$TProduct['qty'].''; + print ''; + print ''; print ''; } if (! empty($TProduct['product'])) { @@ -241,9 +241,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($fk_bom != $object->id) print ''; else print ''; print ''.str_repeat($repeatChar, $TInfos['level']).$prod->getNomUrl(1).''; - print ''.$TInfos['qty'].''; - print ''.$prod->stock_reel.''; - print ''.$prod->stock_theorique.''; + print ''.$TInfos['qty'].''; + print ''.price2num($prod->stock_reel, 'MS').''; + print ''.$prod->stock_theorique.''; print ''; } } @@ -256,9 +256,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (empty($prod->stock_reel)) $prod->stock_reel = 0; print ''; print ''.$prod->getNomUrl(1).''; - print ''.$qty.''; - print ''.$prod->stock_reel.''; - print ''.$prod->stock_theorique.''; + print ''.$qty.''; + print ''.price2num($prod->stock_reel, 'MS').''; + print ''.$prod->stock_theorique.''; print ''; } } diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 20ff5fe27b1..86e07ed424d 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -78,7 +78,7 @@ class BOM extends CommonObject * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). - * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'maxwidth200', 'wordbreak', 'tdoverflowmax200' + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. @@ -97,7 +97,7 @@ class BOM extends CommonObject 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>5), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'noteditable'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of BOM", 'showoncombobox'=>'1',), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'2', 'autofocusoncreate'=>1, 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax200'), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'2', 'autofocusoncreate'=>1, 'css'=>'minwidth300 maxwidth400', 'csslist'=>'tdoverflowmax200'), 'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>33, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble'), 'css'=>'minwidth175', 'csslist'=>'minwidth175 center'), //'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'position'=>32, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing')), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1:(finished IS NULL or finished <> 0)', 'label'=>'Product', 'picto'=>'product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax100'), @@ -1103,6 +1103,23 @@ class BOM extends CommonObject } } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'bom_bomline' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Get Net needs by product * diff --git a/htdocs/bom/tpl/linkedobjectblock.tpl.php b/htdocs/bom/tpl/linkedobjectblock.tpl.php index 2737b425c9c..8a98c078bc5 100644 --- a/htdocs/bom/tpl/linkedobjectblock.tpl.php +++ b/htdocs/bom/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user, $db; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index 8040310ea53..61b394a3b0f 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -126,7 +126,7 @@ print ''; $total_cost = 0; print ''; $coldisplay++; -echo price($line->total_cost); +echo ''.price($line->total_cost).''; print ''; if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines') { @@ -152,12 +152,12 @@ if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines') { print ''; $coldisplay++; if ($i > 0) { - print 'id.'">'; + print 'id.'">'; echo img_up('default', 0, 'imgupforline'); print ''; } if ($i < $num - 1) { - print 'id.'">'; + print 'id.'">'; echo img_down('default', 0, 'imgdownforline'); print ''; } @@ -236,15 +236,16 @@ if ($resql) { // Efficiency print ''.$sub_bom_line->efficiency.''; + // Cost if (!empty($sub_bom->id)) { $sub_bom->calculateCosts(); - print ''.price($sub_bom->total_cost * $sub_bom_line->qty * $line->qty).''; + print ''.price($sub_bom->total_cost * $sub_bom_line->qty * $line->qty).''; $total_cost+= $sub_bom->total_cost * $sub_bom_line->qty * $line->qty; } elseif ($sub_bom_product->cost_price > 0) { - print ''.price($sub_bom_product->cost_price * $sub_bom_line->qty * $line->qty).''; + print ''.price($sub_bom_product->cost_price * $sub_bom_line->qty * $line->qty).''; $total_cost+= $sub_bom_product->cost_price * $sub_bom_line->qty * $line->qty; } elseif ($sub_bom_product->pmp > 0) { // PMP if cost price isn't defined - print ''.price($sub_bom_product->pmp * $sub_bom_line->qty * $line->qty).''; + print ''.price($sub_bom_product->pmp * $sub_bom_line->qty * $line->qty).''; $total_cost.= $sub_bom_product->pmp * $sub_bom_line->qty * $line->qty; } else { // Minimum purchase price if cost price and PMP aren't defined $sql_supplier_price = 'SELECT MIN(price) AS min_price, quantity AS qty FROM '.MAIN_DB_PREFIX.'product_fournisseur_price'; @@ -254,7 +255,7 @@ if ($resql) { $obj = $object->db->fetch_object($resql_supplier_price); $line_cost = $obj->min_price/$obj->qty * $sub_bom_line->qty * $line->qty; - print ''.price($line_cost).''; + print ''.price($line_cost).''; $total_cost+= $line_cost; } } @@ -266,11 +267,12 @@ if ($resql) { } // Replace of the total_cost value by the sum of all sub-BOM lines total_cost +// TODO Remove this bad practice. We should not replace content of ouput using javascript but value should be good during generation of output. if ($total_cost > 0) { $line->total_cost = price($total_cost); ?> trans('Bookmarks').'" href="'.DOL_URL_ROOT.'/bookmarks/list.php" >'; + $listbtn = ''; $listbtn .= img_picto('', 'bookmark', 'class="paddingright"').$langs->trans('Bookmarks').''; // Url to go on create new bookmark page diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 8833978e054..bbc92a83ef1 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -160,7 +160,7 @@ if ($action == 'create') { print ''; - print ''; + print ''; dol_set_focus('#titlebookmark'); // Url @@ -230,9 +230,9 @@ if ($id > 0 && !preg_match('/^add/i', $action)) { print ''; diff --git a/htdocs/cache.manifest b/htdocs/cache.manifest deleted file mode 100644 index 5e514a32a47..00000000000 --- a/htdocs/cache.manifest +++ /dev/null @@ -1,36 +0,0 @@ -CACHE MANIFEST -# version 2013-05-21 13:30:21 -# Note: If this file is dynamic, it must return MIME text/cache-manifest -# Note: Order of CACHE, NETWORK and FALLBACK section does not change behaviour -" Note: - - -# Files listed under CACHE will be ALWAYS cached after they are loaded. -# And they will be always used from Cache after (even after refresh). -CACHE: -theme/dolibarr_logo.svg -support/ -support/index.php - -support/default.css -support/helpcenter.png -support/internet.png -support/mail.png -support/pagemaster.png -support/redstar.png -support/star.png -support/who.png - - -# The NETWORK section contains the path to a folder to ensure that requests -# to load resources will use internet. -# CACHE has priority on NETWORK, so usage is useless -NETWORK: -/ - -# The FALLBACK section contains entries that provide a backup strategy. -# If the browser is unable to retrieve the original content, the fallback resource will be used. -# In the example above, we display a static image in case the dynamic one is unavailable. -FALLBACK: -#/ public/notice.php -#theme/eldy/img/* theme/md/img/* diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index a3d2dc3e57f..434b994ccd2 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1141,10 +1141,10 @@ class Categorie extends CommonObject } // We add the fullpath property to each elements of first level (no parent exists) - dol_syslog(get_class($this)."::get_full_arbo call to build_path_from_id_categ", LOG_DEBUG); + dol_syslog(get_class($this)."::get_full_arbo call to buildPathFromId", LOG_DEBUG); foreach ($this->cats as $key => $val) { //print 'key='.$key.'
    '."\n"; - $this->build_path_from_id_categ($key, 0); // Process a branch from the root category key (this category has no parent) + $this->buildPathFromId($key, 0); // Process a branch from the root category key (this category has no parent) } // Include or exclude leaf including $markafterid from tree @@ -1174,7 +1174,6 @@ class Categorie extends CommonObject return $this->cats; } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * For category id_categ and its childs available in this->cats, define property fullpath and fulllabel. * It is called by get_full_arbo() @@ -1185,19 +1184,18 @@ class Categorie extends CommonObject * @return void * @see get_full_arbo() */ - public function build_path_from_id_categ($id_categ, $protection = 1000) + private function buildPathFromId($id_categ, $protection = 1000) { - // phpcs:enable - dol_syslog(get_class($this)."::build_path_from_id_categ id_categ=".$id_categ." protection=".$protection, LOG_DEBUG); + //dol_syslog(get_class($this)."::buildPathFromId id_categ=".$id_categ." protection=".$protection, LOG_DEBUG); if (!empty($this->cats[$id_categ]['fullpath'])) { // Already defined - dol_syslog(get_class($this)."::build_path_from_id_categ fullpath and fulllabel already defined", LOG_WARNING); + dol_syslog(get_class($this)."::buildPathFromId fullpath and fulllabel already defined", LOG_WARNING); return; } // First build full array $motherof - //$this->load_motherof(); // Disabled because already done by caller of build_path_from_id_categ + //$this->load_motherof(); // Disabled because already done by caller of buildPathFromId // $this->cats[$id_categ] is supposed to be already an array. We just want to complete it with property fullpath and fulllabel diff --git a/htdocs/categories/index.php b/htdocs/categories/index.php index 04f2288ae08..f4456ed79bf 100644 --- a/htdocs/categories/index.php +++ b/htdocs/categories/index.php @@ -133,7 +133,9 @@ if (empty($nosearch)) { print ''; print "\n"; print "\t\t\n"; print "\t\n"; } diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 4a00894d26b..aa513e07794 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -701,7 +701,7 @@ if (empty($reshook) && $action == 'update') { $categories = GETPOST('categories', 'array'); $object->setCategories($categories); - $object->loadReminders(); + $object->loadReminders($remindertype, 0, false); if (!empty($object->reminders) && $object->datep > dol_now()) { foreach ($object->reminders as $reminder) { $reminder->delete($user); @@ -1491,6 +1491,10 @@ if ($id > 0) { $("#fullday").change(function() { setdatefields(); }); + $("#actioncode").change(function() { + if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired"); + else $("#dateend").removeClass("fieldrequired"); + }); })'; print ''."\n"; } @@ -1535,22 +1539,26 @@ if ($id > 0) { print ''; // Date start - end - print ''; @@ -1988,11 +1996,15 @@ if ($id > 0) { // Date start print ''; } diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index eabcb1a55bf..4aca208681b 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -10,6 +10,7 @@ * Copyright (C) 2015-2021 Frédéric France * Copyright (C) 2015 Marcos García * Copyright (C) 2020 Open-Dsi + * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,6 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; if (!empty($conf->facture->enabled)) { require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; } @@ -112,6 +114,7 @@ $cancel = GETPOST('cancel', 'alpha'); $object = new Client($db); $extrafields = new ExtraFields($db); +$formfile = new FormFile($db); // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); @@ -159,7 +162,8 @@ if (empty($reshook)) { // set accountancy code if ($action == 'setcustomeraccountancycode') { $result = $object->fetch($id); - $object->code_compta = GETPOST("customeraccountancycode"); + $object->code_compta_client = GETPOST("customeraccountancycode"); + $object->code_compta = $object->code_compta_client; // For Backward compatibility $result = $object->update($object->id, $user, 1, 1, 0); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -357,9 +361,9 @@ if ($object->id > 0) { print ''; print ''; print ''; } @@ -683,7 +687,7 @@ if ($object->id > 0) { } print '
    '; - print '
    '; + print '
    '; $boxstat = ''; @@ -691,7 +695,7 @@ if ($object->id > 0) { $MAXLIST = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; // Lien recap - $boxstat .= '
    '; + $boxstat .= '
    '; $boxstat .= '
    '.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
    '.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
    '; if ($action == 'edit') { - print 'title).'">'; + print 'title).'">'; } else { - print $object->title; + print dol_escape_htmltag($object->title); } print '
    "; - print dolGetFirstLineOfText($cat->description); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($cat->description, 1)); + $trunclength = 48; + print $form->textwithtooltip(dol_trunc($text, $trunclength), $cat->description); print "
    '.$langs->trans("EventOnFullDay").'fulldayevent ? ' checked' : '').'>
    '.$langs->trans("DateActionStart").' - '.$langs->trans("DateActionEnd").''; + print '
    '; + print ''.$langs->trans("DateActionStart").''; + print ' - '; + print 'type_code == 'AC_RDV' ? ' class="fieldrequired"' : '').'>'.$langs->trans("DateActionEnd").''; + print ''; $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT'); if (GETPOST("afaire") == 1) { - print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuser') : 'tzuser'); + print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); } elseif (GETPOST("afaire") == 2) { - print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuser') : 'tzuser'); + print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); } else { - print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuser') : 'tzuser'); + print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); } print ' - '; if (GETPOST("afaire") == 1) { - print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuser') : 'tzuser'); + print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); } elseif (GETPOST("afaire") == 2) { - print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuser') : 'tzuser'); + print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); } else { - print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuser') : 'tzuser'); + print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); } print '
    '.$langs->trans("DateActionStart").''; + // Test a date before the 27 march and one after + //print dol_print_date($object->datep, 'dayhour', 'gmt'); + //print dol_print_date($object->datep, 'dayhour', 'tzuser'); + //print dol_print_date($object->datep, 'dayhour', 'tzuserrel'); if (empty($object->fulldayevent)) { - print dol_print_date($object->datep, 'dayhour', 'tzuser'); + print dol_print_date($object->datep, 'dayhour', 'tzuserrel'); } else { $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT'); - print dol_print_date($object->datep, 'day', ($tzforfullday ? $tzforfullday : 'tzuser')); + print dol_print_date($object->datep, 'day', ($tzforfullday ? $tzforfullday : 'tzuserrel')); } if ($object->percentage == 0 && $object->datep && $object->datep < ($now - $delay_warning)) { print img_warning($langs->trans("Late")); @@ -2003,10 +2015,10 @@ if ($id > 0) { // Date end print '
    '.$langs->trans("DateActionEnd").''; if (empty($object->fulldayevent)) { - print dol_print_date($object->datef, 'dayhour', 'tzuser'); + print dol_print_date($object->datef, 'dayhour', 'tzuserrel'); } else { $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT'); - print dol_print_date($object->datef, 'day', ($tzforfullday ? $tzforfullday : 'tzuser')); + print dol_print_date($object->datef, 'day', ($tzforfullday ? $tzforfullday : 'tzuserrel')); } if ($object->percentage > 0 && $object->percentage < 100 && $object->datef && $object->datef < ($now - $delay_warning)) { print img_warning($langs->trans("Late")); diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index a5b4f1d8ce9..9d122cfce7e 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -778,7 +778,7 @@ class ActionComm extends CommonObject $sql .= " a.fk_contact, a.percent as percentage,"; $sql .= " a.fk_element as elementid, a.elementtype,"; $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,"; - $sql .= " a.email_msgid, a.email_subject, a.email_from, a.email_to, a.email_tocc, a.email_tobcc, a.errors_to,"; + $sql .= " a.email_msgid, a.email_subject, a.email_from, a.email_sender, a.email_to, a.email_tocc, a.email_tobcc, a.errors_to,"; $sql .= " c.id as type_id, c.type as type_type, c.code as type_code, c.libelle as type_label, c.color as type_color, c.picto as type_picto,"; $sql .= " s.nom as socname,"; $sql .= " u.firstname, u.lastname as lastname,"; @@ -868,6 +868,16 @@ class ActionComm extends CommonObject $this->event_paid = $obj->event_paid; $this->status = $obj->status; + //email information + $this->email_msgid=$obj->email_msgid; + $this->email_from=$obj->email_from; + $this->email_sender=$obj->email_sender; + $this->email_to=$obj->email_to; + $this->email_tocc=$obj->email_tocc; + $this->email_tobcc=$obj->email_tobcc; + $this->email_subject=$obj->email_subject; + $this->errors_to=$obj->errors_to; + $this->fetch_optionals(); if ($loadresources) { @@ -1582,8 +1592,25 @@ class ActionComm extends CommonObject if (isset($this->transparency)) { $tooltip .= '
    '.$langs->trans('Busy').': '.yn($this->transparency); } + if (!empty($this->email_msgid)) { + $langs->load("mails"); + $tooltip .= '
    '; + //$tooltip .= '
    '.img_picto('', 'email').' '.$langs->trans("Email").''; + $tooltip .= '
    '.$langs->trans('MailTopic').': '.$this->email_subject; + $tooltip .= '
    '.$langs->trans('MailFrom').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_from); + $tooltip .= '
    '.$langs->trans('MailTo').':, '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_to); + if (!empty($this->email_tocc)) { + $tooltip .= '
    '.$langs->trans('MailCC').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_tocc); + } + /* Disabled because bcc must remain by defintion not visible + if (!empty($this->email_tobcc)) { + $tooltip .= '
    '.$langs->trans('MailCCC').': '.$this->email_tobcc; + } */ + } if (!empty($this->note_private)) { - $tooltip .= '
    '.$langs->trans('Note').': '.(dol_textishtml($this->note_private) ? str_replace(array("\r", "\n"), "", $this->note_private) : str_replace(array("\r", "\n"), '
    ', $this->note_private)); + $tooltip .= '

    '.$langs->trans('Description').':
    '; + $texttoshow = dolGetFirstLineOfText($this->note_private, 10); + $tooltip .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '
    ', $texttoshow)); } $linkclose = ''; //if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color) @@ -1594,9 +1621,8 @@ class ActionComm extends CommonObject $label = $langs->trans("ShowAction"); $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1).'"'; + $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1, 0, 0, '', 1).'"'; $linkclose .= ' class="'.$classname.' classfortooltip"'; - /* $hookmanager->initHooks(array('actiondao')); $parameters=array('id'=>$this->id); @@ -2210,6 +2236,26 @@ class ActionComm extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $dbs Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $dbs, $origin_id, $dest_id) + { + $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'actioncomm SET fk_element = ' . ((int) $dest_id) . ' WHERE elementtype="product" AND fk_element = '.((int) $origin_id); + // using $dbs, not $this->db because function is static + if (!$dbs->query($sql)) { + //$this->errors = $dbs->lasterror(); + return false; + } + + return true; + } + /** * Is the action delayed? * diff --git a/htdocs/comm/action/class/cactioncomm.class.php b/htdocs/comm/action/class/cactioncomm.class.php index 32c2345a657..8dd6b008045 100644 --- a/htdocs/comm/action/class/cactioncomm.class.php +++ b/htdocs/comm/action/class/cactioncomm.class.php @@ -186,35 +186,55 @@ class CActionComm $qualified = 1; - // $obj->type can be system, systemauto, module, moduleauto, xxx, xxxauto + // $obj->type can be 'system', 'systemauto', 'module', 'moduleauto', 'xxx', 'xxxauto' + // Note: type = system... than type of event is added among other standard events. + // type = module... then type of event is grouped into module defined into module = myobject@mymodule. Example: Event organization or external modules + // type = xxx... then type of event is added into list as a new flat value (not grouped). Example: Agefod external module if ($qualified && $onlyautoornot > 0 && preg_match('/^system/', $obj->type) && !preg_match('/^AC_OTH/', $obj->code)) { $qualified = 0; // We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO) } if ($qualified && !empty($obj->module)) { - if ($obj->module == 'invoice' && empty($conf->facture->enabled) && empty($user->facture->lire)) { - $qualified = 0; + //var_dump($obj->type.' '.$obj->module.' '); var_dump($user->rights->facture->lire); + $qualified = 0; + // Special cases + if ($obj->module == 'invoice' && !empty($conf->facture->enabled) && !empty($user->rights->facture->lire)) { + $qualified = 1; } - if ($obj->module == 'order' && empty($conf->commande->enabled) && empty($user->commande->lire)) { - $qualified = 0; + if ($obj->module == 'order' && !empty($conf->commande->enabled) && empty($user->rights->commande->lire)) { + $qualified = 1; } - if ($obj->module == 'propal' && empty($conf->propal->enabled) && empty($user->propale->lire)) { - $qualified = 0; + if ($obj->module == 'propal' && !empty($conf->propal->enabled) && !empty($user->rights->propale->lire)) { + $qualified = 1; } - if ($obj->module == 'invoice_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && empty($user->fournisseur->facture->lire)) || (!empty($conf->supplier_invoice->enabled) && empty($user->supplier_invoice->lire)))) { - $qualified = 0; + if ($obj->module == 'invoice_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && !empty($user->rights->fournisseur->facture->lire)) || (!empty($conf->rights->supplier_invoice->enabled) && !empty($user->rights->supplier_invoice->lire)))) { + $qualified = 1; } - if ($obj->module == 'order_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && empty($user->fournisseur->commande->lire)) || (empty($conf->supplier_order->enabled) && empty($user->supplier_order->lire)))) { - $qualified = 0; + if ($obj->module == 'order_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && !empty($user->rights->fournisseur->commande->lire)) || (empty($conf->rights->supplier_order->enabled) && !empty($user->rights->supplier_order->lire)))) { + $qualified = 1; } - if ($obj->module == 'shipping' && empty($conf->expedition->enabled) && empty($user->expedition->lire)) { - $qualified = 0; + if ($obj->module == 'shipping' && !empty($conf->expedition->enabled) && !empty($user->rights->expedition->lire)) { + $qualified = 1; } - if (preg_match('/@eventorganization/', $obj->module) && empty($conf->eventorganization->enabled) && empty($user->eventorganization->read)) { - $qualified = 0; + // For the generic case with type = 'module...' and module = 'myobject@mymodule' + $regs = array(); + if (preg_match('/^module/', $obj->type)) { + if (preg_match('/^(.+)@(.+)$/', $obj->module, $regs)) { + $tmpobject = $regs[1]; + $tmpmodule = $regs[2]; + //var_dump($user->$tmpmodule); + if ($tmpmodule && isset($conf->$tmpmodule) && !empty($conf->$tmpmodule->enabled) && (!empty($user->rights->$tmpmodule->read) || !empty($user->rights->$tmpmodule->lire) || !empty($user->rights->$tmpmodule->$tmpobject->read) || !empty($user->rights->$tmpmodule->$tmpobject->lire))) { + $qualified = 1; + } + } } - if (!preg_match('/^system/', $obj->type) && isset($conf->{$obj->module}) && empty($conf->{$obj->module}->enabled)) { - $qualified = 0; + // For the case type is not 'system...' neither 'module', we just check module is on + if (! in_array($obj->type, array('system', 'systemauto', 'module', 'moduleauto'))) { + $tmpmodule = $obj->module; + //var_dump($tmpmodule); + if ($tmpmodule && isset($conf->$tmpmodule) && !empty($conf->$tmpmodule->enabled)) { + $qualified = 1; + } } } diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index e8060bc314d..1b4340276f8 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -49,10 +49,11 @@ if (empty($conf->global->AGENDA_EXT_NB)) { } $MAXAGENDA = $conf->global->AGENDA_EXT_NB; -$filter = GETPOST("search_filter", 'alpha', 3) ?GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); -$filtert = GETPOST("search_filtert", "int", 3) ?GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); -$usergroup = GETPOST("search_usergroup", "int", 3) ?GETPOST("search_usergroup", "int", 3) : GETPOST("usergroup", "int", 3); -$showbirthday = empty($conf->use_javascript_ajax) ?GETPOST("showbirthday", "int") : 1; +$check_holiday = GETPOST('check_holiday', 'int'); +$filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); +$filtert = GETPOST("search_filtert", "int", 3) ? GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); +$usergroup = GETPOST("search_usergroup", "int", 3) ? GETPOST("search_usergroup", "int", 3) : GETPOST("usergroup", "int", 3); +$showbirthday = empty($conf->use_javascript_ajax) ? GETPOST("showbirthday", "int") : 1; // If not choice done on calendar owner (like on left menu link "Agenda"), we filter on user. if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) { @@ -207,16 +208,16 @@ if (GETPOST("viewperuser", 'alpha') || $mode == 'show_peruser') { } /* -if ($action == 'delete_action' && $user->rights->agenda->delete) { - $event = new ActionComm($db); - $event->fetch($actionid); - $event->fetch_optionals(); - $event->fetch_userassigned(); - $event->oldcopy = clone $event; + if ($action == 'delete_action' && $user->rights->agenda->delete) { + $event = new ActionComm($db); + $event->fetch($actionid); + $event->fetch_optionals(); + $event->fetch_userassigned(); + $event->oldcopy = clone $event; - $result = $event->delete(); -} -*/ + $result = $event->delete(); + } + */ /* @@ -579,10 +580,10 @@ if (!empty($conf->use_javascript_ajax)) { // If javascript on $s .= ''."\n"; // Local calendar - $s .= '
    '.$langs->trans("LocalAgenda").'  
    '; + $s .= '
    '.$langs->trans("LocalAgenda").'  
    '; // Holiday calendar - $s .= '
     
    '; + $s .= '
     
    '; // External calendars if (is_array($showextcals) && count($showextcals) > 0) { @@ -607,13 +608,13 @@ if (!empty($conf->use_javascript_ajax)) { // If javascript on foreach ($showextcals as $val) { $htmlname = md5($val['name']); - if (!empty($val['default'])) { + if (!empty($val['default']) || GETPOST('check_ext'.$htmlname, 'int')) { $default = "checked"; } else { $default = ''; } - $s .= '
     
    '; + $s .= '
     
    '; } } @@ -848,6 +849,7 @@ if ($resql) { $event->fk_project = $obj->fk_project; $event->socid = $obj->fk_soc; + $event->thirdparty_id = $obj->fk_soc; $event->contact_id = $obj->fk_contact; // Defined date_start_in_calendar and date_end_in_calendar property @@ -890,13 +892,13 @@ if ($resql) { $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); // $mois, $jour, $annee has been set for user tz $daykeyend = dol_mktime(0, 0, 0, $moisend, $jourend, $anneeend, 'gmt'); // $moisend, $jourend, $anneeend has been set for user tz /* - print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'
    '; - print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'
    '; - print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'
    '; - print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'
    '; - print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'
    '; - print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'
    '; - */ + print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'
    '; + print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'
    '; + print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'
    '; + print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'
    '; + print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'
    '; + print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'
    '; + */ do { //if ($event->id==408) //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'gmt').' - '.dol_print_date($event->datep, 'dayhour', 'gmt').' '.dol_print_date($event->datef, 'dayhour', 'gmt').'
    '; @@ -929,7 +931,7 @@ if ($showbirthday) { $sql = 'SELECT sp.rowid, sp.lastname, sp.firstname, sp.birthday'; $sql .= ' FROM '.MAIN_DB_PREFIX.'socpeople as sp'; $sql .= ' WHERE (priv=0 OR (priv=1 AND fk_user_creat='.((int) $user->id).'))'; - $sql .= " AND sp.entity IN (".getEntity('socpeople').")"; + $sql .= " AND sp.entity IN (".getEntity('contact').")"; if ($mode == 'show_day') { $sql .= ' AND MONTH(birthday) = '.((int) $month); $sql .= ' AND DAY(birthday) = '.((int) $day); diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index e2b412e15db..f6932cc4bef 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -943,8 +943,8 @@ while ($i < min($num, $limit)) { // Description if (!empty($arrayfields['a.note']['checked'])) { print '
    '; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($actionstatic->note_private, 0)); - print $form->textwithtooltip(dol_trunc($text, 40), $actionstatic->note_private); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($actionstatic->note_private, 1)); + print $form->textwithtooltip(dol_trunc($text, 48), $actionstatic->note_private); print '
    '; - print $form->editfieldkey("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta, $object, $user->rights->societe->creer); + print $form->editfieldkey("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta_client, $object, $user->rights->societe->creer); print ''; - print $form->editfieldval("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta, $object, $user->rights->societe->creer); + print $form->editfieldval("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta_client, $object, $user->rights->societe->creer); print '
    '; $boxstat .= ''; print '\n"; + // Preview + $filedir = $conf->commande->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $commande_static->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->order->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/commande/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($commande_static->element, $filename, $filedir); + print ''; + + print '\n"; print ''; print ''; $i++; @@ -1003,6 +1068,35 @@ if ($object->id > 0) { print ''; print ''; if ($objp->date_creation > 0) { print ''; @@ -1076,6 +1170,35 @@ if ($object->id > 0) { print ''; print '\n"; print '\n"; @@ -1137,6 +1260,35 @@ if ($object->id > 0) { print ''; print ''."\n"; //print ''."\n"; print ''."\n"; @@ -1213,6 +1365,7 @@ if ($object->id > 0) { print ''; + if ($objp->frequency && $objp->date_last_gen > 0) { print ''; } else { @@ -1301,6 +1454,35 @@ if ($object->id > 0) { print ''; print ''; if ($objp->df > 0) { print ''; diff --git a/htdocs/comm/contact.php b/htdocs/comm/contact.php index 62f57c008ba..d83fdbcb78c 100644 --- a/htdocs/comm/contact.php +++ b/htdocs/comm/contact.php @@ -88,7 +88,7 @@ if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " ".MAIN_DB_PREFIX."socpeople as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc"; $sql .= " WHERE s.fk_stcomm = st.id"; -$sql .= " AND p.entity IN (".getEntity('socpeople').")"; +$sql .= " AND p.entity IN (".getEntity('contact').")"; if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index aad02f2bd07..dafc1e7ee16 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -568,9 +568,15 @@ if (!empty($conf->societe->enabled) && $user->rights->societe->lire) { if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($socid) { - $sql .= " AND s.rowid = $socid"; + // Add where from hooks + $parameters = array('socid' => $socid); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $companystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($socid > 0) { + $sql .= " AND s.rowid = ".((int) $socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.tms DESC"; $sql .= $db->plimit($max, 0); @@ -664,9 +670,15 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($socid) { - $sql .= " AND s.rowid = ".((int) $socid); + // Add where from hooks + $parameters = array('socid' => $socid); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $companystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($socid > 0) { + $sql .= " AND s.rowid = ".((int) $socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.datec DESC"; $sql .= $db->plimit($max, 0); diff --git a/htdocs/comm/mailing/class/advtargetemailing.class.php b/htdocs/comm/mailing/class/advtargetemailing.class.php index 79e25c83385..62dd24aaaf7 100644 --- a/htdocs/comm/mailing/class/advtargetemailing.class.php +++ b/htdocs/comm/mailing/class/advtargetemailing.class.php @@ -686,7 +686,7 @@ class AdvanceTargetingMailing extends CommonObject $sqlwhere = array(); - $sqlwhere[] = 't.entity IN ('.getEntity('socpeople').')'; + $sqlwhere[] = 't.entity IN ('.getEntity('contact').')'; if (count($arrayquery) > 0) { if (array_key_exists('contact_categ', $arrayquery)) { diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 61a406a2378..0153f554169 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -14,6 +14,7 @@ * Copyright (C) 2016 Marcos García * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2020 Nicolas ZABOURI + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -80,6 +81,7 @@ $confirm = GETPOST('confirm', 'alpha'); $lineid = GETPOST('lineid', 'int'); $contactid = GETPOST('contactid', 'int'); $projectid = GETPOST('projectid', 'int'); +$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1; // PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -116,7 +118,7 @@ $usercandelete = $user->rights->propal->supprimer; $usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->close))); $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->validate))); -$usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->propal->propal_advance->send); +$usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->send))); $usercancreateorder = $user->rights->commande->creer; $usercancreateinvoice = $user->rights->facture->creer; @@ -220,7 +222,7 @@ if (empty($reshook)) { } } - $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null)); + $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null), (GETPOST('update_prices', 'aZ') ? true : false)); if ($result > 0) { header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); exit(); @@ -246,8 +248,11 @@ if (empty($reshook)) { // Remove line $result = $object->deleteline($lineid); // reorder lines - if ($result) { + if ($result > 0) { $object->line_order(true); + } else { + $langs->load("errors"); + setEventMessages($object->error, $object->errors, 'errors'); } if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { @@ -1143,7 +1148,7 @@ if (empty($reshook)) { setEventMessages($mesg, null, 'errors'); } else { // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, min($rank, count($object->lines) + 1), 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise); if ($result > 0) { $db->commit(); @@ -1889,11 +1894,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
    '; print '
    '; @@ -859,6 +863,36 @@ if ($object->id > 0) { $propal_static->total_tva = $objp->total_tva; $propal_static->total_ttc = $objp->total_ttc; print $propal_static->getNomUrl(1); + + // Preview + $filedir = $conf->propal->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $propal_static->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->propal->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/comm/propal/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($propal_static->element, $filename, $filedir); if (($db->jdate($objp->date_limit) < ($now - $conf->propal->cloture->warning_delay)) && $objp->fk_statut == $propal_static::STATUS_VALIDATED) { print " ".img_warning(); } @@ -940,7 +974,38 @@ if ($object->id > 0) { print '
    '; print $commande_static->getNomUrl(1); - print ''.dol_print_date($db->jdate($objp->dc), 'day')."'.dol_print_date($db->jdate($objp->dc), 'day')."'.price($objp->total_ht).''.$commande_static->LibStatut($objp->fk_statut, $objp->facture, 5).'
    '; print $sendingstatic->getNomUrl(1); + // Preview + $filedir = $conf->expedition->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $sendingstatic->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->expedition->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/expedition/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($sendingstatic->element, $filename, $filedir); print ''.dol_print_date($db->jdate($objp->date_creation), 'day').'
    '; print $contrat->getNomUrl(1, 12); + // Preview + $filedir = $conf->contrat->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $contrat->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->contrat->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/contrat/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($contrat->element, $filename, $filedir); print $late; print "'.dol_trunc($objp->refsup, 12)."
    '; print $fichinter_static->getNomUrl(1); + // Preview + $filedir = $conf->fichinter->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $fichinter_static->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->fichinter->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/fichinter/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($fichinter_static->element, $filename, $filedir); print ''.dol_print_date($db->jdate($objp->startdate)).''.convertSecondToTime($objp->duration).''; print $invoicetemplate->getNomUrl(1); print ''.dol_print_date($db->jdate($objp->date_last_gen), 'day').'
    '; print $facturestatic->getNomUrl(1); + // Preview + $filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $facturestatic->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/compta/facture/card.php?id='.$objp->cid; + //print $formfile->getDocumentsLink($facturestatic->element, $filename, $filedir); print ''.dol_print_date($db->jdate($objp->df), 'day').'
    '; $objectsrc->printOriginLinesList(); print '
    '; + print ''; } } elseif ($object->id > 0) { /* @@ -1914,8 +1921,8 @@ if ($action == 'create') { $formquestion = array( // 'text' => $langs->trans("ConfirmClone"), // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')) + array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')), + array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans('PuttingPricesUpToDate'), 'value' => (!empty($conf->global->PROPOSAL_CLONE_UPDATE_PRICES) ? 1 : 0)), ); if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->delivery_date)) { $formquestion[] = array('type' => 'date', 'name' => 'date_delivery', 'label' => $langs->trans("DeliveryDate"), 'value' => $object->delivery_date); @@ -1955,7 +1962,7 @@ if ($action == 'create') { // We verify whether the object is provisionally numbering $ref = substr($object->ref, 1, 4); - if ($ref == 'PROV') { + if ($ref == 'PROV' || $ref == '') { $numref = $object->getNextNumRef($soc); if (empty($numref)) { $error++; diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index f03d66bae54..59a03f78bb2 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -625,7 +625,7 @@ class Proposals extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function deleteContact($id, $contactid, $type) { @@ -799,7 +799,7 @@ class Proposals extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @return array */ diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 029706dfb5d..cfe2a15f2db 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -17,6 +17,7 @@ * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2022 ATM Consulting * Copyright (C) 2022 OpenDSI + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -554,10 +555,11 @@ class Propal extends CommonObject * @param int $origin_id Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be Id of origin object (aka line id), else object id * @param double $pu_ht_devise Unit price in currency * @param int $fk_remise_except Id discount if line is from a discount + * @param int $noupdateafterinsertline No update after insert of line * @return int >0 if OK, <0 if KO * @see add_product() */ - public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $info_bits = 0, $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $fk_remise_except = 0) + public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $info_bits = 0, $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $fk_remise_except = 0, $noupdateafterinsertline = 0) { global $mysoc, $conf, $langs; @@ -743,10 +745,17 @@ class Propal extends CommonObject // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); + } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) { // Update all rank of all other lines + $linecount = count($this->lines); + for ($ii = $ranktouse; $ii <= $linecount; $ii++) { + $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii + 1); + } } // Mise a jour informations denormalisees au niveau de la propale meme - $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + if (empty($noupdateafterinsertline)) { + $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + } if ($result > 0) { $this->db->commit(); @@ -989,6 +998,8 @@ class Propal extends CommonObject $this->db->commit(); return 1; } else { + $this->error = $line->error; + $this->errors = $line->errors; $this->db->rollback(); return -1; } @@ -1009,7 +1020,7 @@ class Propal extends CommonObject */ public function create($user, $notrigger = 0) { - global $conf, $hookmanager; + global $conf, $hookmanager, $mysoc; $error = 0; $now = dol_now(); @@ -1238,7 +1249,10 @@ class Propal extends CommonObject $line->array_options, $line->fk_unit, $origintype, - $originid + $originid, + 0, + 0, + 1 ); if ($result < 0) { @@ -1267,7 +1281,7 @@ class Propal extends CommonObject if (!$error) { // Mise a jour infos denormalisees - $resql = $this->update_price(1); + $resql = $this->update_price(1, 'auto', 0, $mysoc); if ($resql) { $action = 'update'; @@ -1318,11 +1332,12 @@ class Propal extends CommonObject * @param User $user User making the clone * @param int $socid Id of thirdparty * @param int $forceentity Entity id to force + * @param bool $update_prices [=false] Update prices if true * @return int New id of clone */ - public function createFromClone(User $user, $socid = 0, $forceentity = null) + public function createFromClone(User $user, $socid = 0, $forceentity = null, $update_prices = false) { - global $conf, $hookmanager; + global $conf, $hookmanager, $mysoc; dol_include_once('/projet/class/project.class.php'); @@ -1369,6 +1384,55 @@ class Propal extends CommonObject $objsoc->fetch($object->socid); } + // update prices + if ($update_prices === true) { + if ($objsoc->id > 0 && !empty($object->lines)) { + if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + // If price per customer + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + } + + foreach ($object->lines as $line) { + if ($line->fk_product > 0) { + $prod = new Product($this->db); + $res = $prod->fetch($line->fk_product); + if ($res > 0) { + $pu_ht = $prod->price; + $tva_tx = get_default_tva($mysoc, $objsoc, $prod->id); + $remise_percent = $objsoc->remise_percent; + + if (!empty($conf->global->PRODUIT_MULTIPRICES) && $objsoc->price_level > 0) { + $pu_ht = $prod->multiprices[$objsoc->price_level]; + if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) { // using this option is a bug. kept for backward compatibility + if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) { + $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level]; + } + } + } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + $prodcustprice = new Productcustomerprice($this->db); + $filter = array('t.fk_product' => $prod->id, 't.fk_soc' => $objsoc->id); + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result) { + // If there is some prices specific to the customer + if (count($prodcustprice->lines) > 0) { + $pu_ht = price($prodcustprice->lines[0]->price); + $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.' ('.$prodcustprice->lines[0]->default_vat_code.' )' : $prodcustprice->lines[0]->tva_tx); + if ($prodcustprice->lines[0]->default_vat_code && !preg_match('/\(.*\)/', $tva_tx)) { + $tva_tx .= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + } + } + } + } + + $line->subprice = $pu_ht; + $line->tva_tx = $tva_tx; + $line->remise_percent = $remise_percent; + } + } + } + } + } + $object->id = 0; $object->ref = ''; $object->entity = (!empty($forceentity) ? $forceentity : $object->entity); @@ -1724,8 +1788,9 @@ class Propal extends CommonObject */ public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $filters = '') { - global $langs, $conf; // phpcs:enable + global $langs, $conf; + $this->lines = array(); $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; @@ -3762,8 +3827,24 @@ class Propal extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } -} + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'propaldet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } +} /** * Class to manage commercial proposal lines @@ -4188,36 +4269,40 @@ class PropaleLigne extends CommonObjectLine $error = 0; $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE rowid = ".((int) $this->rowid); - dol_syslog("PropaleLigne::delete", LOG_DEBUG); - if ($this->db->query($sql)) { - // Remove extrafields - if (!$error) { - $this->id = $this->rowid; - $result = $this->deleteExtraFields(); - if ($result < 0) { - $error++; - dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); - } + if (!$notrigger) { + // Call trigger + $result = $this->call_trigger('LINEPROPAL_DELETE', $user); + if ($result < 0) { + $error++; } + } + // End call triggers - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('LINEPROPAL_DELETE', $user); - if ($result < 0) { - $this->db->rollback(); - return -1; + if (!$error) { + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "propaldet WHERE rowid = " . ((int) $this->rowid); + dol_syslog("PropaleLigne::delete", LOG_DEBUG); + if ($this->db->query($sql)) { + // Remove extrafields + if (!$error) { + $this->id = $this->rowid; + $result = $this->deleteExtraFields(); + if ($result < 0) { + $error++; + dol_syslog(get_class($this) . "::delete error -4 " . $this->error, LOG_ERR); + } } + } else { + $this->error = $this->db->error() . " sql=" . $sql; + $error++; } - // End call triggers + } - $this->db->commit(); - - return 1; - } else { - $this->error = $this->db->error()." sql=".$sql; + if ($error) { $this->db->rollback(); return -1; + } else { + $this->db->commit(); + return 1; } } @@ -4363,7 +4448,7 @@ class PropaleLigne extends CommonObjectLine if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('LINEPROPAL_UPDATE', $user); + $result = $this->call_trigger('LINEPROPAL_MODIFY', $user); if ($result < 0) { $this->db->rollback(); return -1; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 3e790bf6448..73b4c479b2e 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -356,12 +356,12 @@ if ($action == 'validate' && $permissiontovalidate) { $db->begin(); $error = 0; foreach ($toselect as $checked) { - if ($tmpproposal->fetch($checked)) { - if ($tmpproposal->statut == 0) { - if ($tmpproposal->valid($user)) { + if ($tmpproposal->fetch($checked) > 0) { + if ($tmpproposal->statut == $tmpproposal::STATUS_DRAFT) { + if ($tmpproposal->valid($user) > 0) { setEventMessage($langs->trans('hasBeenValidated', $tmpproposal->ref), 'mesgs'); } else { - setEventMessage($langs->trans('CantBeValidated'), 'errors'); + setEventMessage($tmpproposal->error, $tmpproposal->errors, 'errors'); $error++; } } else { @@ -370,7 +370,7 @@ if ($action == 'validate' && $permissiontovalidate) { $error++; } } else { - dol_print_error($db); + setEventMessages($tmpproposal->error, $tmpproposal->errors, 'errors'); $error++; } } @@ -388,21 +388,21 @@ if ($action == "sign" && $permissiontoclose) { $db->begin(); $error = 0; foreach ($toselect as $checked) { - if ($tmpproposal->fetch($checked)) { + if ($tmpproposal->fetch($checked) > 0) { if ($tmpproposal->statut == $tmpproposal::STATUS_VALIDATED) { $tmpproposal->statut = $tmpproposal::STATUS_SIGNED; - if ($tmpproposal->closeProposal($user, $tmpproposal::STATUS_SIGNED)) { + if ($tmpproposal->closeProposal($user, $tmpproposal::STATUS_SIGNED) >= 0) { setEventMessage($tmpproposal->ref." ".$langs->trans('Signed'), 'mesgs'); } else { - dol_print_error($db); + setEventMessages($tmpproposal->error, $tmpproposal->errors, 'errors'); $error++; } } else { - setEventMessage($tmpproposal->ref." ".$langs->trans('CantBeSign'), 'errors'); + setEventMessage($langs->trans('MustBeValidatedToBeSigned', $tmpproposal->ref), 'errors'); $error++; } } else { - dol_print_error($db); + setEventMessages($tmpproposal->error, $tmpproposal->errors, 'errors'); $error++; } } @@ -413,27 +413,28 @@ if ($action == "sign" && $permissiontoclose) { } } } + if ($action == "nosign" && $permissiontoclose) { if (GETPOST('confirm') == 'yes') { $tmpproposal = new Propal($db); $db->begin(); $error = 0; foreach ($toselect as $checked) { - if ($tmpproposal->fetch($checked)) { + if ($tmpproposal->fetch($checked) > 0) { if ($tmpproposal->statut == $tmpproposal::STATUS_VALIDATED) { $tmpproposal->statut = $tmpproposal::STATUS_NOTSIGNED; - if ($tmpproposal->closeProposal($user, $tmpproposal::STATUS_NOTSIGNED)) { + if ($tmpproposal->closeProposal($user, $tmpproposal::STATUS_NOTSIGNED) > 0) { setEventMessage($tmpproposal->ref." ".$langs->trans('NoSigned'), 'mesgs'); } else { - dol_print_error($db); + setEventMessages($tmpproposal->error, $tmpproposal->errors, 'errors'); $error++; } } else { - setEventMessage($tmpproposal->ref." ".$langs->trans('CantBeClosed'), 'errors'); + setEventMessage($tmpproposal->ref." ".$langs->trans('CantBeNoSign'), 'errors'); $error++; } } else { - dol_print_error($db); + setEventMessages($tmpproposal->error, $tmpproposal->errors, 'errors'); $error++; } } diff --git a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php index adc9de9339e..613f06a6feb 100644 --- a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php +++ b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php @@ -30,7 +30,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index d44093dbab5..c0e96aa4b15 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -62,7 +62,7 @@ if (GETPOST('cancel', 'alpha') && !empty($backtopage)) { exit; } -if ($action == 'confirm_split' && GETPOST("confirm", "alpha") == 'yes' && $user->rights->societe->creer) { +if ($action == 'confirm_split' && GETPOST("confirm", "alpha") == 'yes' && ($user->rights->societe->creer || $user->rights->facture->creer)) { //if ($user->rights->societe->creer) //if ($user->rights->facture->creer) @@ -153,7 +153,7 @@ if ($action == 'confirm_split' && GETPOST("confirm", "alpha") == 'yes' && $user- } } -if ($action == 'setremise' && $user->rights->societe->creer) { +if ($action == 'setremise' && ($user->rights->societe->creer || $user->rights->facture->creer)) { //if ($user->rights->societe->creer) //if ($user->rights->facture->creer) @@ -192,7 +192,7 @@ if ($action == 'setremise' && $user->rights->societe->creer) { } } -if (GETPOST('action', 'aZ09') == 'confirm_remove' && GETPOST("confirm") == 'yes' && $user->rights->societe->creer) { +if (GETPOST('action', 'aZ09') == 'confirm_remove' && GETPOST("confirm") == 'yes' && ($user->rights->societe->creer || $user->rights->facture->creer)) { //if ($user->rights->societe->creer) //if ($user->rights->facture->creer) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 9b11a477d52..3a903e233de 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -13,6 +13,7 @@ * Copyright (C) 2014 Ferran Marcet * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -81,6 +82,7 @@ $contactid = GETPOST('contactid', 'int'); $projectid = GETPOST('projectid', 'int'); $origin = GETPOST('origin', 'alpha'); $originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility +$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1; // PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -939,7 +941,7 @@ if (empty($reshook)) { setEventMessages($mesg, null, 'errors'); } else { // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, $pu_ht_devise); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, min($rank, count($object->lines) + 1), 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, $pu_ht_devise); if ($result > 0) { $ret = $object->fetch($object->id); // Reload to get new records @@ -1369,7 +1371,7 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to build doc - $upload_dir = !empty($conf->propal->multidir_output[$object->entity])?$conf->propal->multidir_output[$object->entity]:$conf->propal->dir_output; + $upload_dir = !empty($conf->commande->multidir_output[$object->entity])?$conf->commande->multidir_output[$object->entity]:$conf->commande->dir_output; $permissiontoadd = $usercancreate; include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; @@ -1862,11 +1864,13 @@ if ($action == 'create' && $usercancreate) { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
    '; print ''; $objectsrc->printOriginLinesList('', $selectedLines); print '
    '; + print '
    '; } print ''; @@ -1900,8 +1904,12 @@ if ($action == 'create' && $usercancreate) { if ($action == 'validate') { // We check that object has a temporary ref $ref = substr($object->ref, 1, 4); - if ($ref == 'PROV') { + if ($ref == 'PROV' || $ref == '') { $numref = $object->getNextNumRef($soc); + if (empty($numref)) { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } } else { $numref = $object->ref; } @@ -1952,8 +1960,9 @@ if ($action == 'create' && $usercancreate) { if ($nbMandated > 0 ) $text .= '
    '.$langs->trans("mandatoryPeriodNeedTobeSetMsgValidate").'
    '; - - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_validate', $formquestion, 0, 1, 220); + if (!$error) { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_validate', $formquestion, 0, 1, 220); + } } // Confirm back to draft status @@ -2515,27 +2524,27 @@ if ($action == 'create' && $usercancreate) { if (empty($reshook)) { // Reopen a closed order if (($object->statut == Commande::STATUS_CLOSED || $object->statut == Commande::STATUS_CANCELED) && $usercancreate) { - print ''.$langs->trans('ReOpen').''; + print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&id='.$object->id, ''); } // Send if (empty($user->socid)) { if ($object->statut > Commande::STATUS_DRAFT || !empty($conf->global->COMMANDE_SENDBYEMAIL_FOR_ALL_STATUS)) { if ($usercansend) { - print ''.$langs->trans('SendMail').''; + print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', ''); } else { - print ''.$langs->trans('SendMail').''; + print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } // Valid if ($object->statut == Commande::STATUS_DRAFT && ($object->total_ttc >= 0 || !empty($conf->global->ORDER_ENABLE_NEGATIVE)) && $numlines > 0 && $usercanvalidate) { - print ''.$langs->trans('Validate').''; + print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&token='.newToken().'&id='.$object->id, ''); } // Edit if ($object->statut == Commande::STATUS_VALIDATED && $usercancreate) { - print ''.$langs->trans('Modify').''; + print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=modif&token='.newToken().'&id='.$object->id, ''); } // Create event /*if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) @@ -2550,7 +2559,7 @@ if ($action == 'create' && $usercancreate) { if (!empty($conf->global->WORKFLOW_CAN_CREATE_PURCHASE_ORDER_FROM_SALE_ORDER)) { if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled)) && $object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfServicesLines() > 0) { if ($usercancreatepurchaseorder) { - print ''.$langs->trans("AddPurchaseOrder").''; + print dolGetButtonAction('', $langs->trans('AddPurchaseOrder'), 'default', DOL_URL_ROOT.'/fourn/commande/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } } } @@ -2561,9 +2570,9 @@ if ($action == 'create' && $usercancreate) { if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfServicesLines() > 0) { if ($user->rights->ficheinter->creer) { - print ''.$langs->trans('AddIntervention').''; + print dolGetButtonAction('', $langs->trans('AddInterventionGR'), 'default', DOL_URL_ROOT.'/fichinter/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } else { - print ''.$langs->trans('AddIntervention').''; + print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('AddIntervention'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } @@ -2573,7 +2582,7 @@ if ($action == 'create' && $usercancreate) { $langs->load("contracts"); if ($user->rights->contrat->creer) { - print ''.$langs->trans('AddContract').''; + print dolGetButtonAction('', $langs->trans('AddContract'), 'default', DOL_URL_ROOT.'/contrat/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } } @@ -2585,52 +2594,52 @@ if ($action == 'create' && $usercancreate) { if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES))) { if (($conf->expedition_bon->enabled && $user->rights->expedition->creer) || ($conf->delivery_note->enabled && $user->rights->expedition->delivery->creer)) { if ($user->rights->expedition->creer) { - print ''.$langs->trans('CreateShipment').''; + print dolGetButtonAction('', $langs->trans('CreateShipment'), 'default', DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id, ''); } else { - print ''.$langs->trans('CreateShipment').''; + print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } else { $langs->load("errors"); - print 'transnoentitiesnoconv("Shipment"))).'">'.$langs->trans('CreateShipment').''; + print dolGetButtonAction($langs->trans('ErrorModuleSetupNotComplete'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } // Set to shipped if (($object->statut == Commande::STATUS_VALIDATED || $object->statut == Commande::STATUS_SHIPMENTONPROCESS) && $usercanclose) { - print ''.$langs->trans('ClassifyShipped').''; + print dolGetButtonAction('', $langs->trans('ClassifyShipped'), 'default', $_SERVER["PHP_SELF"].'?action=shipped&token='.newToken().'&id='.$object->id, ''); } // Create bill and Classify billed // Note: Even if module invoice is not enabled, we should be able to use button "Classified billed" if ($object->statut > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) { if (!empty($conf->facture->enabled) && $user->rights->facture->creer && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { - print ''.$langs->trans("CreateBill").''; + print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { - print ''.$langs->trans("ClassifyBilled").''; + print dolGetButtonAction('', $langs->trans('ClassifyBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifybilled&token='.newToken().'&id='.$object->id, ''); } } if ($object->statut > Commande::STATUS_DRAFT && $object->billed) { if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { - print ''.$langs->trans("ClassifyUnBilled").''; + print dolGetButtonAction('', $langs->trans('ClassifyUnBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifyunbilled&token='.newToken().'&id='.$object->id, ''); } } // Clone if ($usercancreate) { - print ''.$langs->trans("ToClone").''; + print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"].'?action=clone&token='.newToken().'&id='.$object->id.'&socid='.$object->socid, ''); } // Cancel order if ($object->statut == Commande::STATUS_VALIDATED && (!empty($usercanclose) || !empty($usercancancel))) { - print ''.$langs->trans("Cancel").''; + print dolGetButtonAction('', $langs->trans('Cancel'), 'danger', $_SERVER["PHP_SELF"].'?action=cancel&token='.newToken().'&id='.$object->id, ''); } // Delete order if ($usercandelete) { if ($numshipping == 0) { - print ''.$langs->trans('Delete').''; + print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, ''); } else { - print ''.$langs->trans("Delete").''; + print dolGetButtonAction($langs->trans('ShippingExist'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 48865f958a2..17528001d1b 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -135,6 +135,11 @@ class Orders extends DolibarrApi // Add external contacts ids $this->commande->contacts_ids = $this->commande->liste_contact(-1, 'external', $contact_list); $this->commande->fetchObjectLinked(); + + // Add online_payment_url, cf #20477 + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + $this->commande->online_payment_url = getOnlinePaymentUrl(0, 'order', $this->commande->ref); + return $this->_cleanObjectDatas($this->commande); } @@ -230,6 +235,10 @@ class Orders extends DolibarrApi if ($commande_static->fetch($obj->rowid)) { // Add external contacts ids $commande_static->contacts_ids = $commande_static->liste_contact(-1, 'external', 1); + // Add online_payment_url, cf #20477 + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + $commande_static->online_payment_url = getOnlinePaymentUrl(0, 'order', $commande_static->ref); + $obj_ret[] = $this->_cleanObjectDatas($commande_static); } $i++; @@ -574,7 +583,7 @@ class Orders extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function deleteContact($id, $contactid, $type) { @@ -704,7 +713,7 @@ class Orders extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @return array */ @@ -735,6 +744,10 @@ class Orders extends DolibarrApi $this->commande->fetchObjectLinked(); + //fix #20477 : add online_payment_url + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + $this->commande->online_payment_url = getOnlinePaymentUrl(0, 'order', $this->commande->ref); + return $this->_cleanObjectDatas($this->commande); } @@ -974,7 +987,7 @@ class Orders extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function getOrderShipments($id) { @@ -1030,7 +1043,7 @@ class Orders extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function createOrderShipment($id, $warehouse_id) { diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index a9ff2e09cf3..58395162f87 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -9,9 +9,10 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2015 Marcos García - * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2016-2018 Ferran Marcet - * Copyright (C) 2021-2022 Frédéric France + * Copyright (C) 2018 Nicolas ZABOURI + * Copyright (C) 2016-2022 Ferran Marcet + * Copyright (C) 2021-2022 Frédéric France + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -266,6 +267,11 @@ class Commande extends CommonOrder */ public $expeditions; + /** + * @var string payment url + */ + public $online_payment_url; + /** * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') @@ -519,6 +525,7 @@ class Commande extends CommonOrder if ($this->lines[$i]->fk_product > 0) { $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; + $mouvP->setOrigin($this->element, $this->id); // We decrement stock of product (and sub-products) $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("OrderValidatedInDolibarr", $num)); if ($result < 0) { @@ -647,6 +654,7 @@ class Commande extends CommonOrder if ($this->lines[$i]->fk_product > 0) { $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; + $mouvP->setOrigin($this->element, $this->id); // We increment stock of product (and sub-products) $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("OrderBackToDraftInDolibarr", $this->ref)); if ($result < 0) { @@ -828,6 +836,7 @@ class Commande extends CommonOrder for ($i = 0; $i < $num; $i++) { if ($this->lines[$i]->fk_product > 0) { $mouvP = new MouvementStock($this->db); + $mouvP->setOrigin($this->element, $this->id); // We increment stock of product (and sub-products) $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("OrderCanceledInDolibarr", $this->ref)); // price is 0, we don't want WAP to be changed if ($result < 0) { @@ -877,7 +886,7 @@ class Commande extends CommonOrder */ public function create($user, $notrigger = 0) { - global $conf, $langs; + global $conf, $langs, $mysoc; $error = 0; // Clean parameters @@ -1044,7 +1053,8 @@ class Commande extends CommonOrder $origintype, $originid, 0, - $line->ref_ext + $line->ref_ext, + 1 ); if ($result < 0) { if ($result != self::STOCK_NOT_ENOUGH_FOR_ORDER) { @@ -1061,6 +1071,8 @@ class Commande extends CommonOrder } } + $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + // update ref $initialref = '(PROV'.$this->id.')'; if (!empty($this->ref)) { @@ -1438,6 +1450,7 @@ class Commande extends CommonOrder * @param int $origin_id Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be Id of origin object (aka line id), else object id * @param double $pu_ht_devise Unit price in currency * @param string $ref_ext line external reference + * @param int $noupdateafterinsertline No update after insert of line * @return int >0 if OK, <0 if KO * * @see add_product() @@ -1447,7 +1460,7 @@ class Commande extends CommonOrder * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit) * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue) */ - public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $info_bits = 0, $fk_remise_except = 0, $price_base_type = 'HT', $pu_ttc = 0, $date_start = '', $date_end = '', $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $array_options = 0, $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $ref_ext = '') + public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $info_bits = 0, $fk_remise_except = 0, $price_base_type = 'HT', $pu_ttc = 0, $date_start = '', $date_end = '', $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $array_options = 0, $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $ref_ext = '', $noupdateafterinsertline = 0) { global $mysoc, $conf, $langs, $user; @@ -1655,10 +1668,18 @@ class Commande extends CommonOrder // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); + } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) { // Update all rank of all other lines + $linecount = count($this->lines); + for ($ii = $ranktouse; $ii <= $linecount; $ii++) { + $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii + 1); + } } // Mise a jour informations denormalisees au niveau de la commande meme - $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + if (empty($noupdateafterinsertline)) { + $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + } + if ($result > 0) { $this->db->commit(); return $this->line->id; @@ -2021,8 +2042,9 @@ class Commande extends CommonOrder */ public function fetch_lines($only_product = 0, $loadalsotranslation = 0) { - global $langs, $conf; // phpcs:enable + global $langs, $conf; + $this->lines = array(); $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.product_type, l.fk_commande, l.label as custom_label, l.description, l.price, l.qty, l.vat_src_code, l.tva_tx, l.ref_ext,'; @@ -3659,9 +3681,10 @@ class Commande extends CommonOrder * @param int $notooltip 1=Disable tooltip * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @param int $addlinktonotes Add link to notes + * @param string $target attribute target for link * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0) + public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target = '') { global $conf, $langs, $user, $hookmanager; @@ -3715,7 +3738,7 @@ class Commande extends CommonOrder $label .= '
    '.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); } if (!empty($this->date)) { - $label .= '
    '.$langs->trans('Date').': '.dol_print_date($this->date, 'dayhour'); + $label .= '
    '.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); } if (!empty($this->delivery_date)) { $label .= '
    '.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); @@ -3730,6 +3753,11 @@ class Commande extends CommonOrder } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip"'; + + $target_value=array('_self', '_blank', '_parent', '_top'); + if (in_array($target, $target_value)) { + $linkclose .= ' target="'.dol_escape_htmltag($target).'"'; + } } $linkstart = 'call_trigger('LINEORDER_UPDATE', $user); + $result = $this->call_trigger('LINEORDER_MODIFY', $user); if ($result < 0) { $error++; } diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 27391d7a901..52071b672fe 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -201,6 +201,7 @@ $arrayfields = array( 'c.note_private'=>array('label'=>'NotePrivate', 'checked'=>0, 'enabled'=>(empty($conf->global->MAIN_LIST_ALLOW_PRIVATE_NOTES)), 'position'=>140), 'shippable'=>array('label'=>"Shippable", 'checked'=>1,'enabled'=>(!empty($conf->expedition->enabled)), 'position'=>990), 'c.facture'=>array('label'=>"Billed", 'checked'=>1, 'enabled'=>(empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)), 'position'=>995), + 'c.import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>999), 'c.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000) ); // Extra fields @@ -318,7 +319,7 @@ if ($action == 'validate' && $permissiontoadd) { if ($objecttmp->valid($user, $idwarehouse)) { setEventMessage($langs->trans('hasBeenValidated', $objecttmp->ref), 'mesgs'); } else { - setEventMessage($langs->trans('CantBeValidated'), 'errors'); + setEventMessage($objecttmp->error, $objecttmp->errors, 'errors'); $error++; } } else { @@ -345,7 +346,7 @@ if ($action == 'shipped' && $permissiontoadd) { $error = 0; foreach ($toselect as $checked) { if ($objecttmp->fetch($checked)) { - if ($objecttmp->statut == 1) { + if ($objecttmp->statut == 1 || $objecttmp->statut == 2) { if ($objecttmp->cloture($user)) { setEventMessage($langs->trans('PassedInClosedStatus', $objecttmp->ref), 'mesgs'); } else { @@ -441,7 +442,7 @@ $sql .= ' c.date_creation as date_creation, c.tms as date_update, c.date_cloture $sql .= ' p.rowid as project_id, p.ref as project_ref, p.title as project_label,'; $sql .= ' u.login, u.lastname, u.firstname, u.email as user_email, u.statut as user_statut, u.entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender,'; $sql .= ' c.fk_cond_reglement,c.fk_mode_reglement,c.fk_shipping_method,'; -$sql .= ' c.fk_input_reason'; +$sql .= ' c.fk_input_reason, c.import_key'; if (($search_categ_cus > 0) || ($search_categ_cus == -2)) { $sql .= ", cc.fk_categorie, cc.fk_soc"; } @@ -1275,6 +1276,11 @@ if ($resql) { print $form->selectyesno('search_billed', $search_billed, 1, 0, 1, 1); print ''; } + // Import key + if (!empty($arrayfields['c.import_key']['checked'])) { + print ''; + print ''; + } // Status if (!empty($arrayfields['c.fk_statut']['checked'])) { print ''; @@ -1436,6 +1442,9 @@ if ($resql) { if (!empty($arrayfields['c.facture']['checked'])) { print_liste_field_titre($arrayfields['c.facture']['label'], $_SERVER["PHP_SELF"], 'c.facture', '', $param, '', $sortfield, $sortorder, 'center '); } + if (!empty($arrayfields['c.import_key']['checked'])) { + print_liste_field_titre($arrayfields['c.import_key']['label'], $_SERVER["PHP_SELF"], "c.import_key", "", $param, '', $sortfield, $sortorder, 'center '); + } if (!empty($arrayfields['c.fk_statut']['checked'])) { print_liste_field_titre($arrayfields['c.fk_statut']['label'], $_SERVER["PHP_SELF"], "c.fk_statut", "", $param, '', $sortfield, $sortorder, 'center '); } @@ -2063,6 +2072,13 @@ if ($resql) { $totalarray['nbfield']++; } } + // Import key + if (!empty($arrayfields['c.import_key']['checked'])) { + print ''.$obj->import_key.''; + if (!$i) { + $totalarray['nbfield']++; + } + } // Status if (!empty($arrayfields['c.fk_statut']['checked'])) { print ''.$generic_commande->LibStatut($obj->fk_statut, $obj->billed, 5, 1).''; diff --git a/htdocs/commande/tpl/linkedobjectblock.tpl.php b/htdocs/commande/tpl/linkedobjectblock.tpl.php index 2a6140aaeed..8c1df906ab7 100644 --- a/htdocs/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/commande/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 1f821bf733b..8f61261bc11 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -19,11 +19,11 @@ * along with this program. If not, see . */ - /** - * \file htdocs/compta/accounting-files.php - * \ingroup compta - * \brief Page to show portoflio and files of a thirdparty and download it - */ +/** + * \file htdocs/compta/accounting-files.php + * \ingroup compta + * \brief Page to show portoflio and files of a thirdparty and download it + */ if ((array_key_exists('action', $_GET) && $_GET['action'] == 'dl') || (array_key_exists('action', $_POST) && $_POST['action'] == 'dl')) { // To not replace token when downloading file if (!defined('NOTOKENRENEWAL')) { @@ -588,14 +588,13 @@ foreach ($listofchoices as $choice => $val) { print '
    '; } -print ''; +print ''; print ''."\n"; print dol_get_fiche_end(); if (!empty($date_start) && !empty($date_stop)) { - $param = 'action=searchfiles'; $param .= '&date_startday='.GETPOST('date_startday', 'int'); $param .= '&date_startmonth='.GETPOST('date_startmonth', 'int'); $param .= '&date_startyear='.GETPOST('date_startyear', 'int'); @@ -603,13 +602,30 @@ if (!empty($date_start) && !empty($date_stop)) { $param .= '&date_stopmonth='.GETPOST('date_stopmonth', 'int'); $param .= '&date_stopyear='.GETPOST('date_stopyear', 'int'); foreach ($listofchoices as $choice => $val) { - $param .= '&'.$choice.'='.(GETPOST($choice, 'int') ? 1 : 0); + if (GETPOST($choice, 'int')) { + $param .= '&'.$choice.'=1'; + } } - print '
    '."\n"; - print ''; + + $TData = dol_sort_array($filesarray, $sortfield, $sortorder); + + + $filename = dol_print_date($date_start, 'dayrfc', 'tzuserrel')."-".dol_print_date($date_stop, 'dayrfc', 'tzuserrel').'_export.zip'; echo dol_print_date($date_start, 'day', 'tzuserrel')." - ".dol_print_date($date_stop, 'day', 'tzuserrel'); + print ''."\n"; + print $langs->trans("Download"); + print '
    '; + + $param .= '&action=searchfiles'; + + /* + print ''; print ''; print ''; print ''; @@ -620,8 +636,13 @@ if (!empty($date_start) && !empty($date_stop)) { print ''; } - print ''; + print ''; print '
    '."\n"; + */ print '
    '; @@ -645,172 +666,181 @@ if (!empty($date_start) && !empty($date_stop)) { print ''.$langs->trans("Currency").''; } print ''; - if ($result) { - $TData = dol_sort_array($filesarray, $sortfield, $sortorder); - if (empty($TData)) { - print ''.$langs->trans("NoItem").''; - if (!empty($conf->multicurrency->enabled)) { - print ''; + if (empty($TData)) { + print ''.$langs->trans("NoRecordFound").''; + if (!empty($conf->multicurrency->enabled)) { + print ''; + } + print ''; + } else { + // Sort array by date ASC to calculate balance + + $totalET_debit = 0; + $totalIT_debit = 0; + $totalVAT_debit = 0; + $totalET_credit = 0; + $totalIT_credit = 0; + $totalVAT_credit = 0; + + // Display array + foreach ($TData as $data) { + $html_class = ''; + //if (!empty($data['fk_facture'])) $html_class = 'facid-'.$data['fk_facture']; + //elseif (!empty($data['fk_paiement'])) $html_class = 'payid-'.$data['fk_paiement']; + print ''; + + // Type + print ''.$langs->trans($data['item']).''; + + // Date + print ''; + print dol_print_date($data['date'], 'day'); + print "\n"; + + // Date due + print ''; + print dol_print_date($data['date_due'], 'day'); + print "\n"; + + // Ref + print ''; + + if ($data['item'] == 'Invoice') { + $invoice->id = $data['id']; + $invoice->ref = $data['ref']; + $invoice->total_ht = $data['amount_ht']; + $invoice->total_ttc = $data['amount_ttc']; + $invoice->total_tva = $data['amount_vat']; + $invoice->multicurrency_code = $data['currency']; + print $invoice->getNomUrl(1, '', 0, 0, '', 0, 0, 0); + } elseif ($data['item'] == 'SupplierInvoice') { + $supplier_invoice->id = $data['id']; + $supplier_invoice->ref = $data['ref']; + $supplier_invoice->total_ht = $data['amount_ht']; + $supplier_invoice->total_ttc = $data['amount_ttc']; + $supplier_invoice->total_tva = $data['amount_vat']; + $supplier_invoice->multicurrency_code = $data['currency']; + print $supplier_invoice->getNomUrl(1, '', 0, 0, '', 0, 0, 0); + } elseif ($data['item'] == 'ExpenseReport') { + $expensereport->id = $data['id']; + $expensereport->ref = $data['ref']; + print $expensereport->getNomUrl(1, 0, 0, '', 0, 0); + } elseif ($data['item'] == 'SalaryPayment') { + $salary_payment->id = $data['id']; + $salary_payment->ref = $data['ref']; + print $salary_payment->getNomUrl(1); + } elseif ($data['item'] == 'Donation') { + $don->id = $data['id']; + $don->ref = $data['ref']; + print $don->getNomUrl(1, 0, '', 0); + } elseif ($data['item'] == 'SocialContributions') { + $charge_sociales->id = $data['id']; + $charge_sociales->ref = $data['ref']; + print $charge_sociales->getNomUrl(1, 0, 0, 0, 0); + } elseif ($data['item'] == 'VariousPayment') { + $various_payment->id = $data['id']; + $various_payment->ref = $data['ref']; + print $various_payment->getNomUrl(1, '', 0, 0); + } elseif ($data['item'] == 'LoanPayment') { + $payment_loan->id = $data['id']; + $payment_loan->ref = $data['ref']; + print $payment_loan->getNomUrl(1, 0, 0, '', 0); + } else { + print $data['ref']; } - print ''; - } else { - // Sort array by date ASC to calculate balance + print ''; - $totalET_debit = 0; - $totalIT_debit = 0; - $totalVAT_debit = 0; - $totalET_credit = 0; - $totalIT_credit = 0; - $totalVAT_credit = 0; - - // Display array - foreach ($TData as $data) { - $html_class = ''; - //if (!empty($data['fk_facture'])) $html_class = 'facid-'.$data['fk_facture']; - //elseif (!empty($data['fk_paiement'])) $html_class = 'payid-'.$data['fk_paiement']; - print ''; - - // Type - print ''.$langs->trans($data['item']).''; - - // Date - print ''; - print dol_print_date($data['date'], 'day'); - print "\n"; - - // Date due - print ''; - print dol_print_date($data['date_due'], 'day'); - print "\n"; - - // Ref - print ''; - - if ($data['item'] == 'Invoice') { - $invoice->id = $data['id']; - $invoice->ref = $data['ref']; - $invoice->total_ht = $data['amount_ht']; - $invoice->total_ttc = $data['amount_ttc']; - $invoice->total_tva = $data['amount_vat']; - $invoice->multicurrency_code = $data['currency']; - print $invoice->getNomUrl(1, '', 0, 0, '', 0, 0, 0); - } elseif ($data['item'] == 'SupplierInvoice') { - $supplier_invoice->id = $data['id']; - $supplier_invoice->ref = $data['ref']; - $supplier_invoice->total_ht = $data['amount_ht']; - $supplier_invoice->total_ttc = $data['amount_ttc']; - $supplier_invoice->total_tva = $data['amount_vat']; - $supplier_invoice->multicurrency_code = $data['currency']; - print $supplier_invoice->getNomUrl(1, '', 0, 0, '', 0, 0, 0); - } elseif ($data['item'] == 'ExpenseReport') { - $expensereport->id = $data['id']; - $expensereport->ref = $data['ref']; - print $expensereport->getNomUrl(1, 0, 0, '', 0, 0); - } elseif ($data['item'] == 'SalaryPayment') { - $salary_payment->id = $data['id']; - $salary_payment->ref = $data['ref']; - print $salary_payment->getNomUrl(1); - } elseif ($data['item'] == 'Donation') { - $don->id = $data['id']; - $don->ref = $data['ref']; - print $don->getNomUrl(1, 0, '', 0); - } elseif ($data['item'] == 'SocialContributions') { - $charge_sociales->id = $data['id']; - $charge_sociales->ref = $data['ref']; - print $charge_sociales->getNomUrl(1, 0, 0, 0, 0); - } elseif ($data['item'] == 'VariousPayment') { - $various_payment->id = $data['id']; - $various_payment->ref = $data['ref']; - print $various_payment->getNomUrl(1, '', 0, 0); - } elseif ($data['item'] == 'LoanPayment') { - $payment_loan->id = $data['id']; - $payment_loan->ref = $data['ref']; - print $payment_loan->getNomUrl(1, 0, 0, '', 0); - } else { - print $data['ref']; - } - print ''; - - // File link - print ''; - if (!empty($data['files'])) { - foreach ($data['files'] as $id => $filecursor) { - print ''.($filecursor['name'] ? $filecursor['name'] : $filecursor['ref']).' '.$formfile->showPreview($filecursor, $filecursor['modulepart'], $filecursor['subdir'].'/'.$filecursor['name']).'
    '; + // File link + print ''; + if (!empty($data['files'])) { + foreach ($data['files'] as $id => $filecursor) { + $tmppreview = $formfile->showPreview($filecursor, $filecursor['modulepart'], $filecursor['subdir'].'/'.$filecursor['name'], 0); + if ($tmppreview) { + print $tmppreview; } + $filename = ($filecursor['name'] ? $filecursor['name'] : $filecursor['ref']); + print ''; + if (empty($tmppreview)) { + print img_picto('', 'generic', '', false, 0, 0, '', 'pictonopreview pictofixedwidth paddingright'); + } + print $filename; + print '
    '; } - print "\n"; + } + print "\n"; - // Paid - print ''.$data['paid'].''; + // Paid + print ''.($data['paid'] ? yn($data['paid']) : '').''; - // Total ET - print ''.price(price2num($data['sens'] ? $data['amount_ht'] : -$data['amount_ht'], 'MT'))."\n"; - // Total IT - print ''.price(price2num($data['sens'] ? $data['amount_ttc'] : -$data['amount_ttc'], 'MT'))."\n"; - // Total VAT - print ''.price(price2num($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'], 'MT'))."\n"; + // Total ET + print ''.price(price2num($data['sens'] ? $data['amount_ht'] : -$data['amount_ht'], 'MT'))."\n"; + // Total IT + print ''.price(price2num($data['sens'] ? $data['amount_ttc'] : -$data['amount_ttc'], 'MT'))."\n"; + // Total VAT + print ''.price(price2num($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'], 'MT'))."\n"; - print ''.dol_escape_htmltag($data['thirdparty_name'])."\n"; + print ''.dol_escape_htmltag($data['thirdparty_name'])."\n"; - print ''.$data['thirdparty_code']."\n"; + print ''.$data['thirdparty_code']."\n"; - print ''.$data['country_code']."\n"; + print ''.$data['country_code']."\n"; - print ''.dol_escape_htmltag($data['vatnum'])."\n"; + // VAT number + print ''.dol_escape_htmltag($data['vatnum'])."\n"; - if ($data['sens']) { - $totalET_credit += $data['amount_ht']; - $totalIT_credit += $data['amount_ttc']; - $totalVAT_credit += $data['amount_vat']; - } else { - $totalET_debit -= $data['amount_ht']; - $totalIT_debit -= $data['amount_ttc']; - $totalVAT_debit -= $data['amount_vat']; - } - - if (!empty($conf->multicurrency->enabled)) { - print ''.$data['currency']."\n"; - } - - print "\n"; + if ($data['sens']) { + $totalET_credit += $data['amount_ht']; + $totalIT_credit += $data['amount_ttc']; + $totalVAT_credit += $data['amount_vat']; + } else { + $totalET_debit -= $data['amount_ht']; + $totalIT_debit -= $data['amount_ttc']; + $totalVAT_debit -= $data['amount_vat']; } - // Total credits - print ''; - print ''.$langs->trans('Total').' '.$langs->trans('Income').''; - print ''.price(price2num($totalET_credit, 'MT')).''; - print ''.price(price2num($totalIT_credit, 'MT')).''; - print ''.price(price2num($totalVAT_credit, 'MT')).''; - print ''; if (!empty($conf->multicurrency->enabled)) { - print ''; - } - print "\n"; - // Total debits - print ''; - print ''.$langs->trans('Total').' '.$langs->trans('Outcome').''; - print ''.price(price2num($totalET_debit, 'MT')).''; - print ''.price(price2num($totalIT_debit, 'MT')).''; - print ''.price(price2num($totalVAT_debit, 'MT')).''; - print ''; - if (!empty($conf->multicurrency->enabled)) { - print ''; - } - print "\n"; - // Balance - print ''; - print ''.$langs->trans('Total').''; - print ''.price(price2num($totalET_credit + $totalET_debit, 'MT')).''; - print ''.price(price2num($totalIT_credit + $totalIT_debit, 'MT')).''; - print ''.price(price2num($totalVAT_credit + $totalVAT_debit, 'MT')).''; - print ''; - if (!empty($conf->multicurrency->enabled)) { - print ''; + print ''.$data['currency']."\n"; } + print "\n"; } + + // Total credits + print ''; + print ''.$langs->trans('Total').' '.$langs->trans('Income').''; + print ''.price(price2num($totalET_credit, 'MT')).''; + print ''.price(price2num($totalIT_credit, 'MT')).''; + print ''.price(price2num($totalVAT_credit, 'MT')).''; + print ''; + if (!empty($conf->multicurrency->enabled)) { + print ''; + } + print "\n"; + // Total debits + print ''; + print ''.$langs->trans('Total').' '.$langs->trans('Outcome').''; + print ''.price(price2num($totalET_debit, 'MT')).''; + print ''.price(price2num($totalIT_debit, 'MT')).''; + print ''.price(price2num($totalVAT_debit, 'MT')).''; + print ''; + if (!empty($conf->multicurrency->enabled)) { + print ''; + } + print "\n"; + // Balance + print ''; + print ''.$langs->trans('Total').''; + print ''.price(price2num($totalET_credit + $totalET_debit, 'MT')).''; + print ''.price(price2num($totalIT_credit + $totalIT_debit, 'MT')).''; + print ''.price(price2num($totalVAT_credit + $totalVAT_debit, 'MT')).''; + print ''; + if (!empty($conf->multicurrency->enabled)) { + print ''; + } + print "\n"; } + print ""; print ''; } diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index e991831a6dd..8893f91c2c2 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -170,7 +170,7 @@ $arrayfields = array( 'balancebefore'=>array('label'=>$langs->trans("BalanceBefore"), 'checked'=>0, 'position'=>1000), 'balance'=>array('label'=>$langs->trans("Balance"), 'checked'=>1, 'position'=>1001), 'b.num_releve'=>array('label'=>$langs->trans("AccountStatement"), 'checked'=>1, 'position'=>1010), - 'b.conciliated'=>array('label'=>$langs->trans("Conciliated"), 'enabled'=> $object->rappro, 'checked'=>($action == 'reconcile' ? 1 : 0), 'position'=>1020), + 'b.conciliated'=>array('label'=>$langs->trans("BankLineReconciled"), 'enabled'=> $object->rappro, 'checked'=>($action == 'reconcile' ? 1 : 0), 'position'=>1020), ); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 4e37268756d..8ca3272dd78 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -65,7 +65,8 @@ $hookmanager->initHooks(array('bankcard', 'globalcard')); // Security check $id = GETPOST("id", 'int') ? GETPOST("id", 'int') : GETPOST('ref', 'alpha'); -$fieldid = GETPOSTISSET("ref") ? 'ref' : 'rowid'; +$fieldid = GETPOST("id", 'int') ? 'rowid' : 'ref'; + $result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid); @@ -124,6 +125,7 @@ if (empty($reshook)) { $object->bic = trim(GETPOST("bic")); $object->iban = trim(GETPOST("iban")); $object->domiciliation = trim(GETPOST("domiciliation", "nohtml")); + $object->pti_in_ctti = empty(GETPOST("pti_in_ctti")) ? 0 : 1; $object->proprio = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_address = trim(GETPOST("owner_address", 'nohtml')); @@ -224,6 +226,7 @@ if (empty($reshook)) { $object->bic = trim(GETPOST("bic")); $object->iban = trim(GETPOST("iban")); $object->domiciliation = trim(GETPOST("domiciliation", "nohtml")); + $object->pti_in_ctti = empty(GETPOST("pti_in_ctti")) ? 0 : 1; $object->proprio = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_address = trim(GETPOST("owner_address", 'nohtml')); @@ -537,6 +540,13 @@ if ($action == 'create') { print ''.$langs->trans($bickey).''; print ''; + if ($conf->paymentbybanktransfer->enabled) { + print ''.$langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation").''; + print ' '; + print img_picto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp"), 'info'); + print ''; + } + print ''.$langs->trans("BankAccountDomiciliation").''; print ''; + print ''; + print ''; print ''; diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 33558ddf38a..2306e99899b 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -64,6 +64,8 @@ if ($socid && $socid != $object->thirdparty->id) { accessforbidden(); } +$error = 0; + /* * Actions @@ -191,6 +193,39 @@ if ($action == 'setdatep' && GETPOST('datepday')) { setEventMessages($langs->trans('PaymentDateUpdateFailed'), null, 'errors'); } } +if ($action == 'createbankpayment' && !empty($user->rights->facture->paiement)) { + $db->begin(); + + // Create the record into bank for the amount of payment $object + if (!$error) { + $label = '(CustomerInvoicePayment)'; + if (GETPOST('type') == Facture::TYPE_CREDIT_NOTE) { + $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note + } + + $bankaccountid = GETPOST('accountid', 'int'); + if ($bankaccountid > 0) { + $object->paiementcode = $object->type_code; + $object->amounts = $object->getAmountsArray(); + + $result = $object->addPaymentToBank($user, 'payment', $label, $bankaccountid, '', ''); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } else { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankAccount")), null, 'errors'); + $error++; + } + } + + + if (!$error) { + $db->commit(); + } else { + $db->rollback(); + } +} /* @@ -236,7 +271,7 @@ print ''."\n"; // Date payment print ''; // Payment type (VIR, LIQ, ...) @@ -315,7 +350,37 @@ if (!empty($conf->banque->enabled)) { print $bankline->getNomUrl(1, 0, 'showconciliatedandaccounted'); } else { $langs->load("admin"); - print ''.$langs->trans("NoRecordFoundIBankcAccount", $langs->transnoentitiesnoconv("Module85Name")).''; + print ''; + print $langs->trans("NoRecordFoundIBankcAccount", $langs->transnoentitiesnoconv("Module85Name")); + print ''; + if (!empty($user->rights->facture->paiement)) { + // Try to guess $bankaccountidofinvoices that is ID of bank account defined on invoice. + // Return null if not found, return 0 if it has different value for at least 2 invoices, return the value if same on all invoices where a bank is defined. + $amountofpayments = $object->getAmountsArray(); + $bankaccountidofinvoices = null; + foreach ($amountofpayments as $idinvoice => $amountofpayment) { + $tmpinvoice = new Facture($db); + $tmpinvoice->fetch($idinvoice); + if ($tmpinvoice->fk_account > 0 && $bankaccountidofinvoices !== 0) { + if (is_null($bankaccountidofinvoices)) { + $bankaccountidofinvoices = $tmpinvoice->fk_account; + } elseif ($bankaccountidofinvoices != $tmpinvoice->fk_account) { + $bankaccountidofinvoices = 0; + } + } + } + + print ''; + print ''; + print ''; + print ''; + print ' '.$langs->trans("ToCreateRelatedRecordIntoBank").': '; + print $form->select_comptes($bankaccountidofinvoices, 'accountid', 0, '', 2, '', 0, '', 1); + //print ''; + print ''; + //print ''; + print ''; + } } print ''; print ''; diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php index 610974e5528..8c859e6e689 100644 --- a/htdocs/compta/paiement/cheque/card.php +++ b/htdocs/compta/paiement/cheque/card.php @@ -41,12 +41,7 @@ $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -// Security check -$fieldname = (!empty($ref) ? 'ref' : 'rowid'); -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'cheque', $id, 'bordereau_cheque', '', 'fk_user_author', $fieldname); +$object = new RemiseCheque($db); $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); @@ -63,11 +58,22 @@ if (empty($page) || $page == -1) { $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $offset = $limit * $page; -$dir = $conf->bank->dir_output.'/checkdeposits/'; +$upload_dir = $conf->bank->multidir_output[$object->entity ? $object->entity : $conf->entity]."/checkdeposits"; + $filterdate = dol_mktime(0, 0, 0, GETPOST('fdmonth'), GETPOST('fdday'), GETPOST('fdyear')); $filteraccountid = GETPOST('accountid', 'int'); -$object = new RemiseCheque($db); +// Security check +$fieldname = (!empty($ref) ? 'ref' : 'rowid'); +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'cheque', $id, 'bordereau_cheque', '', 'fk_user_author', $fieldname); + +$usercanread = $user->rights->banque->cheque; +$usercancreate = $user->rights->banque->cheque; +$usercandelete = $user->rights->banque->cheque; + /* @@ -241,7 +247,9 @@ if ($action == 'builddoc' && $user->rights->banque->cheque) { $langs->load("other"); - $file = $dir.get_exdir($object->ref, 0, 1, 0, $object, 'cheque').GETPOST('file'); + $filetodelete = GETPOST('file', 'alpha'); + $file = $upload_dir.'/'.$filetodelete; + $ret = dol_delete_file($file, 0, 0, 0, $object); if ($ret) { setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); @@ -634,6 +642,12 @@ if ($action == 'new') { $i = 1; if ($num > 0) { while ($objp = $db->fetch_object($resql)) { + $paymentstatic->id = $objp->pid; + $paymentstatic->ref = $objp->pref; + + $accountlinestatic->id = $objp->rowid; + $accountlinestatic->ref = $objp->ref; + print ''; print ''; print ''; // Operation date @@ -643,8 +657,6 @@ if ($action == 'new') { print ''; // Link to payment print ''; // Link to bank transaction print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/compta/paiement_vat.php b/htdocs/compta/paiement_vat.php index 916a0bf5498..ce224735927 100644 --- a/htdocs/compta/paiement_vat.php +++ b/htdocs/compta/paiement_vat.php @@ -83,7 +83,7 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm == 'y } } - if ($amounts[key($amounts)] <= 0) { + if (empty($amounts[key($amounts)])) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount")), null, 'errors'); $action = 'create'; diff --git a/htdocs/compta/paymentbybanktransfer/index.php b/htdocs/compta/paymentbybanktransfer/index.php index b8675b3a7e5..6c14987e5ba 100644 --- a/htdocs/compta/paymentbybanktransfer/index.php +++ b/htdocs/compta/paymentbybanktransfer/index.php @@ -66,7 +66,7 @@ if (prelevement_check_config('bank-transfer') < 0) { $newcardbutton = ''; if ($usercancreate) { - $newcardbutton .= dolGetButtonTitle($langs->trans('NewStandingOrder'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/compta/prelevement/create.php?type=bank-transfer'); + $newcardbutton .= dolGetButtonTitle($langs->trans('NewPaymentByBankTransfer'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/compta/prelevement/create.php?type=bank-transfer'); } print load_fiche_titre($langs->trans("SuppliersStandingOrdersArea"), $newcardbutton); @@ -90,7 +90,7 @@ print $bprev->nbOfInvoiceToPay('bank-transfer'); print ''; print ''; -print ''; +print ''; print '
    '.$form->editfieldkey("Date", 'datep', $object->date, $object, $user->rights->facture->paiement).''; -print $form->editfieldval("Date", 'datep', $object->date, $object, $user->rights->facture->paiement, 'datehourpicker', '', null, $langs->trans('PaymentDateUpdateSucceeded')); +print $form->editfieldval("Date", 'datep', $object->date, $object, $user->rights->facture->paiement, 'datehourpicker', '', null, $langs->trans('PaymentDateUpdateSucceeded'), '', 0, '', 'id', 'tzuser'); print '
    '.$i.''.dol_print_date($db->jdate($objp->date), 'day').''.price($objp->amount).''; - $paymentstatic->id = $objp->pid; - $paymentstatic->ref = $objp->pref; if ($paymentstatic->id) { print $paymentstatic->getNomUrl(1); } else { @@ -653,8 +665,6 @@ if ($action == 'new') { print ''; - $accountlinestatic->id = $objp->rowid; - $accountlinestatic->ref = $objp->ref; if ($accountlinestatic->id > 0) { print $accountlinestatic->getNomUrl(1); } else { @@ -664,10 +674,10 @@ if ($action == 'new') { // Action button print ''; if ($object->statut == 0) { - print 'rowid.'">'.img_delete().''; + print 'rowid.'">'.img_delete().''; } if ($object->statut == 1 && $objp->statut != 2) { - print 'rowid.'">'.img_picto($langs->trans("RejectCheck"), 'disable').''; + print 'rowid.'">'.img_picto($langs->trans("RejectCheck"), 'disable').''; } if ($objp->statut == 2) { print '   '.img_picto($langs->trans('CheckRejected'), 'statut8').''; @@ -723,11 +733,13 @@ print ''; if ($action != 'new') { if ($object->statut == 1) { - $filename = dol_sanitizeFileName($object->ref); - $filedir = $dir.get_exdir($object->ref, 0, 1, 0, $object, 'checkdeposits'); + // Documents + $objref = dol_sanitizeFileName($object->ref); + $filedir = $upload_dir.'/'.$objref; $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - - print $formfile->showdocuments('remisecheque', $filename, $filedir, $urlsource, 1, 1); + $genallowed = $usercancreate; + $delallowed = $usercandelete; + print $formfile->showdocuments('remisecheque', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); print '
    '; } diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php index c66edfc8fe1..451a18ab05b 100644 --- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php +++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php @@ -615,6 +615,7 @@ class RemiseCheque extends CommonObject // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. $sav_charseSupprimert_output = $outputlangs->charset_output; + $result = $docmodel->write_file($this, $conf->bank->dir_output.'/checkdeposits', $this->ref, $outputlangs); if ($result > 0) { //$outputlangs->charset_output=$sav_charset_output; @@ -729,7 +730,7 @@ class RemiseCheque extends CommonObject $bankline = new AccountLine($db); $bankline->fetch($bank_id); - /* Conciliation is allowed because when check is returned, a new line is created onto bank transaction log. + /* Reconciliation is allowed because when check is returned, a new line is created onto bank transaction log. if ($bankline->rappro) { $this->error='ActionRefusedLineAlreadyConciliated'; @@ -738,7 +739,7 @@ class RemiseCheque extends CommonObject $this->db->begin(); - // Not conciliated, we can delete it + // Not reconciled, we can delete it //$bankline->delete($user); // We delete $bankaccount = $payment->fk_account; diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 84d1b007e09..86dcbdeff39 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -72,8 +72,9 @@ class Paiement extends CommonObject public $amount; // Total amount of payment (in the main currency) public $multicurrency_amount; // Total amount of payment (in the currency of the bank account) - public $amounts = array(); // array: invoice ID => amount for that invoice (in the main currency)> - public $multicurrency_amounts = array(); // array: invoice ID => amount for that invoice (in the invoice's currency)> + public $amounts = array(); // array: invoice ID => amount for that invoice (in the main currency) + public $multicurrency_amounts = array(); // array: invoice ID => amount for that invoice (in the invoice's currency) + public $multicurrency_code = array(); // array: invoice ID => currency code for that invoice public $pos_change = 0; // Excess received in TakePOS cash payment @@ -82,12 +83,12 @@ class Paiement extends CommonObject public $paiementcode; // Code of payment. /** - * @var string type libelle + * @var string Type of payment label */ public $type_label; /** - * @var string type code + * @var string Type of payment code (seems duplicate with $paiementcode); */ public $type_code; @@ -230,7 +231,7 @@ class Paiement extends CommonObject global $conf, $langs; $error = 0; - $way = $this->getWay(); + $way = $this->getWay(); // 'dolibarr' to use amount, 'customer' to use foreign multicurrency amount $now = dol_now(); @@ -239,16 +240,37 @@ class Paiement extends CommonObject $totalamount_converted = 0; $atleastonepaymentnotnull = 0; - if ($way == 'dolibarr') { + if ($way == 'dolibarr') { // Payments were entered into the column of main currency $amounts = &$this->amounts; $amounts_to_update = &$this->multicurrency_amounts; - } else { + } else { // Payments were entered into the column of foreign currency $amounts = &$this->multicurrency_amounts; $amounts_to_update = &$this->amounts; } + $currencyofpayment = ''; + foreach ($amounts as $key => $value) { // How payment is dispatch + if (empty($value)) { + continue; + } + // $key is id of invoice, $value is amount, $way is a 'dolibarr' if amount is in main currency, 'customer' if in foreign currency $value_converted = Multicurrency::getAmountConversionFromInvoiceRate($key, $value, $way); + // Add controls of input validity + if ($value_converted === false) { + // We failed to find the conversion for one invoice + $this->error = 'FailedToFoundTheConversionRateForInvoice'; + return -1; + } + if (empty($currencyofpayment)) { + $currencyofpayment = $this->multicurrency_code[$key]; + } + if ($currencyofpayment != $this->multicurrency_code[$key]) { + // If we have invoices with different currencies in the payment, we stop here + $this->error = 'ErrorYouTryToPayInvoicesWithDifferentCurrenciesInSamePayment'; + return -1; + } + $totalamount_converted += $value_converted; $amounts_to_update[$key] = price2num($value_converted, 'MT'); @@ -260,6 +282,19 @@ class Paiement extends CommonObject } } + if (!empty($currencyofpayment)) { + // We must check that the currency of invoices is the same than the currency of the bank + $bankaccount = new Account($this->db); + $bankaccount->fetch($this->fk_account); + $bankcurrencycode = empty($bankaccount->currency_code) ? $conf->currency : $bankaccount->currency_code; + if ($currencyofpayment != $bankcurrencycode && $currencyofpayment != $conf->currency && $bankcurrencycode != $conf->currency) { + $langs->load("errors"); + $this->error = $langs->trans('ErrorYouTryToPayInvoicesInACurrencyFromBankWithAnotherCurrency', $currencyofpayment, $bankcurrencycode); + return -1; + } + } + + $totalamount = price2num($totalamount); $totalamount_converted = price2num($totalamount_converted); @@ -305,6 +340,7 @@ class Paiement extends CommonObject if (is_numeric($amount) && $amount <> 0) { $amount = price2num($amount); $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement_facture (fk_facture, fk_paiement, amount, multicurrency_amount)"; + // TODO Add multicurrency_code and multicurrency_tx $sql .= " VALUES (".((int) $facid).", ".((int) $this->id).", ".((float) $amount).", ".((float) $this->multicurrency_amounts[$key]).")"; dol_syslog(get_class($this).'::create Amount line '.$key.' insert paiement_facture', LOG_DEBUG); @@ -585,16 +621,19 @@ class Paiement extends CommonObject return -1; } - $this->db->begin(); - $this->fk_account = $accountid; + dol_syslog("addPaymentToBank ".$user->id.", ".$mode.", ".$label.", ".$this->fk_account.", ".$emetteur_nom.", ".$emetteur_banque); + include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; - - dol_syslog("$user->id, $mode, $label, $this->fk_account, $emetteur_nom, $emetteur_banque"); - $acc = new Account($this->db); $result = $acc->fetch($this->fk_account); + if ($result < 0) { + $error++; + return -1; + } + + $this->db->begin(); $totalamount = $this->amount; if (empty($totalamount)) { @@ -951,6 +990,7 @@ class Paiement extends CommonObject * * @param string $filter Filter * @return int|array <0 if KO or array of invoice id + * @see getAmountsArray() */ public function getBillsArray($filter = '') { @@ -984,6 +1024,7 @@ class Paiement extends CommonObject * Return list of amounts of payments. * * @return int|array Array of amount of payments + * @see getBillsArray() */ public function getAmountsArray() { @@ -1171,6 +1212,9 @@ class Paiement extends CommonObject $label .= dol_print_date($dateofpayment, 'dayhour', 'tzuser'); } } + if ($this->amount) { + $label .= '
    '.$langs->trans("Amount").': '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency); + } if ($mode == 'withlistofinvoices') { $arraybill = $this->getBillsArray(); if (is_array($arraybill) && count($arraybill) > 0) { diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index 3732e76b880..d2ed6b939c8 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -528,7 +528,7 @@ while ($i < min($num, $limit)) { // Date if (!empty($arrayfields['p.datep']['checked'])) { $dateformatforpayment = 'dayhour'; - print '
    '.dol_print_date($db->jdate($objp->datep), $dateformatforpayment).''.dol_print_date($db->jdate($objp->datep), $dateformatforpayment, 'tzuser').'
    '.$langs->trans("AmountToWithdraw").'
    '.$langs->trans("AmountToTransfer").''; print price($bprev->SommeAPrelever('bank-transfer'), '', '', 1, -1, -1, 'auto'); print '

    '; @@ -102,7 +102,7 @@ print '
    '; */ $sql = "SELECT f.ref, f.rowid, f.total_ttc, f.fk_statut, f.paye, f.type,"; $sql .= " pfd.date_demande, pfd.amount,"; -$sql .= " s.nom as name, s.email, s.rowid as socid, s.tva_intra"; +$sql .= " s.nom as name, s.email, s.rowid as socid, s.tva_intra, s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; if (empty($user->rights->societe->client->voir) && !$socid) { @@ -149,6 +149,15 @@ if ($resql) { $thirdpartystatic->name = $obj->name; $thirdpartystatic->email = $obj->email; $thirdpartystatic->tva_intra = $obj->tva_intra; + $thirdpartystatic->siren = $obj->idprof1; + $thirdpartystatic->siret = $obj->idprof2; + $thirdpartystatic->ape = $obj->idprof3; + $thirdpartystatic->idprof1 = $obj->idprof1; + $thirdpartystatic->idprof2 = $obj->idprof2; + $thirdpartystatic->idprof3 = $obj->idprof3; + $thirdpartystatic->idprof4 = $obj->idprof4; + $thirdpartystatic->idprof5 = $obj->idprof5; + $thirdpartystatic->idprof6 = $obj->idprof6; print ''; print $invoicestatic->getNomUrl(1, 'withdraw'); @@ -159,7 +168,7 @@ if ($resql) { print ''; print ''; - print price($obj->amount); + print ''.price($obj->amount).''; print ''; print ''; diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index a076299b4cd..469985679c9 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -191,7 +191,7 @@ if ($id > 0 || $ref) { print ''.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; + print ' '.$langs->trans("By").' '.$muser->getNomUrl(-1).''; print ''.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print ''; @@ -237,7 +237,9 @@ if ($id > 0 || $ref) { if ($object->type == 'bank-transfer') { $modulepart = 'paymentbybanktransfer'; } - print ''.$relativepath.''; + print ''.$relativepath; + print img_picto('', 'download', 'class="paddingleft"'); + print ''; print ''; // Other attributes @@ -309,20 +311,22 @@ if ($id > 0 || $ref) { // Actions if ($action != 'settransmitted' && $action != 'setcredited') { print "\n".'
    '."\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if (empty($object->date_trans)) { + if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("SetToStatusSent"), '', 'default', 'card.php?action=settransmitted&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->send); + else print dolGetButtonAction($langs->trans("SetToStatusSent"), '', 'default', 'card.php?action=settransmitted&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->send); + } - if (empty($object->date_trans)) { - if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("SetToStatusSent"), '', 'default', 'card.php?action=settransmitted&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->send); - else print dolGetButtonAction($langs->trans("SetToStatusSent"), '', 'default', 'card.php?action=settransmitted&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->send); + if (!empty($object->date_trans) && $object->date_credit == 0) { + if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("ClassDebited"), '', 'default', 'card.php?action=setcredited&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->debit); + else print dolGetButtonAction($langs->trans("ClassCredited"), '', 'default', 'card.php?action=setcredited&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->credit); + } + + if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("Delete"), '', 'delete', 'card.php?action=delete&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->create); + else print dolGetButtonAction($langs->trans("Delete"), '', 'delete', 'card.php?action=delete&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->creer); } - - if (!empty($object->date_trans) && $object->date_credit == 0) { - if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("ClassDebited"), '', 'default', 'card.php?action=setcredited&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->debit); - else print dolGetButtonAction($langs->trans("ClassCredited"), '', 'default', 'card.php?action=setcredited&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->credit); - } - - if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("Delete"), '', 'delete', 'card.php?action=delete&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->create); - else print dolGetButtonAction($langs->trans("Delete"), '', 'delete', 'card.php?action=delete&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->creer); - print '
    '; } diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 6eac14d3eb3..36d3afd42ad 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -64,6 +64,7 @@ class BonPrelevement extends CommonObject public $emetteur_numero_compte; public $emetteur_code_banque; public $emetteur_number_key; + public $sepa_xml_pti_in_ctti; public $emetteur_iban; public $emetteur_bic; @@ -107,6 +108,7 @@ class BonPrelevement extends CommonObject $this->emetteur_numero_compte = ""; $this->emetteur_code_banque = ""; $this->emetteur_number_key = ""; + $this->sepa_xml_pti_in_ctti = false; $this->emetteur_iban = ""; $this->emetteur_bic = ""; @@ -918,7 +920,7 @@ class BonPrelevement extends CommonObject if (!$error) { $ref = substr($year, -2).$month; - $sql = "SELECT substring(ref from char_length(ref) - 1)"; + $sql = "SELECT substring(ref from char_length(ref) - 1)"; // To extract "YYMMXX" from "TYYMMXX" $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons"; $sql .= " WHERE ref LIKE '%".$this->db->escape($ref)."%'"; $sql .= " AND entity = ".((int) $conf->entity); @@ -929,8 +931,14 @@ class BonPrelevement extends CommonObject if ($resql) { $row = $this->db->fetch_row($resql); - $ref = "T".$ref.str_pad(dol_substr("00".intval($row[0]) + 1, 0, 2), 2, "0", STR_PAD_LEFT); + // Build the new ref + $ref = "T".$ref.str_pad(dol_substr("00".(intval($row[0]) + 1), 0, 2), 2, "0", STR_PAD_LEFT); + + // $conf->abc->dir_output may be: + // /home/ldestailleur/git/dolibarr_15.0/documents/abc/ + // or + // /home/ldestailleur/git/dolibarr_15.0/documents/X/abc with X >= 2 with multicompany. if ($type != 'bank-transfer') { $dir = $conf->prelevement->dir_output.'/receipts'; } else { @@ -947,7 +955,7 @@ class BonPrelevement extends CommonObject $sql .= "ref, entity, datec, type"; $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($ref)."'"; - $sql .= ", ".$conf->entity; + $sql .= ", ".((int) $conf->entity); $sql .= ", '".$this->db->idate($now)."'"; $sql .= ", '".($type == 'bank-transfer' ? 'bank-transfer' : 'debit-order')."'"; $sql .= ")"; @@ -1038,10 +1046,11 @@ class BonPrelevement extends CommonObject } $account = new Account($this->db); if ($account->fetch($id) > 0) { - $this->emetteur_code_banque = $account->code_banque; + $this->emetteur_code_banque = $account->code_banque; $this->emetteur_code_guichet = $account->code_guichet; $this->emetteur_numero_compte = $account->number; - $this->emetteur_number_key = $account->cle_rib; + $this->emetteur_number_key = $account->cle_rib; + $this->sepa_xml_pti_in_ctti = (bool) $account->pti_in_ctti; $this->emetteur_iban = $account->iban; $this->emetteur_bic = $account->bic; @@ -1828,7 +1837,7 @@ class BonPrelevement extends CommonObject $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); if ($type != 'bank-transfer') { - // SEPA Paiement Information of buyer for Direct debit + // SEPA Paiement Information of buyer for Direct Debit $XML_DEBITOR = ''; $XML_DEBITOR .= ' '.$CrLf; $XML_DEBITOR .= ' '.$CrLf; @@ -1881,6 +1890,24 @@ class BonPrelevement extends CommonObject // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum) $XML_CREDITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('CT-'.dol_trunc($row_idfac.'-'.$row_ref, 20, 'right', 'UTF-8', 1)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters $XML_CREDITOR .= ' '.$CrLf; + if (!empty($this->sepa_xml_pti_in_ctti)) { + $XML_CREDITOR .= ' ' . $CrLf; + + // Can be 'NORM' for normal or 'HIGH' for high priority level + if (!empty($conf->global->PAYMENTBYBANKTRANSFER_FORCE_HIGH_PRIORITY)) { + $instrprty = 'HIGH'; + } else { + $instrprty = 'NORM'; + } + $XML_CREDITOR .= ' '.$instrprty.'' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + $XML_CREDITOR .= ' SEPA' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + $XML_CREDITOR .= ' CORE' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + } $XML_CREDITOR .= ' '.$CrLf; $XML_CREDITOR .= ' '.round($row_somme, 2).''.$CrLf; $XML_CREDITOR .= ' '.$CrLf; @@ -2031,6 +2058,7 @@ class BonPrelevement extends CommonObject $this->emetteur_code_guichet = $account->code_guichet; $this->emetteur_numero_compte = $account->number; $this->emetteur_number_key = $account->cle_rib; + $this->sepa_xml_pti_in_ctti = (bool) $account->pti_in_ctti; $this->emetteur_iban = $account->iban; $this->emetteur_bic = $account->bic; @@ -2054,7 +2082,7 @@ class BonPrelevement extends CommonObject $RefBon = $obj->ref; if ($type != 'bank-transfer') { - // SEPA Paiement Information of my company for Direct debit + // SEPA Paiement Information of my company for Direct Debit $XML_SEPA_INFO = ''; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.('DD/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; @@ -2125,17 +2153,17 @@ class BonPrelevement extends CommonObject //$XML_SEPA_INFO .= ' False'.$CrLf; $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; $XML_SEPA_INFO .= ' '.$total.''.$CrLf; - /* - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' TRF'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SECU'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - */ + if (!empty($this->sepa_xml_pti_in_ctti) && !empty($format)) { // @TODO Using $format (FRST ou RCUR) in a section for a Credit Transfer looks strange. + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' SEPA' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' CORE' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' ' . $format . '' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + } $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($this->raison_sociale))).''.$CrLf; diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 3f00a4f0660..1049ce4cf1a 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -449,9 +449,17 @@ if ($resql) { // RIB print ''; - print $bac->iban.(($bac->iban && $bac->bic) ? ' / ' : '').$bac->bic; - if ($bac->verif() <= 0) { - print img_warning('Error on default bank number for IBAN : '.$bac->error_message); + if ($bac->id > 0) { + if (!empty($bac->iban) || !empty($bac->bic)) { + print $bac->iban.(($bac->iban && $bac->bic) ? ' / ' : '').$bac->bic; + if ($bac->verif() <= 0) { + print img_warning('Error on default bank number for IBAN : '.$langs->trans($bac->error_message)); + } + } else { + print img_warning($langs->trans("IBANNotDefined")); + } + } else { + print img_warning($langs->trans("NoBankAccountDefined")); } print ''; diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 35c49df8d1e..0722450a610 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -102,7 +102,7 @@ if ($id > 0 || $ref) { //print ''.$langs->trans("Ref").''.$object->getNomUrl(1).''; print ''.$langs->trans("Date").''.dol_print_date($object->datec, 'day').''; - print ''.$langs->trans("Amount").''.price($object->amount).''; + print ''.$langs->trans("Amount").''.price($object->amount).''; if ($object->date_trans <> 0) { $muser = new User($db); @@ -110,7 +110,7 @@ if ($id > 0 || $ref) { print ''.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; + print ' '.$langs->trans("By").' '.$muser->getNomUrl(-1).''; print ''.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print ''; @@ -156,7 +156,9 @@ if ($id > 0 || $ref) { if ($object->type == 'bank-transfer') { $modulepart = 'paymentbybanktransfer'; } - print ''.$relativepath.''; + print ''.$relativepath; + print img_picto('', 'download', 'class="paddingleft"'); + print ''; print ''; print ''; diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index febc4827a94..086b6b76ef8 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -97,7 +97,7 @@ if ($prev_id > 0 || $ref) { //print ''.$langs->trans("Ref").''.$object->getNomUrl(1).''; print ''.$langs->trans("Date").''.dol_print_date($object->datec, 'day').''; - print ''.$langs->trans("Amount").''.price($object->amount).''; + print ''.$langs->trans("Amount").''.price($object->amount).''; if ($object->date_trans <> 0) { $muser = new User($db); @@ -105,7 +105,7 @@ if ($prev_id > 0 || $ref) { print ''.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; + print ' '.$langs->trans("By").' '.$muser->getNomUrl(-1).''; print ''.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print ''; @@ -151,7 +151,9 @@ if ($prev_id > 0 || $ref) { if ($object->type == 'bank-transfer') { $modulepart = 'paymentbybanktransfer'; } - print ''.$relativepath.''; + print ''.$relativepath; + print img_picto('', 'download', 'class="paddingleft"'); + print ''; print ''; print ''; @@ -207,7 +209,7 @@ if ($resql) { print"\n\n"; print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table - print ''; + print '
    '; print ''; print ''; print ''; diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php index 8255c537442..7e2b5cc6669 100644 --- a/htdocs/compta/prelevement/fiche-stat.php +++ b/htdocs/compta/prelevement/fiche-stat.php @@ -91,7 +91,7 @@ if ($prev_id > 0 || $ref) { //print ''; print ''; - print ''; + print ''; if ($object->date_trans <> 0) { $muser = new User($db); @@ -99,7 +99,7 @@ if ($prev_id > 0 || $ref) { print ''; + print ' '.$langs->trans("By").' '.$muser->getNomUrl(-1).''; print ''; @@ -145,7 +145,9 @@ if ($prev_id > 0 || $ref) { if ($object->type == 'bank-transfer') { $modulepart = 'paymentbybanktransfer'; } - print ''.$relativepath.''; + print ''.$relativepath; + print img_picto('', 'download', 'class="paddingleft"'); + print ''; print '
    '.$langs->trans("Line").''.$langs->trans("ThirdParty").''.$langs->trans("Amount").''.$langs->trans("Reason").''.$langs->trans("ToBill").''.$langs->trans("Invoice").'
    '.$langs->trans("Ref").''.$object->getNomUrl(1).'
    '.$langs->trans("Date").''.dol_print_date($object->datec, 'day').'
    '.$langs->trans("Amount").''.price($object->amount).'
    '.$langs->trans("Amount").''.price($object->amount).'
    '.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
    '.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
    '; print '
    '; @@ -173,7 +175,8 @@ if ($prev_id > 0 || $ref) { print load_fiche_titre($langs->trans("StatisticsByLineStatus"), '', ''); print"\n\n"; - print ''; + print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table + print '
    '; print ''; print ''; @@ -184,10 +187,13 @@ if ($prev_id > 0 || $ref) { print $line->LibStatut($row[1], 1); - print ''; - print ''; + + print '
    '.$langs->trans("Status").''.$langs->trans("Amount").'%
    '; - print price($row[0]); + print ''; + print ''; + print price($row[0]); + print ''; if ($object->amount) { print round($row[0] / $object->amount * 100, 2)." %"; } @@ -200,6 +206,8 @@ if ($prev_id > 0 || $ref) { } print "
    "; + print ""; + $db->free($resql); } else { print $db->error().' '.$sql; diff --git a/htdocs/compta/prelevement/index.php b/htdocs/compta/prelevement/index.php index 4aef7e8b9e4..fc640eccc1c 100644 --- a/htdocs/compta/prelevement/index.php +++ b/htdocs/compta/prelevement/index.php @@ -102,7 +102,7 @@ print '
    '; */ $sql = "SELECT f.ref, f.rowid, f.total_ttc, f.fk_statut, f.paye, f.type,"; $sql .= " pfd.date_demande, pfd.amount,"; -$sql .= " s.nom as name, s.email, s.rowid as socid"; +$sql .= " s.nom as name, s.email, s.rowid as socid, s.tva_intra, s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; if (empty($user->rights->societe->client->voir) && !$socid) { @@ -148,6 +148,16 @@ if ($resql) { $thirdpartystatic->id = $obj->socid; $thirdpartystatic->name = $obj->name; $thirdpartystatic->email = $obj->email; + $thirdpartystatic->tva_intra = $obj->tva_intra; + $thirdpartystatic->siren = $obj->idprof1; + $thirdpartystatic->siret = $obj->idprof2; + $thirdpartystatic->ape = $obj->idprof3; + $thirdpartystatic->idprof1 = $obj->idprof1; + $thirdpartystatic->idprof2 = $obj->idprof2; + $thirdpartystatic->idprof3 = $obj->idprof3; + $thirdpartystatic->idprof4 = $obj->idprof4; + $thirdpartystatic->idprof5 = $obj->idprof5; + $thirdpartystatic->idprof6 = $obj->idprof6; print ''; print $invoicestatic->getNomUrl(1, 'withdraw'); @@ -158,7 +168,7 @@ if ($resql) { print ''; print ''; - print price($obj->amount); + print ''.price($obj->amount).''; print ''; print ''; diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php index 342360bd454..30d4f4ce825 100644 --- a/htdocs/compta/resultat/clientfourn.php +++ b/htdocs/compta/resultat/clientfourn.php @@ -934,33 +934,29 @@ if ($modecompta == 'BOOKKEEPING') { if ($modecompta == 'CREANCES-DETTES' || $modecompta == 'RECETTES-DEPENSES') { if ($modecompta == 'CREANCES-DETTES') { - //$column = 's.dateep'; // We use the date of salary - $column = 'p.datep'; + $column = 's.dateep'; // We use the date of end of period of salary + + $sql = "SELECT u.rowid, u.firstname, u.lastname, s.fk_user as fk_user, s.label as label, date_format($column,'%Y-%m') as dm, sum(s.amount) as amount"; + $sql .= " FROM ".MAIN_DB_PREFIX."salary as s"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = s.fk_user"; + $sql .= " WHERE s.entity IN (".getEntity('salary').")"; + if (!empty($date_start) && !empty($date_end)) { + $sql .= " AND $column >= '".$db->idate($date_start)."' AND $column <= '".$db->idate($date_end)."'"; + } + $sql .= " GROUP BY u.rowid, u.firstname, u.lastname, s.fk_user, s.label, dm"; } else { $column = 'p.datep'; - } - $sql = "SELECT u.rowid, u.firstname, u.lastname, s.fk_user as fk_user, p.label as label, date_format($column,'%Y-%m') as dm, sum(p.amount) as amount"; - $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as p"; - $sql .= " INNER JOIN ".MAIN_DB_PREFIX."salary as s ON s.rowid=p.fk_salary"; - $sql .= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid=s.fk_user"; - $sql .= " WHERE s.entity IN (".getEntity('salary').")"; - if (!empty($date_start) && !empty($date_end)) { - $sql .= " AND $column >= '".$db->idate($date_start)."' AND $column <= '".$db->idate($date_end)."'"; + $sql = "SELECT u.rowid, u.firstname, u.lastname, s.fk_user as fk_user, p.label as label, date_format($column,'%Y-%m') as dm, sum(p.amount) as amount"; + $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as p"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."salary as s ON s.rowid = p.fk_salary"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = s.fk_user"; + $sql .= " WHERE p.entity IN (".getEntity('payment_salary').")"; + if (!empty($date_start) && !empty($date_end)) { + $sql .= " AND $column >= '".$db->idate($date_start)."' AND $column <= '".$db->idate($date_end)."'"; + } + $sql .= " GROUP BY u.rowid, u.firstname, u.lastname, s.fk_user, p.label, dm"; } - $sql .= " GROUP BY u.rowid, u.firstname, u.lastname, s.fk_user, p.label, dm"; - - // For backward compatibility with old module salary - $column = 'p.datep'; - $sql .= " UNION "; - $sql .= " SELECT u.rowid, u.firstname, u.lastname, p.fk_user as fk_user, p.label as label, date_format($column,'%Y-%m') as dm, sum(p.amount) as amount"; - $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as p"; - $sql .= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid=p.fk_user"; - $sql .= " WHERE p.entity IN (".getEntity('payment_salary').")"; - if (!empty($date_start) && !empty($date_end)) { - $sql .= " AND $column >= '".$db->idate($date_start)."' AND $column <= '".$db->idate($date_end)."'"; - } - $sql .= " GROUP BY u.rowid, u.firstname, u.lastname, p.fk_user, p.label, dm"; $newsortfield = $sortfield; if ($newsortfield == 's.nom, s.rowid') { @@ -975,7 +971,7 @@ if ($modecompta == 'BOOKKEEPING') { $sql .= $db->order($newsortfield, $sortorder); } - dol_syslog("get payment salaries"); + dol_syslog("get salaries"); $result = $db->query($sql); $subtotal_ht = 0; $subtotal_ttc = 0; diff --git a/htdocs/compta/resultat/index.php b/htdocs/compta/resultat/index.php index 6aab9093c05..ff770acf554 100644 --- a/htdocs/compta/resultat/index.php +++ b/htdocs/compta/resultat/index.php @@ -615,23 +615,31 @@ if (!empty($conf->tax->enabled) && ($modecompta == 'CREANCES-DETTES' || $modecom if (!empty($conf->salaries->enabled) && ($modecompta == 'CREANCES-DETTES' || $modecompta == "RECETTES-DEPENSES")) { if ($modecompta == 'CREANCES-DETTES') { - //$column = 's.dateep'; // we use the date of salary - $column = 'p.datep'; + $column = 's.dateep'; // we use the date of end of period of salary + + $sql = "SELECT s.label as nom, date_format(".$column.",'%Y-%m') as dm, sum(s.amount) as amount"; + $sql .= " FROM ".MAIN_DB_PREFIX."salary as s"; + $sql .= " WHERE s.entity IN (".getEntity('salary').")"; + if (!empty($date_start) && !empty($date_end)) { + $sql .= " AND ".$column." >= '".$db->idate($date_start)."' AND ".$column." <= '".$db->idate($date_end)."'"; + } + $sql .= " GROUP BY s.label, dm"; } if ($modecompta == "RECETTES-DEPENSES") { $column = 'p.datep'; + + $sql = "SELECT p.label as nom, date_format(".$column.",'%Y-%m') as dm, sum(p.amount) as amount"; + $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as p"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."salary as s ON p.fk_salary = s.rowid"; + $sql .= " WHERE p.entity IN (".getEntity('payment_salary').")"; + if (!empty($date_start) && !empty($date_end)) { + $sql .= " AND ".$column." >= '".$db->idate($date_start)."' AND ".$column." <= '".$db->idate($date_end)."'"; + } + $sql .= " GROUP BY p.label, dm"; } $subtotal_ht = 0; $subtotal_ttc = 0; - $sql = "SELECT p.label as nom, date_format(".$column.",'%Y-%m') as dm, sum(p.amount) as amount"; - $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as p, ".MAIN_DB_PREFIX."salary as s"; - $sql .= " WHERE p.fk_salary = s.rowid"; - $sql .= " AND s.entity IN (".getEntity('salary').")"; - if (!empty($date_start) && !empty($date_end)) { - $sql .= " AND ".$column." >= '".$db->idate($date_start)."' AND ".$column." <= '".$db->idate($date_end)."'"; - } - $sql .= " GROUP BY p.label, dm"; dol_syslog("get social salaries payments"); $result = $db->query($sql); diff --git a/htdocs/compta/resultat/result.php b/htdocs/compta/resultat/result.php index 635531ab86b..c296d4037e5 100644 --- a/htdocs/compta/resultat/result.php +++ b/htdocs/compta/resultat/result.php @@ -334,7 +334,7 @@ if ($modecompta == 'CREANCES-DETTES') { //var_dump($result); //$r = $AccCat->calculate($result); - $r = dol_eval($result, 1); + $r = dol_eval($result, 1, 1, '1'); //var_dump($r); print ''.price($r).''; @@ -353,7 +353,7 @@ if ($modecompta == 'CREANCES-DETTES') { $result = strtr($formula, $vars); //$r = $AccCat->calculate($result); - $r = dol_eval($result, 1); + $r = dol_eval($result, 1, 1, 1); print ''.price($r).''; $sommes[$code]['N'] += $r; @@ -367,7 +367,7 @@ if ($modecompta == 'CREANCES-DETTES') { $result = strtr($formula, $vars); //$r = $AccCat->calculate($result); - $r = dol_eval($result, 1); + $r = dol_eval($result, 1, 1, 1); print ''.price($r).''; $sommes[$code]['M'][$k] += $r; @@ -381,7 +381,7 @@ if ($modecompta == 'CREANCES-DETTES') { $result = strtr($formula, $vars); //$r = $AccCat->calculate($result); - $r = dol_eval($result, 1); + $r = dol_eval($result, 1, 1, 1); print ''.price($r).''; $sommes[$code]['M'][$k] += $r; diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index caa04146264..6996c689922 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -139,7 +139,7 @@ class ChargeSociales extends CommonObject { $sql = "SELECT cs.rowid, cs.date_ech"; $sql .= ", cs.libelle as label, cs.fk_type, cs.amount, cs.fk_projet as fk_project, cs.paye, cs.periode, cs.import_key"; - $sql .= ", cs.fk_account, cs.fk_mode_reglement, cs.fk_user"; + $sql .= ", cs.fk_account, cs.fk_mode_reglement, cs.fk_user, note_public, note_private"; $sql .= ", c.libelle as type_label"; $sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as cs"; @@ -172,6 +172,8 @@ class ChargeSociales extends CommonObject $this->amount = $obj->amount; $this->fk_project = $obj->fk_project; $this->fk_user = $obj->fk_user; + $this->note_public = $obj->note_public; + $this->note_private = $obj->note_private; $this->paye = $obj->paye; $this->periode = $this->db->jdate($obj->periode); $this->import_key = $this->import_key; @@ -362,7 +364,7 @@ class ChargeSociales extends CommonObject if (!$error) { if (!$notrigger) { // Call trigger - $result = $this->call_trigger('SOCIALCHARGES_MODIFY', $user); + $result = $this->call_trigger('SOCIALCONTRIBUTION_MODIFY', $user); if ($result < 0) { $error++; } diff --git a/htdocs/compta/sociales/info.php b/htdocs/compta/sociales/info.php index 546a4c711d0..4c49a3008c6 100644 --- a/htdocs/compta/sociales/info.php +++ b/htdocs/compta/sociales/info.php @@ -81,7 +81,7 @@ $object->info($id); $head = tax_prepare_head($object); -print dol_get_fiche_head($head, 'info', $langs->trans("SocialContribution"), -1, 'bill'); +print dol_get_fiche_head($head, 'info', $langs->trans("SocialContribution"), -1, $object->picto); $morehtmlref = '
    '; // Label of social contribution @@ -115,7 +115,7 @@ print '
    '; print '
    '; -print ''; } else { print ''; } } diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 589d09ce1e7..487c075b3a1 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -376,7 +376,7 @@ class Contact extends CommonObject public function load_state_board() { // phpcs:enable - global $user; + global $user, $hookmanager; $this->nb = array(); $clause = "WHERE"; @@ -394,6 +394,12 @@ class Contact extends CommonObject if ($user->socid > 0) { $sql .= " AND sp.fk_soc = ".((int) $user->socid); } + // Add where from hooks + if (is_object($hookmanager)) { + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $this); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; + } $resql = $this->db->query($sql); if ($resql) { @@ -1820,7 +1826,7 @@ class Contact extends CommonObject $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople=".((int) $this->id)." AND entity IN (".getEntity("societe_contact").")"; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople=".((int) $this->id)." AND entity IN (".getEntity("contact").")"; $result = $this->db->query($sql); if (!$result) { diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 66561730829..31b2153c2c8 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -384,7 +384,7 @@ if (!empty($conf->mailing->enabled)) { } // Add fields from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { @@ -405,7 +405,7 @@ if (!empty($search_categ_supplier) && $search_categ_supplier != '-1') { if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; } -$sql .= ' WHERE p.entity IN ('.getEntity('socpeople').')'; +$sql .= ' WHERE p.entity IN ('.getEntity('contact').')'; if (empty($user->rights->societe->client->voir) && !$socid) { //restriction $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR p.fk_soc IS NULL)"; } @@ -543,7 +543,7 @@ if (!empty($socid)) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; // Add order if ($view == "recent") { @@ -767,7 +767,7 @@ $moreforfilter .= ''; print '
    '; print $moreforfilter; $parameters = array('type'=>$type); -$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print '
    '; @@ -910,7 +910,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook $parameters = array('arrayfields'=>$arrayfields); -$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation if (!empty($arrayfields['p.datec']['checked'])) { @@ -1018,7 +1018,7 @@ $parameters = array( 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, ); -$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (!empty($arrayfields['p.datec']['checked'])) { print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap '); @@ -1255,7 +1255,7 @@ while ($i < min($num, $limit)) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation if (!empty($arrayfields['p.datec']['checked'])) { @@ -1312,7 +1312,7 @@ while ($i < min($num, $limit)) { $db->free($resql); $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); -$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print "
    '; +print '
    '; dol_print_object_info($object); print '
    '; diff --git a/htdocs/compta/sociales/note.php b/htdocs/compta/sociales/note.php new file mode 100644 index 00000000000..cf9d0cbdec5 --- /dev/null +++ b/htdocs/compta/sociales/note.php @@ -0,0 +1,135 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/compta/sociales/note.php + * \ingroup tax + * \brief Tab for notes on Taxes + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +if (!empty($conf->projet->enabled)) { + include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} + +// Load translation files required by the page +$langs->loadLangs(array('compta', 'bills')); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$object = new ChargeSociales($db); +if ($id > 0) { + $object->fetch($id); +} + +// Security check +$socid = GETPOST('socid', 'int'); +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'tax', $object->id, 'chargesociales', 'charges'); + +$permissiontoread = $user->rights->tax->charges->lire; +$permissiontoadd = $user->rights->tax->charges->creer; +$permissionnote = $user->rights->tax->charges->creer; // Used by the include of actions_setnotes.inc.php + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once +} + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans("SocialContribution").' - '.$langs->trans("Note"); +$help_url = 'EN:Module_Taxes_and_social_contributions|FR:Module Taxes et dividendes|ES:Módulo Impuestos y cargas sociales (IVA, impuestos)'; +llxHeader('', $title, $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = tax_prepare_head($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("SocialContribution"), -1, $object->picto); + + $morehtmlref = '
    '; + // Label of social contribution + $morehtmlref .= $form->editfieldkey("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', 0, 1); + $morehtmlref .= $form->editfieldval("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', null, null, '', 1); + // Project + if (!empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
    '.$langs->trans('Project').' : '; + if (!empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title); + } + } else { + $morehtmlref .= ''; + } + } + $morehtmlref .= '
    '; + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + //$object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); + + + print '
    '; + print '
    '; + + + $cssclass = "titlefield"; + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + + print '
    '; + + print dol_get_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/compta/stats/casoc.php b/htdocs/compta/stats/casoc.php index 76dbc56beef..0bef7ff555a 100644 --- a/htdocs/compta/stats/casoc.php +++ b/htdocs/compta/stats/casoc.php @@ -57,6 +57,7 @@ $socid = GETPOST('socid', 'int'); // Category $selected_cat = (int) GETPOST('search_categ', 'int'); +if ($selected_cat == -1) $selected_cat = ''; $subcat = false; if (GETPOST('subcat', 'alpha') === 'yes') { $subcat = true; diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example index 8cd46352ac9..487576ed058 100644 --- a/htdocs/conf/conf.php.example +++ b/htdocs/conf/conf.php.example @@ -204,7 +204,7 @@ $dolibarr_main_authentication='dolibarr'; // $dolibarr_main_auth_ldap_servertype='openldap'; // openldap, activedirectory or egroupware // $dolibarr_main_auth_ldap_login_attribute='loginfield'; // Ex: uid or samaccountname for active directory // $dolibarr_main_auth_ldap_dn='ou=users,dc=my-domain,dc=com'; // Ex: ou=users,dc=my-domain,dc=com -// $dolibarr_main_auth_ldap_filter = ''; // If defined, two previous parameters are not used to find a user into LDAP. Ex: (uid=%1%) or &(uid=%1%)(isMemberOf=cn=Sales,ou=Groups,dc=opencsi,dc=com). +// $dolibarr_main_auth_ldap_filter = ''; // If defined, the two previous parameters (dolibarr_main_auth_ldap_login_attribute and dolibarr_main_auth_ldap_dn) are not used to find a user into LDAP. Instead we use this search string. Ex: (uid=%1%) or &(uid=%1%)(isMemberOf=cn=Sales,ou=Groups,dc=opencsi,dc=com). // $dolibarr_main_auth_ldap_admin_login=''; // Required only if anonymous bind disabled. Ex: cn=admin,dc=example,dc=com // $dolibarr_main_auth_ldap_admin_pass=''; // Required only if anonymous bind disabled. Ex: secret // $dolibarr_main_auth_ldap_debug='false'; diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index bd0d694eb57..ee1d10181ca 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -520,6 +520,29 @@ if (empty($reshook)) { } } + // Update extrafields + if ($action == 'update_extras' && ! empty($user->rights->societe->contact->creer)) { + $object->oldcopy = dol_clone($object); + + // Fill array 'array_options' with data from update form + $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml')); + if ($ret < 0) { + $error++; + } + + if (!$error) { + $result = $object->insertExtraFields('CONTACT_MODIFY'); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } + + if ($error) { + $action = 'edit_extras'; + } + } + // Actions to send emails $triggersendname = 'CONTACT_SENTBYMAIL'; $paramname = 'id'; @@ -601,7 +624,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { */ $object->canvas = $canvas; - $object->state_id = GETPOST("state_id"); + $object->state_id = GETPOST("state_id", "int"); // We set country_id, country_code and label for the selected country $object->country_id = GETPOST("country_id") ? GETPOST("country_id", "int") : (empty($objsoc->country_id) ? $mysoc->country_id : $objsoc->country_id); @@ -674,7 +697,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print '
    '; - print img_picto('', 'company').$form->select_company($socid, 'socid', '', 'SelectThirdParty'); + print img_picto('', 'company').$form->select_company($socid, 'socid', '', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx'); print '
    "; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 87d6b98475b..7265a69d1af 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -2027,62 +2027,73 @@ if ($action == 'create') { $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { + $params = array( + 'attr' => array( + 'title' => '', + 'class' => 'classfortooltip' + ) + ); + // Send if (empty($user->socid)) { if ($object->statut == 1) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->contrat->creer)) { - print ''; + print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle', '', true, $params); } else { - print ''; + print dolGetButtonAction($langs->trans('SendMail'), '', 'default', '#', '', false, $params); } } } if ($object->statut == 0 && $nbofservices) { if ($user->rights->contrat->creer) { - print ''; + print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken(), '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotEnoughPermissions"); + print dolGetButtonAction($langs->trans('Validate'), '', 'default', '#', '', false, $params); } } if ($object->statut == 1) { if ($user->rights->contrat->creer) { - print ''; + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken(), '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotEnoughPermissions"); + print dolGetButtonAction($langs->trans('Modify'), '', 'default', '#', '', false, $params); } } if (!empty($conf->commande->enabled) && $object->statut > 0 && $object->nbofservicesclosed < $nbofservices) { $langs->load("orders"); if ($user->rights->commande->creer) { - print ''; + print dolGetButtonAction($langs->trans('CreateOrder'), '', 'default', DOL_URL_ROOT.'/commande/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id, '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotEnoughPermissions"); + print dolGetButtonAction($langs->trans('CreateOrder'), '', 'default', '#', '', false, $params); } } if (!empty($conf->facture->enabled) && $object->statut > 0) { $langs->load("bills"); if ($user->rights->facture->creer) { - print ''; + print dolGetButtonAction($langs->trans('CreateBill'), '', 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id, '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotEnoughPermissions"); + print dolGetButtonAction($langs->trans('CreateBill'), '', 'default', '#', '', false, $params); } } if ($object->nbofservicesclosed > 0 || $object->nbofserviceswait > 0) { if ($user->rights->contrat->activer) { - print ''; + print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=activate&token='.newToken(), '', true, $params); } else { - print ''; + print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', '#', '', false, $params); } } if ($object->nbofservicesclosed < $nbofservices) { if ($user->rights->contrat->desactiver) { - print ''; + print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=close&token='.newToken(), '', true, $params); } else { - print ''; + print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', '#', '', false, $params); } //if (! $numactive) @@ -2104,16 +2115,17 @@ if ($action == 'create') { // Clone if ($user->rights->contrat->creer) { - print ''; + print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&token='.newToken(), '', true, $params); } // On peut supprimer entite si // - Droit de creer + mode brouillon (erreur creation) // - Droit de supprimer if (($user->rights->contrat->creer && $object->statut == $object::STATUS_DRAFT) || $user->rights->contrat->supprimer) { - print ''; + print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotAllowed"); + print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), '', false, $params); } } diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 4e4437c1b2c..d85ad51946a 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -233,10 +233,10 @@ class Contrat extends CommonObject 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40), 'date_contrat' =>array('type'=>'datetime', 'label'=>'Date contrat', 'enabled'=>1, 'visible'=>-1, 'position'=>45), 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>75), - 'fk_commercial_signature' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk commercial signature', 'enabled'=>1, 'visible'=>-1, 'position'=>80), - 'fk_commercial_suivi' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk commercial suivi', 'enabled'=>1, 'visible'=>-1, 'position'=>85), - 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'fk_commercial_signature' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'SaleRepresentative Signature', 'enabled'=>1, 'visible'=>-1, 'position'=>80), + 'fk_commercial_suivi' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'SaleRepresentative follower', 'enabled'=>1, 'visible'=>-1, 'position'=>85), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90), 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105), 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115), @@ -245,7 +245,7 @@ class Contrat extends CommonObject 'ref_customer' =>array('type'=>'varchar(50)', 'label'=>'Ref customer', 'enabled'=>1, 'visible'=>-1, 'position'=>130), 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>140), - 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Closed')) + 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'notnull'=>1, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Closed')) ); // END MODULEBUILDER PROPERTIES @@ -751,15 +751,14 @@ class Contrat extends CommonObject * Load lines array into this->lines. * This set also nbofserviceswait, nbofservicesopened, nbofservicesexpired and nbofservicesclosed * - * @param int $only_product Return only physical products - * @param int $loadalsotranslation Return translation for products - * - * @return ContratLigne[] Return array of contract lines + * @param int $only_services 0=Default, 1=Force only services (depending on setup, we may also have physical products in a contract) + * @param int $loadalsotranslation 0=Default, 1=Load also translations of product descriptions + * @return ContratLigne[] Return array of contract lines */ - public function fetch_lines($only_product = 0, $loadalsotranslation = 0) + public function fetch_lines($only_services = 0, $loadalsotranslation = 0) { // phpcs:enable - global $langs, $conf, $extrafields; + global $langs, $conf; $this->nbofservices = 0; $this->nbofserviceswait = 0; @@ -773,13 +772,15 @@ class Contrat extends CommonObject $now = dol_now(); + /* if (!is_object($extrafields)) { require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); } $line = new ContratLigne($this->db); - $extrafields->fetch_name_optionals_label($line->table_element, true); + $extrafields->fetch_name_optionals_label(ContratLigne::$table_element, true); + */ $this->lines = array(); $pos = 0; @@ -802,6 +803,9 @@ class Contrat extends CommonObject $sql .= " d.product_type as type"; $sql .= " FROM ".MAIN_DB_PREFIX."contratdet as d LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid"; $sql .= " WHERE d.fk_contrat = ".((int) $this->id); + if ($only_services == 1) { + $sql .= " AND d.product_type = 1"; + } $sql .= " ORDER by d.rowid ASC"; dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); @@ -814,6 +818,7 @@ class Contrat extends CommonObject $objp = $this->db->fetch_object($result); $line = new ContratLigne($this->db); + $line->id = $objp->rowid; $line->ref = $objp->rowid; $line->fk_contrat = $objp->fk_contrat; @@ -840,7 +845,7 @@ class Contrat extends CommonObject $line->type = $objp->type; $line->fk_fournprice = $objp->fk_fournprice; - $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht); + $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $objp->fk_fournprice, $objp->pa_ht); $line->pa_ht = $marginInfos[0]; $line->fk_user_author = $objp->fk_user_author; @@ -882,6 +887,7 @@ class Contrat extends CommonObject } $this->lines[$pos] = $line; + $this->lines_id_index_mapper[$line->id] = $pos; //dol_syslog("1 ".$line->desc); @@ -1792,7 +1798,7 @@ class Contrat extends CommonObject if (empty($error)) { // Call trigger - $result = $this->call_trigger('LINECONTRACT_UPDATE', $user); + $result = $this->call_trigger('LINECONTRACT_MODIFY', $user); if ($result < 0) { $this->db->rollback(); return -3; @@ -2130,19 +2136,27 @@ class Contrat extends CommonObject /** * Return list of other contracts for same company than current contract * - * @param string $option 'all' or 'others' - * @return array|int Array of contracts id or <0 if error + * @param string $option 'all' or 'others' + * @param array $status sort contracts having these status + * @param array $product_categories sort contracts containing these product categories + * @param array $line_status sort contracts where lines have these status + * @return array|int Array of contracts id or <0 if error */ - public function getListOfContracts($option = 'all') + public function getListOfContracts($option = 'all', $status = [], $product_categories = [], $line_status = []) { $tab = array(); $sql = "SELECT c.rowid, c.ref"; $sql .= " FROM ".MAIN_DB_PREFIX."contrat as c"; - $sql .= " WHERE fk_soc =".((int) $this->socid); - if ($option == 'others') { - $sql .= " AND c.rowid <> ".((int) $this->id); + if (!empty($product_categories)) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."contratdet as cd ON cd.fk_contrat = c.rowid"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON cp.fk_product = cd.fk_product AND cp.fk_categorie IN (".$this->db->sanitize(implode(', ', $product_categories)).")"; } + $sql .= " WHERE c.fk_soc =".((int) $this->socid); + $sql .= ($option == 'others') ? " AND c.rowid <> ".((int) $this->id) : ""; + $sql .= (!empty($status)) ? " AND c.statut IN (".$this->db->sanitize(implode(', ', $status)).")" : ""; + $sql .= (!empty($line_status)) ? " AND cd.statut IN (".$this->db->sanitize(implode(', ', $line_status)).")" : ""; + $sql .= " GROUP BY c.rowid"; dol_syslog(get_class($this)."::getOtherContracts()", LOG_DEBUG); $resql = $this->db->query($sql); @@ -2460,6 +2474,23 @@ class Contrat extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'contratdet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Load an object from its id and create a new one in database * @@ -2750,8 +2781,8 @@ class ContratLigne extends CommonObjectLine //'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115), //'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>120), //'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>125), - 'fk_user_ouverture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserOpen', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), - 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserCloture', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), + 'fk_user_ouverture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserStartingService', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), + 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosingService', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 4=>'Open', 5=>'Closed')) ); // END MODULEBUILDER PROPERTIES @@ -3190,7 +3221,7 @@ class ContratLigne extends CommonObjectLine if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('LINECONTRACT_UPDATE', $user); + $result = $this->call_trigger('LINECONTRACT_MODIFY', $user); if ($result < 0) { $error++; $this->db->rollback(); diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index e6446e3585b..6c23cfcf720 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -338,37 +338,61 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { } } // Add where from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters); // Note that $action and $object may have been modified by hook +$parameters = array('search_dfyear' => $search_dfyear, 'search_op2df'=>$search_op2df); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -if ($search_dfyear > 0 && $search_op2df) { - if ($search_op2df == '<=') { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."'"; - } elseif ($search_op2df == '>=') { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; - } else { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; +// Add HAVING from hooks +$parameters = array('search_dfyear' => $search_dfyear, 'search_op2df'=>$search_op2df); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +if (empty($reshook)) { + if ($search_dfyear > 0 && $search_op2df) { + if ($search_op2df == '<=') { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."'"; + } elseif ($search_op2df == '>=') { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; + } else { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; + } } } -$sql .= $db->order($sortfield, $sortorder); - -$totalnboflines = 0; -$result = $db->query($sql); -if ($result) { - $totalnboflines = $db->num_rows($result); -} +$sql .= $hookmanager->resPrint; $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + //$result = $db->query($sql); + //$nbtotalofrecords = $db->num_rows($result); + + if ($search_dfyear > 0 && $search_op2df) { + $resql = $db->query($sql, 0, 'auto', 1); + while ($db->fetch_object($resql)) { + if (empty($nbtotalofrecords)) { + $nbtotalofrecords = 1; // We can't make +1 because init value is '' + } else { + $nbtotalofrecords++; + } + } + } else { + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'contratdet as cd ON c.rowid = cd.fk_contrat/', '', $sqlforcount); + $sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=cd.fk_product/', '', $sqlforcount); + $sqlforcount = preg_replace('/AND cp.fk_categorie = '.((int) $search_product_category).'/', '', $sqlforcount); + $sqlforcount = preg_replace('/GROUP BY.*$/', '', $sqlforcount); + + $resql = $db->query($sqlforcount); + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } } -$sql .= $db->plimit($limit + 1, $offset); +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} $resql = $db->query($sql); if (!$resql) { @@ -508,7 +532,7 @@ print ''; print ''; print ''; -print_barre_liste($langs->trans("ListOfContracts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $totalnboflines, 'contract', 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($langs->trans("ListOfContracts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'contract', 0, $newcardbutton, '', $limit, 0, 0, 1); $topicmail = "SendContractRef"; $modelmail = "contract"; diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 39dfe336a31..adf7a4b6ed7 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -326,25 +326,25 @@ if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue != -1 && $fil $sql .= " AND cd.date_ouverture_prevue ".$filter_opouvertureprevue." '".$db->idate($filter_dateouvertureprevue_start)."'"; } if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_dateouvertureprevue_end)."'"; + $sql .= " AND cd.date_ouverture_prevue ".$filter_opouvertureprevue." '".$db->idate($filter_dateouvertureprevue_start)."' AND '".$db->idate($filter_dateouvertureprevue_end)."'"; } if (!empty($filter_op1) && $filter_op1 != -1 && $filter_op1 != ' BETWEEN ' && $filter_date1_start != '') { $sql .= " AND cd.date_ouverture ".$filter_op1." '".$db->idate($filter_date1_start)."'"; } if (!empty($filter_op1) && $filter_op1 == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_date1_end)."'"; + $sql .= " AND cd.date_ouverture ".$filter_op1." '".$db->idate($filter_date1_start)."' AND '".$db->idate($filter_date1_end)."'"; } if (!empty($filter_op2) && $filter_op2 != -1 && $filter_op2 != ' BETWEEN ' && $filter_date2_start != '') { $sql .= " AND cd.date_fin_validite ".$filter_op2." '".$db->idate($filter_date2_start)."'"; } if (!empty($filter_op2) && $filter_op2 == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_date2_end)."'"; + $sql .= " AND cd.date_fin_validite ".$filter_op2." '".$db->idate($filter_date2_start)."' AND '".$db->idate($filter_date2_end)."'"; } if (!empty($filter_opcloture) && $filter_opcloture != ' BETWEEN ' && $filter_opcloture != -1 && $filter_datecloture_start != '') { $sql .= " AND cd.date_cloture ".$filter_opcloture." '".$db->idate($filter_datecloture_start)."'"; } if (!empty($filter_opcloture) && $filter_opcloture == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_datecloture_end)."'"; + $sql .= " AND cd.date_cloture ".$filter_opcloture." '".$db->idate($filter_datecloture_start)."' AND '".$db->idate($filter_datecloture_end)."'"; } // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index cdbda7a17b8..5f178da19bc 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; @@ -49,7 +49,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { getNomUrl(1); ?> date_contrat, 'day'); ?> - update($user); if ($result > 0) { $action = 'view'; + $urltogo = $backtopage ? str_replace('__ID__', $result, $backtopage) : $backurlforlist; + $urltogo = preg_replace('/--IDFORBACKTOPAGE--/', $object->id, $urltogo); // New method to autoselect project after a New on another form object creation + if ($urltogo) { + header("Location: " . $urltogo); + exit; + } } else { $error++; // Creation KO diff --git a/htdocs/core/actions_dellink.inc.php b/htdocs/core/actions_dellink.inc.php index fbecacce515..9bf56b2f876 100644 --- a/htdocs/core/actions_dellink.inc.php +++ b/htdocs/core/actions_dellink.inc.php @@ -32,7 +32,7 @@ $addlinkid = GETPOST('idtolinkto', 'int'); $addlinkref = GETPOST('reftolinkto', 'alpha'); $cancellink = GETPOST('cancel', 'alpha'); -// Link invoice to order +// Link object to another object if ($action == 'addlink' && !empty($permissiondellink) && !$cancellink && $id > 0 && $addlinkid > 0) { $object->fetch($id); $object->fetch_thirdparty(); @@ -61,7 +61,7 @@ if ($action == 'addlinkbyref' && ! empty($permissiondellink) && !$cancellink && } } -// Delete link +// Delete link in table llx_element_element if ($action == 'dellink' && !empty($permissiondellink) && !$cancellink && $dellinkid > 0) { $result = $object->deleteObjectLinked(0, '', 0, '', $dellinkid); if ($result < 0) { diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index af92138c5d5..22e5bb3f1a6 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -635,6 +635,7 @@ if ($massaction == 'confirm_createbills') { // Create bills from orders. $TFact = array(); $TFactThird = array(); + $TFactThirdNbLines = array(); $nb_bills_created = 0; $lastid= 0; @@ -685,6 +686,7 @@ if ($massaction == 'confirm_createbills') { // Create bills from orders. $lastid = $objecttmp->id; $TFactThird[$cmd->socid] = $objecttmp; + $TFactThirdNbLines[$cmd->socid] = 0; //init nblines to have lines ordered by expedition and rang } else { $langs->load("errors"); $errors[] = $cmd->ref.' : '.$langs->trans($objecttmp->error); @@ -774,6 +776,11 @@ if ($massaction == 'confirm_createbills') { // Create bills from orders. $objecttmp->context['createfromclone']; + $rang = $lines[$i]->rang; + //there may already be rows from previous orders + if (!empty($createbills_onebythird)) + $rang = $TFactThirdNbLines[$cmd->socid]; + $result = $objecttmp->addline( $desc, $lines[$i]->subprice, @@ -791,7 +798,7 @@ if ($massaction == 'confirm_createbills') { // Create bills from orders. 'HT', 0, $product_type, - $lines[$i]->rang, + $rang, $lines[$i]->special_code, $objecttmp->origin, $lines[$i]->rowid, @@ -806,6 +813,8 @@ if ($massaction == 'confirm_createbills') { // Create bills from orders. ); if ($result > 0) { $lineid = $result; + if (!empty($createbills_onebythird)) //increment rang to keep order + $TFactThirdNbLines[$rcp->socid]++; } else { $lineid = 0; $error++; @@ -1209,6 +1218,26 @@ if (!$error && $massaction == 'validate' && $permissiontoadd) { setEventMessages($langs->trans('ErrorMassValidationNotAllowedWhenStockIncreaseOnAction'), null, 'errors'); $error++; } + if ($objecttmp->element == 'facture') { + if (!empty($toselect) && !empty($conf->global->INVOICE_CHECK_POSTERIOR_DATE)) { + // order $toselect by date + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture"; + $sql .= " WHERE rowid IN (".$db->sanitize(implode(",", $toselect)).")"; + $sql .= " ORDER BY datef"; + + $resql = $db->query($sql); + if ($resql) { + $toselectnew = []; + while ( !empty($arr = $db->fetch_row($resql))) { + $toselectnew[] = $arr[0]; + } + $toselect = (empty($toselectnew)) ? $toselect : $toselectnew; + } else { + dol_print_error($db); + $error++; + } + } + } if (!$error) { $db->begin(); @@ -1246,9 +1275,9 @@ if (!$error && $massaction == 'validate' && $permissiontoadd) { $model = $objecttmp->model_pdf; $ret = $objecttmp->fetch($objecttmp->id); // Reload to get new records // To be sure vars is defined - $hidedetails = !empty($hidedetails) ? $hidedetails : 0; - $hidedesc = !empty($hidedesc) ? $hidedesc : 0; - $hideref = !empty($hideref) ? $hideref : 0; + $hidedetails = !empty($hidedetails) ? $hidedetails : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0); + $hidedesc = !empty($hidedesc) ? $hidedesc : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0); + $hideref = !empty($hideref) ? $hideref : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0); $moreparams = !empty($moreparams) ? $moreparams : null; $result = $objecttmp->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); @@ -1397,13 +1426,13 @@ if (!$error && $massaction == 'generate_doc' && $permissiontoread) { // To be sure vars is defined if (empty($hidedetails)) { - $hidedetails = 0; + $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0); } if (empty($hidedesc)) { - $hidedesc = 0; + $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0); } if (empty($hideref)) { - $hideref = 0; + $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0); } if (empty($moreparams)) { $moreparams = null; @@ -1579,17 +1608,20 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ $nbok = 0; foreach ($toselect as $toselectid) { $result = $objecttmp->fetch($toselectid); - if ($result>0) { - if ($objecttmp->statut == Holiday::STATUS_VALIDATED && $user->id == $objecttmp->fk_validator) { + if ($result > 0) { + if ($objecttmp->statut != Holiday::STATUS_VALIDATED) { + setEventMessages($langs->trans('StatusOfRefMustBe', $objecttmp->ref, $langs->transnoentitiesnoconv('Validated')), null, 'warnings'); + continue; + } + if ($user->id == $objecttmp->fk_validator) { $objecttmp->oldcopy = dol_clone($objecttmp); $objecttmp->date_valid = dol_now(); $objecttmp->fk_user_valid = $user->id; $objecttmp->statut = Holiday::STATUS_APPROVED; - $db->begin(); - $verif = $objecttmp->approve($user); + if ($verif <= 0) { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); $error++; @@ -1664,14 +1696,9 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ } } } - - if (!$error) { - $db->commit(); - $nbok++; - } else { - $db->rollback(); - $action = ''; - } + } else { + $langs->load("errors"); + setEventMessages($langs->trans('ErrorNotApproverForHoliday', $objecttmp->ref), null, 'errors'); } } else { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); @@ -1683,7 +1710,7 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ if (!$error) { if ($nbok > 1) { setEventMessages($langs->trans("RecordsApproved", $nbok), null, 'mesgs'); - } else { + } elseif ($nbok == 1) { setEventMessages($langs->trans("RecordAproved"), null, 'mesgs'); } $db->commit(); diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index d31f8d60dfc..f0ef66eb78b 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -109,7 +109,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO } $subject = ''; - $actionmsg = ''; + //$actionmsg = ''; $actionmsg2 = ''; $langs->load('mails'); @@ -317,7 +317,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO if ($action == 'send' || $action == 'relance') { $actionmsg2 = $langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($from, 4, 0, 1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($sendto, 4, 0, 1); - if ($message) { + /*if ($message) { $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from); $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto)); if ($sendtocc) { @@ -326,7 +326,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); $actionmsg = dol_concatdesc($actionmsg, $message); - } + }*/ } // Create form object @@ -376,7 +376,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO $object->socid = $sendtosocid; // To link to a company $object->sendtoid = $sendtoid; // To link to contact-addresses. This is an array. $object->actiontypecode = $actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...) - $object->actionmsg = $actionmsg; // Long text (@todo Replace this with $message, we already have details of email in dedicated properties) + $object->actionmsg = $message; // Long text $object->actionmsg2 = $actionmsg2; // Short text ($langs->transnoentities('MailSentBy')...); $object->trackid = $trackid; diff --git a/htdocs/core/ajax/objectonoff.php b/htdocs/core/ajax/objectonoff.php index 5bac89345ce..ffd05c4747e 100644 --- a/htdocs/core/ajax/objectonoff.php +++ b/htdocs/core/ajax/objectonoff.php @@ -88,7 +88,10 @@ if (($action == 'set') && !empty($id)) { $triggerkey = strtoupper($element).'_UPDATE'; // Special case if ($triggerkey == 'SOCIETE_UPDATE') { - $triggerkey = 'COMPANY_UPDATE'; + $triggerkey = 'COMPANY_MODIFY'; + } + if ($triggerkey == 'PRODUCT_UPDATE') { + $triggerkey = 'PRODUCT_MODIFY'; } $object->setValueFrom($field, $value, $tablename, $id, $format, '', $user, $triggerkey); diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php index 9853faa8585..383f9a0c041 100644 --- a/htdocs/core/ajax/row.php +++ b/htdocs/core/ajax/row.php @@ -81,8 +81,6 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) $perm = 1; } elseif ($table_element_line == 'facturedet_rec' && $user->rights->facture->creer) { $perm = 1; - } elseif ($table_element_line == 'ecm_files' && $user->rights->ecm->creer) { - $perm = 1; } elseif ($table_element_line == 'emailcollector_emailcollectoraction' && $user->admin) { $perm = 1; } elseif ($table_element_line == 'bom_bomline' && $user->rights->bom->write) { @@ -97,10 +95,20 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) $perm = 1; } elseif ($table_element_line == 'facture_fourn_det_rec' && $user->rights->fournisseur->facture->creer) { $perm = 1; - } elseif ($table_element_line == 'ecm_files' && $fk_element == 'fk_product' && (!empty($user->rights->produit->creer) || !empty($user->rights->service->creer))) { - $perm = 1; - } elseif ($table_element_line == 'ecm_files' && $fk_element == 'fk_ticket' && !empty($user->rights->ticket->write)) { + } elseif ($table_element_line == 'product_attribute_value' && $fk_element == 'fk_product_attribute' && ($user->rights->produit->lire || $user->rights->service->lire)) { $perm = 1; + } elseif ($table_element_line == 'ecm_files') { // Used when of page "documents.php" + if (!empty($user->rights->ecm->creer)) { + $perm = 1; + } elseif ($fk_element == 'fk_product' && (!empty($user->rights->produit->creer) || !empty($user->rights->service->creer))) { + $perm = 1; + } elseif ($fk_element == 'fk_ticket' && !empty($user->rights->ticket->write)) { + $perm = 1; + } elseif ($fk_element == 'fk_holiday' && !empty($user->rights->holiday->write)) { + $perm = 1; + } elseif ($fk_element == 'fk_soc' && !empty($user->rights->societe->creer)) { + $perm = 1; + } } elseif ($table_element_line == 'product_association' && $fk_element == 'fk_product' && (!empty($user->rights->produit->creer) || !empty($user->rights->service->creer))) { $perm = 1; } elseif ($table_element_line == 'projet_task' && $fk_element == 'fk_projet' && $user->rights->projet->creer) { diff --git a/htdocs/core/boxes/box_birthdays.php b/htdocs/core/boxes/box_birthdays.php index 62cfaa590ab..41e51eee45e 100644 --- a/htdocs/core/boxes/box_birthdays.php +++ b/htdocs/core/boxes/box_birthdays.php @@ -131,7 +131,7 @@ class box_birthdays extends ModeleBoxes } if ($num == 0) { - $this->info_box_contents[$line][0] = array('td' => 'class="center opacitymedium"', 'text'=>$langs->trans("None")); + $this->info_box_contents[$line][0] = array('td' => 'class="center"', 'text' => ''.$langs->trans("None").''); } $this->db->free($result); @@ -144,8 +144,8 @@ class box_birthdays extends ModeleBoxes } } else { $this->info_box_contents[0][0] = array( - 'td' => 'class="nohover opacitymedium left"', - 'text' => $langs->trans("ReadPermissionNotAllowed") + 'td' => 'class="nohover left"', + 'text' => ''.$langs->trans("ReadPermissionNotAllowed").'' ); } } diff --git a/htdocs/core/boxes/box_birthdays_members.php b/htdocs/core/boxes/box_birthdays_members.php index 5e772ff3593..6138664db2d 100644 --- a/htdocs/core/boxes/box_birthdays_members.php +++ b/htdocs/core/boxes/box_birthdays_members.php @@ -128,7 +128,7 @@ class box_birthdays_members extends ModeleBoxes } if ($num == 0) { - $this->info_box_contents[$line][0] = array('td' => 'class="center opacitymedium"', 'text'=>$langs->trans("None")); + $this->info_box_contents[$line][0] = array('td' => 'class="center"', 'text' => ''.$langs->trans("None").''); } $this->db->free($result); @@ -141,8 +141,8 @@ class box_birthdays_members extends ModeleBoxes } } else { $this->info_box_contents[0][0] = array( - 'td' => 'class="nohover opacitymedium left"', - 'text' => $langs->trans("ReadPermissionNotAllowed") + 'td' => 'class="nohover left"', + 'text' => ''.$langs->trans("ReadPermissionNotAllowed").'' ); } } diff --git a/htdocs/core/boxes/box_clients.php b/htdocs/core/boxes/box_clients.php index 74ba5a9d4c9..2afa630860b 100644 --- a/htdocs/core/boxes/box_clients.php +++ b/htdocs/core/boxes/box_clients.php @@ -76,7 +76,7 @@ class box_clients extends ModeleBoxes */ public function loadBox($max = 5) { - global $user, $langs, $conf; + global $user, $langs, $hookmanager; $langs->load("boxes"); $this->max = $max; @@ -100,9 +100,15 @@ class box_clients extends ModeleBoxes if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($user->socid) { - $sql .= " AND s.rowid = ".((int) $user->socid); + // Add where from hooks + $parameters = array('socid' => $user->socid, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $thirdpartystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($user->socid > 0) { + $sql .= " AND s.rowid = ".((int) $user->socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.tms DESC"; $sql .= $this->db->plimit($max, 0); diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index 0d774faf569..b2ba608d689 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -74,11 +74,15 @@ class box_contacts extends ModeleBoxes */ public function loadBox($max = 5) { - global $user, $langs, $conf; + global $user, $langs, $conf, $hookmanager; + $langs->load("boxes"); $this->max = $max; + $contactstatic = new Contact($this->db); + $societestatic = new Societe($this->db); + $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedContacts", $max)); if ($user->rights->societe->lire && $user->rights->societe->contact->lire) { @@ -106,13 +110,19 @@ class box_contacts extends ModeleBoxes if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } - $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($user->socid) { - $sql .= " AND sp.fk_soc = ".((int) $user->socid); + // Add where from hooks + $parameters = array('socid' => $user->socid, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $contactstatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($user->socid > 0) { + $sql .= " AND sp.fk_soc = ".((int) $user->socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY sp.tms DESC"; $sql .= $this->db->plimit($max, 0); @@ -120,9 +130,6 @@ class box_contacts extends ModeleBoxes if ($result) { $num = $this->db->num_rows($result); - $contactstatic = new Contact($this->db); - $societestatic = new Societe($this->db); - $line = 0; while ($line < $num) { $objp = $this->db->fetch_object($result); diff --git a/htdocs/core/boxes/box_dolibarr_state_board.php b/htdocs/core/boxes/box_dolibarr_state_board.php index 0381b493448..24be4100dab 100644 --- a/htdocs/core/boxes/box_dolibarr_state_board.php +++ b/htdocs/core/boxes/box_dolibarr_state_board.php @@ -79,6 +79,9 @@ class box_dolibarr_state_board extends ModeleBoxes if (empty($user->socid) && empty($conf->global->MAIN_DISABLE_GLOBAL_BOXSTATS)) { $hookmanager = new HookManager($this->db); $hookmanager->initHooks(array('index')); + $object = new stdClass; + $action = ''; + $hookmanager->executeHooks('addStatisticLine', array(), $object, $action); $boxstatItems = array(); $boxstatFromHook = ''; $boxstatFromHook = $hookmanager->resPrint; diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php index 4f297135b26..3cb1f570a30 100644 --- a/htdocs/core/boxes/box_fournisseurs.php +++ b/htdocs/core/boxes/box_fournisseurs.php @@ -71,7 +71,7 @@ class box_fournisseurs extends ModeleBoxes */ public function loadBox($max = 5) { - global $conf, $user, $langs; + global $conf, $user, $langs, $hookmanager; $langs->load("boxes"); $this->max = $max; @@ -95,9 +95,15 @@ class box_fournisseurs extends ModeleBoxes if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($user->socid) { - $sql .= " AND s.rowid = ".((int) $user->socid); + // Add where from hooks + $parameters = array('socid' => $user->socid, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $thirdpartystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($user->socid > 0) { + $sql .= " AND s.rowid = ".((int) $user->socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.tms DESC "; $sql .= $this->db->plimit($max, 0); diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php index 04d785799af..adcc750a6a8 100644 --- a/htdocs/core/boxes/box_graph_product_distribution.php +++ b/htdocs/core/boxes/box_graph_product_distribution.php @@ -150,7 +150,7 @@ class box_graph_product_distribution extends ModeleBoxes $userid = 0; // No filter on user creation $WIDTH = ($nbofgraph >= 2 || !empty($conf->dol_optimize_smallscreen)) ? '300' : '320'; - $HEIGHT = '120'; + $HEIGHT = '150'; // Height require to have 5+1 entries into legend visible. if (!empty($conf->propal->enabled) && !empty($user->rights->propale->lire)) { // Build graphic number of object. $data = array(array('Lib',val1,val2,val3),...) diff --git a/htdocs/core/boxes/box_members_by_type.php b/htdocs/core/boxes/box_members_by_type.php index d7ab444f2da..4bbf20e9cbf 100644 --- a/htdocs/core/boxes/box_members_by_type.php +++ b/htdocs/core/boxes/box_members_by_type.php @@ -177,16 +177,16 @@ class box_members_by_type extends ModeleBoxes ); $this->info_box_contents[$line][] = array( 'td' => 'class="right"', - 'text' => $langs->trans("MembersStatusToValid"), - ); - $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("OutOfDate"), + 'text' => $langs->trans("MembersStatusToValid"), // Draft ); $this->info_box_contents[$line][] = array( 'td' => 'class="right"', 'text' => $langs->trans("UpToDate"), ); + $this->info_box_contents[$line][] = array( + 'td' => 'class="right"', + 'text' => $langs->trans("OutOfDate"), + ); $this->info_box_contents[$line][] = array( 'td' => 'class="right"', 'text' => $langs->trans("MembersStatusExcluded"), @@ -215,12 +215,12 @@ class box_members_by_type extends ModeleBoxes ); $this->info_box_contents[$line][] = array( 'td' => 'class="right"', - 'text' => (isset($MembersValidated[$key]) && ($MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) > 0) ? $MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) : '') . ' ' . $staticmember->LibStatut(Adherent::STATUS_VALIDATED, 1, 0, 3), + 'text' => (isset($MembersUpToDate[$key]) && $MembersUpToDate[$key] > 0 ? $MembersUpToDate[$key] : '') . ' ' . $staticmember->LibStatut(Adherent::STATUS_VALIDATED, 1, $now, 3), 'asis' => 1, ); $this->info_box_contents[$line][] = array( 'td' => 'class="right"', - 'text' => (isset($MembersUpToDate[$key]) && $MembersUpToDate[$key] > 0 ? $MembersUpToDate[$key] : '') . ' ' . $staticmember->LibStatut(Adherent::STATUS_VALIDATED, 1, $now, 3), + 'text' => (isset($MembersValidated[$key]) && ($MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) > 0) ? $MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) : '') . ' ' . $staticmember->LibStatut(Adherent::STATUS_VALIDATED, 1, 1, 3), 'asis' => 1, ); $this->info_box_contents[$line][] = array( @@ -255,12 +255,12 @@ class box_members_by_type extends ModeleBoxes ); $this->info_box_contents[$line][] = array( 'td' => 'class="liste_total right"', - 'text' => $SumValidated.' '.$staticmember->LibStatut(Adherent::STATUS_VALIDATED, 1, 0, 3), + 'text' => $SumUpToDate.' '.$staticmember->LibStatut(Adherent::STATUS_VALIDATED, 1, $now, 3), 'asis' => 1 ); $this->info_box_contents[$line][] = array( 'td' => 'class="liste_total right"', - 'text' => $SumUpToDate.' '.$staticmember->LibStatut(Adherent::STATUS_VALIDATED, 1, $now, 3), + 'text' => $SumValidated.' '.$staticmember->LibStatut(Adherent::STATUS_VALIDATED, 1, 1, 3), 'asis' => 1 ); $this->info_box_contents[$line][] = array( diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index 9a0c76503d0..8ea14ebc8d5 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -103,8 +103,8 @@ class box_produits extends ModeleBoxes } // Add where from hooks if (is_object($hookmanager)) { - $parameters = array('boxproductlist'=>1); - $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('boxproductlist' => 1, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $productstatic); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; } $sql .= $this->db->order('p.datec', 'DESC'); diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php index e074cb76198..72b1957b287 100644 --- a/htdocs/core/boxes/box_produits_alerte_stock.php +++ b/htdocs/core/boxes/box_produits_alerte_stock.php @@ -103,8 +103,8 @@ class box_produits_alerte_stock extends ModeleBoxes } // Add where from hooks if (is_object($hookmanager)) { - $parameters = array('boxproductalertstocklist'=>1); - $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('boxproductalertstocklist' => 1, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $productstatic); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; } $sql .= " GROUP BY p.rowid, p.ref, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.barcode, p.seuil_stock_alerte, p.entity,"; diff --git a/htdocs/core/boxes/box_prospect.php b/htdocs/core/boxes/box_prospect.php index a46713a3206..3bf69f91fe0 100644 --- a/htdocs/core/boxes/box_prospect.php +++ b/htdocs/core/boxes/box_prospect.php @@ -78,7 +78,7 @@ class box_prospect extends ModeleBoxes */ public function loadBox($max = 5) { - global $user, $langs, $conf; + global $user, $langs, $hookmanager; $this->max = $max; @@ -101,9 +101,15 @@ class box_prospect extends ModeleBoxes if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($user->socid) { - $sql .= " AND s.rowid = ".((int) $user->socid); + // Add where from hooks + $parameters = array('socid' => $user->socid, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $thirdpartystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($user->socid > 0) { + $sql .= " AND s.rowid = ".((int) $user->socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.tms DESC"; $sql .= $this->db->plimit($max, 0); diff --git a/htdocs/core/boxes/box_scheduled_jobs.php b/htdocs/core/boxes/box_scheduled_jobs.php index 94695034cce..f2195659654 100644 --- a/htdocs/core/boxes/box_scheduled_jobs.php +++ b/htdocs/core/boxes/box_scheduled_jobs.php @@ -102,7 +102,7 @@ class box_scheduled_jobs extends ModeleBoxes while ($i < $num) { $objp = $this->db->fetch_object($result); - if (dol_eval($objp->test, 1, 1)) { + if (dol_eval($objp->test, 1, 1, '')) { $nextrun = $this->db->jdate($objp->datenextrun); if (empty($nextrun)) { $nextrun = $this->db->jdate($objp->datestart); diff --git a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php index 9a40c3f9aec..403c6c9fc6d 100644 --- a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php +++ b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php @@ -162,7 +162,7 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes $this->info_box_contents[$line][] = array( 'td' => 'class="right"', - 'text' => $delayIcon.' '.($delivery_date ? dol_print_date($delivery_date, 'day', 'tzuserrel') : '').'', + 'text' => $delayIcon.' '.($delivery_date ? dol_print_date($delivery_date, 'day', 'tzuserrel') : '').'', 'asis' => 1 ); diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index a8986475095..b6acbbbfbc9 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -140,7 +140,7 @@ class CMailFile */ public function __construct($subject, $to, $from, $msg, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = 0, $errors_to = '', $css = '', $trackid = '', $moreinheader = '', $sendcontext = 'standard', $replyto = '') { - global $conf, $dolibarr_main_data_root; + global $conf, $dolibarr_main_data_root, $user; // Clean values of $mimefilename_list if (is_array($mimefilename_list)) { @@ -149,31 +149,7 @@ class CMailFile } } - // Add autocopy to if not already in $to (Note: Adding bcc for specific modules are also done from pages) - if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO) && !preg_match('/'.preg_quote($conf->global->MAIN_MAIL_AUTOCOPY_TO, '/').'/i', $to)) { - $addr_bcc .= ($addr_bcc ? ', ' : '').$conf->global->MAIN_MAIL_AUTOCOPY_TO; - } - - $this->subject = $subject; - $this->addr_to = $to; - $this->addr_from = $from; - $this->msg = $msg; - $this->filename_list = $filename_list; - $this->mimetype_list = $mimetype_list; - $this->mimefilename_list = $mimefilename_list; - $this->addr_cc = $addr_cc; - $this->addr_bcc = $addr_bcc; - $this->deliveryreceipt = $deliveryreceipt; - if (empty($replyto)) { - $replyto = $from; - } - $this->reply_to = $replyto; - $this->errors_to = $errors_to; - $this->trackid = $trackid; $this->sendcontext = $sendcontext; - $this->filename_list = $filename_list; - $this->mimetype_list = $mimetype_list; - $this->mimefilename_list = $mimefilename_list; // Define this->sendmode $this->sendmode = ''; @@ -186,10 +162,7 @@ class CMailFile } } if (empty($this->sendmode)) { - $this->sendmode = $conf->global->MAIN_MAIL_SENDMODE; - } - if (empty($this->sendmode)) { - $this->sendmode = 'mail'; + $this->sendmode = (!empty($conf->global->MAIN_MAIL_SENDMODE) ? $conf->global->MAIN_MAIL_SENDMODE : 'mail'); } // We define end of line (RFC 821). @@ -278,20 +251,52 @@ class CMailFile } } - // Add autocopy to if not already in $to (Note: Adding bcc for specific modules are also done from pages) - if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO) && !preg_match('/'.preg_quote($conf->global->MAIN_MAIL_AUTOCOPY_TO, '/').'/i', $to)) { - $addr_bcc .= ($addr_bcc ? ', ' : '').$conf->global->MAIN_MAIL_AUTOCOPY_TO; + // Add auto copy to if not already in $to (Note: Adding bcc for specific modules are also done from pages) + // For example MAIN_MAIL_AUTOCOPY_TO can be 'email@example.com, __USER_EMAIL__, ...' + if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) { + $listofemailstoadd = explode(',', $conf->global->MAIN_MAIL_AUTOCOPY_TO); + foreach ($listofemailstoadd as $key => $val) { + $emailtoadd = $listofemailstoadd[$key]; + if (trim($emailtoadd) == '__USER_EMAIL__') { + if (!empty($user) && !empty($user->email)) { + $emailtoadd = $user->email; + } else { + $emailtoadd = ''; + } + } + if ($emailtoadd && preg_match('/'.preg_quote($emailtoadd, '/').'/i', $to)) { + $emailtoadd = ''; // Email already in the "To" + } + if ($emailtoadd) { + $listofemailstoadd[$key] = $emailtoadd; + } else { + unset($listofemailstoadd[$key]); + } + } + if (!empty($listofemailstoadd)) { + $addr_bcc .= ($addr_bcc ? ', ' : '').join(', ', $listofemailstoadd); + } } + $this->subject = $subject; $this->addr_to = $to; + $this->addr_from = $from; + $this->msg = $msg; + $this->filename_list = $filename_list; + $this->mimetype_list = $mimetype_list; + $this->mimefilename_list = $mimefilename_list; $this->addr_cc = $addr_cc; $this->addr_bcc = $addr_bcc; - $this->reply_to = $replyto; - $this->addr_from = $from; - $this->subject = $subject; - $this->errors_to = $errors_to; $this->deliveryreceipt = $deliveryreceipt; + if (empty($replyto)) { + $replyto = $from; + } + $this->reply_to = $replyto; + $this->errors_to = $errors_to; $this->trackid = $trackid; + $this->filename_list = $filename_list; + $this->mimetype_list = $mimetype_list; + $this->mimefilename_list = $mimefilename_list; if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) { $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 29fd230a61b..e49f8a6a728 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -93,6 +93,14 @@ abstract class CommonInvoice extends CommonObject const STATUS_ABANDONED = 3; + public $sumpayed; + public $sumpayed_multicurrency; + public $sumdeposit; + public $sumdeposit_multicurrency; + public $sumcreditnote; + public $sumcreditnote_multicurrency; + + /** * Return remain amount to pay. Property ->id and ->total_ttc must be set. * This does not include open direct debit requests. @@ -118,8 +126,8 @@ abstract class CommonInvoice extends CommonObject * Return amount of payments already done. This must include ONLY the record into the payment table. * Payments dones using discounts, credit notes, etc are not included. * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float Amount of payment already done, <0 if KO + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float Amount of payment already done, <0 and set ->error if KO */ public function getSommePaiement($multicurrency = 0) { @@ -138,10 +146,13 @@ abstract class CommonInvoice extends CommonObject $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); + $this->db->free($resql); if ($multicurrency) { + $this->sumpayed_multicurrency = $obj->multicurrency_amount; return $obj->multicurrency_amount; } else { + $this->sumpayed = $obj->amount; return $obj->amount; } } else { @@ -154,13 +165,13 @@ abstract class CommonInvoice extends CommonObject * Return amount (with tax) of all deposits invoices used by invoice. * Should always be empty, except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is on (not recommended). * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float <0 if KO, Sum of deposits amount otherwise + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float <0 and set ->error if KO, Sum of deposits amount otherwise */ public function getSumDepositsUsed($multicurrency = 0) { if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') { - // TODO + // FACTURE_DEPOSITS_ARE_JUST_PAYMENTS was never supported for purchase invoice, so we can return 0 with no need of SQL for this case. return 0.0; } @@ -170,6 +181,12 @@ abstract class CommonInvoice extends CommonObject $result = $discountstatic->getSumDepositsUsed($this, $multicurrency); if ($result >= 0) { + if ($multicurrency) { + $this->sumdeposit_multicurrency = $result; + } else { + $this->sumdeposit = $result; + } + return $result; } else { $this->error = $discountstatic->error; @@ -180,8 +197,8 @@ abstract class CommonInvoice extends CommonObject /** * Return amount (with tax) of all credit notes invoices + excess received used by invoice * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float <0 if KO, Sum of credit notes and deposits amount otherwise + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float <0 and set ->error if KO, Sum of credit notes and deposits amount otherwise */ public function getSumCreditNotesUsed($multicurrency = 0) { @@ -190,6 +207,12 @@ abstract class CommonInvoice extends CommonObject $discountstatic = new DiscountAbsolute($this->db); $result = $discountstatic->getSumCreditNotesUsed($this, $multicurrency); if ($result >= 0) { + if ($multicurrency) { + $this->sumcreditnote_multicurrency = $result; + } else { + $this->sumcreditnote = $result; + } + return $result; } else { $this->error = $discountstatic->error; @@ -827,8 +850,10 @@ abstract class CommonInvoice extends CommonObject $tmplang->load("main"); $datestring = dol_print_date($this->date, 'dayhourrfc'); - $pricewithtaxstring = price($this->total_ttc, 0, $tmplang, 0, -1, 2); - $pricetaxstring = price($this->total_tva, 0, $tmplang, 0, -1, 2); + //$pricewithtaxstring = price($this->total_ttc, 0, $tmplang, 0, -1, 2); + //$pricetaxstring = price($this->total_tva, 0, $tmplang, 0, -1, 2); + $pricewithtaxstring = price2num($this->total_ttc, 2, 1); + $pricetaxstring = price2num($this->total_tva, 2, 1); /* $name = implode(unpack("H*", $this->thirdparty->name)); @@ -857,7 +882,7 @@ abstract class CommonInvoice extends CommonObject // Using TLV format $s = pack('C1', 1).pack('C1', strlen($this->thirdparty->name)).$this->thirdparty->name; $s .= pack('C1', 2).pack('C1', strlen($this->thirdparty->tva_intra)).$this->thirdparty->tva_intra; - $s .= pack('C1', 3).pack('C1', strlen($datestring)).$this->date; + $s .= pack('C1', 3).pack('C1', strlen($datestring)).$datestring; $s .= pack('C1', 4).pack('C1', strlen($pricewithtaxstring)).$pricewithtaxstring; $s .= pack('C1', 5).pack('C1', strlen($pricetaxstring)).$pricetaxstring; $s .= ''; // Hash of xml invoice diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index aaa3aa6a766..63d0eb475e5 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7,7 +7,7 @@ * Copyright (C) 2012-2015 Marcos García * Copyright (C) 2012-2015 Raphaël Doursenaud * Copyright (C) 2012 Cedric Salvador - * Copyright (C) 2015-2021 Alexandre Spangaro + * Copyright (C) 2015-2022 Alexandre Spangaro * Copyright (C) 2016 Bahfir abbes * Copyright (C) 2017 ATM Consulting * Copyright (C) 2017-2019 Nicolas ZABOURI @@ -15,6 +15,7 @@ * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2018 Josep Lluís Amador * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Grégory Blémand * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +43,7 @@ */ abstract class CommonObject { + const TRIGGER_PREFIX = ''; // to be overriden in child class implementations, i.e. 'BILL', 'TASK', 'PROPAL', etc. /** * @var DoliDb Database handler (result of a new DoliDB) */ @@ -123,6 +125,12 @@ abstract class CommonObject */ public $linkedObjects; + /** + * @var boolean is linkedObjects full loaded. Loaded by ->fetchObjectLinked + * important for pdf generation time reduction + */ + public $linkedObjectsFullLoaded = false; + /** * @var Object To store a cloned copy of object before to edit it and keep track of old properties */ @@ -2931,15 +2939,20 @@ abstract class CommonObject return -1; } + $fieldposition = 'rang'; // @todo Rename 'rang' into 'position' + if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { + $fieldposition = 'position'; + } + // Count number of lines to reorder (according to choice $renum) $nl = 0; $sql = "SELECT count(rowid) FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); if (!$renum) { - $sql .= ' AND rang = 0'; + $sql .= " AND " . $fieldposition . " = 0"; } if ($renum) { - $sql .= ' AND rang <> 0'; + $sql .= " AND " . $fieldposition . " <> 0"; } dol_syslog(get_class($this)."::line_order", LOG_DEBUG); @@ -2960,7 +2973,7 @@ abstract class CommonObject if ($fk_parent_line) { $sql .= ' AND fk_parent_line IS NULL'; } - $sql .= " ORDER BY rang ASC, rowid ".$rowidorder; + $sql .= " ORDER BY " . $fieldposition . " ASC, rowid " . $rowidorder; dol_syslog(get_class($this)."::line_order search all parent lines", LOG_DEBUG); $resql = $this->db->query($sql); @@ -3001,12 +3014,17 @@ abstract class CommonObject */ public function getChildrenOfLine($id, $includealltree = 0) { + $fieldposition = 'rang'; // @todo Rename 'rang' into 'position' + if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { + $fieldposition = 'position'; + } + $rows = array(); $sql = "SELECT rowid FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); $sql .= ' AND fk_parent_line = '.((int) $id); - $sql .= ' ORDER BY rang ASC'; + $sql .= " ORDER BY " . $fieldposition . " ASC"; dol_syslog(get_class($this)."::getChildrenOfLine search children lines for line ".$id, LOG_DEBUG); $resql = $this->db->query($sql); @@ -3077,7 +3095,7 @@ abstract class CommonObject { global $hookmanager; $fieldposition = 'rang'; // @todo Rename 'rang' into 'position' - if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction'))) { + if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { $fieldposition = 'position'; } @@ -3123,13 +3141,13 @@ abstract class CommonObject { if ($rang > 1) { $fieldposition = 'rang'; - if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction'))) { + if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { $fieldposition = 'position'; } $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) $rang); $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); - $sql .= ' AND rang = '.((int) ($rang - 1)); + $sql .= " AND " . $fieldposition . " = " . ((int) ($rang - 1)); if ($this->db->query($sql)) { $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) ($rang - 1)); $sql .= ' WHERE rowid = '.((int) $rowid); @@ -3154,13 +3172,13 @@ abstract class CommonObject { if ($rang < $max) { $fieldposition = 'rang'; - if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction'))) { + if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { $fieldposition = 'position'; } $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) $rang); $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); - $sql .= ' AND rang = '.((int) ($rang + 1)); + $sql .= " AND " . $fieldposition . " = " . ((int) ($rang + 1)); if ($this->db->query($sql)) { $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) ($rang + 1)); $sql .= ' WHERE rowid = '.((int) $rowid); @@ -3181,7 +3199,12 @@ abstract class CommonObject */ public function getRangOfLine($rowid) { - $sql = "SELECT rang FROM ".$this->db->prefix().$this->table_element_line; + $fieldposition = 'rang'; + if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { + $fieldposition = 'position'; + } + + $sql = "SELECT " . $fieldposition . " FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE rowid = ".((int) $rowid); dol_syslog(get_class($this)."::getRangOfLine", LOG_DEBUG); @@ -3200,9 +3223,14 @@ abstract class CommonObject */ public function getIdOfLine($rang) { + $fieldposition = 'rang'; + if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { + $fieldposition = 'position'; + } + $sql = "SELECT rowid FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); - $sql .= " AND rang = ".((int) $rang); + $sql .= " AND " . $fieldposition . " = ".((int) $rang); $resql = $this->db->query($sql); if ($resql) { $row = $this->db->fetch_row($resql); @@ -3221,7 +3249,7 @@ abstract class CommonObject { // phpcs:enable $positionfield = 'rang'; - if ($this->table_element == 'bom_bom') { + if (in_array($this->table_element, array('bom_bom', 'product_attribute'))) { $positionfield = 'position'; } @@ -3675,7 +3703,7 @@ abstract class CommonObject // Elements of the core modules which have `$module` property but may to which we don't want to prefix module part to the element name for finding the linked object in llx_element_element. // It's because an entry for this element may be exist in llx_element_element before this modification (version <=14.2) and ave named only with their element name in fk_source or fk_target. - $coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization'); + $coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization', 'asset'); // Add module part to target type if object has $module property and isn't in core modules. $targettype = ((!empty($this->module) && ! in_array($this->module, $coremodule)) ? $this->module.'_' : '').$this->element; @@ -3753,6 +3781,10 @@ abstract class CommonObject { global $conf, $hookmanager, $action; + // important for pdf generation time reduction + // this boolean is true if $this->linkedObjects has already been loaded with all objects linked without filter + if ($this->linkedObjectsFullLoaded) return 1; + $this->linkedObjectsIds = array(); $this->linkedObjects = array(); @@ -3814,6 +3846,9 @@ abstract class CommonObject } else { $sql .= "(fk_source = ".((int) $sourceid)." AND sourcetype = '".$this->db->escape($sourcetype)."')"; $sql .= " ".$clause." (fk_target = ".((int) $targetid)." AND targettype = '".$this->db->escape($targettype)."')"; + if ($sourceid == $this->id && $sourcetype == $this->element && $targetid == $this->id && $targettype == $this->element && $clause == 'OR') { + $this->linkedObjectsFullLoaded = true; + } } $sql .= " ORDER BY ".$orderby; @@ -4004,7 +4039,7 @@ abstract class CommonObject $this->context['link_source_type'] = $sourcetype; $this->context['link_target_id'] = $targetid; $this->context['link_target_type'] = $targettype; - $result = $this->call_trigger('OBJECT_LINK_UPDATE', $f_user); + $result = $this->call_trigger('OBJECT_LINK_MODIFY', $f_user); if ($result < 0) { $error++; } @@ -4354,9 +4389,10 @@ abstract class CommonObject * Check is done into this->childtables. There is no check into llx_element_element. * * @param int $id Force id of object + * @param int $entity Force entity to check * @return int <0 if KO, 0 if not used, >0 if already used */ - public function isObjectUsed($id = 0) + public function isObjectUsed($id = 0, $entity = 0) { global $langs; @@ -4379,11 +4415,25 @@ abstract class CommonObject // Test if child exists $haschild = 0; - foreach ($arraytoscan as $table => $elementname) { + foreach ($arraytoscan as $table => $element) { //print $id.'-'.$table.'-'.$elementname.'
    '; - // Check if third party can be deleted - $sql = "SELECT COUNT(*) as nb from ".$this->db->prefix().$table; - $sql .= " WHERE ".$this->fk_element." = ".((int) $id); + // Check if element can be deleted + $sql = "SELECT COUNT(*) as nb"; + $sql.= " FROM ".$this->db->prefix().$table." as c"; + if (!empty($element['parent']) && !empty($element['parentkey'])) { + $sql.= ", ".$this->db->prefix().$element['parent']." as p"; + } + $sql.= " WHERE c.".$this->fk_element." = ".((int) $id); + if (!empty($element['parent']) && !empty($element['parentkey'])) { + $sql.= " AND c.".$element['parentkey']." = p.rowid"; + } + if (!empty($entity)) { + if (!empty($element['parent']) && !empty($element['parentkey'])) { + $sql.= " AND p.entity = ".((int) $entity); + } else { + $sql.= " AND c.entity = ".((int) $entity); + } + } $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); @@ -4391,11 +4441,12 @@ abstract class CommonObject $langs->load("errors"); //print 'Found into table '.$table.', type '.$langs->transnoentitiesnoconv($elementname).', haschild='.$haschild; $haschild += $obj->nb; - if (is_numeric($elementname)) { // old usage - $this->errors[] = $langs->transnoentities("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $table); - } else // new usage: $elementname=Translation key - { - $this->errors[] = $langs->transnoentities("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $langs->transnoentitiesnoconv($elementname)); + if (is_numeric($element)) { // very old usage array('table1', 'table2', ...) + $this->errors[] = $langs->transnoentitiesnoconv("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $table); + } elseif (is_string($element)) { // old usage array('table1' => 'TranslateKey1', 'table2' => 'TranslateKey2', ...) + $this->errors[] = $langs->transnoentitiesnoconv("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $langs->transnoentitiesnoconv($element)); + } else { // new usage: $element['name']=Translation key + $this->errors[] = $langs->transnoentitiesnoconv("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $langs->transnoentitiesnoconv($element['name'])); } break; // We found at least one, we stop here } @@ -4912,6 +4963,7 @@ abstract class CommonObject print ''.$langs->trans('Unit').''; } print ''.$langs->trans('ReductionShort').''; + print ''.$langs->trans('TotalHT').''; print ''.$form->showCheckAddButtons('checkforselect', 1).''; print ''; $i = 0; @@ -5042,6 +5094,7 @@ abstract class CommonObject } $this->tpl['price'] = price($line->subprice); + $this->tpl['total_ht'] = price($line->total_ht); $this->tpl['multicurrency_price'] = price($line->multicurrency_subprice); $this->tpl['qty'] = (($line->info_bits & 2) != 2) ? $line->qty : ' '; if (!empty($conf->global->PRODUCT_USE_UNITS)) { @@ -5566,7 +5619,10 @@ abstract class CommonObject { // phpcs:enable global $langs, $conf; - + if (!empty(self::TRIGGER_PREFIX) && strpos($triggerName, self::TRIGGER_PREFIX . '_') !== 0) { + dol_print_error('', 'The trigger "' . $triggerName . '" does not start with "' . self::TRIGGER_PREFIX . '_" as required.'); + exit; + } if (!is_object($langs)) { // If lang was not defined, we set it. It is required by run_triggers. include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php'; $langs = new Translate('', $conf); @@ -5693,12 +5749,12 @@ abstract class CommonObject $enabled = 1; if (isset($this->fields[$key]['enabled'])) { - $enabled = dol_eval($this->fields[$key]['enabled'], 1); + $enabled = dol_eval($this->fields[$key]['enabled'], 1, 1, '1'); } /*$perms = 1; if (isset($this->fields[$key]['perms'])) { - $perms = dol_eval($this->fields[$key]['perms'], 1); + $perms = dol_eval($this->fields[$key]['perms'], 1, 1, '1'); }*/ if (empty($enabled)) { continue; @@ -5854,7 +5910,7 @@ abstract class CommonObject if (!empty($extrafields) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) { //var_dump($conf->disable_compute); if (empty($conf->disable_compute)) { - $this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0); + $this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, ''); } } } @@ -5958,8 +6014,15 @@ abstract class CommonObject $attributeLabel = $extrafields->attributes[$this->table_element]['label'][$attributeKey]; $attributeParam = $extrafields->attributes[$this->table_element]['param'][$attributeKey]; $attributeRequired = $extrafields->attributes[$this->table_element]['required'][$attributeKey]; + $attributeUnique = $extrafields->attributes[$this->table_element]['unique'][$attributeKey]; $attrfieldcomputed = $extrafields->attributes[$this->table_element]['computed'][$attributeKey]; + // If we clone, we have to clean unique extrafields to prevent duplicates. + // This behaviour can be prevented by external code by changing $this->context['createfromclone'] value in createFrom hook + if (! empty($this->context['createfromclone']) && $this->context['createfromclone'] == 'createfromclone' && ! empty($attributeUnique)) { + $new_array_options[$key] = null; + } + // Similar code than into insertExtraFields if ($attributeRequired) { $mandatorypb = false; @@ -5985,7 +6048,7 @@ abstract class CommonObject if (!empty($attrfieldcomputed)) { if (!empty($conf->global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { - $value = dol_eval($attrfieldcomputed, 1, 0); + $value = dol_eval($attrfieldcomputed, 1, 0, ''); dol_syslog($langs->trans("Extrafieldcomputed")." sur ".$attributeLabel."(".$value.")", LOG_DEBUG); $new_array_options[$key] = $value; } else { @@ -6352,7 +6415,7 @@ abstract class CommonObject if (!empty($attrfieldcomputed)) { if (!empty($conf->global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { - $value = dol_eval($attrfieldcomputed, 1, 0); + $value = dol_eval($attrfieldcomputed, 1, 0, ''); dol_syslog($langs->trans("Extrafieldcomputed")." sur ".$attributeLabel."(".$value.")", LOG_DEBUG); $this->array_options["options_".$key] = $value; } else { @@ -6648,7 +6711,7 @@ abstract class CommonObject // Add validation state class if (!empty($validationClass)) { - $morecss.= ' '.$validationClass; + $morecss.= $validationClass; } if (in_array($type, array('date'))) { @@ -6697,7 +6760,7 @@ abstract class CommonObject if (!preg_match('/search_/', $keyprefix)) { // If keyprefix is search_ or search_options_, we must just use a simple text field require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, !empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_5, '90%'); - $out = $doleditor->Create(1); + $out = $doleditor->Create(1, '', true, '', '', $moreparam, $morecss); } else { $out = ''; } @@ -7067,6 +7130,8 @@ abstract class CommonObject $paramforthenewlink = ''; $paramforthenewlink .= (GETPOSTISSET('action') ? '&action='.GETPOST('action', 'aZ09') : ''); $paramforthenewlink .= (GETPOSTISSET('id') ? '&id='.GETPOST('id', 'int') : ''); + $paramforthenewlink .= (GETPOSTISSET('origin') ? '&origin='.GETPOST('origin', 'aZ09') : ''); + $paramforthenewlink .= (GETPOSTISSET('originid') ? '&originid='.GETPOST('originid', 'int') : ''); $paramforthenewlink .= '&fk_'.strtolower($class).'=--IDFORBACKTOPAGE--'; // TODO Add Javascript code to add input fields already filled into $paramforthenewlink so we won't loose them when going back to main page $out .= ''; @@ -7206,7 +7271,7 @@ abstract class CommonObject if ($computed) { // Make the eval of compute string //var_dump($computed); - $value = dol_eval($computed, 1, 0); + $value = dol_eval($computed, 1, 0, ''); } if (empty($morecss)) { @@ -7717,7 +7782,7 @@ abstract class CommonObject if (empty($reshook)) { if (key_exists('label', $extrafields->attributes[$this->table_element]) && is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label']) > 0) { $out .= "\n"; - $out .= ' '; + $out .= ' '; $out .= "\n"; $extrafields_collapse_num = ''; @@ -7731,7 +7796,7 @@ abstract class CommonObject // Test on 'enabled' ('enabled' is different than 'list' = 'visibility') $enabled = 1; if ($enabled && isset($extrafields->attributes[$this->table_element]['enabled'][$key])) { - $enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1); + $enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1, 1, '1'); } if (empty($enabled)) { continue; @@ -7739,12 +7804,12 @@ abstract class CommonObject $visibility = 1; if ($visibility && isset($extrafields->attributes[$this->table_element]['list'][$key])) { - $visibility = dol_eval($extrafields->attributes[$this->table_element]['list'][$key], 1); + $visibility = dol_eval($extrafields->attributes[$this->table_element]['list'][$key], 1, 1, '1'); } $perms = 1; if ($perms && isset($extrafields->attributes[$this->table_element]['perms'][$key])) { - $perms = dol_eval($extrafields->attributes[$this->table_element]['perms'][$key], 1); + $perms = dol_eval($extrafields->attributes[$this->table_element]['perms'][$key], 1, 1, '1'); } if (($mode == 'create') && abs($visibility) != 1 && abs($visibility) != 3) { @@ -7822,7 +7887,7 @@ abstract class CommonObject } // if colspan=0 or 1, the second column is not extended, so the separator must be on 2 columns - $out .= $extrafields->showSeparator($key, $this, ($colspan ? $colspan + 1 : 2), $display_type); + $out .= $extrafields->showSeparator($key, $this, ($colspan ? $colspan + 1 : 2), $display_type, $mode); } else { $class = (!empty($extrafields->attributes[$this->table_element]['hidden'][$key]) ? 'hideobject ' : ''); $csstyle = ''; @@ -7955,7 +8020,7 @@ abstract class CommonObject $out .= $this->getJSListDependancies(); } - $out .= ' '."\n"; + $out .= ' '."\n"; } } @@ -8059,7 +8124,7 @@ abstract class CommonObject /** * Function used to replace a thirdparty id with another one. - * This function is meant to be called from replaceThirdparty with the appropiate tables + * This function is meant to be called from replaceThirdparty with the appropriate tables * Column name fk_soc MUST be used to identify thirdparties * * @param DoliDB $db Database handler @@ -8076,7 +8141,36 @@ abstract class CommonObject if (!$db->query($sql)) { if ($ignoreerrors) { - return true; // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B. + return true; // TODO Not enough. If there is A-B on kept thirdparty and B-C on old one, we must get A-B-C after merge. Not A-B. + } + //$this->errors = $db->lasterror(); + return false; + } + } + + return true; + } + + /** + * Function used to replace a product id with another one. + * This function is meant to be called from replaceProduct with the appropriate tables + * Column name fk_product MUST be used to identify products + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id (the product to delete) + * @param int $dest_id New product id (the product that will received element of the other) + * @param string[] $tables Tables that need to be changed + * @param int $ignoreerrors Ignore errors. Return true even if errors. We need this when replacement can fails like for categories (categorie of old product may already exists on new one) + * @return bool True if success, False if error + */ + public static function commonReplaceProduct(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors = 0) + { + foreach ($tables as $table) { + $sql = 'UPDATE '.MAIN_DB_PREFIX.$table.' SET fk_product = '.((int) $dest_id).' WHERE fk_product = '.((int) $origin_id); + + if (!$db->query($sql)) { + if ($ignoreerrors) { + return true; // TODO Not enough. If there is A-B on kept product and B-C on old one, we must get A-B-C after merge. Not A-B. } //$this->errors = $db->lasterror(); return false; diff --git a/htdocs/core/class/commonstickergenerator.class.php b/htdocs/core/class/commonstickergenerator.class.php index 284b41ee4ba..8085adf6283 100644 --- a/htdocs/core/class/commonstickergenerator.class.php +++ b/htdocs/core/class/commonstickergenerator.class.php @@ -289,7 +289,7 @@ abstract class CommonStickerGenerator // phpcs:enable $this->_Metric = $format['metric']; $this->_Avery_Name = $format['name']; - $this->_Avery_Code = $format['code']; + $this->_Avery_Code = empty($format['code'])?'':$format['code']; $this->_Margin_Left = $this->convertMetric($format['marginLeft'], $this->_Metric, $this->_Metric_Doc); $this->_Margin_Top = $this->convertMetric($format['marginTop'], $this->_Metric, $this->_Metric_Doc); $this->_X_Space = $this->convertMetric($format['SpaceX'], $this->_Metric, $this->_Metric_Doc); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index c7d01cab586..602e6b560d0 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -165,7 +165,7 @@ class Conf /** * Load setup values into conf object (read llx_const) for a specified entity - * Note that this->db->xxx, this->file->xxx and this->multicompany have been already loaded when setValues is called. + * Note that this->db->xxx, this->file->xxx and this->multicompany have been already loaded when setEntityValues is called. * * @param DoliDB $db Database handler * @param int $entity Entity to get @@ -616,15 +616,15 @@ class Conf if (!empty($this->productbatch->enabled)) { $this->global->STOCK_CALCULATE_ON_BILL = 0; $this->global->STOCK_CALCULATE_ON_VALIDATE_ORDER = 0; - $this->global->STOCK_CALCULATE_ON_SHIPMENT = 1; - $this->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE = 0; + if (empty($this->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) $this->global->STOCK_CALCULATE_ON_SHIPMENT = 1; + if (empty($this->global->STOCK_CALCULATE_ON_SHIPMENT)) $this->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE = 1; $this->global->STOCK_CALCULATE_ON_SUPPLIER_BILL = 0; $this->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER = 0; if (empty($this->reception->enabled)) { $this->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER = 1; } else { - $this->global->STOCK_CALCULATE_ON_RECEPTION = 1; - $this->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE = 0; + if (empty($this->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)) $this->global->STOCK_CALCULATE_ON_RECEPTION = 1; + if (empty($this->global->STOCK_CALCULATE_ON_RECEPTION)) $this->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE = 1; } } @@ -910,7 +910,7 @@ class Conf // Value 1 makes CSRF check for all POST parameters only // Value 2 makes also CSRF check for GET requests with action = a sensitive requests like action=del, action=remove... // Value 3 makes also CSRF check for all GET requests with a param action or massaction - $this->global->MAIN_SECURITY_CSRF_WITH_TOKEN = 1; + $this->global->MAIN_SECURITY_CSRF_WITH_TOKEN = 2; // Note: Set MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL=1 to have a renewal of token at each page call instead of each session (not recommended) } diff --git a/htdocs/core/class/coreobject.class.php b/htdocs/core/class/coreobject.class.php index 91b176f899d..1bb4e92a0c9 100644 --- a/htdocs/core/class/coreobject.class.php +++ b/htdocs/core/class/coreobject.class.php @@ -245,7 +245,7 @@ class CoreObject extends CommonObject $res = $this->updateCommon($user); if ($res) { - $result = $this->call_trigger(strtoupper($this->element).'_UPDATE', $user); + $result = $this->call_trigger(strtoupper($this->element).'_MODIFY', $user); if ($result < 0) { $error++; } else { diff --git a/htdocs/core/class/ctyperesource.class.php b/htdocs/core/class/ctyperesource.class.php index 32fe3164ad8..4a4e5c3d2cb 100644 --- a/htdocs/core/class/ctyperesource.class.php +++ b/htdocs/core/class/ctyperesource.class.php @@ -127,12 +127,12 @@ class Ctyperesource if (!$error) { $this->id = $this->db->last_insert_id($this->db->prefix().$this->table_element); - // Uncomment this and change MYOBJECT to your own tag if you + // Uncomment this and change CTYPERESOURCE to your own tag if you // want this action to call a trigger. //if (!$notrigger) { // // Call triggers - // $result=$this->call_trigger('MYOBJECT_CREATE',$user); + // $result=$this->call_trigger('CTYPERESOURCE_CREATE',$user); // if ($result < 0) $error++; // // End call triggers //} @@ -325,12 +325,12 @@ class Ctyperesource dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); } - // Uncomment this and change MYOBJECT to your own tag if you + // Uncomment this and change CTYPERESOURCE to your own tag if you // want this action calls a trigger. //if (!$error && !$notrigger) { // // Call triggers - // $result=$this->call_trigger('MYOBJECT_MODIFY',$user); + // $result=$this->call_trigger('CTYPERESOURCE_MODIFY',$user); // if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} // // End call triggers //} @@ -363,12 +363,12 @@ class Ctyperesource $this->db->begin(); - // Uncomment this and change MYOBJECT to your own tag if you + // Uncomment this and change CTYPERESOURCE to your own tag if you // want this action calls a trigger. //if (!$error && !$notrigger) { // // Call triggers - // $result=$this->call_trigger('MYOBJECT_DELETE',$user); + // $result=$this->call_trigger('CTYPERESOURCE_DELETE',$user); // if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} // // End call triggers //} diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 7939965828a..dff1383a629 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -54,12 +54,21 @@ class DiscountAbsolute public $fk_soc; public $discount_type; // 0 => customer discount, 1 => supplier discount - public $amount_ht; // - public $amount_tva; // - public $amount_ttc; // - public $multicurrency_amount_ht; - public $multicurrency_amount_tva; - public $multicurrency_amount_ttc; + + public $total_ht; + public $total_tva; + public $total_ttc; + public $amount_ht; // deprecated + public $amount_tva; // deprecated + public $amount_ttc; // deprecated + + public $multicurrency_total_ht; + public $multicurrency_total_tva; + public $multicurrency_total_ttc; + public $multicurrency_amount_ht; // deprecated + public $multicurrency_amount_tva; // deprecated + public $multicurrency_amount_ttc; // deprecated + // Vat rate public $tva_tx; public $vat_src_code; @@ -163,13 +172,21 @@ class DiscountAbsolute $this->fk_soc = $obj->fk_soc; $this->discount_type = $obj->discount_type; - $this->amount_ht = $obj->amount_ht; - $this->amount_tva = $obj->amount_tva; - $this->amount_ttc = $obj->amount_ttc; + $this->total_ht = $obj->amount_ht; + $this->total_tva = $obj->amount_tva; + $this->total_ttc = $obj->amount_ttc; + // For backward compatibility + $this->amount_ht = $this->total_ht; + $this->amount_tva = $this->total_tva; + $this->amount_ttc = $this->total_ttc; - $this->multicurrency_amount_ht = $this->multicurrency_subprice = $obj->multicurrency_amount_ht; - $this->multicurrency_amount_tva = $obj->multicurrency_amount_tva; - $this->multicurrency_amount_ttc = $obj->multicurrency_amount_ttc; + $this->multicurrency_total_ht = $this->multicurrency_subprice = $obj->multicurrency_amount_ht; + $this->multicurrency_total_tva = $obj->multicurrency_amount_tva; + $this->multicurrency_total_ttc = $obj->multicurrency_amount_ttc; + // For backward compatibility + $this->multicurrency_amount_ht = $this->multicurrency_total_ht; + $this->multicurrency_amount_tva = $this->multicurrency_total_tva; + $this->multicurrency_amount_ttc = $this->multicurrency_total_ttc; $this->tva_tx = $obj->tva_tx; $this->vat_src_code = $obj->vat_src_code; @@ -545,7 +562,7 @@ class DiscountAbsolute * Should always be empty, except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is on (not recommended). * * @param CommonInvoice $invoice Object invoice (customer of supplier) - * @param int $multicurrency 1=Return multicurrency_amount instead of amount + * @param int $multicurrency 1=Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount * @return int <0 if KO, Sum of credit notes and deposits amount otherwise */ public function getSumDepositsUsed($invoice, $multicurrency = 0) @@ -586,7 +603,7 @@ class DiscountAbsolute * Return amount (with tax) of all credit notes invoices + excess received used by invoice as a payment * * @param CommonInvoice $invoice Object invoice - * @param int $multicurrency 1=Return multicurrency_amount instead of amount + * @param int $multicurrency 1=Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount * @return int <0 if KO, Sum of credit notes and excess received amount otherwise */ public function getSumCreditNotesUsed($invoice, $multicurrency = 0) @@ -626,7 +643,7 @@ class DiscountAbsolute * Return amount (with tax) of all converted amount for this credit note * * @param CommonInvoice $invoice Object invoice - * @param int $multicurrency Return multicurrency_amount instead of amount + * @param int $multicurrency Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount * @return int <0 if KO, Sum of credit notes and deposits amount otherwise */ public function getSumFromThisCreditNotesNotUsed($invoice, $multicurrency = 0) diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index da98719d828..23c04a98a81 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -44,6 +44,8 @@ class DolEditor public $height; public $width; public $readonly; + public $posx; + public $posy; /** @@ -64,8 +66,9 @@ class DolEditor * @param int $rows Size of rows for textarea tool * @param string $cols Size of cols for textarea tool (textarea number of cols '70' or percent 'x%') * @param int $readonly 0=Read/Edit, 1=Read only + * @param array $poscursor Array for initial cursor position array('x'=>x, 'y'=>y) */ - public function __construct($htmlname, $content, $width = '', $height = 200, $toolbarname = 'Basic', $toolbarlocation = 'In', $toolbarstartexpanded = false, $uselocalbrowser = true, $okforextendededitor = true, $rows = 0, $cols = 0, $readonly = 0) + public function __construct($htmlname, $content, $width = '', $height = 200, $toolbarname = 'Basic', $toolbarlocation = 'In', $toolbarstartexpanded = false, $uselocalbrowser = true, $okforextendededitor = true, $rows = 0, $cols = 0, $readonly = 0, $poscursor = array()) { global $conf, $langs; @@ -106,8 +109,10 @@ class DolEditor $this->toolbarstartexpanded = $toolbarstartexpanded; $this->rows = max(ROWS_3, $rows); $this->cols = (preg_match('/%/', $cols) ? $cols : max(40, $cols)); // If $cols is a percent, we keep it, otherwise, we take max - $this->height = $height; + $this->height = $height; $this->width = $width; + $this->posx = empty($poscursor['x']) ? 0 : $poscursor['x']; + $this->posy = empty($poscursor['y']) ? 0 : $poscursor['y']; } } @@ -121,9 +126,11 @@ class DolEditor * @param boolean $disallowAnyContent Disallow to use any content. true=restrict to a predefined list of allowed elements. Used by CKEditor only. * @param string $titlecontent Show title content before editor area. Used by ACE editor only. * @param string $option For ACE editor, set the source language ('html', 'php', 'javascript', ...) + * @param string $moreparam Add extra tags to the textarea + * @param string $morecss Add extra css to the textarea * @return void|string */ - public function Create($noprint = 0, $morejs = '', $disallowAnyContent = true, $titlecontent = '', $option = '') + public function Create($noprint = 0, $morejs = '', $disallowAnyContent = true, $titlecontent = '', $option = '', $moreparam = '', $morecss = '') { // phpcs:enable global $conf, $langs; @@ -141,7 +148,7 @@ class DolEditor //$out.= ''; @@ -186,10 +193,10 @@ class DolEditor removePlugins : \''.$pluginstodisable.'\', readOnly : '.($this->readonly ? 'true' : 'false').', htmlEncodeOutput :'.$htmlencode_force.', - allowedContent :'.($disallowAnyContent ? 'false' : 'true').', - extraAllowedContent : \'a[target];div{float,display}\', /* Add the style float and display into div to default other allowed tags */ - disallowedContent : '.($disallowAnyContent ? '\'\'' : '\'\'').', - fullPage : '.($fullpage ? 'true' : 'false').', + allowedContent :'.($disallowAnyContent ? 'false' : 'true').', /* Advanced Content Filter (ACF) is own when allowedContent is false */ + extraAllowedContent : \'a[target];div{float,display}\', /* Add the style float and display into div to default other allowed tags */ + disallowedContent : '.($disallowAnyContent ? '\'\'' : '\'\'').', /* Tags that are not allowed */ + fullPage : '.($fullpage ? 'true' : 'false').', /* if true, the html, header and body tags are kept */ toolbar: \''.$this->toolbarname.'\', toolbarStartupExpanded: '.($this->toolbarstartexpanded ? 'true' : 'false').', width: '.($this->width ? '\''.$this->width.'\'' : '\'\'').', @@ -257,9 +264,12 @@ class DolEditor $out .= ''."\n"; } + } else { + $this->expand_display[$collapse_group] = 1; } return $out; @@ -1968,17 +1978,17 @@ class ExtraFields $enabled = 1; if (isset($this->attributes[$object->table_element]['enabled'][$key])) { // 'enabled' is often a condition on module enabled or not - $enabled = dol_eval($this->attributes[$object->table_element]['enabled'][$key], 1); + $enabled = dol_eval($this->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'); } $visibility = 1; if (isset($this->attributes[$object->table_element]['list'][$key])) { // 'list' is option for visibility - $visibility = dol_eval($this->attributes[$object->table_element]['list'][$key], 1); + $visibility = dol_eval($this->attributes[$object->table_element]['list'][$key], 1, 1, '1'); } $perms = 1; if (isset($this->attributes[$object->table_element]['perms'][$key])) { - $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1); + $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1, 1, '1'); } if (empty($enabled)) { continue; diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index a40ec3e30c3..5f87d81db9d 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -195,6 +195,7 @@ class HookManager 'getFormatedSupplierRef', 'getIdProfUrl', 'getInputIdProf', + 'menuDropdownQuickaddItems', 'menuLeftMenuItems', 'moveUploadedFile', 'moreHtmlStatus', diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 6e5c0a572d2..a20d2cd62b2 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -16,7 +16,7 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2012-2015 Raphaël Doursenaud * Copyright (C) 2014-2020 Alexandre Spangaro - * Copyright (C) 2018-2021 Ferran Marcet + * Copyright (C) 2018-2022 Ferran Marcet * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018 Christophe Battarel @@ -200,9 +200,10 @@ class Form * @param int $notabletag Do no output table tags * @param string $formatfunc Call a specific function to output field in view mode (For example: 'dol_print_email') * @param string $paramid Key of parameter for id ('id', 'socid') + * @param string $gm 'auto' or 'tzuser' or 'tzserver' (when $typeofdata is a date) * @return string HTML edit field */ - public function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 0, $formatfunc = '', $paramid = 'id') + public function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 0, $formatfunc = '', $paramid = 'id', $gm = 'auto') { global $conf, $langs; @@ -257,9 +258,9 @@ class Form $ret .= dol_string_neverthesehtmltags($valuetoshow, array('textarea')); $ret .= ''; } elseif ($typeofdata == 'day' || $typeofdata == 'datepicker') { - $ret .= $this->selectDate($value, $htmlname, 0, 0, 1, 'form'.$htmlname, 1, 0); + $ret .= $this->selectDate($value, $htmlname, 0, 0, 1, 'form'.$htmlname, 1, 0, 0, '', '', '', '', 1, '', '', $gm); } elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') { - $ret .= $this->selectDate($value, $htmlname, 1, 1, 1, 'form'.$htmlname, 1, 0); + $ret .= $this->selectDate($value, $htmlname, 1, 1, 1, 'form'.$htmlname, 1, 0, 0, '', '', '', '', 1, '', '', $gm); } elseif (preg_match('/^select;/', $typeofdata)) { $arraydata = explode(',', preg_replace('/^select;/', '', $typeofdata)); $arraylist = array(); @@ -311,9 +312,9 @@ class Form } elseif (preg_match('/^restricthtml/', $typeofdata)) { $ret .= dol_string_onlythesehtmltags($value); } elseif ($typeofdata == 'day' || $typeofdata == 'datepicker') { - $ret .= ''.dol_print_date($value, 'day').''; + $ret .= ''.dol_print_date($value, 'day', $gm).''; } elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') { - $ret .= ''.dol_print_date($value, 'dayhour').''; + $ret .= ''.dol_print_date($value, 'dayhour', $gm).''; } elseif (preg_match('/^select;/', $typeofdata)) { $arraydata = explode(',', preg_replace('/^select;/', '', $typeofdata)); $arraylist = array(); @@ -791,7 +792,7 @@ class Form // Warning: if you set submit button to disabled, post using 'Enter' will no more work if there is no another input submit. So we add a hidden button $ret .= ''; // Hidden button BEFORE so it is the one used when we submit with ENTER. - $ret .= 'use_javascript_ajax) ? '' : ' style="display: none"').' class="button small'.(empty($conf->use_javascript_ajax) ? '' : ' hideobject').' '.$name.' '.$name.'confirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">'; + $ret .= 'use_javascript_ajax) ? '' : ' style="display: none"').' class="button smallpaddingimp'.(empty($conf->use_javascript_ajax) ? '' : ' hideobject').' '.$name.' '.$name.'confirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">'; $ret .= '
    '; if (!empty($conf->use_javascript_ajax)) { @@ -1320,6 +1321,7 @@ class Form { // phpcs:enable global $conf, $user, $langs; + global $hookmanager; $out = ''; $num = 0; @@ -1367,6 +1369,10 @@ class Form if (!empty($excludeids)) { $sql .= " AND s.rowid NOT IN (".$this->db->sanitize(join(',', $excludeids)).")"; } + // Add where from hooks + $parameters = array(); + $reshook = $hookmanager->executeHooks('selectThirdpartyListWhere', $parameters); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; // Add criteria if ($filterkey && $filterkey != '') { $sql .= " AND ("; @@ -1599,7 +1605,7 @@ class Form * @param string $exclude List of contacts id to exclude * @param string $limitto Disable answers that are not id in this array list * @param integer $showfunction Add function into label - * @param string $moreclass Add more class to class style + * @param string $morecss Add more class to class style * @param integer $showsoc Add company into label * @param int $forcecombo Force to use combo box * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) @@ -1609,10 +1615,10 @@ class Form * @return int <0 if KO, Nb of contact in list if OK * @deprecated You can use selectcontacts directly (warning order of param was changed) */ - public function select_contacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $showsoc = 0, $forcecombo = 0, $events = array(), $options_only = false, $moreparam = '', $htmlid = '') + public function select_contacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $morecss = '', $showsoc = 0, $forcecombo = 0, $events = array(), $options_only = false, $moreparam = '', $htmlid = '') { // phpcs:enable - print $this->selectcontacts($socid, $selected, $htmlname, $showempty, $exclude, $limitto, $showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events, $moreparam, $htmlid); + print $this->selectcontacts($socid, $selected, $htmlname, $showempty, $exclude, $limitto, $showfunction, $morecss, $options_only, $showsoc, $forcecombo, $events, $moreparam, $htmlid); return $this->num; } @@ -1629,7 +1635,7 @@ class Form * @param string $exclude List of contacts id to exclude * @param string $limitto Disable answers that are not id in this array list * @param integer $showfunction Add function into label - * @param string $moreclass Add more class to class style + * @param string $morecss Add more class to class style * @param bool $options_only Return options only (for ajax treatment) * @param integer $showsoc Add company into label * @param int $forcecombo Force to use combo box (so no ajax beautify effect) @@ -1640,7 +1646,7 @@ class Form * @param integer $disableifempty Set tag 'disabled' on select if there is no choice * @return int|string <0 if KO, HTML with select string if OK. */ - public function selectcontacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $moreclass = '', $options_only = false, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $multiple = false, $disableifempty = 0) + public function selectcontacts($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $morecss = '', $options_only = false, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $multiple = false, $disableifempty = 0) { global $conf, $langs, $hookmanager, $action; @@ -1672,13 +1678,17 @@ class Form if ($showsoc > 0 || !empty($conf->global->CONTACT_SHOW_EMAIL_PHONE_TOWN_SELECTLIST)) { $sql .= " LEFT OUTER JOIN ".$this->db->prefix()."societe as s ON s.rowid=sp.fk_soc"; } - $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; if ($socid > 0 || $socid == -1) { $sql .= " AND sp.fk_soc = ".((int) $socid); } if (!empty($conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX)) { $sql .= " AND sp.statut <> 0"; } + // Add where from hooks + $parameters = array(); + $reshook = $hookmanager->executeHooks('selectContactListWhere', $parameters); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY sp.lastname ASC"; dol_syslog(get_class($this)."::selectcontacts", LOG_DEBUG); @@ -1687,7 +1697,7 @@ class Form $num = $this->db->num_rows($resql); if ($htmlname != 'none' && !$options_only) { - $out .= ''; } if ($showempty && ! is_numeric($showempty)) { @@ -2085,7 +2095,7 @@ class Form if ($num) { // Enhance with select2 include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; - $out = ajax_combobox($htmlname).$out; + $out .= ajax_combobox($htmlname); } } else { dol_print_error($this->db); @@ -2094,6 +2104,7 @@ class Form if ($outputmode) { return $outarray; } + return $out; } @@ -2461,6 +2472,7 @@ class Form { // phpcs:enable global $langs, $conf; + global $hookmanager; $out = ''; $outarray = array(); @@ -2606,6 +2618,10 @@ class Form } elseif (empty($conf->service->enabled)) { // when service module is disabled, show products only $sql .= " AND p.fk_product_type = 0"; } + // Add where from hooks + $parameters = array(); + $reshook = $hookmanager->executeHooks('selectProductsListWhere', $parameters); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; // Add criteria on ref/label if ($filterkey != '') { $sql .= ' AND ('; @@ -3179,6 +3195,7 @@ class Form { // phpcs:enable global $langs, $conf, $user; + global $hookmanager; $out = ''; $outarray = array(); @@ -3228,6 +3245,10 @@ class Form if (!empty($filtre)) { $sql .= " ".$filtre; } + // Add where from hooks + $parameters = array(); + $reshook = $hookmanager->executeHooks('selectSuppliersProductsListWhere', $parameters); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; // Add criteria on ref/label if ($filterkey != '') { $sql .= ' AND ('; @@ -3688,7 +3709,6 @@ class Form } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Load into cache list of payment terms @@ -4900,7 +4920,7 @@ class Form $more .= '
    '; $more .= '
    '.$input['label'].'
    '; $more .= ''; $formconfirm .= ''; $formconfirm .= $this->selectyesno("confirm", $newselectedchoice, 0, false, 0, 0, 'marginleftonly marginrightonly'); - $formconfirm .= ''; + $formconfirm .= ''; $formconfirm .= ''; $formconfirm .= ''."\n"; @@ -5199,6 +5221,7 @@ class Form $out .= ''; $out .= ''; } else { + $out .= ''; if ($selected) { $projet = new Project($this->db); $projet->fetch($selected); @@ -5206,6 +5229,7 @@ class Form } else { $out .= " "; } + $out .= ''; } if (empty($nooutput)) { @@ -6675,7 +6699,7 @@ class Form // phpcs:enable global $langs; - $retstring = ''; + $retstring = ''; $hourSelected = 0; $minSelected = 0; @@ -6707,7 +6731,7 @@ class Form if ($typehour != 'text') { $retstring .= ' '.$langs->trans('HourShort'); } else { - $retstring .= ':'; + $retstring .= ':'; } // Minutes @@ -6735,7 +6759,7 @@ class Form $retstring .= ' '.$langs->trans('MinuteShort'); } - //$retstring.=" "; + $retstring.=""; if (!empty($nooutput)) { return $retstring; @@ -7164,7 +7188,7 @@ class Form * @param int $limit Limit on number of returned lines * @param int $status Ticket status * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) + * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon before and placeholder, 3 search icon after) * @param array $ajaxoptions Options for ajax_autocompleter * @param int $socid Thirdparty Id (to get also price dedicated to this customer) * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. @@ -7522,7 +7546,7 @@ class Form if (!empty($objecttmp->fields)) { // For object that declare it, it is better to use declared fields (like societe, contact, ...) $tmpfieldstoshow = ''; foreach ($objecttmp->fields as $key => $val) { - if (!dol_eval($val['enabled'], 1, 1)) { + if (!dol_eval($val['enabled'], 1, 1, 1, '1')) { continue; } if (!empty($val['showoncombobox'])) { @@ -8582,6 +8606,7 @@ class Form print '
    '; print ''; print ''; + print ''; print ''; print ''; print ''; @@ -8839,7 +8864,7 @@ class Form // Add where from hooks if (is_object($hookmanager)) { - $parameters = array(); + $parameters = array('showrefnav' => true); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook $object->next_prev_filter .= $hookmanager->resPrint; } diff --git a/htdocs/core/class/html.formaccounting.class.php b/htdocs/core/class/html.formaccounting.class.php index 2e1b9661f58..67d12147a3a 100644 --- a/htdocs/core/class/html.formaccounting.class.php +++ b/htdocs/core/class/html.formaccounting.class.php @@ -439,9 +439,10 @@ class FormAccounting extends Form * @param int|string $showempty Add an empty field * @param string $morecss More css * @param string $usecache Key to use to store result into a cache. Next call with same key will reuse the cache. + * @param string $labelhtmlname HTML name of label for autofill of account from name. * @return string String with HTML select */ - public function select_auxaccount($selectid, $htmlname = 'account_num_aux', $showempty = 0, $morecss = 'maxwidth250', $usecache = '') + public function select_auxaccount($selectid, $htmlname = 'account_num_aux', $showempty = 0, $morecss = 'maxwidth250', $usecache = '', $labelhtmlname = '') { // phpcs:enable @@ -505,6 +506,19 @@ class FormAccounting extends Form // Build select $out .= Form::selectarray($htmlname, $aux_account, $selectid, ($showempty ? (is_numeric($showempty) ? 1 : $showempty): 0), 0, 0, '', 0, 0, 0, '', $morecss, 1); + //automatic filling if we give the name of the subledger_label input + if (!empty($conf->use_javascript_ajax) && !empty($labelhtmlname)) { + $out .= ''; + } return $out; } diff --git a/htdocs/core/class/html.formcategory.class.php b/htdocs/core/class/html.formcategory.class.php index 518a8f93290..707b5d5d0ac 100644 --- a/htdocs/core/class/html.formcategory.class.php +++ b/htdocs/core/class/html.formcategory.class.php @@ -49,15 +49,55 @@ class FormCategory extends Form $categoryArray = $this->select_all_categories($type, "", "", 64, 0, 1); $categoryArray[-2] = "- ".$langs->trans('NotCategorized')." -"; - $tmptitle = $langs->trans("Category"); + $tmptitle = $langs->transnoentitiesnoconv("Category"); $filter = ''; $filter .= '
    '; $filter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"'); //$filter .= $langs->trans('Categories').": "; - $filter .= Form::multiselectarray($htmlName, $categoryArray, $preSelected, 0, 0, "minwidth300", 0, 0, '', '', $tmptitle); + $filter .= Form::multiselectarray($htmlName, $categoryArray, $preSelected, 0, 0, "minwidth300 widthcentpercentminusx", 0, 0, '', '', $tmptitle); $filter .= "
    "; return $filter; } + + /** + * Prints a select form for products categories + * @param string $selected Id category pre-selection + * @param string $htmlname Name of HTML field + * @param int $showempty Add an empty field + * @return integer|null + */ + public function selectProductCategory($selected = 0, $htmlname = 'product_category_id', $showempty = 0) + { + global $conf; + + $sql = "SELECT cp.fk_categorie as cat_index, cat.label FROM `llx_categorie_product` as cp INNER JOIN llx_categorie as cat ON cat.rowid = cp.fk_categorie GROUP BY cp.fk_categorie;"; + + dol_syslog(get_class($this)."::selectProductCategory", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + print ''); + + return $num_rows; + } else { + dol_print_error($this->db); + } + } } diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index 5b3d07fe80f..f976fac978d 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -406,7 +406,7 @@ class FormCompany extends Form // Show break $key = $langs->trans("Country".strtoupper($obj->country_code)); $valuetoshow = ($key != "Country".strtoupper($obj->country_code)) ? $obj->country_code." - ".$key : $obj->country; - print '\n"; + print '\n"; $country = $obj->country; } @@ -618,7 +618,7 @@ class FormCompany extends Form */ public function selectCompaniesForNewContact($object, $var_id, $selected = '', $htmlname = 'newcompany', $limitto = '', $forceid = 0, $moreparam = '', $morecss = '') { - global $conf, $langs; + global $conf, $hookmanager; if (!empty($conf->use_javascript_ajax) && !empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT)) { // Use Ajax search @@ -718,6 +718,10 @@ class FormCompany extends Form if (is_array($limitto) && count($limitto)) { $sql .= " AND s.rowid IN (".$this->db->sanitize(join(',', $limitto)).")"; } + // Add where from hooks + $parameters = array(); + $reshook = $hookmanager->executeHooks('selectCompaniesForNewContactListWhere', $parameters); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.nom ASC"; $resql = $this->db->query($sql); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 217bba55330..b955fa4a51d 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -360,8 +360,8 @@ class FormFile * This also set the property $this->numoffiles * * @param string $modulepart Module the files are related to ('propal', 'facture', 'facture_fourn', 'mymodule', 'mymodule:MyObject', 'mymodule_temp', ...) - * @param string $modulesubdir Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module. - * @param string $filedir Directory to scan + * @param string $modulesubdir Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into a subdir of module. + * @param string $filedir Directory to scan (must not end with a /). Example: '/mydolibarrdocuments/facture/FAYYMM-1234' * @param string $urlsource Url of origin page (for return) * @param int|string[] $genallowed Generation is allowed (1/0 or array list of templates) * @param int $delallowed Remove is allowed (1/0) @@ -1283,12 +1283,22 @@ class FormFile } print ''; print ''; - if (!$disablemove) { + if (empty($disablemove) && count($filearray) > 1) { print ''; } print "\n"; } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($filearray, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if ($sortfield && $sortorder) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $filearray = dol_sort_array($filearray, $sortfield, $sortorder); + } + } + print ''; //print $url.' sortfield='.$sortfield.' sortorder='.$sortorder; print_liste_field_titre('Documents2', $url, "name", "", $param, '', $sortfield, $sortorder, 'left '); @@ -1301,21 +1311,11 @@ class FormFile print_liste_field_titre(''); // Action button print_liste_field_titre(''); - if (!$disablemove) { + if (empty($disablemove) && count($filearray) > 1) { print_liste_field_titre(''); } print "\n"; - // Get list of files stored into database for same relative directory - if ($relativedir) { - completeFileArrayWithDatabaseInfo($filearray, $relativedir); - - //var_dump($sortfield.' - '.$sortorder); - if ($sortfield && $sortorder) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) - $filearray = dol_sort_array($filearray, $sortfield, $sortorder); - } - } - $nboffiles = count($filearray); if ($nboffiles > 0) { include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; @@ -1506,22 +1506,22 @@ class FormFile if (!empty($conf->global->MAIN_ECM_DISABLE_JS)) { $useajax = 0; } - print ''.img_delete().''; + print ''.img_delete().''; } print ""; - if (empty($disablemove)) { + if (empty($disablemove) && count($filearray) > 1) { if ($nboffiles > 1 && $conf->browser->layout != 'phone') { print ''; } else { - print 'browser->layout != 'phone' && empty($disablemove)) ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'>'; + print 'browser->layout != 'phone') ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'>'; print ''; } } @@ -1531,7 +1531,7 @@ class FormFile print ''; print ''; print ''; - if (empty($disablemove)) { + if (empty($disablemove) && count($filearray) > 1) { print ''; } } @@ -1542,7 +1542,7 @@ class FormFile } if ($nboffiles == 0) { $colspan = '6'; - if (empty($disablemove)) { + if (empty($disablemove) && count($filearray) > 1) { $colspan++; // 6 columns or 7 } print '\n"; if (isset($extrafields->attributes[$elementtype]['type']) && is_array($extrafields->attributes[$elementtype]['type']) && count($extrafields->attributes[$elementtype]['type'])) { foreach ($extrafields->attributes[$elementtype]['type'] as $key => $value) { - /*if (! dol_eval($extrafields->attributes[$elementtype]['enabled'][$key], 1)) { + /*if (! dol_eval($extrafields->attributes[$elementtype]['enabled'][$key], 1, 1, '1')) { // TODO Uncomment this to exclude extrafields of modules not enabled. Add a link to "Show extrafields disabled" // continue; }*/ diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index 2dd9751a4c6..5f463e44846 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -259,7 +259,7 @@ $arrayfields = array( 'rowid' => array('label'=>$langs->trans("Id"), 'checked'=>1), 'nature' => array('label'=>$langs->trans("NatureOfContact"), 'checked'=>1), 'thirdparty' => array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), - 'contact' => array('label'=>$langs->trans("Users").'/'.$langs->trans("Contacts"), 'checked'=>1), + 'contact' => array('label'=>$langs->trans("Users").' | '.$langs->trans("Contacts"), 'checked'=>1), 'type' => array('label'=>$langs->trans("ContactType"), 'checked'=>1), 'status' => array('label'=>$langs->trans("Status"), 'checked'=>1), 'link' => array('label'=>$langs->trans("Link"), 'checked'=>1), diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index fdc315a588d..8b48a63e34d 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -66,7 +66,7 @@ if (in_array($modulepart, array('product', 'produit', 'societe', 'user', 'ticket * Confirm form to delete a file */ -if ($action == 'deletefile') { +if ($action == 'deletefile' || $action == 'deletelink') { $langs->load("companies"); // Need for string DeleteFile+ConfirmDeleteFiles print $form->formconfirm( $_SERVER["PHP_SELF"].'?id='.$object->id.'&urlfile='.urlencode(GETPOST("urlfile")).'&linkid='.GETPOST('linkid', 'int').(empty($param) ? '' : $param), diff --git a/htdocs/core/tpl/extrafields_list_array_fields.tpl.php b/htdocs/core/tpl/extrafields_list_array_fields.tpl.php index f7c9fc201f4..f691c55bd0c 100644 --- a/htdocs/core/tpl/extrafields_list_array_fields.tpl.php +++ b/htdocs/core/tpl/extrafields_list_array_fields.tpl.php @@ -18,15 +18,14 @@ if (!empty($extrafieldsobjectkey)) { // $extrafieldsobject is the $object->table if (empty($extrafieldsobjectprefix)) { $extrafieldsobjectprefix = 'ef.'; } - foreach ($extrafields->attributes[$extrafieldsobjectkey]['label'] as $key => $val) { if (!empty($extrafields->attributes[$extrafieldsobjectkey]['list'][$key])) { $arrayfields[$extrafieldsobjectprefix.$key] = array( 'label' => $extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 'type' => $extrafields->attributes[$extrafieldsobjectkey]['type'][$key], - 'checked' => (($extrafields->attributes[$extrafieldsobjectkey]['list'][$key] < 0) ? 0 : 1), + 'checked' => ((dol_eval($extrafields->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '1') <= 0) ? 0 : 1), 'position' => $extrafields->attributes[$extrafieldsobjectkey]['pos'][$key], - 'enabled' => (abs((int) $extrafields->attributes[$extrafieldsobjectkey]['list'][$key]) != 3 && $extrafields->attributes[$extrafieldsobjectkey]['perms'][$key]), + 'enabled' => (abs((int) dol_eval($extrafields->attributes[$extrafieldsobjectkey]['list'][$key], 1)) != 3 && dol_eval($extrafields->attributes[$extrafieldsobjectkey]['perms'][$key], 1, 1, '1')), 'langfile' => $extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key], 'help' => $extrafields->attributes[$extrafieldsobjectkey]['help'][$key], ); diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php index 80d6cd7da56..00c2739e3f8 100644 --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php @@ -38,7 +38,7 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield //var_dump($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key]); //var_dump($obj); //var_dump($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key]); - $value = dol_eval($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key], 1); + $value = dol_eval($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key], 1, 1, '0'); //var_dump($value); } diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 8afa9a16ff0..3db65e198c5 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -1,7 +1,7 @@ * Copyright (C) 2014 Juanjo Menent - * Copyright (C) 2021 Frédéric France + * Copyright (C) 2021 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,7 +40,7 @@ if (!is_object($form)) { ?> attributes[$object->table_element]['l // Print line tr of extra field if ($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra] == 'separate') { - $extrafields_collapse_num = ''; - $extrafield_param = $extrafields->attributes[$object->table_element]['param'][$tmpkeyextra]; - if (!empty($extrafield_param) && is_array($extrafield_param)) { - $extrafield_param_list = array_keys($extrafield_param['options']); - - if (count($extrafield_param_list) > 0) { - $extrafield_collapse_display_value = intval($extrafield_param_list[0]); - - if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) { - $extrafields_collapse_num = $extrafields->attributes[$object->table_element]['pos'][$tmpkeyextra]; - } - } - } + $extrafields_collapse_num = $tmpkeyextra; print $extrafields->showSeparator($tmpkeyextra, $object); @@ -134,7 +122,7 @@ if (empty($reshook) && isset($extrafields->attributes[$object->table_element]['l print ' trextrafields_collapse_last'; } print '"'; - if (empty($extrafields->expand_display[$collapse_group])) { + if (isset($extrafields->expand_display) && empty($extrafields->expand_display[$collapse_group])) { print ' style="display: none;"'; } print '>'; @@ -161,6 +149,7 @@ if (empty($reshook) && isset($extrafields->attributes[$object->table_element]['l //var_dump($user->rights); $permok = false; $keyforperm = $object->element; + if ($object->element == 'fichinter') { $keyforperm = 'ficheinter'; } diff --git a/htdocs/core/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php index e776388ac53..573ae315913 100644 --- a/htdocs/core/tpl/filemanager.tpl.php +++ b/htdocs/core/tpl/filemanager.tpl.php @@ -34,6 +34,8 @@ if (empty($conf) || !is_object($conf)) { require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; +$langs->load("ecm"); + if (empty($module)) { $module = 'ecm'; } diff --git a/htdocs/core/tpl/list_print_total.tpl.php b/htdocs/core/tpl/list_print_total.tpl.php index b015dc51fdc..8d84228e2ec 100644 --- a/htdocs/core/tpl/list_print_total.tpl.php +++ b/htdocs/core/tpl/list_print_total.tpl.php @@ -14,7 +14,7 @@ if (isset($totalarray['pos'])) { $i++; if (!empty($totalarray['pos'][$i])) { print ' + '; $coldisplay++; @@ -641,17 +651,20 @@ if (!empty($usemargins) && $user->rights->margins->creer) { $("#select_type").change(function() { setforfree(); - if (jQuery('#select_type').val() >= 0) - { - /* focus work on a standard textarea but not if field was replaced with CKEDITOR */ + + if (jQuery('#select_type').val() >= 0) { + console.log("Set focus on description field"); + /* this focus code works on a standard textarea but not if field was replaced with CKEDITOR */ jQuery('#dp_desc').focus(); - /* focus if CKEDITOR */ - if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") - { + /* this focus code works for CKEDITOR */ + if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined") { var editor = CKEDITOR.instances['dp_desc']; - if (editor) { editor.focus(); } + if (editor) { + editor.focus(); + } } } + console.log("Hide/show date according to product type"); if (jQuery('#select_type').val() == '0') { @@ -1030,18 +1043,18 @@ if (!empty($usemargins) && $user->rights->margins->creer) { jQuery("#multicurrency_price_ht").val('').show(); jQuery("#title_up_ht, #title_up_ht_currency").show(); - jQuery("#price_ht").val('').hide(); + //jQuery("#price_ht").val('').hide(); jQuery("#multicurrency_price_ht").val('').hide(); jQuery("#title_up_ht, #title_up_ht_currency").hide(); - global->MAIN_ENABLE_EDIT_PREDEF_PRICETTC)) { ?> - jQuery("#price_ttc").val('').hide(); - jQuery("#multicurrency_price_ttc").val('').hide(); - jQuery("#title_up_ttc, #title_up_ttc_currency").hide(); - + global->MAIN_DISABLE_EDIT_PREDEF_PRICETTC)) { ?> jQuery("#price_ttc").val('').show(); jQuery("#multicurrency_price_ttc").val('').show(); jQuery("#title_up_ttc, #title_up_ttc_currency").show(); + + jQuery("#price_ttc").val('').hide(); + jQuery("#multicurrency_price_ttc").val('').hide(); + jQuery("#title_up_ttc, #title_up_ttc_currency").hide(); jQuery("#fourn_ref, #tva_tx, #title_vat").hide(); /* jQuery("#title_fourn_ref").hide(); */ diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 0f0043eadd6..c59949d5fb7 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -6,6 +6,7 @@ * Copyright (C) 2012-2014 Raphaël Doursenaud * Copyright (C) 2013 Florian Henry * Copyright (C) 2018 Frédéric France + * Copyright (C) 2022 OpenDSI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,6 +73,11 @@ if (in_array($object->element, array('propal', 'supplier_proposal', 'facture', ' if (!empty($conf->multicurrency->enabled) && $this->multicurrency_code != $conf->currency) { $colspan += 2; } +if (!empty($conf->asset->enabled) && $object->element == 'invoice_supplier') { + $colspan++; +} + + print "\n"; @@ -84,7 +90,7 @@ $coldisplay = 0; $coldisplay++; ?> - + - '; } +if (!empty($conf->asset->enabled) && $object->element == 'invoice_supplier') { + print ''; +} + print ''; // No width to allow autodim print ''; diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 36eceb87341..c2d81b81eb5 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -6,6 +6,7 @@ * Copyright (C) 2012-2014 Raphaël Doursenaud * Copyright (C) 2013 Florian Henry * Copyright (C) 2017 Juanjo Menent + * Copyright (C) 2022 OpenDSI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -171,13 +172,13 @@ if (($line->info_bits & 2) == 2) { print '
    '; } if ($line->date_start_fill) { - print ''.$langs->trans('AutoFillDateFromShort').': '.yn($line->date_start_fill); + print ''.$langs->trans('AutoFillDateFromShort').': '.yn($line->date_start_fill); } if ($line->date_start_fill && $line->date_end_fill) { print ' - '; } if ($line->date_end_fill) { - print ''.$langs->trans('AutoFillDateToShort').': '.yn($line->date_end_fill); + print ''.$langs->trans('AutoFillDateToShort').': '.yn($line->date_end_fill); } if ($line->date_start_fill || $line->date_end_fill) { print '
    '; @@ -199,7 +200,16 @@ if (($line->info_bits & 2) == 2) { } } - //print get_date_range($line->date_start, $line->date_end, $format); + // If we show the lines in a context to create a recurring sale invoice + if (basename($_SERVER["PHP_SELF"]) == 'card-rec.php') { + $default_start_fill = getDolGlobalInt('INVOICEREC_SET_AUTOFILL_DATE_START'); + $default_end_fill = getDolGlobalInt('INVOICEREC_SET_AUTOFILL_DATE_END'); + print '
    '; + print ''.$langs->trans('AutoFillDateFromShort').': '.yn($default_start_fill); + print ' - '; + print ''.$langs->trans('AutoFillDateToShort').': '.yn($default_end_fill); + print '
    '; + } } // Add description in form @@ -387,6 +397,35 @@ if ($this->statut == 0 && !empty($object_rights->creer) && $action != 'selectlin } } + if (!empty($conf->asset->enabled) && $object->element == 'invoice_supplier') { + print '
    '; + } + print ''; print ''; print ''; print ''; @@ -41,6 +42,7 @@ if (!empty($conf->global->PRODUCT_USE_UNITS)) { } print ''; +print ''; $selected = 1; if (!empty($selectedLines) && !in_array($this->tpl['id'], $selectedLines)) { diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php index 64d545ba583..02bc8ce421f 100644 --- a/htdocs/core/tpl/resource_add.tpl.php +++ b/htdocs/core/tpl/resource_add.tpl.php @@ -13,9 +13,11 @@ require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; $form = new Form($db); $formresources = new FormResource($db); -$out = '
    '; +$out = ''; -$out .= '
    '; +$out .= '
    '; + +$out .= ''; $out .= ''; $out .= ''; $out .= ''; @@ -23,21 +25,30 @@ $out .= ''; $out .= ''; $out .= ''; +$out .= '
    '; // Place -$out .= '
    '.$langs->trans("SelectResource").'
    '; -$out .= '
    '; +$out .= '
    '.$langs->trans("SelectResource").'
    '; +$out .= '
    '; $events = array(); $out .= $formresources->select_resource_list('', 'fk_resource', '', 1, 1, 0, $events, '', 2, null); $out .= '
    '; -$out .= '
    '.$form->selectyesno('busy', (GETPOSTISSET('busy') ? GETPOST('busy') : 1), 1).'
    '; -$out .= '
    '.$form->selectyesno('mandatory', (GETPOSTISSET('mandatory') ? GETPOST('mandatory') : 0), 1).'
    '; +$out .= '
    '; +//$out .= $form->selectyesno('busy', (GETPOSTISSET('busy') ? GETPOST('busy') : 1), 1); +$out .= ''; +$out .= '
    '; +$out .= '
    '; +//$out .= $form->selectyesno('mandatory', (GETPOSTISSET('mandatory') ? GETPOST('mandatory') : 0), 1); +$out .= ''; +$out .= '
    '; -$out .= '
    '; +$out .= '
    '; $out .= ''; $out .= '
    '; +$out .= '
    '; + $out .= ''; $out .= '
    '; diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index 048dc170c0a..1d46aec1008 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -424,6 +424,61 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } + if ($action == 'TICKET_CREATE') { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + // Auto link contract + if (!empty($conf->contract->enabled) && !empty($conf->ticket->enabled) && !empty($conf->ficheinter->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_TICKET_LINK_CONTRACT) && !empty($conf->global->TICKET_PRODUCT_CATEGORY) && !empty($object->fk_soc)) { + $societe = new Societe($this->db); + $company_ids = (empty($conf->global->WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS)) ? [$object->fk_soc] : $societe->getParentsForCompany($object->fk_soc, [$object->fk_soc]); + + $contrat = new Contrat($this->db); + $number_contracts_found = 0; + foreach ($company_ids as $company_id) { + $contrat->socid = $company_id; + $list = $contrat->getListOfContracts($option = 'all', $status = [Contrat::STATUS_DRAFT, Contrat::STATUS_VALIDATED], $product_categories = [$conf->global->TICKET_PRODUCT_CATEGORY], $line_status = [ContratLigne::STATUS_INITIAL, ContratLigne::STATUS_OPEN]); + if (is_array($list) && !empty($list)) { + $number_contracts_found = count($list); + if ($number_contracts_found == 1) { + $contractid = $list[0]->id; + $object->setContract($contractid); + break; + } elseif ($number_contracts_found > 1) { + foreach ($list as $linked_contract) { + $object->setContract($linked_contract->id); + // don't set '$contractid' so it is not used when creating an intervention. + } + if (empty(NOLOGIN)) setEventMessage($langs->trans('TicketManyContractsLinked'), 'warnings'); + break; + } + } + } + if ($number_contracts_found == 0) { + if (empty(NOLOGIN)) setEventMessage($langs->trans('TicketNoContractFoundToLink'), 'mesgs'); + } + } + // Automatically create intervention + if (!empty($conf->ficheinter->enabled) && !empty($conf->ticket->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_TICKET_CREATE_INTERVENTION)) { + $fichinter = new Fichinter($this->db); + $fichinter->socid = (int) $object->fk_soc; + $fichinter->fk_project = $projectid; + $fichinter->fk_contrat = (int) $object->fk_contract; + $fichinter->author = $user->id; + $fichinter->model_pdf = (!empty($conf->global->FICHEINTER_ADDON_PDF)) ? $conf->global->FICHEINTER_ADDON_PDF : 'soleil'; + $fichinter->origin = $object->element; + $fichinter->origin_id = $object->id; + + // Extrafields + $extrafields = new ExtraFields($this->db); + $extrafields->fetch_name_optionals_label($fichinter->table_element); + $array_options = $extrafields->getOptionalsFromPost($fichinter->table_element); + $fichinter->array_options = $array_options; + + $id = $fichinter->create($user); + if ($id <= 0) { + setEventMessages($fichinter->error, null, 'errors'); + } + } + } return 0; } diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index 2ff5d3f9c43..cf6a8220c29 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -958,11 +958,13 @@ class InterfaceActionsAuto extends DolibarrTriggers } } + /* Seems no more required: We have the data in dedicated field now. if (!empty($user->login)) { $object->actionmsg = dol_concatdesc($langs->transnoentities("Author").': '.$user->login, $object->actionmsg); } elseif (isset($object->origin_email)) { $object->actionmsg = dol_concatdesc($langs->transnoentities("Author").': '.$object->origin_email, $object->actionmsg); } + */ dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); @@ -1019,7 +1021,7 @@ class InterfaceActionsAuto extends DolibarrTriggers $actioncomm->type_code = $object->actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...) $actioncomm->code = 'AC_'.$action; $actioncomm->label = $object->actionmsg2; - $actioncomm->note_private = $object->actionmsg; // TODO Replace with ($actioncomm->email_msgid ? $object->email_content : $object->actionmsg) + $actioncomm->note_private = $object->actionmsg; $actioncomm->fk_project = $projectid; $actioncomm->datep = $now; $actioncomm->datef = $now; diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index fe89a05ab20..6e4f8cb1563 100644 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2006-2011 Laurent Destailleur * Copyright (C) 2011 Regis Houssin * Copyright (C) 2013-2014 Marcos García + * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -90,9 +91,25 @@ class InterfaceNotification extends DolibarrTriggers public function getListOfManagedEvents() { global $conf; + global $hookmanager; + + + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('notification')); + + $reshook = $hookmanager->executeHooks('notifsupported', $parameters, $object, $action); + if (empty($reshook)) { + if (!empty($hookmanager->resArray['arrayofnotifsupported'])) { + $this->listofmanagedevents = array_merge($this->listofmanagedevents, $hookmanager->resArray['arrayofnotifsupported']); + } + } $ret = array(); + $sql = "SELECT rowid, code, label, description, elementtype"; $sql .= " FROM ".MAIN_DB_PREFIX."c_action_trigger"; $sql .= $this->db->order("rang, elementtype, code"); diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php index dfd83022393..e13328e0a2a 100644 --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php @@ -133,77 +133,28 @@ class InterfaceTicketEmail extends DolibarrTriggers $langs->load('ticket'); + $subject_admin = 'TicketNewEmailSubjectAdmin'; + $body_admin = 'TicketNewEmailBodyAdmin'; + $subject_customer = 'TicketNewEmailSubjectCustomer'; + $body_customer = 'TicketNewEmailBodyCustomer'; + $see_ticket_customer = 'TicketNewEmailBodyInfosTrackUrlCustomer'; + // Send email to notification email if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && empty($object->context['disableticketemail'])) { $sendto = empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; - if ($sendto) { - // Init to avoid errors - $filepath = array(); - $filename = array(); - $mimetype = array(); - - /* Send email to admin */ - $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectAdmin'); - $message_admin = $langs->transnoentities('TicketNewEmailBodyAdmin', $object->track_id).'

    '; - $message_admin .= '
    • '.$langs->trans('Title').' : '.$object->subject.'
    • '; - $message_admin .= '
    • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
    • '; - $message_admin .= '
    • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
    • '; - $message_admin .= '
    • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
    • '; - $message_admin .= '
    • '.$langs->trans('From').' : '.($object->email_from ? $object->email_from : ($object->fk_user_create > 0 ? $langs->trans('Internal') : '')).'
    • '; - // Extrafields - $extraFields = new ExtraFields($this->db); - $extraFields->fetch_name_optionals_label($object->table_element); - if (is_array($object->array_options) && count($object->array_options) > 0) { - foreach ($object->array_options as $key => $value) { - $key = substr($key, 8); // remove "options_" - $message_admin .= '
    • '.$langs->trans($extraFields->attributes[$object->element]['label'][$key]).' : '.$extraFields->showOutputField($key, $value, '', $object->table_element).'
    • '; - } - } - $message_admin .= '
    '; - - if ($object->fk_soc > 0) { - $object->fetch_thirdparty(); - $message_admin .= '

    '.$langs->trans('Company').' : '.$object->thirdparty->name.'

    '; - } - - $message = $object->message; - if (!dol_textishtml($message)) { - $message = dol_nl2br($message); - } - $message_admin .= '

    '.$langs->trans('Message').' :
    '.$message.'

    '; - $message_admin .= '

    '.$langs->trans('SeeThisTicketIntomanagementInterface').'

    '; - - $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; - $replyto = $from; - - $trackid = 'tic'.$object->id; - - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; - $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; - } - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); - if ($mailfile->error) { - dol_syslog($mailfile->error, LOG_DEBUG); - } else { - $result = $mailfile->sendfile(); - } - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; - } + $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); } } // Send email to customer - if (empty($conf->global->TICKET_DISABLE_CUSTOMER_MAILS) && empty($object->context['disableticketemail']) && $object->notify_tiers_at_create) { $sendto = ''; //if contact selected send to email's contact else send to email's thirdparty $contactid = GETPOST('contactid', 'alpha'); + $res = 0; if (!empty($contactid)) { $contact = new Contact($this->db); @@ -218,77 +169,7 @@ class InterfaceTicketEmail extends DolibarrTriggers } if ($sendto) { - // Init to avoid errors - $filepath = array(); - $filename = array(); - $mimetype = array(); - - $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectCustomer'); - $message_customer = $langs->transnoentities('TicketNewEmailBodyCustomer', $object->track_id).'

    '; - $message_customer .= '
    • '.$langs->trans('Title').' : '.$object->subject.'
    • '; - $message_customer .= '
    • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
    • '; - $message_customer .= '
    • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
    • '; - $message_customer .= '
    • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
    • '; - - // Extrafields - foreach ($this->attributes[$object->table_element]['label'] as $key => $value) { - $enabled = 1; - if ($enabled && isset($this->attributes[$object->table_element]['list'][$key])) { - $enabled = dol_eval($this->attributes[$object->table_element]['list'][$key], 1); - } - $perms = 1; - if ($perms && isset($this->attributes[$object->table_element]['perms'][$key])) { - $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1); - } - - $qualified = true; - if (empty($enabled)) { - $qualified = false; - } - if (empty($perms)) { - $qualified = false; - } - - if ($qualified) { - $message_customer .= '
    • '.$langs->trans($key).' : '.$value.'
    • '; - } - } - - $message_customer .= '
    '; - - $message = $object->message; - if (!dol_textishtml($message)) { - $message = dol_nl2br($message); - } - $message_customer .= '

    '.$langs->trans('Message').' :
    '.$message.'

    '; - $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id; - $message_customer .= '

    '.$langs->trans('TicketNewEmailBodyInfosTrackUrlCustomer').' : '.$url_public_ticket.'

    '; - $message_customer .= '

    '.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'

    '; - - $from = (empty($conf->global->MAIN_INFO_SOCIETE_NOM) ? '' : $conf->global->MAIN_INFO_SOCIETE_NOM.' ').'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; - $replyto = $from; - - $trackid = 'tic'.$object->id; - - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; - $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; - } - include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); - if ($mailfile->error) { - dol_syslog($mailfile->error, LOG_DEBUG); - } else { - $result = $mailfile->sendfile(); - if ($result) { - // update last_msg_sent date - $object->date_last_msg_sent = dol_now(); - $object->update($user); - } - } - if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; - } + $this->composeAndSendCustomerMessage($sendto, $subject_customer, $body_customer, $see_ticket_customer, $object, $langs, $conf); } } @@ -305,10 +186,226 @@ class InterfaceTicketEmail extends DolibarrTriggers case 'TICKET_CLOSE': dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + $langs->load('ticket'); + + $subject_admin = 'TicketCloseEmailSubjectAdmin'; + $body_admin = 'TicketCloseEmailBodyAdmin'; + $subject_customer = 'TicketCloseEmailSubjectCustomer'; + $body_customer = 'TicketCloseEmailBodyCustomer'; + $see_ticket_customer = 'TicketCloseEmailBodyInfosTrackUrlCustomer'; + + // Send email to notification email + if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && empty($object->context['disableticketemail'])) { + $sendto = empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) ? '' : $conf->global->TICKET_NOTIFICATION_EMAIL_TO; + if ($sendto) { + $this->composeAndSendAdminMessage($sendto, $subject_admin, $body_admin, $object, $langs); + } + } + + // Send email to customer. + if (empty($conf->global->TICKET_DISABLE_CUSTOMER_MAILS) && empty($object->context['disableticketemail'])) { + $linked_contacts = $object->listeContact(-1, 'thirdparty'); + $linked_contacts = array_merge($linked_contacts, $object->listeContact(-1, 'internal')); + if (empty($linked_contacts) && !empty($conf->global->TICKET_NOTIFY_AT_CLOSING) && !empty($object->fk_soc)) { + $object->fetch_thirdparty(); + $linked_contacts[] = $object->thirdparty->email; + } + + $contactid = GETPOST('contactid', 'int'); + $res = 0; + + if ($contactid > 0) { + $contact = new Contact($this->db); + $res = $contact->fetch($contactid); + if (! in_array($contact, $linked_contacts)) { + $error_msg = $langs->trans('Error'). ': '; + $error_msg .= $langs->transnoentities('TicketWrongContact'); + setEventMessages($error_msg, [], 'errors'); + $ok = 0; + break; + } + } + + $sendto = ''; + if ($res > 0 && !empty($contact->email) && !empty($contact->statut)) { + $sendto = $contact->email; + } elseif ( !empty($linked_contacts) && ($contactid == -2 || (GETPOST('massaction', 'alpha') == 'close' && GETPOST('confirm', 'alpha') == 'yes'))) { + // if sending to all contacts or sending to contacts while mass closing + $temp_emails = []; + foreach ($linked_contacts as $contact) { + $temp_emails[] = $contact['email']; + } + $sendto = implode(", ", $temp_emails); + unset($temp_emails); + unset($linked_contacts); + } + if ($sendto) { + $this->composeAndSendCustomerMessage($sendto, $subject_customer, $body_customer, $see_ticket_customer, $object, $langs, $conf); + } + } + $ok = 1; break; } - return $ok; } + + /** + * Composes and sends a message concerning a ticket, to be sent to admin address. + * + * @param string $sendto Addresses to send the mail, format "first@address.net, second@address.net," etc. + * @param string $base_subject email subject. Non-translated string. + * @param string $body email body (first line). Non-translated string. + * @param Ticket $object the ticket thet the email refers to + * @param Translate $langs the translation object + * @return void + */ + private function composeAndSendAdminMessage($sendto, $base_subject, $body, Ticket $object, Translate $langs) + { + global $conf; + + // Init to avoid errors + $filepath = array(); + $filename = array(); + $mimetype = array(); + + /* Send email to admin */ + $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject, $object->ref, $object->track_id); + $message_admin = $langs->transnoentities($body, $object->track_id).'
    '; + $message_admin .= '
    • '.$langs->trans('Title').' : '.$object->subject.'
    • '; + $message_admin .= '
    • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
    • '; + $message_admin .= '
    • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
    • '; + $message_admin .= '
    • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
    • '; + $message_admin .= '
    • '.$langs->trans('From').' : '.($object->email_from ? $object->email_from : ($object->fk_user_create > 0 ? $langs->trans('Internal') : '')).'
    • '; + // Extrafields + $extraFields = new ExtraFields($this->db); + $extraFields->fetch_name_optionals_label($object->table_element); + if (is_array($object->array_options) && count($object->array_options) > 0) { + foreach ($object->array_options as $key => $value) { + $key = substr($key, 8); // remove "options_" + $message_admin .= '
    • '.$langs->trans($extraFields->attributes[$object->element]['label'][$key]).' : '.$extraFields->showOutputField($key, $value, '', $object->table_element).'
    • '; + } + } + if ($object->fk_soc > 0) { + $object->fetch_thirdparty(); + $message_admin .= '
    • '.$langs->trans('Company').' : '.$object->thirdparty->name.'
    • '; + } + $message_admin .= '
    '; + + $message = $object->message; + if (!dol_textishtml($message)) { + $message = dol_nl2br($message); + } + $message_admin .= '

    '.$langs->trans('Message').' :

    '.$message.'


    '; + $message_admin .= '

    '.$langs->trans('SeeThisTicketIntomanagementInterface').'

    '; + + $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; + + $trackid = 'tic'.$object->id; + + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; + $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; + } + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); + if ($mailfile->error) { + dol_syslog($mailfile->error, LOG_DEBUG); + } else { + $result = $mailfile->sendfile(); + } + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; + } + } + + /** + * Composes and sends a message concerning a ticket, to be sent to customer addresses. + * + * @param string $sendto Addresses to send the mail, format "first@address.net, second@address.net, " etc. + * @param string $base_subject email subject. Non-translated string. + * @param string $body email body (first line). Non-translated string. + * @param string $see_ticket string indicating the ticket public address + * @param Ticket $object the ticket thet the email refers to + * @param Translate $langs the translation object + * @return void + */ + private function composeAndSendCustomerMessage($sendto, $base_subject, $body, $see_ticket, Ticket $object, Translate $langs) + { + global $conf, $user; + + // Init to avoid errors + $filepath = array(); + $filename = array(); + $mimetype = array(); + + $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities($base_subject); + $message_customer = $langs->transnoentities($body, $object->track_id).'
    '; + $message_customer .= '
    • '.$langs->trans('Title').' : '.$object->subject.'
    • '; + $message_customer .= '
    • '.$langs->trans('Type').' : '.$langs->getLabelFromKey($this->db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code).'
    • '; + $message_customer .= '
    • '.$langs->trans('Category').' : '.$langs->getLabelFromKey($this->db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code).'
    • '; + $message_customer .= '
    • '.$langs->trans('Severity').' : '.$langs->getLabelFromKey($this->db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code).'
    • '; + + // Extrafields + if (is_array($this->attributes[$object->table_element]['label'])) { + foreach ($this->attributes[$object->table_element]['label'] as $key => $value) { + $enabled = 1; + if ($enabled && isset($this->attributes[$object->table_element]['list'][$key])) { + $enabled = dol_eval($this->attributes[$object->table_element]['list'][$key], 1); + } + $perms = 1; + if ($perms && isset($this->attributes[$object->table_element]['perms'][$key])) { + $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1); + } + + $qualified = true; + if (empty($enabled)) { + $qualified = false; + } + if (empty($perms)) { + $qualified = false; + } + + if ($qualified) { + $message_customer .= '
    • ' . $langs->trans($key) . ' : ' . $value . '
    • '; + } + } + } + + $message_customer .= '
    '; + + $message = $object->message; + if (!dol_textishtml($message)) { + $message = dol_nl2br($message); + } + $message_customer .= '

    '.$langs->trans('Message').' :

    '.$message.'


    '; + $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id; + $message_customer .= '

    '.$langs->trans($see_ticket).' : '.$url_public_ticket.'

    '; + $message_customer .= '

    '.$langs->trans('TicketEmailPleaseDoNotReplyToThisEmail').'

    '; + + $from = (empty($conf->global->MAIN_INFO_SOCIETE_NOM) ? '' : $conf->global->MAIN_INFO_SOCIETE_NOM.' ').'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; + + $trackid = 'tic'.$object->id; + + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; + $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; + } + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message_customer, $filepath, $mimetype, $filename, '', '', 0, -1, '', '', $trackid, '', 'ticket'); + if ($mailfile->error) { + dol_syslog($mailfile->error, LOG_DEBUG); + } else { + $result = $mailfile->sendfile(); + if ($result) { + // update last_msg_sent date + $object->fetch($object->id); + $object->date_last_msg_sent = dol_now(); + $object->update($user); + } + } + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { + $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; + } + } } diff --git a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php index 0e571f26c98..dfac4c5b84d 100644 --- a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php +++ b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php @@ -183,7 +183,7 @@ class InterfaceStripe extends DolibarrTriggers if ($action == 'COMPANY_DELETE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (!empty($conf->global->STRIPE_DELETE_STRIPE_ACCOUNT_WHEN_DELETING_THIRPARTY)) { + if (!empty($conf->global->STRIPE_DELETE_STRIPE_ACCOUNT_WHEN_DELETING_THIRDPARTY)) { // By default, we do not delete the stripe account. We may need to reuse it with its payment_intent, for example if delete is for a merge of thirdparties. $stripeacc = $stripe->getStripeAccount($service); // No need of network access for this. May return '' if no Oauth defined. diff --git a/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php b/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php index 8025f0c0293..8a2cffe05f3 100644 --- a/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php +++ b/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php @@ -18,17 +18,7 @@ /** * \file core/triggers/interface_99_modZapier_ZapierTriggers.class.php * \ingroup zapier - * \brief Example trigger. - * - * - * \remarks You can create other triggers by copying this one. - * - File name should be either: - * - interface_99_modZapier_MyTrigger.class.php - * - interface_99_all_MyTrigger.class.php - * - The file must stay in core/triggers - * - The class name must be InterfaceMytrigger - * - The constructor method must be named InterfaceMytrigger - * - The name property name must be MyTrigger + * \brief File for Zappier Triggers. */ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php index 97199614ece..8205696751b 100644 --- a/htdocs/core/website.inc.php +++ b/htdocs/core/website.inc.php @@ -27,6 +27,11 @@ include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; +$website = null; +$websitepage = null; +$weblangs = null; +$pagelangs = null; + // Detection browser (copy of code from main.inc.php) if (isset($_SERVER["HTTP_USER_AGENT"]) && is_object($conf) && empty($conf->browser->name)) { $tmp = getBrowserInfo($_SERVER["HTTP_USER_AGENT"]); @@ -68,7 +73,7 @@ if ($pageid > 0) { $weblangs->setDefaultLang(GETPOSTISSET('lang') ? GETPOST('lang', 'aZ09') : (empty($_COOKIE['weblangs-shortcode']) ? 'auto' : preg_replace('/[^a-zA-Z0-9_\-]/', '', $_COOKIE['weblangs-shortcode']))); $pagelangs->setDefaultLang($websitepage->lang ? $websitepage->lang : $weblangs->shortlang); - if (!defined('USEDOLIBARREDITOR') && (in_array($websitepage->type_container, array('menu', 'other')) || empty($websitepage->status))) { + if (!defined('USEDOLIBARREDITOR') && (in_array($websitepage->type_container, array('menu', 'other')) || empty($websitepage->status) && !defined('USEDOLIBARRSERVER'))) { $weblangs->load("website"); http_response_code(404); print '


    '.$weblangs->trans("YouTryToAccessToAFileThatIsNotAWebsitePage", $websitepage->pageurl, $websitepage->type_container, $websitepage->status).'
    '; diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index fc208fd9ac3..7ee64ec2c6f 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -478,8 +478,12 @@ if ($num > 0) { if (empty($obj)) { break; } - if (isset($obj->test) && !verifCond($obj->test)) { - continue; // Discard line with test = false + + if (isset($obj->test)) { + $veriftest = verifCond($obj->test); + if (!$veriftest) { + continue; // Discard line with test = false + } } $object->id = $obj->rowid; diff --git a/htdocs/datapolicy/README.md b/htdocs/datapolicy/README.md index e2bde95a6d8..0d70b287a81 100644 --- a/htdocs/datapolicy/README.md +++ b/htdocs/datapolicy/README.md @@ -1,5 +1,7 @@ DataPolicy ========== + This module provides features to be compliant with data privacy rules of your country. -A schedlued job is installed to automatically clean old record in your database. You defined what to delete and when in the setup of module. \ No newline at end of file +A scheduled job is installed to automatically delete old records in your database. +In the setup of the module you define what should be deleted and when. diff --git a/htdocs/delivery/card.php b/htdocs/delivery/card.php index 00975946f6b..382e78df8d3 100644 --- a/htdocs/delivery/card.php +++ b/htdocs/delivery/card.php @@ -90,6 +90,9 @@ $error = 0; $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +// Delete Link +$permissiondellink = $user->rights->expedition->delivery->supprimer; // Used by the include of actions_dellink.inc.php +include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once if ($action == 'add') { $db->begin(); @@ -649,15 +652,15 @@ if ($action == 'create') { // Create. Seems to no be used if ($object->statut == 0 && $num_prod > 0) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->delivery->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->delivery_advance->validate))) { - print ''.$langs->trans("Validate").''; + print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=valid&token='.newToken().'&id='.$object->id, ''); } } if ($user->rights->expedition->delivery->supprimer) { if ($conf->expedition_bon->enabled) { - print ''.$langs->trans("Delete").''; + print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&expid='.$object->origin_id.'&action=delete&token='.newToken().'&backtopage='.urlencode(DOL_URL_ROOT.'/expedition/card.php?id='.$object->origin_id), ''); } else { - print ''.$langs->trans("Delete").''; + print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, ''); } } diff --git a/htdocs/delivery/class/delivery.class.php b/htdocs/delivery/class/delivery.class.php index 3241461ace1..f41b855e123 100644 --- a/htdocs/delivery/class/delivery.class.php +++ b/htdocs/delivery/class/delivery.class.php @@ -796,10 +796,10 @@ class Delivery extends CommonObject $num = $this->db->num_rows($resql); $i = 0; while ($i < $num) { - $line = new DeliveryLine($this->db); - $obj = $this->db->fetch_object($resql); + $line = new DeliveryLine($this->db); + $line->id = $obj->rowid; $line->label = $obj->custom_label; $line->description = $obj->description; @@ -1092,6 +1092,23 @@ class Delivery extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'deliverydet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } } diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index 597f15b7f10..f9af0568bf0 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -293,7 +293,7 @@ class Donations extends DolibarrApi * @throws RestException 304 * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error * * @return array */ diff --git a/htdocs/don/class/paymentdonation.class.php b/htdocs/don/class/paymentdonation.class.php index 0f8db03597d..6de83f5570e 100644 --- a/htdocs/don/class/paymentdonation.class.php +++ b/htdocs/don/class/paymentdonation.class.php @@ -64,7 +64,8 @@ class PaymentDonation extends CommonObject public $amounts = array(); // Array of amounts - public $typepayment; + public $fk_typepayment; // Payment mode ID + public $paymenttype; // Payment mode ID public $num_payment; @@ -268,7 +269,8 @@ class PaymentDonation extends CommonObject $this->tms = $this->db->jdate($obj->tms); $this->datep = $this->db->jdate($obj->datep); $this->amount = $obj->amount; - $this->fk_typepayment = $obj->fk_typepayment; + $this->fk_typepayment = $obj->fk_typepayment; // For backward compatibility + $this->paymenttype = $obj->fk_typepayment; $this->num_payment = $obj->num_payment; $this->note_public = $obj->note_public; $this->fk_bank = $obj->fk_bank; @@ -545,6 +547,7 @@ class PaymentDonation extends CommonObject $this->datep = ''; $this->amount = ''; $this->fk_typepayment = ''; + $this->paymenttype = ''; $this->num_payment = ''; $this->note_public = ''; $this->fk_bank = ''; diff --git a/htdocs/don/tpl/linkedobjectblock.tpl.php b/htdocs/don/tpl/linkedobjectblock.tpl.php index 4097e73d560..5d564d43f7a 100644 --- a/htdocs/don/tpl/linkedobjectblock.tpl.php +++ b/htdocs/don/tpl/linkedobjectblock.tpl.php @@ -19,7 +19,7 @@ * */ -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index f99a567a314..fb9b2a35dd0 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -627,10 +627,10 @@ class EcmDirectory extends CommonObject * date_c Date creation * fk_user_c User creation * login_c Login creation - * fullpath Full path of id (Added by build_path_from_id_categ call) - * fullrelativename Full path name (Added by build_path_from_id_categ call) - * fulllabel Full label (Added by build_path_from_id_categ call) - * level Level of line (Added by build_path_from_id_categ call) + * fullpath Full path of id (Added by buildPathFromId call) + * fullrelativename Full path name (Added by buildPathFromId call) + * fulllabel Full label (Added by buildPathFromId call) + * level Level of line (Added by buildPathFromId call) * * @param int $force Force reload of full arbo even if already loaded in cache $this->cats * @return array Tableau de array @@ -698,10 +698,10 @@ class EcmDirectory extends CommonObject // We add properties fullxxx to all elements foreach ($this->cats as $key => $val) { - if (isset($motherof[$key])) { + if (isset($this->motherof[$key])) { continue; } - $this->build_path_from_id_categ($key, 0); + $this->buildPathFromId($key, 0); } $this->cats = dol_sort_array($this->cats, 'fulllabel', 'asc', true, false); @@ -710,7 +710,6 @@ class EcmDirectory extends CommonObject return $this->cats; } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Define properties fullpath, fullrelativename, fulllabel of a directory of array this->cats and all its childs. * Separator between directories is always '/', whatever is OS. @@ -719,9 +718,8 @@ class EcmDirectory extends CommonObject * @param int $protection Deep counter to avoid infinite loop * @return void */ - public function build_path_from_id_categ($id_categ, $protection = 0) + private function buildPathFromId($id_categ, $protection = 0) { - // phpcs:enable // Define fullpath if (!empty($this->cats[$id_categ]['id_mere'])) { $this->cats[$id_categ]['fullpath'] = $this->cats[$this->cats[$id_categ]['id_mere']]['fullpath']; @@ -745,7 +743,7 @@ class EcmDirectory extends CommonObject } if (isset($this->cats[$id_categ]['id_children']) && is_array($this->cats[$id_categ]['id_children'])) { foreach ($this->cats[$id_categ]['id_children'] as $key => $val) { - $this->build_path_from_id_categ($val, $protection); + $this->buildPathFromId($val, $protection); } } } diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 2f9bf4c41e5..d8d1da60e24 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -327,7 +327,11 @@ class EcmFiles extends CommonObject $resql = $this->db->query($sql); if (!$resql) { $error++; - $this->errors[] = 'Error '.$this->db->lasterror(); + if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $this->errors[] = 'Error DB_ERROR_RECORD_ALREADY_EXISTS : '.$this->db->lasterror(); + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + } dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); } @@ -365,7 +369,7 @@ class EcmFiles extends CommonObject * @param string $ref Hash of file name (filename+filepath). Not always defined on some version. * @param string $relativepath Relative path of file from document directory. Example: 'path/path2/file' or 'path/path2/*' * @param string $hashoffile Hash of file content. Take the first one found if same file is at different places. This hash will also change if file content is changed. - * @param string $hashforshare Hash of file sharing. + * @param string $hashforshare Hash of file sharing or 'shared' * @param string $src_object_type src_object_type to search (value of object->table_element) * @param string $src_object_id src_object_id to search * @return int <0 if KO, 0 if not found, >0 if OK @@ -421,12 +425,16 @@ class EcmFiles extends CommonObject $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'"; $sql .= " AND t.entity = ".$conf->entity; // unique key include the entity so each company has its own index } elseif (!empty($hashforshare)) { - $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'"; + if ($hashforshare != 'shared') { + $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'"; + } else { + $sql .= " AND t.share IS NOT NULL AND t.share <> ''"; + } //$sql .= " AND t.entity = ".$conf->entity; // hashforshare already unique } elseif ($src_object_type && $src_object_id) { // Warning: May return several record, and only first one is returned ! $sql .= " AND t.src_object_type = '".$this->db->escape($src_object_type)."' AND t.src_object_id = ".((int) $src_object_id); - $sql .= " AND t.entity = ".$conf->entity; + $sql .= " AND t.entity = ".((int) $conf->entity); } else { $sql .= ' AND t.rowid = '.((int) $id); // rowid already unique } diff --git a/htdocs/emailcollector/lib/emailcollector.lib.php b/htdocs/emailcollector/lib/emailcollector.lib.php index 9b63bbea66a..60611c35841 100644 --- a/htdocs/emailcollector/lib/emailcollector.lib.php +++ b/htdocs/emailcollector/lib/emailcollector.lib.php @@ -87,9 +87,10 @@ function emailcollectorPrepareHead($object) } /** - * Récupère les parties d'un message - * @param object $structure structure du message - * @return object|boolean parties du message|false en cas d'erreur + * Get parts of a message + * + * @param object $structure Structure of message + * @return object|boolean Parties du message|false en cas d'erreur */ function getParts($structure) { @@ -97,9 +98,10 @@ function getParts($structure) } /** - * Tableau définissant la pièce jointe - * @param object $part partie du message - * @return object|boolean définition du message|false en cas d'erreur + * Array with joined files + * + * @param object $part Part of message + * @return object|boolean Definition of message|false en cas d'erreur */ function getDParameters($part) { @@ -107,10 +109,11 @@ function getDParameters($part) } /** - * Récupère les pièces d'un mail donné - * @param integer $jk numéro du mail - * @param object $mbox object connection imaap - * @return array type, filename, pos + * Get attachments of a given mail + * + * @param integer $jk Number of email + * @param object $mbox object connection imaap + * @return array type, filename, pos */ function getAttachments($jk, $mbox) { @@ -140,7 +143,8 @@ function getAttachments($jk, $mbox) } /** - * Récupère la contenu de la pièce jointe par rapport a sa position dans un mail donné + * Get content of a joined file from its position into a given email + * * @param integer $jk numéro du mail * @param integer $fpos position de la pièce jointe * @param integer $type type de la pièce jointe @@ -156,11 +160,12 @@ function getFileData($jk, $fpos, $type, $mbox) } /** - * Sauvegarde de la pièce jointe dans le dossier défini avec un nom unique - * @param string $path chemin de sauvegarde dui fichier - * @param string $filename nom du fichier - * @param mixed $data contenu à sauvegarder - * @return string emplacement du fichier + * Save joined file into a directory with a given name + * + * @param string $path Path to file + * @param string $filename Name of file + * @param mixed $data contenu à sauvegarder + * @return string emplacement du fichier **/ function saveAttachment($path, $filename, $data) { @@ -186,10 +191,11 @@ function saveAttachment($path, $filename, $data) } /** - * Décode le contenu du message - * @param string $message message - * @param integer $coding type de contenu - * @return message décodé + * Decode content of a message + * + * @param string $message Message + * @param integer $coding Type of content + * @return string Decoded message **/ function getDecodeValue($message, $coding) { diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index d105ad05c43..943205adca2 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index e084c68cfe7..ab2699187b2 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -122,11 +122,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php index 9f761c24bc6..127ea95a424 100644 --- a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php +++ b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -echo "\n"; +echo "\n"; global $user; diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 00693469948..8045edde410 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -13,6 +13,7 @@ * Copyright (C) 2016 Yasser Carreón * Copyright (C) 2018 Frédéric France * Copyright (C) 2020 Lenin Rivas + * Copyright (C) 2022 Josep Lluís Amador * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1208,6 +1209,7 @@ if ($action == 'create') { print ''; } else { if (! empty($conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS)) { + print ''; print ''; } @@ -1458,6 +1460,11 @@ if ($action == 'create') { } foreach ($product->stock_warehouse as $warehouse_id => $stock_warehouse) { + if (!empty($warehousePicking) && !in_array($warehouse_id, $warehousePicking)) { + // if a warehouse was selected by user, picking is limited to this warehouse and his children + continue; + } + $tmpwarehouseObject->fetch($warehouse_id); if (($stock_warehouse->real > 0) && (count($stock_warehouse->detail_batch))) { foreach ($stock_warehouse->detail_batch as $dbatch) { @@ -2459,9 +2466,9 @@ if ($action == 'create') { if ($object->statut == Expedition::STATUS_DRAFT && $num_prod > 0) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->shipping_advance->validate))) { - print ''.$langs->trans("Validate").''; + print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=valid&token='.newToken().'&id='.$object->id, ''); } else { - print ''.$langs->trans("Validate").''; + print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } @@ -2469,9 +2476,9 @@ if ($action == 'create') { // 0=draft, 1=validated, 2=billed, we miss a status "delivered" (only available on order) if ($object->statut == Expedition::STATUS_CLOSED && $user->rights->expedition->creer) { if (!empty($conf->facture->enabled) && !empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? - print ''.$langs->trans("ClassifyUnbilled").''; + print dolGetButtonAction('', $langs->trans('ClassifyUnbilled'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&id='.$object->id, ''); } else { - print ''.$langs->trans("ReOpen").''; + print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&id='.$object->id, ''); } } @@ -2479,9 +2486,9 @@ if ($action == 'create') { if (empty($user->socid)) { if ($object->statut > 0) { if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->expedition->shipping_advance->send) { - print ''.$langs->trans('SendMail').''; + print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', ''); } else { - print ''.$langs->trans('SendMail').''; + print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } @@ -2491,14 +2498,14 @@ if ($action == 'create') { if ($user->rights->facture->creer) { // TODO show button only if (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // If we do that, we must also make this option official. - print ''.$langs->trans("CreateBill").''; + print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } } // This is just to generate a delivery receipt //var_dump($object->linkedObjectsIds['delivery']); if ($conf->delivery_note->enabled && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED) && $user->rights->expedition->delivery->creer && empty($object->linkedObjectsIds['delivery'])) { - print ''.$langs->trans("CreateDeliveryOrder").''; + print dolGetButtonAction('', $langs->trans('CreateDeliveryOrder'), 'default', $_SERVER["PHP_SELF"].'?action=create_delivery&token='.newToken().'&id='.$object->id, ''); } // Close if ($object->statut == Expedition::STATUS_VALIDATED) { @@ -2509,20 +2516,20 @@ if ($action == 'create') { $label = "ClassifyBilled"; $paramaction = 'classifybilled'; } - print ''.$langs->trans($label).''; + print dolGetButtonAction('', $langs->trans($label), 'default', $_SERVER["PHP_SELF"].'?action='. $paramaction .'&token='.newToken().'&id='.$object->id, ''); } } // Cancel if ($object->statut == Expedition::STATUS_VALIDATED) { if ($user->rights->expedition->supprimer) { - print ''.$langs->trans("Cancel").''; + print dolGetButtonAction('', $langs->trans('Cancel'), 'danger', $_SERVER["PHP_SELF"].'?action=cancel&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', ''); } } // Delete if ($user->rights->expedition->supprimer) { - print ''.$langs->trans("Delete").''; + print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, ''); } } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 8490fa67753..3415dabc33d 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -9,7 +9,7 @@ * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2014-2017 Francis Appels * Copyright (C) 2015 Claudio Aschieri - * Copyright (C) 2016-2021 Ferran Marcet + * Copyright (C) 2016-2022 Ferran Marcet * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018-2022 Frédéric France * Copyright (C) 2020 Lenin Rivas @@ -367,13 +367,15 @@ class Expedition extends CommonObject // Insert of lines $num = count($this->lines); for ($i = 0; $i < $num; $i++) { - if (!isset($this->lines[$i]->detail_batch)) { // no batch management - if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) <= 0) { - $error++; - } - } else { // with batch management - if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) <= 0) { - $error++; + if (empty($this->lines[$i]->product_type) || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + if (!isset($this->lines[$i]->detail_batch)) { // no batch management + if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) <= 0) { + $error++; + } + } else { // with batch management + if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) <= 0) { + $error++; + } } } } @@ -751,6 +753,7 @@ class Expedition extends CommonObject //var_dump($this->lines[$i]); $mouvS = new MouvementStock($this->db); $mouvS->origin = dol_clone($this, 1); + $mouvS->setOrigin($this->element, $this->id); if (empty($obj->edbrowid)) { // line without batch detail @@ -913,6 +916,7 @@ class Expedition extends CommonObject // Copy the rang of the order line to the expedition line $line->rang = $orderline->rang; + $line->product_type = $orderline->product_type; if (!empty($conf->stock->enabled) && !empty($orderline->fk_product)) { $fk_product = $orderline->fk_product; @@ -965,6 +969,8 @@ class Expedition extends CommonObject } $this->lines[$num] = $line; + + return 1; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -1565,9 +1571,12 @@ class Expedition extends CommonObject { // phpcs:enable global $conf, $mysoc; - // TODO: recuperer les champs du document associe a part + $this->lines = array(); + // NOTE: This fetch_lines is special because it groups all lines with the same origin_line_id into one line. + // TODO: See if we can restore a common fetch_lines (one line = one record) + $sql = "SELECT cd.rowid, cd.fk_product, cd.label as custom_label, cd.description, cd.qty as qty_asked, cd.product_type, cd.fk_unit"; $sql .= ", cd.total_ht, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.total_tva"; $sql .= ", cd.vat_src_code, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.info_bits, cd.price, cd.subprice, cd.remise_percent,cd.buy_price_ht as pa_ht"; @@ -1579,7 +1588,7 @@ class Expedition extends CommonObject $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product"; $sql .= " WHERE ed.fk_expedition = ".((int) $this->id); $sql .= " AND ed.fk_origin_line = cd.rowid"; - $sql .= " ORDER BY cd.rang, ed.fk_origin_line"; + $sql .= " ORDER BY cd.rang, ed.fk_origin_line"; // We need after a break on fk_origin_line but when there is no break on fk_origin_line, cd.rang is same so we can add it as first order criteria. dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); $resql = $this->db->query($sql); @@ -1597,22 +1606,21 @@ class Expedition extends CommonObject $this->total_localtax1 = 0; $this->total_localtax2 = 0; - $line = new ExpeditionLigne($this->db); $shipmentlinebatch = new ExpeditionLineBatch($this->db); while ($i < $num) { $obj = $this->db->fetch_object($resql); - if ($originline == $obj->fk_origin_line) { + if ($originline > 0 && $originline == $obj->fk_origin_line) { $line->entrepot_id = 0; // entrepod_id in details_entrepot $line->qty_shipped += $obj->qty_shipped; } else { $line = new ExpeditionLigne($this->db); - $line->entrepot_id = $obj->fk_entrepot; - $line->qty_shipped = $obj->qty_shipped; + $line->entrepot_id = $obj->fk_entrepot; // this is a property of a shipment line + $line->qty_shipped = $obj->qty_shipped; // this is a property of a shipment line } - $detail_entrepot = new stdClass; + $detail_entrepot = new stdClass(); $detail_entrepot->entrepot_id = $obj->fk_entrepot; $detail_entrepot->qty_shipped = $obj->qty_shipped; $detail_entrepot->line_id = $obj->line_id; @@ -1708,6 +1716,8 @@ class Expedition extends CommonObject } } + $line->fetch_optionals(); + if ($originline != $obj->fk_origin_line) { $this->lines[$lineindex] = $line; $lineindex++; @@ -1718,7 +1728,7 @@ class Expedition extends CommonObject $line->total_ttc += $tabprice[2]; $line->total_tva += $tabprice[1]; } - $line->fetch_optionals(); + $i++; $originline = $obj->fk_origin_line; } @@ -2236,6 +2246,7 @@ class Expedition extends CommonObject $mouvS = new MouvementStock($this->db); $mouvS->origin = &$this; + $mouvS->setOrigin($this->element, $this->id); if (empty($obj->edbrowid)) { // line without batch detail @@ -2407,6 +2418,7 @@ class Expedition extends CommonObject //var_dump($this->lines[$i]); $mouvS = new MouvementStock($this->db); $mouvS->origin = &$this; + $mouvS->setOrigin($this->element, $this->id); if (empty($obj->edbrowid)) { // line without batch detail @@ -2611,6 +2623,12 @@ class ExpeditionLigne extends CommonObjectLine */ public $product_desc; + /** + * Type of the product. 0 for product, 1 for service + * @var int + */ + public $product_type = 0; + /** * @var int rang of line */ @@ -3013,7 +3031,7 @@ class ExpeditionLigne extends CommonObjectLine if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('LINESHIPPING_UPDATE', $user); + $result = $this->call_trigger('LINESHIPPING_MODIFY', $user); if ($result < 0) { $this->errors[] = $this->error; $error++; diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 378d95e00c8..2d81c5e0545 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -116,7 +116,7 @@ $fieldstosearchall = array( 'e.ref'=>"Ref", 's.nom'=>"ThirdParty", 'e.note_public'=>'NotePublic', - 'e.shipping_method_id'=>'SendingMethod', + //'e.fk_shipping_method'=>'SendingMethod', // TODO fix this, does not work 'e.tracking_number'=>"TrackingNumber", ); if (empty($user->socid)) { @@ -134,7 +134,7 @@ $arrayfields = array( 'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0, 'position'=>7), 'typent.code'=>array('label'=>$langs->trans("ThirdPartyType"), 'checked'=>$checkedtypetiers, 'position'=>8), 'e.date_delivery'=>array('label'=>$langs->trans("DateDeliveryPlanned"), 'checked'=>1, 'position'=>9), - 'e.shipping_method_id'=>array('label'=>$langs->trans('SendingMethod'), 'checked'=>1, 'position'=>10), + 'e.fk_shipping_method'=>array('label'=>$langs->trans('SendingMethod'), 'checked'=>1, 'position'=>10), 'e.tracking_number'=>array('label'=>$langs->trans("TrackingNumber"), 'checked'=>1, 'position'=>11), 'e.weight'=>array('label'=>$langs->trans("Weight"), 'checked'=>0, 'position'=>12), 'e.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), @@ -654,7 +654,7 @@ if (!empty($arrayfields['e.date_delivery']['checked'])) { print '
    '; print ''; } -if (!empty($arrayfields['e.shipping_method_id']['checked'])) { +if (!empty($arrayfields['e.fk_shipping_method']['checked'])) { // Delivery method print '
    \n"; } - if (!empty($arrayfields['e.shipping_method_id']['checked'])) { + if (!empty($arrayfields['e.fk_shipping_method']['checked'])) { // Get code using getLabelFromKey $code=$langs->getLabelFromKey($db, $shipment->shipping_method_id, 'c_shipment_mode', 'rowid', 'code'); print ''; - print ''; + print ''; + print ''; //print ''; - print ''; + print ''; if (!empty($conf->projet->enabled)) { - print ''; + print ''; } - print ''; + print ''; if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) { - print ''; + print ''; } - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; if ($action != 'editline') { - print ''; - print ''; + print ''; + print ''; } // Picture print ''; + print ''; // Num - print ''; // Date - print ''; + print ''; // Project if (!empty($conf->projet->enabled)) { - print ''; // IK if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) { - print ''; } // Comment - print ''; + print ''; // VAT rate - print ''; + print ''; // Unit price HT - print ''; - print ''; + print ''; - print ''; + print ''; if ($action != 'editline') { - print ''; - print ''; + print ''; + print ''; } // Column with preview - print ''; - print ''; // Ajout des boutons de modification/suppression if (($object->status < ExpenseReport::STATUS_VALIDATED || $object->status == ExpenseReport::STATUS_REFUSED) && $user->rights->expensereport->creer) { - print ''; - print ''; - print ''; + print ''; print ''; - print ''; + print ''; if (!empty($conf->projet->enabled)) { print ''; } - print ''; + print ''; if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) { print ''; } - print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print ''; print ''; print ''; print ''; print ''; print ''; - print ''; // Line number print ''; // Select date - print ''; // Select project if (!empty($conf->projet->enabled)) { - print ''; } // Select type - print ''; @@ -2525,12 +2533,12 @@ if ($action == 'create') { } // Add comments - print ''; // Select VAT - print ''; // Unit price net - print ''; // Unit price with tax - print ''; // Quantity - print ''; @@ -2561,7 +2569,7 @@ if ($action == 'create') { print ''; } - print ''; diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index df942ff93e6..37319a3ec71 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -401,7 +401,7 @@ class ExpenseReports extends DolibarrApi * * @throws RestException 401 Not allowed * @throws RestException 404 Expense report not found - * @throws RestException 500 + * @throws RestException 500 System error */ public function put($id, $request_data = null) { diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index be49b0a8c0c..1ed0e7a30f5 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -26,6 +26,7 @@ * \brief File to manage Expense Reports */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php'; require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_rule.class.php'; @@ -513,7 +514,7 @@ class ExpenseReport extends CommonObject if ($result) { if (!$notrigger) { // Call trigger - $result = $this->call_trigger('EXPENSE_REPORT_UPDATE', $user); + $result = $this->call_trigger('EXPENSE_REPORT_MODIFY', $user); if ($result < 0) { $error++; @@ -1092,7 +1093,7 @@ class ExpenseReport extends CommonObject if (!$notrigger) { // Call trigger - $result = $this->call_trigger('EXPENSEREPORT_DELETE', $user); + $result = $this->call_trigger('EXPENSE_REPORT_DELETE', $user); if ($result < 0) { $error++; } @@ -2047,7 +2048,7 @@ class ExpenseReport extends CommonObject } /** - * Update an expense report line + * Update an expense report line. * * @param int $rowid Line to edit * @param int $type_fees_id Type payment @@ -2060,9 +2061,10 @@ class ExpenseReport extends CommonObject * @param int $expensereport_id Expense report id * @param int $fk_c_exp_tax_cat Id of category of car * @param int $fk_ecm_files Id of ECM file to link to this expensereport line + * @param int $notrigger 1=No trigger * @return int <0 if KO, >0 if OK */ - public function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id, $fk_c_exp_tax_cat = 0, $fk_ecm_files = 0) + public function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id, $fk_c_exp_tax_cat = 0, $fk_ecm_files = 0, $notrigger = 0) { global $user, $mysoc; @@ -2152,9 +2154,19 @@ class ExpenseReport extends CommonObject $this->applyOffset(); $this->checkRules(); - + $error = 0; $result = $this->line->update($user); - if ($result > 0) { + + if ($result > 0 && !$notrigger) { + // Call triggers + $result = $this->call_trigger('EXPENSE_REPORT_DET_MODIFY', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + if ($result > 0 && $error == 0) { $this->db->commit(); return 1; } else { @@ -2169,20 +2181,33 @@ class ExpenseReport extends CommonObject /** * deleteline * - * @param int $rowid Row id - * @param User $fuser User - * @return int <0 if KO, >0 if OK + * @param int $rowid Row id + * @param User $fuser User + * @param int $notrigger 1=No trigger + * @return int <0 if KO, >0 if OK */ - public function deleteline($rowid, $fuser = '') + public function deleteline($rowid, $fuser = '', $notrigger = 0) { + $error=0; + $this->db->begin(); - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line; + if (!$notrigger) { + // Call triggers + $result = $this->call_trigger('EXPENSE_REPORT_DET_DELETE', $fuser); + if ($result < 0) { + $error++; + } + // End call triggers + } + + $sql = ' DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line; $sql .= ' WHERE rowid = '.((int) $rowid); dol_syslog(get_class($this)."::deleteline sql=".$sql); $result = $this->db->query($sql); - if (!$result) { + + if (!$result || $error > 0 ) { $this->error = $this->db->error(); dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR); $this->db->rollback(); @@ -2545,7 +2570,7 @@ class ExpenseReport extends CommonObject /** * Class of expense report details lines */ -class ExpenseReportLine +class ExpenseReportLine extends CommonObjectLine { /** * @var DoliDB Database handler. @@ -2752,6 +2777,17 @@ class ExpenseReportLine if ($resql) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'expensereport_det'); + + if (!$error && !$notrigger) { + // Call triggers + $result = $this->call_trigger('EXPENSE_REPORT_DET_CREATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + if (!$fromaddline) { $tmpparent = new ExpenseReport($this->db); $tmpparent->fetch($this->fk_expensereport); diff --git a/htdocs/expensereport/tpl/linkedobjectblock.tpl.php b/htdocs/expensereport/tpl/linkedobjectblock.tpl.php index 6a36b62f924..f97099e57dc 100644 --- a/htdocs/expensereport/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expensereport/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index a99a858adaf..0d7e5278a14 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1003,11 +1003,13 @@ if ($action == 'create') { $title = $langs->trans('Services'); print load_fiche_titre($title); + print '
    '; print '
    '; if ($i > 0) { print 'id.'">'.img_up('default', 0, 'imgupforline').''; } - if ($i < $nboffiles - 1) { + if ($i < ($nboffiles - 1)) { print 'id.'">'.img_down('default', 0, 'imgdownforline').''; } print '
    '; @@ -2032,7 +2032,7 @@ class FormFile print ''; print ''; - print ''; + print '
    '; print ''; print_liste_field_titre( $langs->trans("Links"), @@ -2117,7 +2117,7 @@ class FormFile print ''; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index ccdfa261fc8..ce94d6128dc 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -216,19 +216,19 @@ function dolGetLdapPasswordHash($password, $type = 'md5') * If GETPOST('action','aZ09') defined, we also check write and delete permission. * This method check permission on module then call checkUserAccessToObject() for permission on object (according to entity and socid of user). * - * @param User $user User to check - * @param string $features Features to check (it must be module $object->element. Can be a 'or' check with 'levela|levelb'. - * Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) - * This is used to check permission $user->rights->features->... - * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). - * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany module. Param not used if objectid is null (optional). - * @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'. - * This is used to check permission $user->rights->features->feature2... - * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) - * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) - * @param int $isdraft 1=The object with id=$objectid is a draft - * @param int $mode Mode (0=default, 1=return with not die) - * @return int If mode = 0 (default): Always 1, die process if not allowed. If mode = 1: Return 0 if access not allowed. + * @param User $user User to check + * @param string $features Features to check (it must be module $object->element. Can be a 'or' check with 'levela|levelb'. + * Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) + * This is used to check permission $user->rights->features->... + * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). + * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany module. Param not used if objectid is null (optional). + * @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'. + * This is used to check permission $user->rights->features->feature2... + * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) + * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) + * @param int $isdraft 1=The object with id=$objectid is a draft + * @param int $mode Mode (0=default, 1=return with not die) + * @return int If mode = 0 (default): Always 1, die process if not allowed. If mode = 1: Return 0 if access not allowed. * @see dol_check_secure_access_document(), checkUserAccessToObject() */ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0) @@ -236,6 +236,8 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f global $db, $conf; global $hookmanager; + $objectid = ((int) $objectid); // For the case value is coming from a non sanitized user input + //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft"); //print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid; //print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select; @@ -270,7 +272,6 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f $features = 'produit'; } - // Get more permissions checks from hooks $parameters = array('features'=>$features, 'originalfeatures'=>$originalfeatures, 'objectid'=>$objectid, 'dbt_select'=>$dbt_select, 'idtype'=>$dbt_select, 'isdraft'=>$isdraft); $reshook = $hookmanager->executeHooks('restrictedArea', $parameters); @@ -288,10 +289,6 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f return 1; } - if ($dbt_select != 'rowid' && $dbt_select != 'id') { - $objectid = "'".$objectid."'"; - } - // Features/modules to check $featuresarray = array($features); if (preg_match('/&/', $features)) { diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index e156c83b147..4b70419630f 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -111,7 +111,7 @@ function checkLoginPassEntity($usertotest, $passwordtotest, $entitytotest, $auth // Load translation files required by the page $langs->loadLangs(array('other', 'main', 'errors')); - $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorFailedToLoadLoginFileForMode", $mode); + $_SESSION["dol_loginmesg"] = (empty($_SESSION["dol_loginmesg"]) ? '' : $_SESSION["dol_loginmesg"].', ').$langs->transnoentitiesnoconv("ErrorFailedToLoadLoginFileForMode", $mode); } } } diff --git a/htdocs/core/lib/signature.lib.php b/htdocs/core/lib/signature.lib.php index 1d529be6327..c57807800d7 100644 --- a/htdocs/core/lib/signature.lib.php +++ b/htdocs/core/lib/signature.lib.php @@ -119,11 +119,9 @@ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1) } // For multicompany - /* - if (!empty($out)) { - $out .= "&entity=".$conf->entity; // Check the entity because He may be the same reference in several entities + if (!empty($out) && !empty($conf->multicompany->enabled)) { + $out .= "&entity=".$conf->entity; // Check the entity because we may have the same reference in several entities } - */ return $out; } diff --git a/htdocs/core/lib/tax.lib.php b/htdocs/core/lib/tax.lib.php index 490b95cc92d..a0602dfd74e 100644 --- a/htdocs/core/lib/tax.lib.php +++ b/htdocs/core/lib/tax.lib.php @@ -66,11 +66,29 @@ function tax_prepare_head(ChargeSociales $object) $head[$h][2] = 'documents'; $h++; + + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = DOL_URL_ROOT.'/compta/sociales/note.php?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + } + $head[$h][2] = 'note'; + $h++; + + $head[$h][0] = DOL_URL_ROOT.'/compta/sociales/info.php?id='.$object->id; $head[$h][1] = $langs->trans("Info"); $head[$h][2] = 'info'; $h++; + complete_head_from_modules($conf, $langs, $object, $head, $h, 'tax', 'remove'); return $head; diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 2792b6d9997..c963c74c8b6 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -507,7 +507,6 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) } // BorderTableActive - /* Disabled because not supported by md theme if ($foruserprofile) { } else { $default = $langs->trans('No'); @@ -525,7 +524,6 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) print ''; print ''; } - */ // Background color THEME_ELDY_BACKBODY if ($foruserprofile) { diff --git a/htdocs/core/login/functions_dolibarr.php b/htdocs/core/login/functions_dolibarr.php index 292ce1b44f5..610072aa35a 100644 --- a/htdocs/core/login/functions_dolibarr.php +++ b/htdocs/core/login/functions_dolibarr.php @@ -143,7 +143,11 @@ function check_user_password_dolibarr($usertotest, $passwordtotest, $entitytotes $ret = $mc->checkRight($obj->rowid, $entitytotest); if ($ret < 0) { dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentication KO entity '".$entitytotest."' not allowed for user '".$obj->rowid."'", LOG_NOTICE); + $login = ''; // force authentication failure + if ($mc->db->lasterror()) { + $_SESSION["dol_loginmesg"] = $mc->db->lasterror(); + } } } } diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php index 1db98f5384e..1d86bd19549 100644 --- a/htdocs/core/login/functions_ldap.php +++ b/htdocs/core/login/functions_ldap.php @@ -109,9 +109,9 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) $userSearchFilter = str_replace('%1%', $usertotest, $dolibarr_main_auth_ldap_filter); } - // If admin login provided + // If admin login or ldap auth filter provided // Code to get user in LDAP from an admin connection (may differ from user connection, done later) - if ($ldapadminlogin) { + if ($ldapadminlogin || $dolibarr_main_auth_ldap_filter) { $result = $ldap->connect_bind(); if ($result > 0) { $resultFetchLdapUser = $ldap->fetch($usertotest, $userSearchFilter); diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 3b173cecb26..9a91aa58ac1 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -8,28 +8,34 @@ delete from llx_menu where menu_handler=__HANDLER__ and entity=__ENTITY__; -- -- table llx_menu -- -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '1', 1__+MAX_llx_menu__, __HANDLER__, 'top', 'home', '', 0, '/index.php?mainmenu=home&leftmenu=', 'Home', -1, '', '', '', 2, 10, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('societe|fournisseur|supplier_order|supplier_invoice', '($conf->societe->enabled && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) || !empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || $conf->supplier_order->enabled || $conf->supplier_invoice->enabled))', 2__+MAX_llx_menu__, __HANDLER__, 'top', 'companies', '', 0, '/societe/index.php?mainmenu=companies&leftmenu=', 'ThirdParties', -1, 'companies', '$user->rights->societe->lire || $user->rights->societe->contact->lire', '', 2, 20, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('product|service', '$conf->product->enabled || $conf->service->enabled', 3__+MAX_llx_menu__, __HANDLER__, 'top', 'products', '', 0, '/product/index.php?mainmenu=products&leftmenu=', 'ProductsPipeServices', -1, 'products', '$user->rights->produit->lire||$user->rights->service->lire', '', 0, 30, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('bom|mrp', '$conf->bom->enabled || $conf->mrp->enabled', 16__+MAX_llx_menu__, __HANDLER__, 'top', 'mrp', '', 0, '/mrp/index.php?mainmenu=mrp&leftmenu=', 'MRP', -1, 'mrp', '$user->rights->bom->read||$user->rights->mrp->read', '', 0, 31, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('projet', '$conf->projet->enabled', 7__+MAX_llx_menu__, __HANDLER__, 'top', 'project', '', 0, '/projet/index.php?mainmenu=project&leftmenu=', 'Projects', -1, 'projects', '$user->rights->projet->lire', '', 2, 32, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('propal|commande|fournisseur|supplier_order|supplier_invoice|contrat|ficheinter', '$conf->propal->enabled || $conf->commande->enabled || $conf->supplier_order->enabled || $conf->contrat->enabled || $conf->ficheinter->enabled', 5__+MAX_llx_menu__, __HANDLER__, 'top', 'commercial', '', 0, '/comm/index.php?mainmenu=commercial&leftmenu=', 'Commercial', -1, 'commercial', '$user->rights->societe->lire || $user->rights->societe->contact->lire', '', 2, 40, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('facture|don|tax|salaries|loan|banque', '$conf->comptabilite->enabled || $conf->accounting->enabled || $conf->facture->enabled || $conf->don->enabled || $conf->tax->enabled || $conf->salaries->enabled || $conf->supplier_invoice->enabled || $conf->loan->enabled || $conf->banque->enabled', 6__+MAX_llx_menu__, __HANDLER__, 'top', 'billing', '', 0, '/compta/index.php?mainmenu=billing&leftmenu=', 'MenuFinancial', -1, 'compta', '$user->rights->facture->lire|| $user->rights->don->lire || $user->rights->tax->charges->lire || $user->rights->salaries->read || $user->rights->loan->read || $user->rights->banque->lire', '', 2, 50, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('banque|prelevement', '$conf->banque->enabled || $conf->prelevement->enabled', 14__+MAX_llx_menu__, __HANDLER__, 'top', 'bank', '', 0, '/compta/bank/list.php?mainmenu=bank&leftmenu=bank', 'MenuBankCash', -1, 'banks', '$user->rights->banque->lire || $user->rights->prelevement->bons->lire', '', 0, 52, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('comptabilite|accounting|asset', '$conf->comptabilite->enabled || $conf->accounting->enabled || $conf->asset->enabled', 9__+MAX_llx_menu__, __HANDLER__, 'top', 'accountancy', '', 0, '/compta/index.php?mainmenu=accountancy&leftmenu=accountancy', 'MenuAccountancy', -1, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->mouvements->lire || $user->rights->asset->read', '', 2, 54, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '', 8__+MAX_llx_menu__, __HANDLER__, 'top', 'tools', '', 0, '/core/tools.php?mainmenu=tools&leftmenu=', 'Tools', -1, 'other', '', '', 2, 90, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('adherent', '$conf->adherent->enabled', 13__+MAX_llx_menu__, __HANDLER__, 'top', 'members', '', 0, '/adherents/index.php?mainmenu=members&leftmenu=', 'Members', -1, 'members', '$user->rights->adherent->lire', '', 2, 19, __ENTITY__); -insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('hrm|holiday|deplacement|expensereport', '$conf->hrm->enabled || $conf->holiday->enabled || $conf->deplacement->enabled || $conf->expensereport->enabled', 15__+MAX_llx_menu__, __HANDLER__, 'top', 'hrm', '', 0, '/hrm/index.php?mainmenu=hrm&leftmenu=', 'HRM', -1, 'holiday', '$user->rights->user->user->lire || $user->rights->holiday->read || $user->rights->deplacement->lire || $user->rights->expensereport->lire', '', 0, 80, __ENTITY__); + +-- Top-Menu +-- old: (module, enabled, rowid, ...) +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 1__+MAX_llx_menu__, '', '1', __HANDLER__, 'top', 'home', '', 0, '/index.php?mainmenu=home&leftmenu=', 'Home', -1, '', '', '', 2, 10, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 2__+MAX_llx_menu__, 'societe|fournisseur|supplier_order|supplier_invoice', '($conf->societe->enabled && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) || !empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || $conf->supplier_order->enabled || $conf->supplier_invoice->enabled))', __HANDLER__, 'top', 'companies', '', 0, '/societe/index.php?mainmenu=companies&leftmenu=', 'ThirdParties', -1, 'companies', '$user->rights->societe->lire || $user->rights->societe->contact->lire', '', 2, 20, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 3__+MAX_llx_menu__, 'product|service', '$conf->product->enabled || $conf->service->enabled', __HANDLER__, 'top', 'products', '', 0, '/product/index.php?mainmenu=products&leftmenu=', 'ProductsPipeServices', -1, 'products', '$user->rights->produit->lire||$user->rights->service->lire', '', 0, 30, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 16__+MAX_llx_menu__, 'bom|mrp', '$conf->bom->enabled || $conf->mrp->enabled', __HANDLER__, 'top', 'mrp', '', 0, '/mrp/index.php?mainmenu=mrp&leftmenu=', 'MRP', -1, 'mrp', '$user->rights->bom->read||$user->rights->mrp->read', '', 0, 31, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 7__+MAX_llx_menu__, 'projet', '$conf->projet->enabled', __HANDLER__, 'top', 'project', '', 0, '/projet/index.php?mainmenu=project&leftmenu=', 'Projects', -1, 'projects', '$user->rights->projet->lire', '', 2, 32, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 5__+MAX_llx_menu__, 'propal|commande|fournisseur|supplier_order|supplier_invoice|contrat|ficheinter', '$conf->propal->enabled || $conf->commande->enabled || $conf->supplier_order->enabled || $conf->contrat->enabled || $conf->ficheinter->enabled', __HANDLER__, 'top', 'commercial', '', 0, '/comm/index.php?mainmenu=commercial&leftmenu=', 'Commercial', -1, 'commercial', '$user->rights->societe->lire || $user->rights->societe->contact->lire', '', 2, 40, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 6__+MAX_llx_menu__, 'facture|don|tax|salaries|loan|banque', '$conf->comptabilite->enabled || $conf->accounting->enabled || $conf->facture->enabled || $conf->don->enabled || $conf->tax->enabled || $conf->salaries->enabled || $conf->supplier_invoice->enabled || $conf->loan->enabled || $conf->banque->enabled', __HANDLER__, 'top', 'billing', '', 0, '/compta/index.php?mainmenu=billing&leftmenu=', 'MenuFinancial', -1, 'compta', '$user->rights->facture->lire|| $user->rights->don->lire || $user->rights->tax->charges->lire || $user->rights->salaries->read || $user->rights->loan->read || $user->rights->banque->lire', '', 2, 50, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 14__+MAX_llx_menu__, 'banque|prelevement', '$conf->banque->enabled || $conf->prelevement->enabled', __HANDLER__, 'top', 'bank', '', 0, '/compta/bank/list.php?mainmenu=bank&leftmenu=bank', 'MenuBankCash', -1, 'banks', '$user->rights->banque->lire || $user->rights->prelevement->bons->lire', '', 0, 52, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 9__+MAX_llx_menu__, 'comptabilite|accounting|asset', '$conf->comptabilite->enabled || $conf->accounting->enabled || $conf->asset->enabled', __HANDLER__, 'top', 'accountancy', '', 0, '/compta/index.php?mainmenu=accountancy&leftmenu=accountancy', 'MenuAccountancy', -1, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->mouvements->lire || $user->rights->asset->read', '', 2, 54, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 8__+MAX_llx_menu__, '', '', __HANDLER__, 'top', 'tools', '', 0, '/core/tools.php?mainmenu=tools&leftmenu=', 'Tools', -1, 'other', '', '', 2, 90, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 13__+MAX_llx_menu__, 'adherent', '$conf->adherent->enabled', __HANDLER__, 'top', 'members', '', 0, '/adherents/index.php?mainmenu=members&leftmenu=', 'Members', -1, 'members', '$user->rights->adherent->lire', '', 2, 19, __ENTITY__); +insert into llx_menu (rowid, module, enabled, menu_handler, type, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ( 15__+MAX_llx_menu__, 'hrm|holiday|deplacement|expensereport', '$conf->hrm->enabled || $conf->holiday->enabled || $conf->deplacement->enabled || $conf->expensereport->enabled', __HANDLER__, 'top', 'hrm', '', 0, '/hrm/index.php?mainmenu=hrm&leftmenu=', 'HRM', -1, 'holiday', '$user->rights->user->user->lire || $user->rights->holiday->read || $user->rights->deplacement->lire || $user->rights->expensereport->lire', '', 0, 80, __ENTITY__); + + +-- Sub-Menues -- Home - Dashboard insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '1', __HANDLER__, 'left', 90__+MAX_llx_menu__, 'home', '', 1__+MAX_llx_menu__, '/index.php', 'MyDashboard', 0, '', '', '', 2, 0, __ENTITY__); -- Home - Setup -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$user->admin', __HANDLER__, 'left', 100__+MAX_llx_menu__, 'home', 'setup', 1__+MAX_llx_menu__, '/admin/index.php?mainmenu=home&leftmenu=setup', 'Setup', 0, 'admin', '', '', 2, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 101__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/company.php?mainmenu=home&leftmenu=setup', 'MenuCompanySetup', 1, 'admin', '', '', 2, 1, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 102__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/ihm.php?mainmenu=home&leftmenu=setup', 'GUISetup', 1, 'admin', '', '', 2, 4, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 114__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/translation.php?mainmenu=home&leftmenu=setup', 'Translation', 1, 'admin', '', '', 2, 4, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 115__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/defaultvalues.php?mainmenu=home&leftmenu=setup', 'DefaultValues', 1, 'admin', '', '', 2, 4, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$user->admin' , __HANDLER__, 'left', 100__+MAX_llx_menu__, 'home', 'setup', 1__+MAX_llx_menu__, '/admin/index.php?mainmenu=home&leftmenu=setup', 'Setup', 0, 'admin', '', '', 2, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 101__+MAX_llx_menu__, 'home', '' , 100__+MAX_llx_menu__, '/admin/company.php?mainmenu=home&leftmenu=setup', 'MenuCompanySetup', 1, 'admin', '', '', 2, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 102__+MAX_llx_menu__, 'home', '' , 100__+MAX_llx_menu__, '/admin/ihm.php?mainmenu=home&leftmenu=setup', 'GUISetup', 1, 'admin', '', '', 2, 4, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 114__+MAX_llx_menu__, 'home', '' , 100__+MAX_llx_menu__, '/admin/translation.php?mainmenu=home&leftmenu=setup', 'Translation', 1, 'admin', '', '', 2, 4, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 115__+MAX_llx_menu__, 'home', '' , 100__+MAX_llx_menu__, '/admin/defaultvalues.php?mainmenu=home&leftmenu=setup', 'DefaultValues', 1, 'admin', '', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 103__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/modules.php?mainmenu=home&leftmenu=setup', 'Modules', 1, 'admin', '', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 104__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/boxes.php?mainmenu=home&leftmenu=setup', 'Boxes', 1, 'admin', '', '', 2, 6, __ENTITY__); @@ -42,6 +48,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 113__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/sms.php?mainmenu=home&leftmenu=setup', 'SMS', 1, 'admin', '', '', 2, 12, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 111__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/dict.php?mainmenu=home&leftmenu=setup', 'Dictionary', 1, 'admin', '', '', 2, 13, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 112__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/const.php?mainmenu=home&leftmenu=setup', 'OtherSetup', 1, 'admin', '', '', 2, 14, __ENTITY__); + -- Home - Admin tools insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$user->admin', __HANDLER__, 'left', 300__+MAX_llx_menu__, 'home', 'admintools', 1__+MAX_llx_menu__, '/admin/tools/index.php?mainmenu=home&leftmenu=admintools', 'AdminTools', 0, 'admin', '', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="admintools"', __HANDLER__, 'left', 201__+MAX_llx_menu__, 'home', '', 300__+MAX_llx_menu__, '/admin/system/dolibarr.php?mainmenu=home&leftmenu=admintools', 'InfoDolibarr', 1, 'admin', '', '', 2, 0, __ENTITY__); @@ -62,6 +69,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="admintools"', __HANDLER__, 'left', 311__+MAX_llx_menu__, 'home', '', 300__+MAX_llx_menu__, '/admin/system/about.php?mainmenu=home&leftmenu=admintools', 'ExternalResources', 1, 'admin', '', '', 2, 14, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="admintools"', __HANDLER__, 'left', 320__+MAX_llx_menu__, 'home', '', 300__+MAX_llx_menu__, '/product/admin/product_tools.php?mainmenu=home&leftmenu=admintools', 'ProductVatMassChange', 1, 'products', '', '', 2, 15, __ENTITY__); + -- Home - Menu users and groups insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '1', __HANDLER__, 'left', 400__+MAX_llx_menu__, 'home', 'users', 1__+MAX_llx_menu__, '/user/home.php?mainmenu=home&leftmenu=users', 'MenuUsersAndGroups', 0, 'users', '', '', 2, 4, __ENTITY__); @@ -84,6 +92,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 507__+MAX_llx_menu__, 'companies', '', 506__+MAX_llx_menu__, '/societe/card.php?mainmenu=companies&leftmenu=prospects&action=create&type=p', 'MenuNewProspect', 2, 'companies', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 509__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/list.php?mainmenu=companies&type=c&leftmenu=customers', 'ListCustomersShort', 1, 'companies', '$user->rights->societe->lire', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 510__+MAX_llx_menu__, 'companies', '', 509__+MAX_llx_menu__, '/societe/card.php?mainmenu=companies&leftmenu=customers&action=create&type=c', 'MenuNewCustomer', 2, 'companies', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); + -- Third parties - Contacts insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 600__+MAX_llx_menu__, 'companies', 'contacts', 2__+MAX_llx_menu__, '/contact/list.php?mainmenu=companies&leftmenu=contacts', 'ContactsAddresses', 0, 'companies', '$user->rights->societe->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 601__+MAX_llx_menu__, 'companies', '', 600__+MAX_llx_menu__, '/contact/card.php?mainmenu=companies&leftmenu=contacts&action=create', 'NewContactAddress', 1, 'companies', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); @@ -92,15 +101,19 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 605__+MAX_llx_menu__, 'companies', '', 602__+MAX_llx_menu__, '/contact/list.php?mainmenu=companies&leftmenu=contacts&type=c', 'ThirdPartyCustomers', 2, 'companies', '$user->rights->societe->contact->lire', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled))', __HANDLER__, 'left', 606__+MAX_llx_menu__, 'companies', '', 602__+MAX_llx_menu__, '/contact/list.php?mainmenu=companies&leftmenu=contacts&type=f', 'ThirdPartySuppliers', 2, 'companies', '$user->rights->societe->contact->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 607__+MAX_llx_menu__, 'companies', '', 602__+MAX_llx_menu__, '/contact/list.php?mainmenu=companies&leftmenu=contacts&type=o', 'Others', 2, 'companies', '$user->rights->societe->contact->lire', '', 2, 4, __ENTITY__); + -- Third parties - Category customer insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->categorie->enabled', __HANDLER__, 'left', 650__+MAX_llx_menu__, 'companies', 'cat', 2__+MAX_llx_menu__, '/categories/index.php?mainmenu=companies&leftmenu=cat&type=1', 'SuppliersCategoriesShort', 0, 'categories', '$user->rights->categorie->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->categorie->enabled', __HANDLER__, 'left', 651__+MAX_llx_menu__, 'companies', '', 650__+MAX_llx_menu__, '/categories/card.php?mainmenu=companies&action=create&type=1', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); + -- Third parties - Category supplier insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '(!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) && $conf->categorie->enabled', __HANDLER__, 'left', 660__+MAX_llx_menu__, 'companies', 'cat', 2__+MAX_llx_menu__, '/categories/index.php?mainmenu=companies&leftmenu=cat&type=2', 'CustomersProspectsCategoriesShort', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '(!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) && $conf->categorie->enabled', __HANDLER__, 'left', 661__+MAX_llx_menu__, 'companies', '', 660__+MAX_llx_menu__, '/categories/card.php?mainmenu=companies&action=create&type=2', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); + -- Third parties - Category contact insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->categorie->enabled', __HANDLER__, 'left', 670__+MAX_llx_menu__, 'companies', 'cat', 2__+MAX_llx_menu__, '/categories/index.php?mainmenu=companies&leftmenu=cat&type=4', 'ContactCategoriesShort', 0, 'categories', '$user->rights->categorie->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->categorie->enabled', __HANDLER__, 'left', 671__+MAX_llx_menu__, 'companies', '', 670__+MAX_llx_menu__, '/categories/card.php?mainmenu=companies&action=create&type=4', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); + -- Product - Product insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->product->enabled', __HANDLER__, 'left', 2800__+MAX_llx_menu__, 'products', 'product', 3__+MAX_llx_menu__, '/product/index.php?mainmenu=products&leftmenu=product&type=0', 'Products', 0, 'products', '$user->rights->produit->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->product->enabled', __HANDLER__, 'left', 2801__+MAX_llx_menu__, 'products', '', 2800__+MAX_llx_menu__, '/product/card.php?mainmenu=products&leftmenu=product&action=create&type=0', 'NewProduct', 1, 'products', '$user->rights->produit->creer', '', 2, 0, __ENTITY__); @@ -112,11 +125,13 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->variants->enabled', __HANDLER__, 'left', 2807__+MAX_llx_menu__, 'products', '', 2800__+MAX_llx_menu__, '/variants/list.php?mainmenu=products', 'VariantAttributes', 1, 'products', '$user->rights->produit->lire', '', 2, 7, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->propal->enabled', __HANDLER__, 'left', 2804__+MAX_llx_menu__, 'products', '', 2800__+MAX_llx_menu__, '/product/stats/card.php?mainmenu=products&id=all&leftmenu=stats&type=0', 'Statistics', 1, 'main', '$user->rights->produit->lire', '', 2, 8, __ENTITY__); + -- Product - Services insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->service->enabled', __HANDLER__, 'left', 2900__+MAX_llx_menu__, 'products', 'service', 3__+MAX_llx_menu__, '/product/index.php?mainmenu=products&leftmenu=service&type=1', 'Services', 0, 'products', '$user->rights->service->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->service->enabled', __HANDLER__, 'left', 2901__+MAX_llx_menu__, 'products', '', 2900__+MAX_llx_menu__, '/product/card.php?mainmenu=products&leftmenu=service&action=create&type=1', 'NewService', 1, 'products', '$user->rights->service->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->service->enabled', __HANDLER__, 'left', 2902__+MAX_llx_menu__, 'products', '', 2900__+MAX_llx_menu__, '/product/list.php?mainmenu=products&leftmenu=service&type=1', 'List', 1, 'products', '$user->rights->service->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->propal->enabled', __HANDLER__, 'left', 2903__+MAX_llx_menu__, 'products', '', 2900__+MAX_llx_menu__, '/product/stats/card.php?mainmenu=products&id=all&leftmenu=stats&type=1', 'Statistics', 1, 'main', '$user->rights->service->lire', '', 2, 5, __ENTITY__); + -- Product - Stocks insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3100__+MAX_llx_menu__, 'products', 'stock', 3__+MAX_llx_menu__, '/product/stock/index.php?mainmenu=products&leftmenu=stock', 'Stock', 0, 'stocks', '$user->rights->stock->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3101__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/card.php?mainmenu=products&action=create', 'MenuNewWarehouse', 1, 'stocks', '$user->rights->stock->creer', '', 2, 0, __ENTITY__); @@ -128,11 +143,13 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left -- Product - Categories insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3200__+MAX_llx_menu__, 'products', 'cat', 3__+MAX_llx_menu__, '/categories/index.php?mainmenu=products&leftmenu=cat&type=0', 'Categories', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3201__+MAX_llx_menu__, 'products', '', 3200__+MAX_llx_menu__, '/categories/card.php?mainmenu=products&action=create&type=0', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); + -- Product - Shipment insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expedition->enabled', __HANDLER__, 'left', 1300__+MAX_llx_menu__, 'commercial', 'sendings', 3__+MAX_llx_menu__, '/expedition/index.php?mainmenu=commercial&leftmenu=sendings', 'Shipments', 0, 'sendings', '$user->rights->expedition->lire', '', 2, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expedition->enabled && $leftmenu=="sendings"', __HANDLER__, 'left', 1301__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/expedition/card.php?mainmenu=commercial&action=create2&leftmenu=sendings', 'NewSending', 1, 'sendings', '$user->rights->expedition->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expedition->enabled && $leftmenu=="sendings"', __HANDLER__, 'left', 1302__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/expedition/list.php?mainmenu=commercial&leftmenu=sendings', 'List', 1, 'sendings', '$user->rights->expedition->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expedition->enabled && $leftmenu=="sendings"', __HANDLER__, 'left', 1303__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/expedition/stats/index.php?mainmenu=commercial&leftmenu=sendings', 'Statistics', 1, 'sendings', '$user->rights->expedition->lire', '', 2, 2, __ENTITY__); + -- Product - Reception insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->reception->enabled', __HANDLER__, 'left', 1350__+MAX_llx_menu__, 'commercial', 'receptions', 3__+MAX_llx_menu__, '/reception/index.php?mainmenu=commercial&leftmenu=receptions', 'Receptions', 0, 'receptions', '$user->rights->reception->lire', '', 2, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->reception->enabled && $leftmenu=="receptions"', __HANDLER__, 'left', 1351__+MAX_llx_menu__, 'commercial', '', 1350__+MAX_llx_menu__, '/reception/card.php?mainmenu=commercial&action=create2&leftmenu=receptions', 'NewSending', 1, 'receptions', '$user->rights->reception->creer', '', 2, 0, __ENTITY__); @@ -149,6 +166,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->propal->enabled && $leftmenu=="propals"', __HANDLER__, 'left', 1106__+MAX_llx_menu__, 'commercial', '', 1102__+MAX_llx_menu__, '/comm/propal/list.php?mainmenu=commercial&leftmenu=propals&search_status=3', 'PropalStatusNotSigned', 1, 'propal', '$user->rights->propale->lire', '', 2, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->propal->enabled && $leftmenu=="propals"', __HANDLER__, 'left', 1107__+MAX_llx_menu__, 'commercial', '', 1102__+MAX_llx_menu__, '/comm/propal/list.php?mainmenu=commercial&leftmenu=propals&search_status=4', 'PropalStatusBilled', 1, 'propal', '$user->rights->propale->lire', '', 2, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->propal->enabled', __HANDLER__, 'left', 1110__+MAX_llx_menu__, 'commercial', '', 1100__+MAX_llx_menu__, '/comm/propal/stats/index.php?mainmenu=commercial&leftmenu=propals', 'Statistics', 1, 'propal', '$user->rights->propale->lire', '', 2, 4, __ENTITY__); + -- Commercial - Customer's orders insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->commande->enabled', __HANDLER__, 'left', 1200__+MAX_llx_menu__, 'commercial', 'orders', 5__+MAX_llx_menu__, '/commande/index.php?mainmenu=commercial&leftmenu=orders', 'CustomersOrders', 0, 'orders', '$user->rights->commande->lire', '', 2, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->commande->enabled', __HANDLER__, 'left', 1201__+MAX_llx_menu__, 'commercial', '', 1200__+MAX_llx_menu__, '/commande/card.php?mainmenu=commercial&action=create&leftmenu=orders', 'NewOrder', 1, 'orders', '$user->rights->commande->creer', '', 2, 0, __ENTITY__); @@ -160,11 +178,13 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->commande->enabled && $leftmenu=="orders"', __HANDLER__, 'left', 1207__+MAX_llx_menu__, 'commercial', '', 1202__+MAX_llx_menu__, '/commande/list.php?mainmenu=commercial&leftmenu=orders&search_status=4', 'StatusOrderProcessed', 1, 'orders', '$user->rights->commande->lire', '', 2, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->commande->enabled && $leftmenu=="orders"', __HANDLER__, 'left', 1208__+MAX_llx_menu__, 'commercial', '', 1202__+MAX_llx_menu__, '/commande/list.php?mainmenu=commercial&leftmenu=orders&search_status=-1', 'StatusOrderCanceledShort', 1, 'orders', '$user->rights->commande->lire', '', 2, 7, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->commande->enabled', __HANDLER__, 'left', 1209__+MAX_llx_menu__, 'commercial', '', 1200__+MAX_llx_menu__, '/commande/stats/index.php?mainmenu=commercial&leftmenu=orders', 'Statistics', 1, 'orders', '$user->rights->commande->lire', '', 2, 4, __ENTITY__); + -- Commercial - Supplier's proposals insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_proposal->enabled', __HANDLER__, 'left', 1650__+MAX_llx_menu__, 'commercial', 'propals_supplier', 3__+MAX_llx_menu__, '/supplier_proposal/index.php?leftmenu=propals_supplier', 'SupplierProposalsShort', 0, 'supplier_proposal', '$user->rights->supplier_proposal->lire', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_proposal->enabled', __HANDLER__, 'left', 1651__+MAX_llx_menu__, 'commercial', '', 1650__+MAX_llx_menu__, '/supplier_proposal/card.php?action=create&leftmenu=supplier_proposals', 'SupplierProposalNew', 1, 'supplier_proposal', '$user->rights->supplier_proposal->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_proposal->enabled', __HANDLER__, 'left', 1652__+MAX_llx_menu__, 'commercial', '', 1650__+MAX_llx_menu__, '/supplier_proposal/list.php?leftmenu=supplier_proposals', 'List', 1, 'supplier_proposal', '$user->rights->supplier_proposal->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_proposal->enabled', __HANDLER__, 'left', 1653__+MAX_llx_menu__, 'commercial', '', 1650__+MAX_llx_menu__, '/comm/propal/stats/index.php?leftmenu=supplier_proposals&mode=supplier', 'Statistics', 1, 'supplier_proposal', '$user->rights->supplier_proposal->lire', '', 2, 2, __ENTITY__); + -- Commercial - Supplier's orders insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_order->enabled', __HANDLER__, 'left', 5100__+MAX_llx_menu__, 'commercial', 'orders_suppliers', 5__+MAX_llx_menu__, '/fourn/commande/index.php?mainmenu=commercial&leftmenu=orders_suppliers', 'SuppliersOrders', 0, 'orders', '($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->lire)', '', 2, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_order->enabled', __HANDLER__, 'left', 5101__+MAX_llx_menu__, 'commercial', '', 5100__+MAX_llx_menu__, '/fourn/commande/card.php?mainmenu=commercial&action=create&leftmenu=orders_suppliers', 'NewSupplierOrderShort', 1, 'orders', '($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer)', '', 2, 0, __ENTITY__); @@ -178,6 +198,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_order->enabled && $leftmenu=="orders_suppliers"', __HANDLER__, 'left', 5109__+MAX_llx_menu__, 'commercial', '', 5102__+MAX_llx_menu__, '/fourn/commande/list.php?mainmenu=commercial&leftmenu=orders_suppliers&statut=6,7', 'StatusOrderCanceled', 1, 'orders', '($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->lire)', '', 2, 8, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_order->enabled && $leftmenu=="orders_suppliers"', __HANDLER__, 'left', 5110__+MAX_llx_menu__, 'commercial', '', 5102__+MAX_llx_menu__, '/fourn/commande/list.php?mainmenu=commercial&leftmenu=orders_suppliers&statut=9', 'StatusOrderRefused', 1, 'orders', '($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->lire)', '', 2, 9, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_order->enabled', __HANDLER__, 'left', 5111__+MAX_llx_menu__, 'commercial', '', 5100__+MAX_llx_menu__, '/commande/stats/index.php?mainmenu=commercial&leftmenu=orders_suppliers&mode=supplier', 'Statistics', 1, 'orders', '($user->rights->fournisseur->commande->lire || $user->rights->supplier_order->lire)', '', 2, 7, __ENTITY__); + -- Commercial - Contracts insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->contrat->enabled', __HANDLER__, 'left', 1400__+MAX_llx_menu__, 'commercial', 'contracts', 5__+MAX_llx_menu__, '/contrat/index.php?mainmenu=commercial&leftmenu=contracts', 'Contracts', 0, 'contracts', '$user->rights->contrat->lire', '', 2, 7, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->contrat->enabled', __HANDLER__, 'left', 1401__+MAX_llx_menu__, 'commercial', '', 1400__+MAX_llx_menu__, '/contrat/card.php?mainmenu=commercial&action=create&leftmenu=contracts', 'NewContract', 1, 'contracts', '$user->rights->contrat->creer', '', 2, 0, __ENTITY__); @@ -187,11 +208,13 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->contrat->enabled && $leftmenu=="contracts"', __HANDLER__, 'left', 1405__+MAX_llx_menu__, 'commercial', '', 1403__+MAX_llx_menu__, '/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4', 'MenuRunningServices', 2, 'contracts', '$user->rights->contrat->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->contrat->enabled && $leftmenu=="contracts"', __HANDLER__, 'left', 1406__+MAX_llx_menu__, 'commercial', '', 1403__+MAX_llx_menu__, '/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&filter=expired', 'MenuExpiredServices', 2, 'contracts', '$user->rights->contrat->lire', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->contrat->enabled && $leftmenu=="contracts"', __HANDLER__, 'left', 1407__+MAX_llx_menu__, 'commercial', '', 1403__+MAX_llx_menu__, '/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=5', 'MenuClosedServices', 2, 'contracts', '$user->rights->contrat->lire', '', 2, 3, __ENTITY__); + -- Commercial - Interventions insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->ficheinter->enabled', __HANDLER__, 'left', 1500__+MAX_llx_menu__, 'commercial', 'ficheinter', 5__+MAX_llx_menu__, '/fichinter/list.php?mainmenu=commercial&leftmenu=ficheinter', 'Interventions', 0, 'interventions', '$user->rights->ficheinter->lire', '', 2, 8, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->ficheinter->enabled', __HANDLER__, 'left', 1501__+MAX_llx_menu__, 'commercial', '', 1500__+MAX_llx_menu__, '/fichinter/card.php?mainmenu=commercial&action=create&leftmenu=ficheinter', 'NewIntervention', 1, 'interventions', '$user->rights->ficheinter->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->ficheinter->enabled', __HANDLER__, 'left', 1502__+MAX_llx_menu__, 'commercial', '', 1500__+MAX_llx_menu__, '/fichinter/list.php?mainmenu=commercial&leftmenu=ficheinter', 'List', 1, 'interventions', '$user->rights->ficheinter->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->ficheinter->enabled', __HANDLER__, 'left', 1503__+MAX_llx_menu__, 'commercial', '', 1500__+MAX_llx_menu__, '/fichinter/stats/index.php?mainmenu=commercial&leftmenu=ficheinter', 'Statistics', 1, 'interventions', '$user->rights->ficheinter->lire', '', 2, 2, __ENTITY__); + -- Billing - Supplier invoice insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1600__+MAX_llx_menu__, 'billing', 'supplier_bills', 6__+MAX_llx_menu__, '/fourn/facture/list.php?mainmenu=billing&leftmenu=suppliers_bills', 'BillsSuppliers', 0, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1601__+MAX_llx_menu__, 'billing', '', 1600__+MAX_llx_menu__, '/fourn/facture/card.php?mainmenu=billing&action=create&leftmenu=suppliers_bills', 'NewBill', 1, 'bills', '$user->rights->fournisseur->facture->creer', '', 2, 0, __ENTITY__); @@ -200,6 +223,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1603__+MAX_llx_menu__, 'billing', 'suppliers_bills_payment', 1600__+MAX_llx_menu__, '/fourn/facture/paiement.php?mainmenu=billing&leftmenu=suppliers_bills_payment', 'Payments', 1, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1605__+MAX_llx_menu__, 'billing', 'suppliers_bills_reports', 1603__+MAX_llx_menu__, '/fourn/facture/rapport.php?mainmenu=billing&leftmenu=suppliers_bills_reports', 'Reporting', 2, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->supplier_invoice->enabled', __HANDLER__, 'left', 1604__+MAX_llx_menu__, 'billing', 'customers_bills_stats', 1600__+MAX_llx_menu__, '/compta/facture/stats/index.php?mainmenu=billing&leftmenu=customers_bills_stats&mode=supplier', 'Statistics', 1, 'bills', '$user->rights->fournisseur->facture->lire', '', 2, 8, __ENTITY__); + -- Billing - Customer invoice insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1700__+MAX_llx_menu__, 'billing', 'customer_bills', 6__+MAX_llx_menu__, '/compta/facture/list.php?mainmenu=billing&leftmenu=customers_bills', 'BillsCustomers', 0, 'bills', '$user->rights->facture->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1701__+MAX_llx_menu__, 'billing', '', 1700__+MAX_llx_menu__, '/compta/facture/card.php?mainmenu=billing&action=create&leftmenu=customers_bills', 'NewBill', 1, 'bills', '$user->rights->facture->creer', '', 2, 3, __ENTITY__); @@ -215,42 +239,52 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1704__+MAX_llx_menu__, 'billing', 'customers_bills_payment', 1700__+MAX_llx_menu__, '/compta/paiement/list.php?mainmenu=billing&leftmenu=customers_bills_payment', 'Payments', 1, 'bills', '$user->rights->facture->lire', '', 2, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1710__+MAX_llx_menu__, 'billing', 'customers_bills_reports', 1704__+MAX_llx_menu__, '/compta/paiement/rapport.php?mainmenu=billing&leftmenu=customers_bills_reports', 'Reportings', 2, 'bills', '$user->rights->facture->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1714__+MAX_llx_menu__, 'billing', 'customers_bills_stats', 1700__+MAX_llx_menu__, '/compta/facture/stats/index.php?mainmenu=billing&leftmenu=customers_bills_stats', 'Statistics', 1, 'bills', '$user->rights->facture->lire', '', 2, 8, __ENTITY__); + -- Billing - Orders to bill insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->commande->enabled', __HANDLER__, 'left', 1900__+MAX_llx_menu__, 'billing', 'orders', 6__+MAX_llx_menu__, '/commande/list.php?mainmenu=billing&leftmenu=orders&search_status=3', 'MenuOrdersToBill', 0, 'orders', '$user->rights->commande->lire', '', 0, 3, __ENTITY__); + -- Donations insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->don->enabled', __HANDLER__, 'left', 2000__+MAX_llx_menu__, 'billing', 'donations', 6__+MAX_llx_menu__, '/don/index.php?mainmenu=billing&leftmenu=donations', 'Donations', 0, 'donations', '$user->rights->don->lire', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->don->enabled && $leftmenu=="donations"', __HANDLER__, 'left', 2001__+MAX_llx_menu__, 'billing', '', 2000__+MAX_llx_menu__, '/don/card.php?mainmenu=billing&leftmenu=donations&action=create', 'NewDonation', 1, 'donations', '$user->rights->don->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->don->enabled && $leftmenu=="donations"', __HANDLER__, 'left', 2002__+MAX_llx_menu__, 'billing', '', 2000__+MAX_llx_menu__, '/don/list.php?mainmenu=billing&leftmenu=donations', 'List', 1, 'donations', '$user->rights->don->lire', '', 2, 1, __ENTITY__); -- insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->don->enabled && $leftmenu=="donations"', __HANDLER__, 'left', 2003__+MAX_llx_menu__, 'billing', '', 2000__+MAX_llx_menu__, '/don/stats/index.php?mainmenu=billing&leftmenu=donations', 'Statistics', 1, 'donations', '$user->rights->don->lire', '', 2, 2, __ENTITY__); + -- Special expenses insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled || $conf->salaries->enabled || $conf->loan->enabled || $conf->banque->enabled', __HANDLER__, 'left', 2200__+MAX_llx_menu__, 'billing', 'tax', 6__+MAX_llx_menu__, '/compta/charges/index.php?mainmenu=billing&leftmenu=tax', 'MenuTaxesAndSpecialExpenses', 0, 'compta', '(! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) || (! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read)) || (! empty($conf->loan->enabled) && $user->rights->loan->read) || (! empty($conf->banque->enabled) && $user->rights->banque->lire)', '', 0, 6, __ENTITY__); + -- Social contributions insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled', __HANDLER__, 'left', 2250__+MAX_llx_menu__, 'billing', 'tax_social', 2200__+MAX_llx_menu__, '/compta/sociales/list.php?mainmenu=billing&leftmenu=tax_social', 'SocialContributions', 1, '', '$user->rights->tax->charges->lire', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && $leftmenu=="tax_social"', __HANDLER__, 'left', 2251__+MAX_llx_menu__, 'billing', '', 2250__+MAX_llx_menu__, '/compta/sociales/card.php?mainmenu=billing&leftmenu=tax_social&action=create', 'MenuNewSocialContribution', 2, '', '$user->rights->tax->charges->creer', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && $leftmenu=="tax_social"', __HANDLER__, 'left', 2252__+MAX_llx_menu__, 'billing', '', 2250__+MAX_llx_menu__, '/compta/sociales/payments.php?mainmenu=billing&leftmenu=tax_social', 'Payments', 2, '', '$user->rights->tax->charges->lire', '', 0, 3, __ENTITY__); --- VAT + +-- VAT/TVA/IVA insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS)', __HANDLER__, 'left', 2300__+MAX_llx_menu__, 'billing', 'tax_vat', 2200__+MAX_llx_menu__, '/compta/tva/list.php?mainmenu=billing&leftmenu=tax_vat', 'VAT', 1, 'companies', '$user->rights->tax->charges->lire', '', 0, 7, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2301__+MAX_llx_menu__, 'billing', '', 2300__+MAX_llx_menu__, '/compta/tva/card.php?mainmenu=billing&leftmenu=tax_vat&action=create', 'New', 2, 'companies', '$user->rights->tax->charges->creer', '', 0, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2302__+MAX_llx_menu__, 'billing', '', 2300__+MAX_llx_menu__, '/compta/tva/list.php?mainmenu=billing&leftmenu=tax_vat', 'List', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2303__+MAX_llx_menu__, 'billing', '', 2300__+MAX_llx_menu__, '/compta/tva/index.php?mainmenu=billing&leftmenu=tax_vat', 'ReportByMonth', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2304__+MAX_llx_menu__, 'billing', '', 2300__+MAX_llx_menu__, '/compta/tva/clients.php?mainmenu=billing&leftmenu=tax_vat', 'ReportByThirdparties', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2305__+MAX_llx_menu__, 'billing', '', 2300__+MAX_llx_menu__, '/compta/tva/quadri_detail.php?mainmenu=billing&leftmenu=tax_vat', 'ReportByQuarter', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 4, __ENTITY__); + -- Salary insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->salaries->enabled', __HANDLER__, 'left', 2210__+MAX_llx_menu__, 'billing', 'tax_sal', 6__+MAX_llx_menu__, '/salaries/list.php?mainmenu=billing&leftmenu=tax_salary', 'Salaries', 0, 'salaries', '$user->rights->salaries->read', '', 0, 10, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->salaries->enabled && $leftmenu=="tax_salary"', __HANDLER__, 'left', 2211__+MAX_llx_menu__, 'billing', '', 2210__+MAX_llx_menu__, '/salaries/card.php?mainmenu=billing&leftmenu=tax_salary&action=create', 'NewPayment', 1, 'companies', '$user->rights->salaries->write', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->salaries->enabled && $leftmenu=="tax_salary"', __HANDLER__, 'left', 2212__+MAX_llx_menu__, 'billing', '', 2210__+MAX_llx_menu__, '/salaries/list.php?mainmenu=billing&leftmenu=tax_salary', 'Payments', 1, 'companies', '$user->rights->salaries->read', '', 0, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->salaries->enabled && $leftmenu=="tax_salary"', __HANDLER__, 'left', 2213__+MAX_llx_menu__, 'billing', '', 2210__+MAX_llx_menu__, '/salaries/stats/index.php?mainmenu=billing&leftmenu=tax_salary', 'Statistics', 1, 'companies', '$user->rights->salaries->read', '', 0, 4, __ENTITY__); + -- Loan insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->loan->enabled', __HANDLER__, 'left', 2220__+MAX_llx_menu__, 'billing', 'tax_loan', 6__+MAX_llx_menu__, '/loan/list.php?mainmenu=billing&leftmenu=tax_loan', 'Loans', 0, 'loan', '$user->rights->loan->read', '', 0, 20, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->loan->enabled && $leftmenu=="tax_loan"', __HANDLER__, 'left', 2221__+MAX_llx_menu__, 'billing', '', 2220__+MAX_llx_menu__, '/loan/card.php?mainmenu=billing&leftmenu=tax_loan&action=create', 'NewLoan', 1, 'loan', '$user->rights->loan->write', '', 0, 2, __ENTITY__); --insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->loan->enabled && $leftmenu=="tax_loan"', __HANDLER__, 'left', 2222__+MAX_llx_menu__, 'billing', '', 2220__+MAX_llx_menu__, '/loan/payment/list.php?mainmenu=billing&leftmenu=tax_loan', 'Payments', 1, 'companies', '$user->rights->loan->read', '', 0, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->loan->enabled && $leftmenu=="tax_loan" && ! empty($conf->global->LOAN_SHOW_CALCULATOR)', __HANDLER__, 'left', 2223__+MAX_llx_menu__, 'billing', '', 2220__+MAX_llx_menu__, '/loan/calc.php?mainmenu=billing&leftmenu=tax_loan', 'Calculator', 1, 'companies', '$user->rights->loan->calc', '', 0, 4, __ENTITY__); + -- Various payments insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)', __HANDLER__, 'left', 2350__+MAX_llx_menu__, 'billing', 'tax_various', 6__+MAX_llx_menu__, '/compta/bank/various_payment/list.php?mainmenu=billing&leftmenu=tax_various', 'MenuVariousPayment', 0, 'banks', '$user->rights->banque->lire', '', 0, 30, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && $leftmenu=="tax_various"', __HANDLER__, 'left', 2351__+MAX_llx_menu__, 'billing', '', 2350__+MAX_llx_menu__, '/compta/bank/various_payment/card.php?mainmenu=billing&leftmenu=tax_various&action=create', 'New', 1, 'various_payment', '$user->rights->banque->modifier', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && $leftmenu=="tax_various"', __HANDLER__, 'left', 2352__+MAX_llx_menu__, 'billing', '', 2350__+MAX_llx_menu__, '/compta/bank/various_payment/list.php?mainmenu=billing&leftmenu=tax_various', 'List', 1, 'various_payment', '$user->rights->banque->lire', '', 0, 3, __ENTITY__); + -- Accounting (Double entries) insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2400__+MAX_llx_menu__, 'accountancy', 'accountancy', 9__+MAX_llx_menu__, '/accountancy/index.php?mainmenu=accountancy&leftmenu=accountancy', 'MenuAccountancy', 0, 'main', '! empty($conf->accounting->enabled) || $user->rights->accounting->bind->write || $user->rights->accounting->bind->write || $user->rights->compta->resultat->lire', '', 0, 7, __ENTITY__); + -- Setup insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2451__+MAX_llx_menu__, 'accountancy', 'accountancy_admin', 2400__+MAX_llx_menu__, '/accountancy/index.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'Setup', 1, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 1, __ENTITY__); @@ -271,8 +305,10 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2465__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_export', 2451__+MAX_llx_menu__, '/accountancy/admin/export.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'ExportOptions', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 60, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin" && $conf->global->MAIN_FEATURES_LEVEL > 1', __HANDLER__, 'left', 2466__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_closure', 2451__+MAX_llx_menu__, '/accountancy/admin/closure.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuClosureAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 70, __ENTITY__); + -- Accounting period insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin" && $conf->global->MAIN_FEATURES_LEVEL > 0', __HANDLER__, 'left', 2450__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_period', 2451__+MAX_llx_menu__, '/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'FiscalPeriod', 1, 'admin', '', '', 2, 80, __ENTITY__); + -- Binding insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $conf->facture->enabled && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_SALES)', __HANDLER__, 'left', 2401__+MAX_llx_menu__, 'accountancy', 'accountancy_dispatch_customer', 2400__+MAX_llx_menu__, '/accountancy/customer/index.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer', 'CustomersVentilation', 1, 'accountancy', '$user->rights->accounting->bind->write', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $conf->facture->enabled && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_SALES) && $leftmenu=="accountancy_dispatch_customer"', __HANDLER__, 'left', 2402__+MAX_llx_menu__, 'accountancy', '', 2401__+MAX_llx_menu__, '/accountancy/customer/list.php?mainmenu=accountancy', 'ToDispatch', 2, 'accountancy', '$user->rights->accounting->bind->write', '', 0, 3, __ENTITY__); @@ -283,22 +319,29 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $conf->expensereport->enabled && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS)', __HANDLER__, 'left', 2420__+MAX_llx_menu__, 'accountancy', 'accountancy_dispatch_expensereport', 2400__+MAX_llx_menu__, '/accountancy/expensereport/index.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_expensereport', 'ExpenseReportsVentilation', 1, 'accountancy', '$user->rights->accounting->bind->write', '', 0, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $conf->expensereport->enabled && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS) && $leftmenu=="accountancy_dispatch_expensereport"', __HANDLER__, 'left', 2421__+MAX_llx_menu__, 'accountancy', '', 2420__+MAX_llx_menu__, '/accountancy/expensereport/list.php?mainmenu=accountancy', 'ToDispatch', 2, 'accountancy', '$user->rights->accounting->bind->write', '', 0, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $conf->expensereport->enabled && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS) && $leftmenu=="accountancy_dispatch_expensereport"', __HANDLER__, 'left', 2422__+MAX_llx_menu__, 'accountancy', '', 2420__+MAX_llx_menu__, '/accountancy/expensereport/lines.php?mainmenu=accountancy', 'Dispatched', 2, 'accountancy', '$user->rights->accounting->bind->write', '', 0, 7, __ENTITY__); + -- Export accounting documents insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->comptabilite->enabled || $conf->accounting->enabled', __HANDLER__, 'left', 2436__+MAX_llx_menu__, 'accountancy', 'accountancy_files', 2400__+MAX_llx_menu__, '/compta/accounting-files.php?mainmenu=accountancy&leftmenu=accountancy_files', 'AccountantFiles', 1, 'accountancy', '$user->rights->compta->resultat->lire || $user->rights->accounting->mouvements->lire', '', 0, 16, __ENTITY__); + -- Journals --insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2705__+MAX_llx_menu__, 'accountancy', '', 2400__+MAX_llx_menu__, '', 'Journalization', 1, 'main', '$user->rights->accounting->comptarapport->lire', '', 0, 1, __ENTITY__); --insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2707__+MAX_llx_menu__, 'accountancy', '', 2705__+MAX_llx_menu__, '/accountancy/journal/bankjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal=3', 'BankJournal', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 1, __ENTITY__); --insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2708__+MAX_llx_menu__, 'accountancy', '', 2705__+MAX_llx_menu__, '/accountancy/journal/expensereportsjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal=6', 'ExpenseReportJournal', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 2, __ENTITY__); --insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2709__+MAX_llx_menu__, 'accountancy', '', 2705__+MAX_llx_menu__, '/accountancy/journal/purchasesjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal=2', 'PurchasesJournal', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 3, __ENTITY__); --insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2706__+MAX_llx_menu__, 'accountancy', '', 2705__+MAX_llx_menu__, '/accountancy/journal/sellsjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal=1', 'SellsJournal', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 4, __ENTITY__); + -- Balance insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2430__+MAX_llx_menu__, 'accountancy', 'balance', 2400__+MAX_llx_menu__, '/accountancy/bookkeeping/balance.php?mainmenu=accountancy&leftmenu=accountancy_balance', 'AccountBalance', 1, 'accountancy', '$user->rights->accounting->mouvements->lire', '', 0, 10, __ENTITY__); + -- General Ledger insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2432__+MAX_llx_menu__, 'accountancy', 'bookkeeping', 2400__+MAX_llx_menu__, '/accountancy/bookkeeping/listbyaccount.php?mainmenu=accountancy&leftmenu=accountancy_bookeeping', 'Bookkeeping', 1, 'accountancy', '$user->rights->accounting->mouvements->lire', '', 0, 12, __ENTITY__); + -- Journals insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2434__+MAX_llx_menu__, 'accountancy', 'bookkeeping', 2400__+MAX_llx_menu__, '/accountancy/bookkeeping/list.php?mainmenu=accountancy&leftmenu=accountancy_bookeeping', 'Journals', 1, 'accountancy', '$user->rights->accounting->mouvements->lire', '', 0, 15, __ENTITY__); + -- Closure insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2437__+MAX_llx_menu__, 'accountancy', 'accountancy_closure', 2400__+MAX_llx_menu__, '/accountancy/closure/index.php?mainmenu=accountancy&leftmenu=accountancy_closure', 'MenuAccountancyClosure', 1, 'accountancy', '$user->rights->accounting->fiscalyear->write', '', 0, 17, __ENTITY__); + -- Reports insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2440__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2400__+MAX_llx_menu__, '/compta/resultat/index.php?mainmenu=accountancy&leftmenu=accountancy_report', 'Reportings', 1, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 17, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_report"', __HANDLER__, 'left', 2441__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2440__+MAX_llx_menu__, '/compta/resultat/index.php?mainmenu=accountancy&leftmenu=accountancy_report', 'MenuReportInOut', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 18, __ENTITY__); @@ -308,6 +351,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_report"', __HANDLER__, 'left', 2445__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2444__+MAX_llx_menu__, '/compta/stats/casoc.php?mainmenu=accountancy&leftmenu=accountancy_report', 'ByCompanies', 3, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 22, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_report"', __HANDLER__, 'left', 2446__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2444__+MAX_llx_menu__, '/compta/stats/cabyuser.php?mainmenu=accountancy&leftmenu=accountancy_report', 'ByUsers', 3, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 23, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_report"', __HANDLER__, 'left', 2447__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2444__+MAX_llx_menu__, '/compta/stats/cabyprodserv.php?mainmenu=accountancy&leftmenu=accountancy_report', 'ByProductsAndServices', 3, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 24, __ENTITY__); + -- Accounting simple insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->comptabilite->enabled', __HANDLER__, 'left', 2700__+MAX_llx_menu__, 'accountancy', 'ca', 9__+MAX_llx_menu__, '/compta/resultat/index.php?mainmenu=accountancy&leftmenu=ca', 'Reportings', 0, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 11, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->comptabilite->enabled && $leftmenu=="ca"', __HANDLER__, 'left', 2711__+MAX_llx_menu__, 'accountancy', '', 2700__+MAX_llx_menu__, '/compta/resultat/index.php?mainmenu=accountancy&leftmenu=ca', 'MenuReportInOut', 1, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 0, __ENTITY__); @@ -316,6 +360,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->comptabilite->enabled && $leftmenu=="ca"', __HANDLER__, 'left', 2714__+MAX_llx_menu__, 'accountancy', '', 2703__+MAX_llx_menu__, '/compta/stats/casoc.php?mainmenu=accountancy&leftmenu=ca', 'ByCompanies', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->comptabilite->enabled && $leftmenu=="ca"', __HANDLER__, 'left', 2715__+MAX_llx_menu__, 'accountancy', '', 2703__+MAX_llx_menu__, '/compta/stats/cabyuser.php?mainmenu=accountancy&leftmenu=ca', 'ByUsers', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->comptabilite->enabled && $leftmenu=="ca"', __HANDLER__, 'left', 2716__+MAX_llx_menu__, 'accountancy', '', 2703__+MAX_llx_menu__, '/compta/stats/cabyprodserv.php?mainmenu=accountancy&leftmenu=ca', 'ByProductsAndServices', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 1, __ENTITY__); + -- Assets insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->asset->enabled', __HANDLER__, 'left', 3000__+MAX_llx_menu__, 'accountancy', 'asset', 9__+MAX_llx_menu__, '/asset/list.php?mainmenu=accountancy&leftmenu=asset', 'MenuAssets', 1, 'assets', '$user->rights->asset->read', '', 0, 20, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->asset->enabled && $leftmenu=="asset"', __HANDLER__, 'left', 3001__+MAX_llx_menu__, 'asset', '', 3000__+MAX_llx_menu__, '/asset/card.php?mainmenu=accountancy&leftmenu=asset&action=create', 'MenuNewAsset', 2, 'assets', '$user->rights->asset->write', '', 0, 21, __ENTITY__); @@ -323,10 +368,12 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->asset->enabled && $leftmenu=="asset"', __HANDLER__, 'left', 3004__+MAX_llx_menu__, 'asset', 'asset_type', 3000__+MAX_llx_menu__, '/asset/type.php?mainmenu=accountancy&leftmenu=asset', 'MenuTypeAssets', 2, 'assets', '$user->rights->asset->read', '', 0, 23, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->asset->enabled && $leftmenu=="asset"', __HANDLER__, 'left', 3005__+MAX_llx_menu__, 'asset', '', 3004__+MAX_llx_menu__, '/asset/type.php?mainmenu=accountancy&action=create', 'MenuNewTypeAssets', 3, 'assets', '$user->rights->asset->setup_advance', '', 0, 24, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->asset->enabled && $leftmenu=="asset"', __HANDLER__, 'left', 3006__+MAX_llx_menu__, 'asset', '', 3004__+MAX_llx_menu__, '/asset/type.php?mainmenu=accountancy', 'MenuListTypeAssets', 3, 'assets', '$user->rights->asset->read', '', 0, 25, __ENTITY__); + -- Check deposit insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT) && ! empty($conf->banque->enabled) && (! empty($conf->facture->enabled) || ! empty($conf->global->MAIN_MENU_CHEQUE_DEPOSIT_ON))', __HANDLER__, 'left', 1711__+MAX_llx_menu__, 'accountancy', 'checks', 14__+MAX_llx_menu__, '/compta/paiement/cheque/index.php?mainmenu=bank&leftmenu=checks', 'MenuChequeDeposits', 0, 'bills', '$user->rights->banque->lire', '', 2, 9, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT) && ! empty($conf->banque->enabled) && (! empty($conf->facture->enabled) || ! empty($conf->global->MAIN_MENU_CHEQUE_DEPOSIT_ON))', __HANDLER__, 'left', 1712__+MAX_llx_menu__, 'accountancy', '', 1711__+MAX_llx_menu__, '/compta/paiement/cheque/card.php?mainmenu=bank&leftmenu=checks&action=new', 'NewCheckDeposit', 1, 'compta', '$user->rights->banque->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT) && ! empty($conf->banque->enabled) && (! empty($conf->facture->enabled) || ! empty($conf->global->MAIN_MENU_CHEQUE_DEPOSIT_ON))', __HANDLER__, 'left', 1713__+MAX_llx_menu__, 'accountancy', '', 1711__+MAX_llx_menu__, '/compta/paiement/cheque/list.php?mainmenu=bank&leftmenu=checks', 'List', 1, 'bills', '$user->rights->banque->lire', '', 2, 1, __ENTITY__); + -- PaymentByDirectDebit insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled', __HANDLER__, 'left', 2500__+MAX_llx_menu__, 'accountancy', 'withdraw', 14__+MAX_llx_menu__, '/compta/prelevement/index.php?mainmenu=bank&leftmenu=withdraw', 'PaymentByDirectDebit', 0, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 9, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled && $leftmenu=="withdraw"', __HANDLER__, 'left', 2502__+MAX_llx_menu__, 'accountancy', '', 2500__+MAX_llx_menu__, '/compta/prelevement/create.php?mainmenu=bank&leftmenu=withdraw', 'NewStandingOrder', 1, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 0, __ENTITY__); @@ -334,6 +381,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled && $leftmenu=="withdraw"', __HANDLER__, 'left', 2504__+MAX_llx_menu__, 'accountancy', '', 2500__+MAX_llx_menu__, '/compta/prelevement/list.php?mainmenu=bank&leftmenu=withdraw', 'WithdrawalsLines', 1, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled && $leftmenu=="withdraw"', __HANDLER__, 'left', 2506__+MAX_llx_menu__, 'accountancy', '', 2500__+MAX_llx_menu__, '/compta/prelevement/rejets.php?mainmenu=bank&leftmenu=withdraw', 'Rejects', 1, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled && $leftmenu=="withdraw"', __HANDLER__, 'left', 2507__+MAX_llx_menu__, 'accountancy', '', 2500__+MAX_llx_menu__, '/compta/prelevement/stats.php?mainmenu=bank&leftmenu=withdraw', 'Statistics', 1, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 6, __ENTITY__); + -- PaymentByCreditTransfer insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled', __HANDLER__, 'left', 2510__+MAX_llx_menu__, 'accountancy', 'banktransfer', 14__+MAX_llx_menu__, '/compta/prelevement/index.php?mainmenu=bank&leftmenu=banktransfer&type=bank-transfer', 'PaymentByBankTransfer', 0, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 9, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled && $leftmenu=="banktransfer"', __HANDLER__, 'left', 2512__+MAX_llx_menu__, 'accountancy', '', 2510__+MAX_llx_menu__, '/compta/prelevement/create.php?mainmenu=bank&leftmenu=banktransfer&type=bank-transfer', 'NewStandingOrder', 1, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 0, __ENTITY__); @@ -341,6 +389,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled && $leftmenu=="banktransfer"', __HANDLER__, 'left', 2514__+MAX_llx_menu__, 'accountancy', '', 2510__+MAX_llx_menu__, '/compta/prelevement/list.php?mainmenu=bank&leftmenu=banktransfer&type=bank-transfer', 'WithdrawalsLines', 1, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled && $leftmenu=="banktransfer"', __HANDLER__, 'left', 2516__+MAX_llx_menu__, 'accountancy', '', 2510__+MAX_llx_menu__, '/compta/prelevement/rejets.php?mainmenu=bank&leftmenu=banktransfer&type=bank-transfer', 'Rejects', 1, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->prelevement->enabled && $leftmenu=="banktransfer"', __HANDLER__, 'left', 2517__+MAX_llx_menu__, 'accountancy', '', 2510__+MAX_llx_menu__, '/compta/prelevement/stats.php?mainmenu=bank&leftmenu=banktransfer&type=bank-transfer', 'Statistics', 1, 'withdrawals', '$user->rights->prelevement->bons->lire', '', 2, 6, __ENTITY__); + -- Bank insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled', __HANDLER__, 'left', 2600__+MAX_llx_menu__, 'accountancy', 'bank', 14__+MAX_llx_menu__, '/compta/bank/list.php?mainmenu=bank&leftmenu=bank', 'MenuBankCash', 0, 'banks', '$user->rights->banque->lire', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && ($leftmenu=="bank" || $leftmenu=="checks" || $leftmenu=="withdraw")', __HANDLER__, 'left', 2601__+MAX_llx_menu__, 'accountancy', '', 2600__+MAX_llx_menu__, '/compta/bank/card.php?mainmenu=bank&action=create&leftmenu=bank', 'MenuNewFinancialAccount', 1, 'banks', '$user->rights->banque->configurer', '', 0, 0, __ENTITY__); @@ -348,9 +397,12 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && ($leftmenu=="bank" || $leftmenu=="checks" || $leftmenu=="withdraw")', __HANDLER__, 'left', 2603__+MAX_llx_menu__, 'accountancy', '', 2600__+MAX_llx_menu__, '/compta/bank/bankentries_list.php?mainmenu=bank&leftmenu=bank', 'ListTransactions', 1, 'banks', '$user->rights->banque->lire', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && ($leftmenu=="bank" || $leftmenu=="checks" || $leftmenu=="withdraw")', __HANDLER__, 'left', 2604__+MAX_llx_menu__, 'accountancy', '', 2600__+MAX_llx_menu__, '/compta/bank/budget.php?mainmenu=bank&leftmenu=bank', 'ListTransactionsByCategory', 1, 'banks', '$user->rights->banque->lire', '', 0, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && ($leftmenu=="bank" || $leftmenu=="checks" || $leftmenu=="withdraw")', __HANDLER__, 'left', 2606__+MAX_llx_menu__, 'accountancy', '', 2600__+MAX_llx_menu__, '/compta/bank/transfer.php?mainmenu=bank&leftmenu=bank', 'BankTransfers', 1, 'banks', '$user->rights->banque->transfer', '', 0, 5, __ENTITY__); + -- Bank - Categories insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 2650__+MAX_llx_menu__, 'accountancy', 'cat', 14__+MAX_llx_menu__, '/categories/index.php?mainmenu=bank&leftmenu=bank&type=5', 'Categories', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 2651__+MAX_llx_menu__, 'accountancy', '', 2650__+MAX_llx_menu__, '/categories/card.php?mainmenu=bank&leftmenu=bank&action=create&type=5', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); + + -- Project insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3600__+MAX_llx_menu__, 'project', 'projects', 7__+MAX_llx_menu__, '/projet/index.php?mainmenu=project&leftmenu=projects', 'LeadsOrProjects', 0, 'projects', '$user->rights->projet->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3601__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/card.php?mainmenu=project&leftmenu=projects&action=create', 'New', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__); @@ -366,19 +418,22 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled && !$conf->global->PROJECT_HIDE_TASKS', __HANDLER__, 'left', 3400__+MAX_llx_menu__, 'project', '', 7__+MAX_llx_menu__, '/projet/activity/perweek.php?mainmenu=project&leftmenu=projects', 'NewTimeSpent', 0, 'projects', '$user->rights->projet->lire', '', 2, 3, __ENTITY__); +-- Project - Categories +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3804__+MAX_llx_menu__, 'project', 'cat', 7__+MAX_llx_menu__, '/categories/index.php?mainmenu=project&leftmenu=cat&type=6', 'Categories', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3805__+MAX_llx_menu__, 'project', '', 3804__+MAX_llx_menu__, '/categories/card.php?mainmenu=project&action=create&type=6', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); + + -- BOM insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->bom->enabled', __HANDLER__, 'left', 5400__+MAX_llx_menu__, 'mrp', 'bom', 16__+MAX_llx_menu__, '/bom/bom_list.php?mainmenu=mrp&leftmenu=bom', 'MenuBOM', 1, 'mrp', '$user->rights->bom->read', '', 0, 20, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->bom->enabled', __HANDLER__, 'left', 5401__+MAX_llx_menu__, 'mrp', '', 5400__+MAX_llx_menu__, '/bom/bom_card.php?mainmenu=mrp&leftmenu=bom&action=create', 'NewBOM', 2, 'mrp', '$user->rights->bom->write', '', 0, 21, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->bom->enabled', __HANDLER__, 'left', 5403__+MAX_llx_menu__, 'mrp', '', 5400__+MAX_llx_menu__, '/bom/bom_list.php?mainmenu=mrp&leftmenu=bom', 'List', 2, 'mrp', '$user->rights->bom->read', '', 0, 22, __ENTITY__); --- MRP + +-- MRP/MO insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->bom->enabled', __HANDLER__, 'left', 5450__+MAX_llx_menu__, 'mrp', 'mrp', 16__+MAX_llx_menu__, '/mrp/mo_list.php?mainmenu=mrp&leftmenu=mrp', 'MenuMRP', 1, 'mrp', '$user->rights->mrp->read', '', 0, 20, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->bom->enabled', __HANDLER__, 'left', 5451__+MAX_llx_menu__, 'mrp', '', 5450__+MAX_llx_menu__, '/mrp/mo_card.php?mainmenu=mrp&leftmenu=mrp&action=create', 'NewMO', 2, 'mrp', '$user->rights->mrp->write', '', 0, 21, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->bom->enabled', __HANDLER__, 'left', 5453__+MAX_llx_menu__, 'mrp', '', 5450__+MAX_llx_menu__, '/mrp/mo_list.php?mainmenu=mrp&leftmenu=mrp', 'List', 2, 'mrp', '$user->rights->mrp->read', '', 0, 22, __ENTITY__); --- Project - Categories -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3804__+MAX_llx_menu__, 'project', 'cat', 7__+MAX_llx_menu__, '/categories/index.php?mainmenu=project&leftmenu=cat&type=6', 'Categories', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3805__+MAX_llx_menu__, 'project', '', 3804__+MAX_llx_menu__, '/categories/card.php?mainmenu=project&action=create&type=6', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); -- Tools insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', 'empty($user->socid)', __HANDLER__, 'left', 3900__+MAX_llx_menu__, 'tools', 'email_templates', 8__+MAX_llx_menu__, '/admin/mails_templates.php?mainmenu=tools&leftmenu=email_templates', 'EMailTemplates', 0, '', '', '', 0, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->mailing->enabled', __HANDLER__, 'left', 3910__+MAX_llx_menu__, 'tools', 'mailing', 8__+MAX_llx_menu__, '/comm/mailing/index.php?mainmenu=tools&leftmenu=mailing', 'EMailings', 0, 'mails', '$user->rights->mailing->lire', '', 0, 0, __ENTITY__); @@ -388,6 +443,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->export->enabled', __HANDLER__, 'left', 4101__+MAX_llx_menu__, 'tools', '', 4100__+MAX_llx_menu__, '/exports/export.php?mainmenu=tools&leftmenu=export', 'NewExport', 1, 'exports', '$user->rights->export->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->import->enabled', __HANDLER__, 'left', 4130__+MAX_llx_menu__, 'tools', 'import', 8__+MAX_llx_menu__, '/imports/index.php?mainmenu=tools&leftmenu=import', 'FormatedImport', 0, 'exports', '$user->rights->import->run', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->import->enabled', __HANDLER__, 'left', 4131__+MAX_llx_menu__, 'tools', '', 4130__+MAX_llx_menu__, '/imports/import.php?mainmenu=tools&leftmenu=import', 'NewImport', 1, 'exports', '$user->rights->import->run', '', 2, 0, __ENTITY__); + -- Members insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4200__+MAX_llx_menu__, 'members', 'members', 13__+MAX_llx_menu__, '/adherents/index.php?mainmenu=members&leftmenu=members', 'Members', 0, 'members', '$user->rights->adherent->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4201__+MAX_llx_menu__, 'members', '', 4200__+MAX_llx_menu__, '/adherents/card.php?mainmenu=members&leftmenu=members&action=create', 'NewMember', 1, 'members', '$user->rights->adherent->creer', '', 2, 0, __ENTITY__); @@ -401,6 +457,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4209__+MAX_llx_menu__, 'members', '', 4200__+MAX_llx_menu__, '/adherents/stats/geo.php?mainmenu=members&leftmenu=members&mode=memberbycountry', 'MenuMembersStats', 1, 'members', '$user->rights->adherent->lire', '', 2, 7, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '! empty($conf->global->MEMBER_LINK_TO_HTPASSWDFILE) && $conf->adherent->enabled', __HANDLER__, 'left', 4502__+MAX_llx_menu__, 'members', '', 4200__+MAX_llx_menu__, '/adherents/htpasswd.php?mainmenu=members&leftmenu=export', 'Filehtpasswd', 1, 'members', '$user->rights->adherent->export', '', 2, 9, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4503__+MAX_llx_menu__, 'members', '', 4200__+MAX_llx_menu__, '/adherents/cartes/carte.php?mainmenu=members&leftmenu=export', 'MembersCards', 1, 'members', '$user->rights->adherent->export', '', 2, 10, __ENTITY__); + -- Members - Subscriptions insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4300__+MAX_llx_menu__, 'members', '', 13__+MAX_llx_menu__, '/adherents/index.php?mainmenu=members&leftmenu=members', 'Subscriptions', 0, 'compta', '$user->rights->adherent->cotisation->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4301__+MAX_llx_menu__, 'members', '', 4300__+MAX_llx_menu__, '/adherents/list.php?mainmenu=members&statut=-1&leftmenu=accountancy', 'NewSubscription', 1, 'compta', '$user->rights->adherent->cotisation->creer', '', 2, 0, __ENTITY__); @@ -409,13 +466,17 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4700__+MAX_llx_menu__, 'members', 'setup', 13__+MAX_llx_menu__, '/adherents/type.php?mainmenu=members&leftmenu=setup', 'MembersTypes', 0, 'members', '$user->rights->adherent->configurer', '', 2, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4701__+MAX_llx_menu__, 'members', '', 4700__+MAX_llx_menu__, '/adherents/type.php?mainmenu=members&leftmenu=setup&action=create', 'New', 1, 'members', '$user->rights->adherent->configurer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled', __HANDLER__, 'left', 4702__+MAX_llx_menu__, 'members', '', 4700__+MAX_llx_menu__, '/adherents/type.php?mainmenu=members&leftmenu=setup', 'List', 1, 'members', '$user->rights->adherent->configurer', '', 2, 1, __ENTITY__); + -- Members - Category member insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled && $conf->categorie->enabled', __HANDLER__, 'left', 5200__+MAX_llx_menu__, 'members', 'cat', 13__+MAX_llx_menu__, '/categories/index.php?mainmenu=members&leftmenu=cat&type=3', 'MembersCategoriesShort', 0, 'categories', '$user->rights->categorie->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->adherent->enabled && $conf->categorie->enabled', __HANDLER__, 'left', 5201__+MAX_llx_menu__, 'members', '', 5200__+MAX_llx_menu__, '/categories/card.php?mainmenu=members&action=create&type=3', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__); + + -- HRM - Employee insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->hrm->enabled', __HANDLER__, 'left', 4600__+MAX_llx_menu__, 'hrm', 'hrm', 15__+MAX_llx_menu__, '/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee', 'Employees', 0, 'hrm', '$user->rights->user->user->lire', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->hrm->enabled', __HANDLER__, 'left', 4601__+MAX_llx_menu__, 'hrm', '', 4600__+MAX_llx_menu__, '/user/card.php?mainmenu=hrm&action=create&employee=1', 'NewEmployee', 1, 'hrm', '$user->rights->user->user->creer', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->hrm->enabled', __HANDLER__, 'left', 4602__+MAX_llx_menu__, 'hrm', '', 4600__+MAX_llx_menu__, '/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee&contextpage=employeelist', 'List', 1, 'hrm', '$user->rights->user->user->lire', '', 0, 2, __ENTITY__); + -- HRM - Holiday insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5000__+MAX_llx_menu__, 'hrm', 'hrm', 15__+MAX_llx_menu__, '/holiday/list.php?mainmenu=hrm&leftmenu=hrm', 'CPTitreMenu', 0, 'holiday', '$user->rights->holiday->read', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5001__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/card.php?mainmenu=hrm&action=create', 'MenuAddCP', 1, 'holiday', '$user->rights->holiday->write', '', 0, 1, __ENTITY__); @@ -423,11 +484,13 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5003__+MAX_llx_menu__, 'hrm', '', 5002__+MAX_llx_menu__, '/holiday/list.php?mainmenu=hrm&search_statut=2&leftmenu=hrm', 'ListToApprove', 2, 'trips', '$user->rights->holiday->read', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5004__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/define_holiday.php?mainmenu=hrm&action=request', 'MenuConfCP', 1, 'holiday', '$user->rights->holiday->define_holiday', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5005__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/view_log.php?mainmenu=hrm&action=request', 'MenuLogCP', 1, 'holiday', '$user->rights->holiday->define_holiday', '', 0, 3, __ENTITY__); + -- HRM - Trips and expenses (old module) insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->deplacement->enabled', __HANDLER__, 'left', 2100__+MAX_llx_menu__, 'accountancy', 'tripsandexpenses', 15__+MAX_llx_menu__, '/compta/deplacement/index.php?mainmenu=accountancy&leftmenu=tripsandexpenses', 'TripsAndExpenses', 0, 'trips', '$user->rights->deplacement->lire', '', 0, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->deplacement->enabled', __HANDLER__, 'left', 2101__+MAX_llx_menu__, 'accountancy', '', 2100__+MAX_llx_menu__, '/compta/deplacement/card.php?mainmenu=accountancy&action=create&leftmenu=tripsandexpenses', 'New', 1, 'trips', '$user->rights->deplacement->creer', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->deplacement->enabled', __HANDLER__, 'left', 2102__+MAX_llx_menu__, 'accountancy', '', 2100__+MAX_llx_menu__, '/compta/deplacement/list.php?mainmenu=accountancy&leftmenu=tripsandexpenses', 'List', 1, 'trips', '$user->rights->deplacement->lire', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->deplacement->enabled', __HANDLER__, 'left', 2103__+MAX_llx_menu__, 'accountancy', '', 2100__+MAX_llx_menu__, '/compta/deplacement/stats/index.php?mainmenu=accountancy&leftmenu=tripsandexpenses', 'Statistics', 1, 'trips', '$user->rights->deplacement->lire', '', 0, 2, __ENTITY__); + -- HRM - Expense reports insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expensereport->enabled', __HANDLER__, 'left', 5300__+MAX_llx_menu__, 'hrm', 'expensereport', 15__+MAX_llx_menu__, '/expensereport/index.php?mainmenu=hrm&leftmenu=expensereport', 'TripsAndExpenses', 0, 'trips', '$user->rights->expensereport->lire', '', 0, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expensereport->enabled', __HANDLER__, 'left', 5301__+MAX_llx_menu__, 'hrm', '', 5300__+MAX_llx_menu__, '/expensereport/card.php?mainmenu=hrm&action=create&leftmenu=expensereport', 'New', 1, 'trips', '$user->rights->expensereport->creer', '', 0, 1, __ENTITY__); diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 6504cfa27a6..6b415aec7a2 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -410,7 +410,7 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t // To enable when page exists if (empty($conf->global->ACCOUNTANCY_SHOW_DEVELOP_JOURNAL)) { - if ($nature == 'various' || $nature == 'hasnew' || $nature == 'inventory') { + if ($nature == 'hasnew' || $nature == 'inventory') { $nature = ''; } } diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index e69644bd123..b44f082d650 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -156,8 +156,8 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'name' => 'Products', 'link' => '/product/index.php?mainmenu=products&leftmenu=', 'title' => (!empty($conf->product->enabled) && !empty($conf->service->enabled)) - ? (array("TMenuProducts", " | ", "TMenuServices")) - : (!empty($conf->product->enabled) ? "TMenuProducts" : "TMenuServices"), + ? (array("TMenuProducts", " | ", "TMenuServices")) + : (!empty($conf->product->enabled) ? "TMenuProducts" : "TMenuServices"), 'level' => 0, 'enabled' => $showmode = isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal), 'target' => $atarget, @@ -232,7 +232,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = || !empty($conf->supplier_order->enabled) || !empty($conf->contrat->enabled) || !empty($conf->ficheinter->enabled) - ) ? 1 : 0, + ) ? 1 : 0, 'perms'=>(!empty($user->rights->propal->lire) || !empty($user->rights->commande->lire) || !empty($user->rights->supplier_proposal->lire) @@ -241,17 +241,17 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = || !empty($user->rights->supplier_order->lire) || !empty($user->rights->contrat->lire) || !empty($user->rights->ficheinter->lire) - ), + ), 'module'=>'propal|commande|supplier_proposal|supplier_order|contrat|ficheinter' ); $onlysupplierorder = !empty($user->rights->fournisseur->commande->lire) && - empty($user->rights->propal->lire) && - empty($user->rights->commande->lire) && - empty($user->rights->supplier_order->lire) && - empty($user->rights->supplier_proposal->lire) && - empty($user->rights->contrat->lire) && - empty($user->rights->ficheinter->lire); + empty($user->rights->propal->lire) && + empty($user->rights->commande->lire) && + empty($user->rights->supplier_order->lire) && + empty($user->rights->supplier_proposal->lire) && + empty($user->rights->contrat->lire) && + empty($user->rights->ficheinter->lire); $menu_arr[] = array( 'name' => 'Commercial', @@ -524,7 +524,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = $idsel, $classname, $newTabMenu[$i]['prefix'] - ); + ); } // Sort on position @@ -544,9 +544,9 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = if (!empty($mysoc->logo_squarred_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_squarred_mini)) { $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_squarred_mini); /*} elseif (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) - { - $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_mini); - }*/ + { + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_mini); + }*/ } else { $urllogo = DOL_URL_ROOT.'/theme/dolibarr_512x512_white.png'; $logoContainerAdditionalClass = ''; @@ -676,8 +676,6 @@ function print_end_menu_array() print "\n"; } - - /** * Core function to output left menu eldy * Fill &$menu (example with $forcemainmenu='home' $forceleftmenu='all', return left menu tree of Home) @@ -697,7 +695,7 @@ function print_end_menu_array() function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabMenu, &$menu, $noout = 0, $forcemainmenu = '', $forceleftmenu = '', $moredata = null, $type_user = 0) { - global $user, $conf, $langs, $dolibarr_main_db_name, $mysoc, $hookmanager; + global $user, $conf, $langs, $hookmanager; //var_dump($tabMenu); @@ -739,1223 +737,84 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM * Menu HOME */ if ($mainmenu == 'home') { - $langs->load("users"); - - // Home - dashboard - $newmenu->add("/index.php?mainmenu=home&leftmenu=home", $langs->trans("MyDashboard"), 0, 1, '', $mainmenu, 'home', 0, '', '', '', ''); - - // Setup - $newmenu->add("/admin/index.php?mainmenu=home&leftmenu=setup", $langs->trans("Setup"), 0, $user->admin, '', $mainmenu, 'setup', 0, '', '', '', ''); - - if ($usemenuhider || empty($leftmenu) || $leftmenu == "setup") { - // Load translation files required by the page - $langs->loadLangs(array("admin", "help")); - - $warnpicto = ''; - if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY)) { - $langs->load("errors"); - $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete")); - } - $newmenu->add("/admin/company.php?mainmenu=home", $langs->trans("MenuCompanySetup").$warnpicto, 1); - - $warnpicto = ''; - if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only user module enabled - $langs->load("errors"); - $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete")); - } - $newmenu->add("/admin/modules.php?mainmenu=home", $langs->trans("Modules").$warnpicto, 1); - $newmenu->add("/admin/ihm.php?mainmenu=home", $langs->trans("GUISetup"), 1); - $newmenu->add("/admin/menus.php?mainmenu=home", $langs->trans("Menus"), 1); - - $newmenu->add("/admin/translation.php?mainmenu=home", $langs->trans("Translation"), 1); - $newmenu->add("/admin/defaultvalues.php?mainmenu=home", $langs->trans("DefaultValues"), 1); - $newmenu->add("/admin/boxes.php?mainmenu=home", $langs->trans("Boxes"), 1); - $newmenu->add("/admin/delais.php?mainmenu=home", $langs->trans("MenuWarnings"), 1); - $newmenu->add("/admin/security_other.php?mainmenu=home", $langs->trans("Security"), 1); - $newmenu->add("/admin/limits.php?mainmenu=home", $langs->trans("MenuLimits"), 1); - $newmenu->add("/admin/pdf.php?mainmenu=home", $langs->trans("PDF"), 1); - - $warnpicto = ''; - if (!empty($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'mail' && empty($conf->global->MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP)) { - $langs->load("errors"); - $warnpicto = img_warning($langs->trans("WarningPHPMailD")); - } - if (!empty($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmail')) && empty($conf->global->MAIN_MAIL_SMTP_SERVER)) { - $langs->load("errors"); - $warnpicto = img_warning($langs->trans("ErrorSetupOfEmailsNotComplete")); - } - - $newmenu->add("/admin/mails.php?mainmenu=home", $langs->trans("Emails").$warnpicto, 1); - $newmenu->add("/admin/sms.php?mainmenu=home", $langs->trans("SMS"), 1); - $newmenu->add("/admin/dict.php?mainmenu=home", $langs->trans("Dictionary"), 1); - $newmenu->add("/admin/const.php?mainmenu=home", $langs->trans("OtherSetup"), 1); - } - - // System tools - $newmenu->add("/admin/tools/index.php?mainmenu=home&leftmenu=admintools", $langs->trans("AdminTools"), 0, $user->admin, '', $mainmenu, 'admintools', 0, '', '', '', ''); - if ($usemenuhider || empty($leftmenu) || preg_match('/^admintools/', $leftmenu)) { - // Load translation files required by the page - $langs->loadLangs(array('admin', 'help')); - - $newmenu->add('/admin/system/dolibarr.php?mainmenu=home&leftmenu=admintools_info', $langs->trans('InfoDolibarr'), 1); - if ($usemenuhider || empty($leftmenu) || $leftmenu == 'admintools_info') { - $newmenu->add('/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', $langs->trans('Modules'), 2); - $newmenu->add('/admin/triggers.php?mainmenu=home&leftmenu=admintools_info', $langs->trans('Triggers'), 2); - $newmenu->add('/admin/system/filecheck.php?mainmenu=home&leftmenu=admintools_info', $langs->trans('FileCheck'), 2); - } - $newmenu->add('/admin/system/browser.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoBrowser'), 1); - $newmenu->add('/admin/system/os.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoOS'), 1); - $newmenu->add('/admin/system/web.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoWebServer'), 1); - $newmenu->add('/admin/system/phpinfo.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoPHP'), 1); - $newmenu->add('/admin/system/database.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoDatabase'), 1); - $newmenu->add("/admin/system/perf.php?mainmenu=home&leftmenu=admintools", $langs->trans("InfoPerf"), 1); - $newmenu->add("/admin/system/security.php?mainmenu=home&leftmenu=admintools", $langs->trans("InfoSecurity"), 1); - $newmenu->add("/admin/tools/dolibarr_export.php?mainmenu=home&leftmenu=admintools", $langs->trans("Backup"), 1); - $newmenu->add("/admin/tools/dolibarr_import.php?mainmenu=home&leftmenu=admintools", $langs->trans("Restore"), 1); - $newmenu->add("/admin/tools/update.php?mainmenu=home&leftmenu=admintools", $langs->trans("MenuUpgrade"), 1); - $newmenu->add("/admin/tools/purge.php?mainmenu=home&leftmenu=admintools", $langs->trans("Purge"), 1); - $newmenu->add("/admin/tools/listevents.php?mainmenu=home&leftmenu=admintools", $langs->trans("Audit"), 1); - $newmenu->add("/admin/tools/listsessions.php?mainmenu=home&leftmenu=admintools", $langs->trans("Sessions"), 1); - $newmenu->add('/admin/system/about.php?mainmenu=home&leftmenu=admintools', $langs->trans('ExternalResources'), 1); - - if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { - $langs->load("products"); - $newmenu->add("/product/admin/product_tools.php?mainmenu=home&leftmenu=admintools", $langs->trans("ProductVatMassChange"), 1, $user->admin); - } - } - - $newmenu->add("/user/home.php?leftmenu=users", $langs->trans("MenuUsersAndGroups"), 0, $user->rights->user->user->lire, '', $mainmenu, 'users', 0, '', '', '', img_picto('', 'user', 'class="paddingright pictofixedwidth"')); - if ($user->rights->user->user->lire) { - if ($usemenuhider || empty($leftmenu) || $leftmenu == "users") { - $newmenu->add("", $langs->trans("Users"), 1, $user->rights->user->user->lire || $user->admin); - $newmenu->add("/user/card.php?leftmenu=users&action=create", $langs->trans("NewUser"), 2, ($user->rights->user->user->creer || $user->admin) && !(!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE), '', 'home'); - $newmenu->add("/user/list.php?leftmenu=users", $langs->trans("ListOfUsers"), 2, $user->rights->user->user->lire || $user->admin); - $newmenu->add("/user/hierarchy.php?leftmenu=users", $langs->trans("HierarchicView"), 2, $user->rights->user->user->lire || $user->admin); - if (!empty($conf->categorie->enabled)) { - $langs->load("categories"); - $newmenu->add("/categories/index.php?leftmenu=users&type=7", $langs->trans("UsersCategoriesShort"), 2, $user->rights->categorie->lire, '', $mainmenu, 'cat'); - } - $newmenu->add("", $langs->trans("Groups"), 1, ($user->rights->user->user->lire || $user->admin) && !(!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); - $newmenu->add("/user/group/card.php?leftmenu=users&action=create", $langs->trans("NewGroup"), 2, ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) ? $user->rights->user->group_advance->write : $user->rights->user->user->creer) || $user->admin) && !(!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); - $newmenu->add("/user/group/list.php?leftmenu=users", $langs->trans("ListOfGroups"), 2, ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) ? $user->rights->user->group_advance->read : $user->rights->user->user->lire) || $user->admin) && !(!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); - } - } + get_left_menu_home($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } - /* * Menu THIRDPARTIES */ if ($mainmenu == 'companies') { - // Societes - if (!empty($conf->societe->enabled)) { - $langs->load("companies"); - $newmenu->add("/societe/index.php?leftmenu=thirdparties", $langs->trans("ThirdParty"), 0, $user->rights->societe->lire, '', $mainmenu, 'thirdparties', 0, '', '', '', img_picto('', 'company', 'class="paddingright pictofixedwidth"')); - - if ($user->rights->societe->creer) { - $newmenu->add("/societe/card.php?action=create", $langs->trans("MenuNewThirdParty"), 1); - if (!$conf->use_javascript_ajax) { - $newmenu->add("/societe/card.php?action=create&private=1", $langs->trans("MenuNewPrivateIndividual"), 1); - } - } - } - - $newmenu->add("/societe/list.php?leftmenu=thirdparties", $langs->trans("List"), 1); - - // Prospects - if (!empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { - $langs->load("commercial"); - $newmenu->add("/societe/list.php?type=p&leftmenu=prospects", $langs->trans("ListProspectsShort"), 2, $user->rights->societe->lire, '', $mainmenu, 'prospects'); - /* no more required, there is a filter that can do more - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=-1", $langs->trans("LastProspectDoNotContact"), 2, $user->rights->societe->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=0", $langs->trans("LastProspectNeverContacted"), 2, $user->rights->societe->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=1", $langs->trans("LastProspectToContact"), 2, $user->rights->societe->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=2", $langs->trans("LastProspectContactInProcess"), 2, $user->rights->societe->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=3", $langs->trans("LastProspectContactDone"), 2, $user->rights->societe->lire); - */ - $newmenu->add("/societe/card.php?leftmenu=prospects&action=create&type=p", $langs->trans("MenuNewProspect"), 3, $user->rights->societe->creer); - } - - // Customers/Prospects - if (!empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { - $langs->load("commercial"); - $newmenu->add("/societe/list.php?type=c&leftmenu=customers", $langs->trans("ListCustomersShort"), 2, $user->rights->societe->lire, '', $mainmenu, 'customers'); - - $newmenu->add("/societe/card.php?leftmenu=customers&action=create&type=c", $langs->trans("MenuNewCustomer"), 3, $user->rights->societe->creer); - } - - // Suppliers - if (!empty($conf->societe->enabled) && (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) || !empty($conf->supplier_proposal->enabled))) { - $langs->load("suppliers"); - $newmenu->add("/societe/list.php?type=f&leftmenu=suppliers", $langs->trans("ListSuppliersShort"), 2, ($user->rights->fournisseur->lire || $user->rights->supplier_order->lire || $user->rights->supplier_invoice->lire || $user->rights->supplier_proposal->lire), '', $mainmenu, 'suppliers'); - $newmenu->add("/societe/card.php?leftmenu=suppliers&action=create&type=f", $langs->trans("MenuNewSupplier"), 3, $user->rights->societe->creer && ($user->rights->fournisseur->lire || $user->rights->supplier_order->lire || $user->rights->supplier_invoice->lire || $user->rights->supplier_proposal->lire)); - } - - // Categories - if (!empty($conf->categorie->enabled)) { - $langs->load("categories"); - if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { - // Categories prospects/customers - $menutoshow = $langs->trans("CustomersProspectsCategoriesShort"); - if (!empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { - $menutoshow = $langs->trans("CustomersCategoriesShort"); - } - if (!empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { - $menutoshow = $langs->trans("ProspectsCategoriesShort"); - } - $newmenu->add("/categories/index.php?leftmenu=cat&type=2", $menutoshow, 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); - } - // Categories suppliers - if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { - $newmenu->add("/categories/index.php?leftmenu=catfournish&type=1", $langs->trans("SuppliersCategoriesShort"), 1, $user->rights->categorie->lire); - } - } - - // Contacts - $newmenu->add("/societe/index.php?leftmenu=thirdparties", (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")), 0, $user->rights->societe->contact->lire, '', $mainmenu, 'contacts', 0, '', '', '', img_picto('', 'contact', 'class="paddingright pictofixedwidth"')); - - $newmenu->add("/contact/card.php?leftmenu=contacts&action=create", (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("NewContact") : $langs->trans("NewContactAddress")), 1, $user->rights->societe->contact->creer); - $newmenu->add("/contact/list.php?leftmenu=contacts", $langs->trans("List"), 1, $user->rights->societe->contact->lire); - if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { - $newmenu->add("/contact/list.php?leftmenu=contacts&type=p", $langs->trans("Prospects"), 2, $user->rights->societe->contact->lire); - } - if (empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { - $newmenu->add("/contact/list.php?leftmenu=contacts&type=c", $langs->trans("Customers"), 2, $user->rights->societe->contact->lire); - } - if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { - $newmenu->add("/contact/list.php?leftmenu=contacts&type=f", $langs->trans("Suppliers"), 2, $user->rights->societe->contact->lire); - } - $newmenu->add("/contact/list.php?leftmenu=contacts&type=o", $langs->trans("ContactOthers"), 2, $user->rights->societe->contact->lire); - //$newmenu->add("/contact/list.php?userid=$user->id", $langs->trans("MyContacts"), 1, $user->rights->societe->contact->lire); - - // Categories - if (!empty($conf->categorie->enabled)) { - $langs->load("categories"); - // Categories Contact - $newmenu->add("/categories/index.php?leftmenu=catcontact&type=4", $langs->trans("ContactCategoriesShort"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); - } + get_left_menu_thridparties($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } /* * Menu COMMERCIAL (propal, commande, supplier_proposal, supplier_order, contrat, ficheinter) */ if ($mainmenu == 'commercial') { - $langs->load("companies"); - - // Customer proposal - if (!empty($conf->propal->enabled)) { - $langs->load("propal"); - $newmenu->add("/comm/propal/index.php?leftmenu=propals", $langs->trans("Proposals"), 0, $user->rights->propale->lire, '', $mainmenu, 'propals', 100, '', '', '', img_picto('', 'propal', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/comm/propal/card.php?action=create&leftmenu=propals", $langs->trans("NewPropal"), 1, $user->rights->propale->creer); - $newmenu->add("/comm/propal/list.php?leftmenu=propals", $langs->trans("List"), 1, $user->rights->propale->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "propals") { - $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=0", $langs->trans("PropalsDraft"), 2, $user->rights->propale->lire); - $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=1", $langs->trans("PropalsOpened"), 2, $user->rights->propale->lire); - $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=2", $langs->trans("PropalStatusSigned"), 2, $user->rights->propale->lire); - $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=3", $langs->trans("PropalStatusNotSigned"), 2, $user->rights->propale->lire); - $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=4", $langs->trans("PropalStatusBilled"), 2, $user->rights->propale->lire); - //$newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=2,3,4", $langs->trans("PropalStatusClosedShort"), 2, $user->rights->propale->lire); - } - $newmenu->add("/comm/propal/stats/index.php?leftmenu=propals", $langs->trans("Statistics"), 1, $user->rights->propale->lire); - } - - // Customers orders - if (!empty($conf->commande->enabled)) { - $langs->load("orders"); - $newmenu->add("/commande/index.php?leftmenu=orders", $langs->trans("CustomersOrders"), 0, $user->rights->commande->lire, '', $mainmenu, 'orders', 200, '', '', '', img_picto('', 'order', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/commande/card.php?action=create&leftmenu=orders", $langs->trans("NewOrder"), 1, $user->rights->commande->creer); - $newmenu->add("/commande/list.php?leftmenu=orders", $langs->trans("List"), 1, $user->rights->commande->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "orders") { - $newmenu->add("/commande/list.php?leftmenu=orders&search_status=0", $langs->trans("StatusOrderDraftShort"), 2, $user->rights->commande->lire); - $newmenu->add("/commande/list.php?leftmenu=orders&search_status=1", $langs->trans("StatusOrderValidated"), 2, $user->rights->commande->lire); - if (!empty($conf->expedition->enabled)) { - $newmenu->add("/commande/list.php?leftmenu=orders&search_status=2", $langs->trans("StatusOrderSentShort"), 2, $user->rights->commande->lire); - } - $newmenu->add("/commande/list.php?leftmenu=orders&search_status=3", $langs->trans("StatusOrderDelivered"), 2, $user->rights->commande->lire); - //$newmenu->add("/commande/list.php?leftmenu=orders&search_status=4", $langs->trans("StatusOrderProcessed"), 2, $user->rights->commande->lire); - $newmenu->add("/commande/list.php?leftmenu=orders&search_status=-1", $langs->trans("StatusOrderCanceledShort"), 2, $user->rights->commande->lire); - } - $newmenu->add("/commande/stats/index.php?leftmenu=orders", $langs->trans("Statistics"), 1, $user->rights->commande->lire); - } - - // Supplier proposal - if (!empty($conf->supplier_proposal->enabled)) { - $langs->load("supplier_proposal"); - $newmenu->add("/supplier_proposal/index.php?leftmenu=propals_supplier", $langs->trans("SupplierProposalsShort"), 0, $user->rights->supplier_proposal->lire, '', $mainmenu, 'propals_supplier', 300, '', '', '', img_picto('', 'supplier_proposal', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/supplier_proposal/card.php?action=create&leftmenu=supplier_proposals", $langs->trans("SupplierProposalNew"), 1, $user->rights->supplier_proposal->creer); - $newmenu->add("/supplier_proposal/list.php?leftmenu=supplier_proposals", $langs->trans("List"), 1, $user->rights->supplier_proposal->lire); - $newmenu->add("/comm/propal/stats/index.php?leftmenu=supplier_proposals&mode=supplier", $langs->trans("Statistics"), 1, $user->rights->supplier_proposal->lire); - } - - // Suppliers orders - if (!empty($conf->supplier_order->enabled)) { - $langs->load("orders"); - $newmenu->add("/fourn/commande/index.php?leftmenu=orders_suppliers", $langs->trans("SuppliersOrders"), 0, $user->rights->fournisseur->commande->lire, '', $mainmenu, 'orders_suppliers', 400, '', '', '', img_picto('', 'supplier_order', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/fourn/commande/card.php?action=create&leftmenu=orders_suppliers", $langs->trans("NewSupplierOrderShort"), 1, $user->rights->fournisseur->commande->creer); - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers", $langs->trans("List"), 1, $user->rights->fournisseur->commande->lire); - - if ($usemenuhider || empty($leftmenu) || $leftmenu == "orders_suppliers") { - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=0", $langs->trans("StatusSupplierOrderDraftShort"), 2, $user->rights->fournisseur->commande->lire); - if (empty($conf->global->SUPPLIER_ORDER_HIDE_VALIDATED)) { - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=1", $langs->trans("StatusSupplierOrderValidated"), 2, $user->rights->fournisseur->commande->lire); - } - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=2", $langs->trans("StatusSupplierOrderApprovedShort"), 2, $user->rights->fournisseur->commande->lire); - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=3", $langs->trans("StatusSupplierOrderOnProcessShort"), 2, $user->rights->fournisseur->commande->lire); - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=4", $langs->trans("StatusSupplierOrderReceivedPartiallyShort"), 2, $user->rights->fournisseur->commande->lire); - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=5", $langs->trans("StatusSupplierOrderReceivedAll"), 2, $user->rights->fournisseur->commande->lire); - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=6,7", $langs->trans("StatusSupplierOrderCanceled"), 2, $user->rights->fournisseur->commande->lire); - $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=9", $langs->trans("StatusSupplierOrderRefused"), 2, $user->rights->fournisseur->commande->lire); - } - // Billed is another field. We should add instead a dedicated filter on list. if ($usemenuhider || empty($leftmenu) || $leftmenu=="orders_suppliers") $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&billed=1", $langs->trans("Billed"), 2, $user->rights->fournisseur->commande->lire); - - - $newmenu->add("/commande/stats/index.php?leftmenu=orders_suppliers&mode=supplier", $langs->trans("Statistics"), 1, $user->rights->fournisseur->commande->lire); - } - - // Contrat - if (!empty($conf->contrat->enabled)) { - $langs->load("contracts"); - $newmenu->add("/contrat/index.php?leftmenu=contracts", $langs->trans("ContractsSubscriptions"), 0, $user->rights->contrat->lire, '', $mainmenu, 'contracts', 2000, '', '', '', img_picto('', 'contract', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/contrat/card.php?action=create&leftmenu=contracts", $langs->trans("NewContractSubscription"), 1, $user->rights->contrat->creer); - $newmenu->add("/contrat/list.php?leftmenu=contracts", $langs->trans("List"), 1, $user->rights->contrat->lire); - $newmenu->add("/contrat/services_list.php?leftmenu=contracts", $langs->trans("MenuServices"), 1, $user->rights->contrat->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "contracts") { - $newmenu->add("/contrat/services_list.php?leftmenu=contracts&mode=0", $langs->trans("MenuInactiveServices"), 2, $user->rights->contrat->lire); - $newmenu->add("/contrat/services_list.php?leftmenu=contracts&mode=4", $langs->trans("MenuRunningServices"), 2, $user->rights->contrat->lire); - $newmenu->add("/contrat/services_list.php?leftmenu=contracts&mode=4&filter=expired", $langs->trans("MenuExpiredServices"), 2, $user->rights->contrat->lire); - $newmenu->add("/contrat/services_list.php?leftmenu=contracts&mode=5", $langs->trans("MenuClosedServices"), 2, $user->rights->contrat->lire); - } - } - - // Interventions - if (!empty($conf->ficheinter->enabled)) { - $langs->load("interventions"); - $newmenu->add("/fichinter/index.php?leftmenu=ficheinter", $langs->trans("Interventions"), 0, $user->rights->ficheinter->lire, '', $mainmenu, 'ficheinter', 2200, '', '', '', img_picto('', 'intervention', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/fichinter/card.php?action=create&leftmenu=ficheinter", $langs->trans("NewIntervention"), 1, $user->rights->ficheinter->creer, '', '', '', 201); - $newmenu->add("/fichinter/list.php?leftmenu=ficheinter", $langs->trans("List"), 1, $user->rights->ficheinter->lire, '', '', '', 202); - if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - $newmenu->add("/fichinter/card-rec.php?leftmenu=ficheinter", $langs->trans("ListOfTemplates"), 1, $user->rights->ficheinter->lire, '', '', '', 203); - } - $newmenu->add("/fichinter/stats/index.php?leftmenu=ficheinter", $langs->trans("Statistics"), 1, $user->rights->ficheinter->lire); - } + get_left_menu_commercial($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } - /* * Menu COMPTA-FINANCIAL */ if ($mainmenu == 'billing') { - $langs->load("companies"); - - // Customers invoices - if (!empty($conf->facture->enabled)) { - $langs->load("bills"); - $newmenu->add("/compta/facture/index.php?leftmenu=customers_bills", $langs->trans("BillsCustomers"), 0, $user->rights->facture->lire, '', $mainmenu, 'customers_bills', 0, '', '', '', img_picto('', 'bill', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/compta/facture/card.php?action=create", $langs->trans("NewBill"), 1, $user->rights->facture->creer); - $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills", $langs->trans("List"), 1, $user->rights->facture->lire, '', $mainmenu, 'customers_bills_list'); - - if ($usemenuhider || empty($leftmenu) || preg_match('/customers_bills(|_draft|_notpaid|_paid|_canceled)$/', $leftmenu)) { - $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_draft&search_status=0", $langs->trans("BillShortStatusDraft"), 2, $user->rights->facture->lire); - $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_notpaid&search_status=1", $langs->trans("BillShortStatusNotPaid"), 2, $user->rights->facture->lire); - $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_paid&search_status=2", $langs->trans("BillShortStatusPaid"), 2, $user->rights->facture->lire); - $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_canceled&search_status=3", $langs->trans("BillShortStatusCanceled"), 2, $user->rights->facture->lire); - } - $newmenu->add("/compta/facture/invoicetemplate_list.php?leftmenu=customers_bills_templates", $langs->trans("ListOfTemplates"), 1, $user->rights->facture->creer, '', $mainmenu, 'customers_bills_templates'); // No need to see recurring invoices, if user has no permission to create invoice. - - $newmenu->add("/compta/paiement/list.php?leftmenu=customers_bills_payment", $langs->trans("Payments"), 1, $user->rights->facture->lire, '', $mainmenu, 'customers_bills_payment'); - - if (!empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) { - $newmenu->add("/compta/paiement/tovalidate.php?leftmenu=customers_bills_tovalid", $langs->trans("MenuToValid"), 2, $user->rights->facture->lire, '', $mainmenu, 'customer_bills_tovalid'); - } - if ($usemenuhider || empty($leftmenu) || preg_match('/customers_bills/', $leftmenu)) { - $newmenu->add("/compta/paiement/rapport.php?leftmenu=customers_bills_payment_report", $langs->trans("Reportings"), 2, $user->rights->facture->lire, '', $mainmenu, 'customers_bills_payment_report'); - } - - $newmenu->add("/compta/facture/stats/index.php?leftmenu=customers_bills_stats", $langs->trans("Statistics"), 1, $user->rights->facture->lire, '', $mainmenu, 'customers_bills_stats'); - } - - // Suppliers invoices - if (!empty($conf->societe->enabled) && !empty($conf->supplier_invoice->enabled)) { - $langs->load("bills"); - $newmenu->add("/fourn/facture/index.php?leftmenu=suppliers_bills", $langs->trans("BillsSuppliers"), 0, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills', 0, '', '', '', img_picto('', 'supplier_invoice', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/fourn/facture/card.php?leftmenu=suppliers_bills&action=create", $langs->trans("NewBill"), 1, ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer), '', $mainmenu, 'suppliers_bills_create'); - $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills", $langs->trans("List"), 1, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_list'); - - if ($usemenuhider || empty($leftmenu) || preg_match('/suppliers_bills/', $leftmenu)) { - $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_draft&search_status=0", $langs->trans("BillShortStatusDraft"), 2, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_draft'); - $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_notpaid&search_status=1", $langs->trans("BillShortStatusNotPaid"), 2, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_notpaid'); - $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_paid&search_status=2", $langs->trans("BillShortStatusPaid"), 2, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_paid'); - } - - $newmenu->add("/fourn/facture/list-rec.php?leftmenu=supplierinvoicestemplate_list", $langs->trans("ListOfTemplates"), 1, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'supplierinvoicestemplate_list'); - - $newmenu->add("/fourn/paiement/list.php?leftmenu=suppliers_bills_payment", $langs->trans("Payments"), 1, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_payment'); - - if ($usemenuhider || empty($leftmenu) || preg_match('/suppliers_bills/', $leftmenu)) { - $newmenu->add("/fourn/facture/rapport.php?leftmenu=suppliers_bills_payment_report", $langs->trans("Reportings"), 2, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_payment_report'); - } - - $newmenu->add("/compta/facture/stats/index.php?mode=supplier&leftmenu=suppliers_bills_stats", $langs->trans("Statistics"), 1, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_stats'); - } - - // Orders - if (!empty($conf->commande->enabled)) { - $langs->load("orders"); - if (!empty($conf->facture->enabled)) { - $newmenu->add("/commande/list.php?leftmenu=orders&search_status=-3&billed=0&contextpage=billableorders", $langs->trans("MenuOrdersToBill2"), 0, $user->rights->commande->lire, '', $mainmenu, 'orders', 0, '', '', '', img_picto('', 'order', 'class="paddingright pictofixedwidth"')); - } - //if ($usemenuhider || empty($leftmenu) || $leftmenu=="orders") $newmenu->add("/commande/", $langs->trans("StatusOrderToBill"), 1, $user->rights->commande->lire); - } - - // Supplier Orders to bill - if (!empty($conf->supplier_invoice->enabled)) { - if (!empty($conf->global->SUPPLIER_MENU_ORDER_RECEIVED_INTO_INVOICE)) { - $langs->load("supplier"); - $newmenu->add("/fourn/commande/list.php?leftmenu=orders&search_status=5&billed=0", $langs->trans("MenuOrdersSupplierToBill"), 0, $user->rights->commande->lire, '', $mainmenu, 'orders', 0, '', '', '', img_picto('', 'supplier_order', 'class="paddingright pictofixedwidth"')); - //if ($usemenuhider || empty($leftmenu) || $leftmenu=="orders") $newmenu->add("/commande/", $langs->trans("StatusOrderToBill"), 1, $user->rights->commande->lire); - } - } - - - // Donations - if (!empty($conf->don->enabled)) { - $langs->load("donations"); - $newmenu->add("/don/index.php?leftmenu=donations&mainmenu=billing", $langs->trans("Donations"), 0, $user->rights->don->lire, '', $mainmenu, 'donations', 0, '', '', '', img_picto('', 'donation', 'class="paddingright pictofixedwidth"')); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "donations") { - $newmenu->add("/don/card.php?leftmenu=donations&action=create", $langs->trans("NewDonation"), 1, $user->rights->don->creer); - $newmenu->add("/don/list.php?leftmenu=donations", $langs->trans("List"), 1, $user->rights->don->lire); - } - // if ($leftmenu=="donations") $newmenu->add("/don/stats/index.php",$langs->trans("Statistics"), 1, $user->rights->don->lire); - } - - // Taxes and social contributions - if (!empty($conf->tax->enabled)) { - $newmenu->add("/compta/charges/index.php?leftmenu=tax&mainmenu=billing", $langs->trans("MenuTaxesAndSpecialExpenses"), 0, $user->rights->tax->charges->lire, '', $mainmenu, 'tax', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); - - $newmenu->add("/compta/sociales/list.php?leftmenu=tax_social", $langs->trans("MenuSocialContributions"), 1, $user->rights->tax->charges->lire); - if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_social/i', $leftmenu)) { - $newmenu->add("/compta/sociales/card.php?leftmenu=tax_social&action=create", $langs->trans("MenuNewSocialContribution"), 2, $user->rights->tax->charges->creer); - $newmenu->add("/compta/sociales/list.php?leftmenu=tax_social", $langs->trans("List"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/sociales/payments.php?leftmenu=tax_social&mainmenu=billing", $langs->trans("Payments"), 2, $user->rights->tax->charges->lire); - } - // VAT - if (empty($conf->global->TAX_DISABLE_VAT_MENUS)) { - global $mysoc; - - $newmenu->add("/compta/tva/list.php?leftmenu=tax_vat&mainmenu=billing", $langs->transcountry("VAT", $mysoc->country_code), 1, $user->rights->tax->charges->lire, '', $mainmenu, 'tax_vat'); - if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_vat/i', $leftmenu)) { - $newmenu->add("/compta/tva/card.php?leftmenu=tax_vat&action=create", $langs->trans("New"), 2, $user->rights->tax->charges->creer); - $newmenu->add("/compta/tva/list.php?leftmenu=tax_vat", $langs->trans("List"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/tva/payments.php?mode=tvaonly&leftmenu=tax_vat", $langs->trans("Payments"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/tva/index.php?leftmenu=tax_vat", $langs->trans("ReportByMonth"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/tva/clients.php?leftmenu=tax_vat", $langs->trans("ReportByThirdparties"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/tva/quadri_detail.php?leftmenu=tax_vat", $langs->trans("ReportByQuarter"), 2, $user->rights->tax->charges->lire); - } - - //Local Taxes 1 - if ($mysoc->useLocalTax(1) && (isset($mysoc->localtax1_assuj) && $mysoc->localtax1_assuj == "1")) { - $newmenu->add("/compta/localtax/list.php?leftmenu=tax_1_vat&mainmenu=billing&localTaxType=1", $langs->transcountry("LT1", $mysoc->country_code), 1, $user->rights->tax->charges->lire); - if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_1_vat/i', $leftmenu)) { - $newmenu->add("/compta/localtax/card.php?leftmenu=tax_1_vat&action=create&localTaxType=1", $langs->trans("New"), 2, $user->rights->tax->charges->creer); - $newmenu->add("/compta/localtax/list.php?leftmenu=tax_1_vat&localTaxType=1", $langs->trans("List"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/localtax/index.php?leftmenu=tax_1_vat&localTaxType=1", $langs->trans("ReportByMonth"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/localtax/clients.php?leftmenu=tax_1_vat&localTaxType=1", $langs->trans("ReportByThirdparties"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/localtax/quadri_detail.php?leftmenu=tax_1_vat&localTaxType=1", $langs->trans("ReportByQuarter"), 2, $user->rights->tax->charges->lire); - } - } - //Local Taxes 2 - if ($mysoc->useLocalTax(2) && (isset($mysoc->localtax2_assuj) && $mysoc->localtax2_assuj == "1")) { - $newmenu->add("/compta/localtax/list.php?leftmenu=tax_2_vat&mainmenu=billing&localTaxType=2", $langs->transcountry("LT2", $mysoc->country_code), 1, $user->rights->tax->charges->lire); - if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_2_vat/i', $leftmenu)) { - $newmenu->add("/compta/localtax/card.php?leftmenu=tax_2_vat&action=create&localTaxType=2", $langs->trans("New"), 2, $user->rights->tax->charges->creer); - $newmenu->add("/compta/localtax/list.php?leftmenu=tax_2_vat&localTaxType=2", $langs->trans("List"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/localtax/index.php?leftmenu=tax_2_vat&localTaxType=2", $langs->trans("ReportByMonth"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/localtax/clients.php?leftmenu=tax_2_vat&localTaxType=2", $langs->trans("ReportByThirdparties"), 2, $user->rights->tax->charges->lire); - $newmenu->add("/compta/localtax/quadri_detail.php?leftmenu=tax_2_vat&localTaxType=2", $langs->trans("ReportByQuarter"), 2, $user->rights->tax->charges->lire); - } - } - } - } - - // Salaries - if (!empty($conf->salaries->enabled)) { - $langs->load("salaries"); - $newmenu->add("/salaries/list.php?leftmenu=tax_salary&mainmenu=billing", $langs->trans("Salaries"), 0, $user->rights->salaries->read, '', $mainmenu, 'tax_salary', 0, '', '', '', img_picto('', 'salary', 'class="paddingright pictofixedwidth"')); - if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_salary/i', $leftmenu)) { - $newmenu->add("/salaries/card.php?leftmenu=tax_salary&action=create", $langs->trans("New"), 1, $user->rights->salaries->write); - $newmenu->add("/salaries/list.php?leftmenu=tax_salary", $langs->trans("List"), 1, $user->rights->salaries->read); - $newmenu->add("/salaries/payments.php?leftmenu=tax_salary", $langs->trans("Payments"), 1, $user->rights->salaries->read); - $newmenu->add("/salaries/stats/index.php?leftmenu=tax_salary", $langs->trans("Statistics"), 1, $user->rights->salaries->read); - } - } - - // Loan - if (!empty($conf->loan->enabled)) { - $langs->load("loan"); - $newmenu->add("/loan/list.php?leftmenu=tax_loan&mainmenu=billing", $langs->trans("Loans"), 0, $user->rights->loan->read, '', $mainmenu, 'tax_loan', 0, '', '', '', img_picto('', 'loan', 'class="paddingright pictofixedwidth"')); - if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_loan/i', $leftmenu)) { - $newmenu->add("/loan/card.php?leftmenu=tax_loan&action=create", $langs->trans("NewLoan"), 1, $user->rights->loan->write); - //$newmenu->add("/loan/payment/list.php?leftmenu=tax_loan",$langs->trans("Payments"),2,$user->rights->loan->read); - } - } - - // Various payment - if (!empty($conf->banque->enabled) && empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)) { - $langs->load("banks"); - $newmenu->add("/compta/bank/various_payment/list.php?leftmenu=tax_various&mainmenu=billing", $langs->trans("MenuVariousPayment"), 0, $user->rights->banque->lire, '', $mainmenu, 'tax_various', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); - if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_various/i', $leftmenu)) { - $newmenu->add("/compta/bank/various_payment/card.php?leftmenu=tax_various&action=create", $langs->trans("New"), 1, $user->rights->banque->modifier); - $newmenu->add("/compta/bank/various_payment/list.php?leftmenu=tax_various", $langs->trans("List"), 1, $user->rights->banque->lire); - } - } + get_left_menu_billing($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } /* * Menu COMPTA-FINANCIAL */ if ($mainmenu == 'accountancy') { - $langs->load("companies"); - - // Accounting (Double entries) - if (!empty($conf->accounting->enabled)) { - //$permtoshowmenu = (!empty($conf->accounting->enabled) || $user->rights->accounting->bind->write || $user->rights->compta->resultat->lire); - //$newmenu->add("/accountancy/index.php?leftmenu=accountancy", $langs->trans("MenuAccountancy"), 0, $permtoshowmenu, '', $mainmenu, 'accountancy'); - - // Configuration - $newmenu->add("/accountancy/index.php?leftmenu=accountancy_admin", $langs->trans("Setup"), 0, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin', 1, '', '', '', img_picto('', 'technic', 'class="paddingright pictofixedwidth"')); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/', $leftmenu)) { - $newmenu->add("/accountancy/admin/index.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("General"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_general', 10); - - // Fiscal year - Not really yet used. In a future will lock some periods. - if ($conf->global->MAIN_FEATURES_LEVEL > 1) { - $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("FiscalPeriod"), 1, $user->rights->accounting->fiscalyear->write, '', $mainmenu, 'fiscalyear', 20); - } - - $newmenu->add("/accountancy/admin/journals_list.php?id=35&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingJournals"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_journal', 30); - $newmenu->add("/accountancy/admin/accountmodel.php?id=31&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Pcg_version"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chartmodel', 40); - $newmenu->add("/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Chartofaccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 41); - $newmenu->add("/accountancy/admin/subaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("ChartOfSubaccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 41); - $newmenu->add("/accountancy/admin/categories_list.php?id=32&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingCategory"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 50); - $newmenu->add("/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDefaultAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 60); - if (!empty($conf->banque->enabled)) { - $newmenu->add("/compta/bank/list.php?mainmenu=accountancy&leftmenu=accountancy_admin&search_status=-1", $langs->trans("MenuBankAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_bank', 70); - } - if (!empty($conf->facture->enabled) || ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled))) { - $newmenu->add("/admin/dict.php?id=10&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuVatAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 80); - } - if (!empty($conf->tax->enabled)) { - $newmenu->add("/admin/dict.php?id=7&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuTaxAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 90); - } - if (!empty($conf->expensereport->enabled)) { - $newmenu->add("/admin/dict.php?id=17&from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuExpenseReportAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 100); - } - $newmenu->add("/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuProductsAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_product', 110); - if ($conf->global->MAIN_FEATURES_LEVEL > 1) { - $newmenu->add("/accountancy/admin/closure.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuClosureAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_closure', 120); - } - $newmenu->add("/accountancy/admin/export.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("ExportOptions"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_export', 130); - } - - // Transfer in accounting - $newmenu->add("/accountancy/index.php?leftmenu=accountancy_transfer", $langs->trans("TransferInAccounting"), 0, $user->rights->accounting->bind->write, '', $mainmenu, 'transfer', 1, '', '', '', img_picto('', 'long-arrow-alt-right', 'class="paddingright pictofixedwidth"')); - - // Binding - // $newmenu->add("", $langs->trans("Binding"), 0, $user->rights->accounting->bind->write, '', $mainmenu, 'dispatch'); - if (!empty($conf->facture->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_SALES)) { - $newmenu->add("/accountancy/customer/index.php?leftmenu=accountancy_dispatch_customer&mainmenu=accountancy", $langs->trans("CustomersVentilation"), 1, $user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_customer'); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_dispatch_customer/', $leftmenu)) { - $newmenu->add("/accountancy/customer/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer", $langs->trans("ToBind"), 2, $user->rights->accounting->bind->write); - $newmenu->add("/accountancy/customer/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer", $langs->trans("Binded"), 2, $user->rights->accounting->bind->write); - } - } - if (!empty($conf->supplier_invoice->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_PURCHASES)) { - $newmenu->add("/accountancy/supplier/index.php?leftmenu=accountancy_dispatch_supplier&mainmenu=accountancy", $langs->trans("SuppliersVentilation"), 1, $user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_supplier'); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_dispatch_supplier/', $leftmenu)) { - $newmenu->add("/accountancy/supplier/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_supplier", $langs->trans("ToBind"), 2, $user->rights->accounting->bind->write); - $newmenu->add("/accountancy/supplier/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_supplier", $langs->trans("Binded"), 2, $user->rights->accounting->bind->write); - } - } - if (!empty($conf->expensereport->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS)) { - $newmenu->add("/accountancy/expensereport/index.php?leftmenu=accountancy_dispatch_expensereport&mainmenu=accountancy", $langs->trans("ExpenseReportsVentilation"), 1, $user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_expensereport'); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_dispatch_expensereport/', $leftmenu)) { - $newmenu->add("/accountancy/expensereport/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_expensereport", $langs->trans("ToBind"), 2, $user->rights->accounting->bind->write); - $newmenu->add("/accountancy/expensereport/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_expensereport", $langs->trans("Binded"), 2, $user->rights->accounting->bind->write); - } - } - - // Journals - if (!empty($conf->accounting->enabled) && !empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { - $newmenu->add('', $langs->trans("RegistrationInAccounting"), 1, $user->rights->accounting->comptarapport->lire, '', '', ''); - - // Multi journal - $sql = "SELECT rowid, code, label, nature"; - $sql .= " FROM ".MAIN_DB_PREFIX."accounting_journal"; - $sql .= " WHERE entity = ".$conf->entity; - $sql .= " AND active = 1"; - $sql .= " ORDER BY nature ASC, label DESC"; - - $resql = $db->query($sql); - if ($resql) { - $numr = $db->num_rows($resql); - $i = 0; - - if ($numr > 0) { - while ($i < $numr) { - $objp = $db->fetch_object($resql); - - $nature = ''; - - // Must match array $sourceList defined into journals_list.php - if ($objp->nature == 2 && !empty($conf->facture->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_SALES)) { - $nature = "sells"; - } - if ($objp->nature == 3 - && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled)) - && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_PURCHASES)) { - $nature = "purchases"; - } - if ($objp->nature == 4 && !empty($conf->banque->enabled)) { - $nature = "bank"; - } - if ($objp->nature == 5 && !empty($conf->expensereport->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS)) { - $nature = "expensereports"; - } - if ($objp->nature == 1) { - $nature = "various"; - } - if ($objp->nature == 8) { - $nature = "inventory"; - } - if ($objp->nature == 9) { - $nature = "hasnew"; - } - - // To enable when page exists - if (empty($conf->global->ACCOUNTANCY_SHOW_DEVELOP_JOURNAL)) { - if ($nature == 'various' || $nature == 'hasnew' || $nature == 'inventory') { - $nature = ''; - } - } - - if ($nature) { - $langs->load('accountancy'); - $journallabel = $langs->transnoentities($objp->label); // Labels in this table are set by loading llx_accounting_abc.sql. Label can be 'ACCOUNTING_SELL_JOURNAL', 'InventoryJournal', ... - $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal='.$objp->rowid, $journallabel, 2, $user->rights->accounting->comptarapport->lire); - } - $i++; - } - } else { - // Should not happend. Entries are added - $newmenu->add('', $langs->trans("NoJournalDefined"), 2, $user->rights->accounting->comptarapport->lire); - } - } else { - dol_print_error($db); - } - $db->free($resql); - } - - // Files - if (empty($conf->global->ACCOUNTANCY_HIDE_EXPORT_FILES_MENU)) { - $newmenu->add("/compta/accounting-files.php?mainmenu=accountancy&leftmenu=accountancy_files", $langs->trans("AccountantFiles"), 1, $user->rights->accounting->mouvements->lire); - } - - - // Accounting - $newmenu->add("/accountancy/index.php?leftmenu=accountancy_accountancy", $langs->trans("MenuAccountancy"), 0, $user->rights->accounting->mouvements->lire || $user->rights->accounting->comptarapport->lire, '', $mainmenu, 'accountancy', 1, '', '', '', img_picto('', 'accountancy', 'class="paddingright pictofixedwidth"')); - - // General Ledger - $newmenu->add("/accountancy/bookkeeping/listbyaccount.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("Bookkeeping"), 1, $user->rights->accounting->mouvements->lire); - - // Journals - $newmenu->add("/accountancy/bookkeeping/list.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("Journals"), 1, $user->rights->accounting->mouvements->lire); - - // Account Balance - $newmenu->add("/accountancy/bookkeeping/balance.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("AccountBalance"), 1, $user->rights->accounting->mouvements->lire); - - // Closure - $newmenu->add("/accountancy/closure/index.php?mainmenu=accountancy&leftmenu=accountancy_closure", $langs->trans("MenuAccountancyClosure"), 1, $user->rights->accounting->fiscalyear->write, '', $mainmenu, 'closure'); - - // Reports - $newmenu->add("/accountancy/index.php?leftmenu=accountancy_report", $langs->trans("Reportings"), 1, $user->rights->accounting->comptarapport->lire, '', $mainmenu, 'ca'); - - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { - $newmenu->add("/compta/resultat/index.php?leftmenu=accountancy_report", $langs->trans("MenuReportInOut"), 2, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=accountancy_report", $langs->trans("ByPredefinedAccountGroups"), 3, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/resultat/result.php?leftmenu=accountancy_report", $langs->trans("ByPersonalizedAccountGroups"), 3, $user->rights->accounting->comptarapport->lire); - } - - $modecompta = 'CREANCES-DETTES'; - if (!empty($conf->accounting->enabled) && !empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { - $modecompta = 'BOOKKEEPING'; // Not yet implemented. Should be BOOKKEEPINGCOLLECTED - } - if ($modecompta) { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { - $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportTurnover"), 2, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 3, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 3, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 3, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/byratecountry.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByVatRate"), 3, $user->rights->accounting->comptarapport->lire); - } - } - - $modecompta = 'RECETTES-DEPENSES'; - //if (! empty($conf->accounting->enabled) && ! empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') $modecompta=''; // Not yet implemented. Should be BOOKKEEPINGCOLLECTED - if ($modecompta) { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { - $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportTurnoverCollected"), 2, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 3, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 3, $user->rights->accounting->comptarapport->lire); - //$newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"),3,$user->rights->accounting->comptarapport->lire); - //$newmenu->add("/compta/stats/byratecountry.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByVatRate"),3,$user->rights->accounting->comptarapport->lire); - } - } - - $modecompta = 'CREANCES-DETTES'; - if (!empty($conf->accounting->enabled) && !empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { - $modecompta = 'BOOKKEEPING'; // Not yet implemented. - } - if ($modecompta && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled))) { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { - $newmenu->add("/compta/stats/supplier_turnover.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnover"), 2, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/supplier_turnover_by_thirdparty.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 3, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/supplier_turnover_by_prodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 3, $user->rights->accounting->comptarapport->lire); - } - } - - $modecompta = 'RECETTES-DEPENSES'; - if (!empty($conf->accounting->enabled) && !empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { - $modecompta = 'BOOKKEEPINGCOLLECTED'; // Not yet implemented. - } - if ($modecompta && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled))) { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { - $newmenu->add("/compta/stats/supplier_turnover.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnoverCollected"), 2, $user->rights->accounting->comptarapport->lire); - $newmenu->add("/compta/stats/supplier_turnover_by_thirdparty.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 3, $user->rights->accounting->comptarapport->lire); - } - } - } - - // Accountancy (simple) - if (!empty($conf->comptabilite->enabled)) { - // Files - if (empty($conf->global->ACCOUNTANCY_HIDE_EXPORT_FILES_MENU)) { - $newmenu->add("/compta/accounting-files.php?mainmenu=accountancy&leftmenu=accountancy_files", $langs->trans("AccountantFiles"), 0, $user->rights->compta->resultat->lire, '', $mainmenu, 'files'); - } - - // Bilan, resultats - $newmenu->add("/compta/resultat/index.php?leftmenu=report&mainmenu=accountancy", $langs->trans("Reportings"), 0, $user->rights->compta->resultat->lire, '', $mainmenu, 'ca'); - - if ($usemenuhider || empty($leftmenu) || preg_match('/report/', $leftmenu)) { - $newmenu->add("/compta/resultat/index.php?leftmenu=report", $langs->trans("MenuReportInOut"), 1, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=report", $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); - /* On verra ca avec module compabilite expert - $newmenu->add("/compta/resultat/compteres.php?leftmenu=report","Compte de resultat",2,$user->rights->compta->resultat->lire); - $newmenu->add("/compta/resultat/bilan.php?leftmenu=report","Bilan",2,$user->rights->compta->resultat->lire); - */ - - /* - $newmenu->add("/compta/stats/cumul.php?leftmenu=report","Cumule",2,$user->rights->compta->resultat->lire); - if (! empty($conf->propal->enabled)) { - $newmenu->add("/compta/stats/prev.php?leftmenu=report","Previsionnel",2,$user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/comp.php?leftmenu=report","Transforme",2,$user->rights->compta->resultat->lire); - } - */ - - $modecompta = 'CREANCES-DETTES'; - $newmenu->add("/compta/stats/index.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ReportTurnover"), 1, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/casoc.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/cabyuser.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 2, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/byratecountry.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ByVatRate"), 2, $user->rights->compta->resultat->lire); - - $modecompta = 'RECETTES-DEPENSES'; - $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportTurnoverCollected"), 1, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire); - - //Achats - $modecompta = 'CREANCES-DETTES'; - $newmenu->add("/compta/stats/supplier_turnover.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnover"), 1, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/supplier_turnover_by_thirdparty.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/supplier_turnover_by_prodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 2, $user->rights->compta->resultat->lire); - - /* - $modecompta = 'RECETTES-DEPENSES'; - $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnoverCollected"), 1, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); - $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire); - */ - - // Journals - $newmenu->add("/compta/journal/sellsjournal.php?leftmenu=report", $langs->trans("SellsJournal"), 1, $user->rights->compta->resultat->lire, '', '', '', 50); - $newmenu->add("/compta/journal/purchasesjournal.php?leftmenu=report", $langs->trans("PurchasesJournal"), 1, $user->rights->compta->resultat->lire, '', '', '', 51); - } - //if ($leftmenu=="ca") $newmenu->add("/compta/journaux/index.php?leftmenu=ca",$langs->trans("Journals"),1,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); - } - - // Intracomm report - if (!empty($conf->intracommreport->enabled)) { - $newmenu->add("/intracommreport/list.php?leftmenu=intracommreport", $langs->trans("MenuIntracommReport"), 0, $user->rights->intracommreport->read, '', $mainmenu, 'intracommreport', 60, '', '', '', img_picto('', 'intracommreport', 'class="paddingright pictofixedwidth"')); - if ($usemenuhider || empty($leftmenu) || preg_match('/intracommreport/', $leftmenu)) { - // DEB / DES - $newmenu->add("/intracommreport/card.php?action=create&leftmenu=intracommreport", $langs->trans("MenuIntracommReportNew"), 1, $user->rights->intracommreport->write, '', $mainmenu, 'intracommreport', 1); - $newmenu->add("/intracommreport/list.php?leftmenu=intracommreport", $langs->trans("MenuIntracommReportList"), 1, $user->rights->intracommreport->read, '', $mainmenu, 'intracommreport', 1); - } - } - - // Assets - if (!empty($conf->asset->enabled)) { - $newmenu->add("/asset/list.php?leftmenu=asset&mainmenu=accountancy", $langs->trans("MenuAssets"), 0, $user->rights->asset->read, '', $mainmenu, 'asset', 100, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/asset/card.php?leftmenu=asset&action=create", $langs->trans("MenuNewAsset"), 1, $user->rights->asset->write); - $newmenu->add("/asset/list.php?leftmenu=asset&mainmenu=accountancy", $langs->trans("MenuListAssets"), 1, $user->rights->asset->read); - $newmenu->add("/asset/type.php?leftmenu=asset_type", $langs->trans("MenuTypeAssets"), 1, $user->rights->asset->read, '', $mainmenu, 'asset_type'); - if ($usemenuhider || empty($leftmenu) || preg_match('/asset_type/', $leftmenu)) { - $newmenu->add("/asset/type.php?leftmenu=asset_type&action=create", $langs->trans("MenuNewTypeAssets"), 2, $user->rights->asset->setup_advance); - $newmenu->add("/asset/type.php?leftmenu=asset_type", $langs->trans("MenuListTypeAssets"), 2, $user->rights->asset->read); - } - } + get_left_menu_accountancy($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user, $db); } - /* * Menu BANK */ if ($mainmenu == 'bank') { - // Load translation files required by the page - $langs->loadLangs(array("withdrawals", "banks", "bills", "categories")); - - // Bank-Cash account - if (!empty($conf->banque->enabled)) { - $newmenu->add("/compta/bank/list.php?leftmenu=bank&mainmenu=bank", $langs->trans("MenuBankCash"), 0, $user->rights->banque->lire, '', $mainmenu, 'bank', 0, '', '', '', img_picto('', 'bank_account', 'class="paddingright pictofixedwidth"')); - - $newmenu->add("/compta/bank/card.php?action=create", $langs->trans("MenuNewFinancialAccount"), 1, $user->rights->banque->configurer); - $newmenu->add("/compta/bank/list.php?leftmenu=bank&mainmenu=bank", $langs->trans("List"), 1, $user->rights->banque->lire, '', $mainmenu, 'bank'); - $newmenu->add("/compta/bank/bankentries_list.php", $langs->trans("ListTransactions"), 1, $user->rights->banque->lire); - $newmenu->add("/compta/bank/budget.php", $langs->trans("ListTransactionsByCategory"), 1, $user->rights->banque->lire); - - $newmenu->add("/compta/bank/transfer.php", $langs->trans("MenuBankInternalTransfer"), 1, $user->rights->banque->transfer); - } - - if (!empty($conf->categorie->enabled)) { - $langs->load("categories"); - $newmenu->add("/categories/index.php?type=5", $langs->trans("Rubriques"), 1, $user->rights->categorie->creer, '', $mainmenu, 'tags'); - $newmenu->add("/compta/bank/categ.php", $langs->trans("RubriquesTransactions"), 1, $user->rights->banque->configurer, '', $mainmenu, 'tags'); - } - - // Direct debit order - if (!empty($conf->prelevement->enabled)) { - $newmenu->add("/compta/prelevement/index.php?leftmenu=withdraw&mainmenu=bank", $langs->trans("PaymentByDirectDebit"), 0, $user->rights->prelevement->bons->lire, '', $mainmenu, 'withdraw', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); - - if ($usemenuhider || empty($leftmenu) || $leftmenu == "withdraw") { - $newmenu->add("/compta/prelevement/create.php?mainmenu=bank", $langs->trans("NewStandingOrder"), 1, $user->rights->prelevement->bons->creer); - - $newmenu->add("/compta/prelevement/orders_list.php?mainmenu=bank", $langs->trans("WithdrawalsReceipts"), 1, $user->rights->prelevement->bons->lire); - $newmenu->add("/compta/prelevement/list.php?mainmenu=bank", $langs->trans("WithdrawalsLines"), 1, $user->rights->prelevement->bons->lire); - $newmenu->add("/compta/prelevement/rejets.php?mainmenu=bank", $langs->trans("Rejects"), 1, $user->rights->prelevement->bons->lire); - $newmenu->add("/compta/prelevement/stats.php?mainmenu=bank", $langs->trans("Statistics"), 1, $user->rights->prelevement->bons->lire); - } - } - - // Bank transfer order - if (!empty($conf->paymentbybanktransfer->enabled)) { - $newmenu->add("/compta/paymentbybanktransfer/index.php?leftmenu=banktransfer&mainmenu=bank", $langs->trans("PaymentByBankTransfer"), 0, $user->rights->paymentbybanktransfer->read, '', $mainmenu, 'banktransfer', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); - - if ($usemenuhider || empty($leftmenu) || $leftmenu == "banktransfer") { - $newmenu->add("/compta/prelevement/create.php?type=bank-transfer&mainmenu=bank", $langs->trans("NewPaymentByBankTransfer"), 1, $user->rights->paymentbybanktransfer->create); - - $newmenu->add("/compta/prelevement/orders_list.php?type=bank-transfer&mainmenu=bank", $langs->trans("PaymentByBankTransferReceipts"), 1, $user->rights->paymentbybanktransfer->read); - $newmenu->add("/compta/prelevement/list.php?type=bank-transfer&mainmenu=bank", $langs->trans("PaymentByBankTransferLines"), 1, $user->rights->paymentbybanktransfer->read); - $newmenu->add("/compta/prelevement/rejets.php?type=bank-transfer&mainmenu=bank", $langs->trans("Rejects"), 1, $user->rights->paymentbybanktransfer->read); - $newmenu->add("/compta/prelevement/stats.php?type=bank-transfer&mainmenu=bank", $langs->trans("Statistics"), 1, $user->rights->paymentbybanktransfer->read); - } - } - - // Management of checks - if (empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT) && !empty($conf->banque->enabled) && (!empty($conf->facture->enabled) || !empty($conf->global->MAIN_MENU_CHEQUE_DEPOSIT_ON))) { - $newmenu->add("/compta/paiement/cheque/index.php?leftmenu=checks&mainmenu=bank", $langs->trans("MenuChequeDeposits"), 0, $user->rights->banque->cheque, '', $mainmenu, 'checks', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); - if (preg_match('/checks/', $leftmenu)) { - $newmenu->add("/compta/paiement/cheque/card.php?leftmenu=checks_bis&action=new&mainmenu=bank", $langs->trans("NewChequeDeposit"), 1, $user->rights->banque->cheque); - $newmenu->add("/compta/paiement/cheque/list.php?leftmenu=checks_bis&mainmenu=bank", $langs->trans("List"), 1, $user->rights->banque->cheque); - } - } - - // Cash Control - if (!empty($conf->takepos->enabled) || !empty($conf->cashdesk->enabled)) { - $permtomakecashfence = ($user->hasRight('cashdesk', 'run')|| $user->hasRight('takepos', 'run')); - $newmenu->add("/compta/cashcontrol/cashcontrol_list.php?action=list", $langs->trans("POS"), 0, $permtomakecashfence, '', $mainmenu, 'cashcontrol', 0, '', '', '', img_picto('', 'pos', 'class="pictofixedwidth"')); - $newmenu->add("/compta/cashcontrol/cashcontrol_card.php?action=create", $langs->trans("NewCashFence"), 1, $permtomakecashfence); - $newmenu->add("/compta/cashcontrol/cashcontrol_list.php?action=list", $langs->trans("List"), 1, $permtomakecashfence); - } + get_left_menu_bank($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } /* * Menu PRODUCTS-SERVICES */ if ($mainmenu == 'products') { - // Products - if (!empty($conf->product->enabled)) { - $newmenu->add("/product/index.php?leftmenu=product&type=0", $langs->trans("Products"), 0, $user->rights->produit->lire, '', $mainmenu, 'product', 0, '', '', '', img_picto('', 'product', 'class="pictofixedwidth"')); - $newmenu->add("/product/card.php?leftmenu=product&action=create&type=0", $langs->trans("NewProduct"), 1, $user->rights->produit->creer); - $newmenu->add("/product/list.php?leftmenu=product&type=0", $langs->trans("List"), 1, $user->rights->produit->lire); - if (!empty($conf->stock->enabled)) { - $newmenu->add("/product/reassort.php?type=0", $langs->trans("MenuStocks"), 1, $user->rights->produit->lire && $user->rights->stock->lire); - } - if (!empty($conf->productbatch->enabled)) { - $langs->load("stocks"); - $newmenu->add("/product/reassortlot.php?type=0", $langs->trans("StocksByLotSerial"), 1, $user->rights->produit->lire && $user->rights->stock->lire); - $newmenu->add("/product/stock/productlot_list.php", $langs->trans("LotSerial"), 1, $user->rights->produit->lire && $user->rights->stock->lire); - } - if (!empty($conf->variants->enabled)) { - $newmenu->add("/variants/list.php", $langs->trans("VariantAttributes"), 1, $user->rights->produit->lire); - } - if (!empty($conf->propal->enabled) || (!empty($conf->commande->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->facture->enabled) || !empty($conf->fournisseur->enabled) || !empty($conf->supplier_proposal->enabled) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { - $newmenu->add("/product/stats/card.php?id=all&leftmenu=stats&type=0", $langs->trans("Statistics"), 1, $user->rights->produit->lire && $user->rights->propale->lire); - } - - // Categories - if (!empty($conf->categorie->enabled)) { - $langs->load("categories"); - $newmenu->add("/categories/index.php?leftmenu=cat&type=0", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); - //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire); - } - } - - // Services - if (!empty($conf->service->enabled)) { - $newmenu->add("/product/index.php?leftmenu=service&type=1", $langs->trans("Services"), 0, $user->rights->service->lire, '', $mainmenu, 'service', 0, '', '', '', img_picto('', 'service', 'class="pictofixedwidth"')); - $newmenu->add("/product/card.php?leftmenu=service&action=create&type=1", $langs->trans("NewService"), 1, $user->rights->service->creer); - $newmenu->add("/product/list.php?leftmenu=service&type=1", $langs->trans("List"), 1, $user->rights->service->lire); - if (!empty($conf->propal->enabled) || !empty($conf->commande->enabled) || !empty($conf->facture->enabled) || (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_proposal->enabled) || !empty($conf->supplier_oder->enabled) || !empty($conf->supplier_invoice->enabled)) { - $newmenu->add("/product/stats/card.php?id=all&leftmenu=stats&type=1", $langs->trans("Statistics"), 1, $user->rights->service->lire || $user->rights->product->lire); - } - // Categories - if (!empty($conf->categorie->enabled)) { - $langs->load("categories"); - $newmenu->add("/categories/index.php?leftmenu=cat&type=0", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); - //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire); - } - } - - // Warehouse - if (!empty($conf->stock->enabled)) { - $langs->load("stocks"); - $newmenu->add("/product/stock/index.php?leftmenu=stock", $langs->trans("Warehouses"), 0, $user->rights->stock->lire, '', $mainmenu, 'stock', 0, '', '', '', img_picto('', 'stock', 'class="pictofixedwidth"')); - $newmenu->add("/product/stock/card.php?action=create", $langs->trans("MenuNewWarehouse"), 1, $user->rights->stock->creer); - $newmenu->add("/product/stock/list.php", $langs->trans("List"), 1, $user->rights->stock->lire); - $newmenu->add("/product/stock/movement_list.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire); - - $newmenu->add("/product/stock/massstockmove.php", $langs->trans("MassStockTransferShort"), 1, $user->rights->stock->mouvement->creer); - if ($conf->supplier_order->enabled) { - $newmenu->add("/product/stock/replenish.php", $langs->trans("Replenishment"), 1, $user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire); - } - $newmenu->add("/product/stock/stockatdate.php", $langs->trans("StockAtDate"), 1, $user->rights->produit->lire && $user->rights->stock->lire); - - // Categories for warehouses - if (!empty($conf->categorie->enabled)) { - $newmenu->add("/categories/index.php?leftmenu=stock&type=9", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); - } - } - - // Inventory - if (!empty($conf->stock->enabled)) { - $langs->load("stocks"); - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $newmenu->add("/product/inventory/list.php?leftmenu=stock_inventories", $langs->trans("Inventories"), 0, $user->rights->stock->lire, '', $mainmenu, 'stock', 0, '', '', '', img_picto('', 'inventory', 'class="pictofixedwidth"')); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "stock_inventories") { - $newmenu->add("/product/inventory/card.php?action=create&leftmenu=stock_inventories", $langs->trans("NewInventory"), 1, $user->rights->stock->creer); - $newmenu->add("/product/inventory/list.php?leftmenu=stock_inventories", $langs->trans("List"), 1, $user->rights->stock->lire); - } - } else { - $newmenu->add("/product/inventory/list.php?leftmenu=stock_inventories", $langs->trans("Inventories"), 0, $user->rights->stock->inventory_advance->read, '', $mainmenu, 'stock', 0, '', '', '', img_picto('', 'inventory', 'class="pictofixedwidth"')); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "stock_inventories") { - $newmenu->add("/product/inventory/card.php?action=create&leftmenu=stock_inventories", $langs->trans("NewInventory"), 1, $user->rights->stock->inventory_advance->write); - $newmenu->add("/product/inventory/list.php?leftmenu=stock_inventories", $langs->trans("List"), 1, $user->rights->stock->inventory_advance->read); - } - } - } - - // Shipments - if (!empty($conf->expedition->enabled)) { - $langs->load("sendings"); - $newmenu->add("/expedition/index.php?leftmenu=sendings", $langs->trans("Shipments"), 0, $user->rights->expedition->lire, '', $mainmenu, 'sendings', 0, '', '', '', img_picto('', 'shipment', 'class="pictofixedwidth"')); - $newmenu->add("/expedition/card.php?action=create2&leftmenu=sendings", $langs->trans("NewSending"), 1, $user->rights->expedition->creer); - $newmenu->add("/expedition/list.php?leftmenu=sendings", $langs->trans("List"), 1, $user->rights->expedition->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "sendings") { - $newmenu->add("/expedition/list.php?leftmenu=sendings&search_status=0", $langs->trans("StatusSendingDraftShort"), 2, $user->rights->expedition->lire); - $newmenu->add("/expedition/list.php?leftmenu=sendings&search_status=1", $langs->trans("StatusSendingValidatedShort"), 2, $user->rights->expedition->lire); - $newmenu->add("/expedition/list.php?leftmenu=sendings&search_status=2", $langs->trans("StatusSendingProcessedShort"), 2, $user->rights->expedition->lire); - } - $newmenu->add("/expedition/stats/index.php?leftmenu=sendings", $langs->trans("Statistics"), 1, $user->rights->expedition->lire); - } - - // Receptions - if (!empty($conf->reception->enabled)) { - $langs->load("receptions"); - $newmenu->add("/reception/index.php?leftmenu=receptions", $langs->trans("Receptions"), 0, $user->rights->reception->lire, '', $mainmenu, 'receptions', 0, '', '', '', img_picto('', 'dollyrevert', 'class="pictofixedwidth"')); - $newmenu->add("/reception/card.php?action=create2&leftmenu=receptions", $langs->trans("NewReception"), 1, $user->rights->reception->creer); - $newmenu->add("/reception/list.php?leftmenu=receptions", $langs->trans("List"), 1, $user->rights->reception->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "receptions") { - $newmenu->add("/reception/list.php?leftmenu=receptions&search_status=0", $langs->trans("StatusReceptionDraftShort"), 2, $user->rights->reception->lire); - } - if ($usemenuhider || empty($leftmenu) || $leftmenu == "receptions") { - $newmenu->add("/reception/list.php?leftmenu=receptions&search_status=1", $langs->trans("StatusReceptionValidatedShort"), 2, $user->rights->reception->lire); - } - if ($usemenuhider || empty($leftmenu) || $leftmenu == "receptions") { - $newmenu->add("/reception/list.php?leftmenu=receptions&search_status=2", $langs->trans("StatusReceptionProcessedShort"), 2, $user->rights->reception->lire); - } - $newmenu->add("/reception/stats/index.php?leftmenu=receptions", $langs->trans("Statistics"), 1, $user->rights->reception->lire); - } + get_left_menu_products($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } /* * Menu PRODUCTS-SERVICES MRP - GPAO */ if ($mainmenu == 'mrp') { - // BOM - if (!empty($conf->bom->enabled) || !empty($conf->mrp->enabled)) { - $langs->load("mrp"); - - $newmenu->add("", $langs->trans("MenuBOM"), 0, $user->rights->bom->read, '', $mainmenu, 'bom', 0, '', '', '', img_picto('', 'bom', 'class="paddingrightonly pictofixedwidth"')); - $newmenu->add("/bom/bom_card.php?leftmenu=bom&action=create", $langs->trans("NewBOM"), 1, $user->rights->bom->write, '', $mainmenu, 'bom'); - $newmenu->add("/bom/bom_list.php?leftmenu=bom", $langs->trans("List"), 1, $user->rights->bom->read, '', $mainmenu, 'bom'); - } - - if (!empty($conf->mrp->enabled)) { - $langs->load("mrp"); - - $newmenu->add("", $langs->trans("MenuMRP"), 0, $user->rights->mrp->read, '', $mainmenu, 'mo', 0, '', '', '', img_picto('', 'mrp', 'class="paddingrightonly pictofixedwidth"')); - $newmenu->add("/mrp/mo_card.php?leftmenu=mo&action=create", $langs->trans("NewMO"), 1, $user->rights->mrp->write, '', $mainmenu, 'mo'); - $newmenu->add("/mrp/mo_list.php?leftmenu=mo", $langs->trans("List"), 1, $user->rights->mrp->read, '', $mainmenu, 'mo'); - } + get_left_menu_mrp($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } /* * Menu PROJECTS */ if ($mainmenu == 'project') { - if (!empty($conf->projet->enabled)) { - $langs->load("projects"); - - $search_project_user = GETPOST('search_project_user', 'int'); - - $tmpentry = array( - 'enabled'=>(!empty($conf->projet->enabled)), - 'perms'=>(!empty($user->rights->projet->lire)), - 'module'=>'projet' - ); - $showmode = isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); - - $titleboth = $langs->trans("LeadsOrProjects"); - $titlenew = $langs->trans("NewLeadOrProject"); // Leads and opportunities by default - if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { - $titleboth = $langs->trans("Projects"); - $titlenew = $langs->trans("NewProject"); - } - if (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only - $titleboth = $langs->trans("Leads"); - $titlenew = $langs->trans("NewLead"); - } - - // Project assigned to user - $newmenu->add("/projet/index.php?leftmenu=projects".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titleboth, 0, $user->rights->projet->lire, '', $mainmenu, 'projects', 0, '', '', '', img_picto('', 'project', 'class="pictofixedwidth"')); - $newmenu->add("/projet/card.php?leftmenu=projects&action=create".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titlenew, 1, $user->rights->projet->creer); - - if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { - $newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user ? '&search_project_user='.$search_project_user : '').'&search_status=99', $langs->trans("List"), 1, $showmode, '', 'project', 'list'); - } elseif (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 1) { - $newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $showmode, '', 'project', 'list'); - $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_usage_opportunity=1&search_status=99&search_opp_status=openedopp&contextpage=lead', $langs->trans("ListOpenLeads"), 2, $showmode); - $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_opp_status=notopenedopp&search_status=99&contextpage=project', $langs->trans("ListOpenProjects"), 2, $showmode); - } elseif (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only - $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_usage_opportunity=1&search_status=99', $langs->trans("List"), 2, $showmode); - } - - $newmenu->add("/projet/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); - - // Categories - if (!empty($conf->categorie->enabled)) { - $langs->load("categories"); - $newmenu->add("/categories/index.php?leftmenu=cat&type=6", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); - } - - if (empty($conf->global->PROJECT_HIDE_TASKS)) { - // Project affected to user - $newmenu->add("/projet/activity/index.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("Activities"), 0, $user->rights->projet->lire, '', 'project', 'tasks', 0, '', '', '', img_picto('', 'projecttask', 'class="pictofixedwidth"')); - $newmenu->add("/projet/tasks.php?leftmenu=tasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); - $newmenu->add("/projet/tasks/list.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $user->rights->projet->lire); - $newmenu->add("/projet/tasks/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); - - $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', 'project', 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="pictofixedwidth"')); - } - } + get_left_menu_projects($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } /* * Menu HRM - */ + */ if ($mainmenu == 'hrm') { - // HRM module - if (!empty($conf->hrm->enabled)) { - $langs->load("hrm"); - - $newmenu->add("/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee", $langs->trans("Employees"), 0, $user->rights->user->user->lire, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); - $newmenu->add("/user/card.php?mainmenu=hrm&leftmenu=hrm&action=create&employee=1", $langs->trans("NewEmployee"), 1, $user->rights->user->user->creer); - $newmenu->add("/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee&contextpage=employeelist", $langs->trans("List"), 1, $user->rights->user->user->lire); - - $newmenu->add("/hrm/index.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("SkillsManagement"), 0, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); - - if ($usemenuhider || empty($leftmenu) || $leftmenu == "hrm_sm") { - // Skills - $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("Skills"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'shapes', 'class="pictofixedwidth"')); - //$newmenu->add("/hrm/skill_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->trans("NewSkill"), 1, $user->rights->hrm->all->write); - //$newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); - - // Job (Description of work to do and skills required) - $newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("JobsPosition"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'technic', 'class="pictofixedwidth"')); - //$newmenu->add("/hrm/job_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->transnoentities("NewObject", $langs->trans("Job")), 1, $user->rights->hrm->all->write); - //$newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); - - // Position = Link job - user - $newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("EmployeePositions"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user-cog', 'class="pictofixedwidth"')); - //$newmenu->add("/hrm/position.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->transnoentities("NewObject", $langs->trans("Position")), 1, $user->rights->hrm->all->write); - //$newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); - - // Evaluation - $newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("Evalutions"), 1, $user->rights->hrm->evaluation->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); - //$newmenu->add("/hrm/evaluation_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->trans("NewEval"), 1, $user->rights->hrm->evaluation->write); - //$newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->evaluation->read); - $newmenu->add("/hrm/compare.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("SkillComparison"), 1, $user->rights->hrm->evaluation->read || $user->rights->hrm->compare_advance->read); - } - } - - // Leave/Holiday/Vacation module - if (!empty($conf->holiday->enabled)) { - // Load translation files required by the page - $langs->loadLangs(array("holiday", "trips")); - - $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("CPTitreMenu"), 0, $user->rights->holiday->read, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'holiday', 'class="pictofixedwidth"')); - $newmenu->add("/holiday/card.php?mainmenu=hrm&leftmenu=holiday&action=create", $langs->trans("New"), 1, $user->rights->holiday->write); - $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("List"), 1, $user->rights->holiday->read); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "hrm") { - $newmenu->add("/holiday/list.php?search_status=1&mainmenu=hrm&leftmenu=hrm", $langs->trans("DraftCP"), 2, $user->rights->holiday->read); - $newmenu->add("/holiday/list.php?search_status=2&mainmenu=hrm&leftmenu=hrm", $langs->trans("ToReviewCP"), 2, $user->rights->holiday->read); - $newmenu->add("/holiday/list.php?search_status=3&mainmenu=hrm&leftmenu=hrm", $langs->trans("ApprovedCP"), 2, $user->rights->holiday->read); - $newmenu->add("/holiday/list.php?search_status=4&mainmenu=hrm&leftmenu=hrm", $langs->trans("CancelCP"), 2, $user->rights->holiday->read); - $newmenu->add("/holiday/list.php?search_status=5&mainmenu=hrm&leftmenu=hrm", $langs->trans("RefuseCP"), 2, $user->rights->holiday->read); - } - $newmenu->add("/holiday/define_holiday.php?mainmenu=hrm&action=request", $langs->trans("MenuConfCP"), 1, $user->rights->holiday->read); - $newmenu->add("/holiday/month_report.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("MenuReportMonth"), 1, $user->rights->holiday->readall); - $newmenu->add("/holiday/view_log.php?mainmenu=hrm&leftmenu=holiday&action=request", $langs->trans("MenuLogCP"), 1, $user->rights->holiday->define_holiday); - } - - // Trips and expenses (old module) - if (!empty($conf->deplacement->enabled)) { - $langs->load("trips"); - $newmenu->add("/compta/deplacement/index.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->deplacement->lire, '', $mainmenu, 'tripsandexpenses', 0, '', '', '', img_picto('', 'trip', 'class="pictofixedwidth"')); - $newmenu->add("/compta/deplacement/card.php?action=create&leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("New"), 1, $user->rights->deplacement->creer); - $newmenu->add("/compta/deplacement/list.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("List"), 1, $user->rights->deplacement->lire); - $newmenu->add("/compta/deplacement/stats/index.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("Statistics"), 1, $user->rights->deplacement->lire); - } - - // Expense report - if (!empty($conf->expensereport->enabled)) { - $langs->load("trips"); - $newmenu->add("/expensereport/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->expensereport->lire, '', $mainmenu, 'expensereport', 0, '', '', '', img_picto('', 'trip', 'class="pictofixedwidth"')); - $newmenu->add("/expensereport/card.php?action=create&leftmenu=expensereport&mainmenu=hrm", $langs->trans("New"), 1, $user->rights->expensereport->creer); - $newmenu->add("/expensereport/list.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("List"), 1, $user->rights->expensereport->lire); - if ($usemenuhider || empty($leftmenu) || $leftmenu == "expensereport") { - $newmenu->add("/expensereport/list.php?search_status=0&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Draft"), 2, $user->rights->expensereport->lire); - $newmenu->add("/expensereport/list.php?search_status=2&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Validated"), 2, $user->rights->expensereport->lire); - $newmenu->add("/expensereport/list.php?search_status=5&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Approved"), 2, $user->rights->expensereport->lire); - $newmenu->add("/expensereport/list.php?search_status=6&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Paid"), 2, $user->rights->expensereport->lire); - $newmenu->add("/expensereport/list.php?search_status=4&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Canceled"), 2, $user->rights->expensereport->lire); - $newmenu->add("/expensereport/list.php?search_status=99&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Refused"), 2, $user->rights->expensereport->lire); - } - $newmenu->add("/expensereport/stats/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("Statistics"), 1, $user->rights->expensereport->lire); - } - - if (!empty($conf->projet->enabled)) { - if (empty($conf->global->PROJECT_HIDE_TASKS)) { - $langs->load("projects"); - - $search_project_user = GETPOST('search_project_user', 'int'); - - $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', $mainmenu, 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="pictofixedwidth"')); - } - } + get_left_menu_hrm($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } - /* * Menu TOOLS */ if ($mainmenu == 'tools') { - if (empty($user->socid)) { // limit to internal users - $langs->load("mails"); - $newmenu->add("/admin/mails_templates.php?leftmenu=email_templates", $langs->trans("EMailTemplates"), 0, 1, '', $mainmenu, 'email_templates', 0, '', '', '', img_picto('', 'email', 'class="paddingright pictofixedwidth"')); - } - - if (!empty($conf->mailing->enabled)) { - $newmenu->add("/comm/mailing/index.php?leftmenu=mailing", $langs->trans("EMailings"), 0, $user->rights->mailing->lire, '', $mainmenu, 'mailing', 0, '', '', '', img_picto('', 'email', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/comm/mailing/card.php?leftmenu=mailing&action=create", $langs->trans("NewMailing"), 1, $user->rights->mailing->creer); - $newmenu->add("/comm/mailing/list.php?leftmenu=mailing", $langs->trans("List"), 1, $user->rights->mailing->lire); - } - - if (!empty($conf->export->enabled)) { - $langs->load("exports"); - $newmenu->add("/exports/index.php?leftmenu=export", $langs->trans("FormatedExport"), 0, $user->rights->export->lire, '', $mainmenu, 'export', 0, '', '', '', img_picto('', 'technic', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/exports/export.php?leftmenu=export", $langs->trans("NewExport"), 1, $user->rights->export->creer); - //$newmenu->add("/exports/export.php?leftmenu=export",$langs->trans("List"),1, $user->rights->export->lire); - } - - if (!empty($conf->import->enabled)) { - $langs->load("exports"); - $newmenu->add("/imports/index.php?leftmenu=import", $langs->trans("FormatedImport"), 0, $user->rights->import->run, '', $mainmenu, 'import', 0, '', '', '', img_picto('', 'technic', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/imports/import.php?leftmenu=import", $langs->trans("NewImport"), 1, $user->rights->import->run); - } + get_left_menu_tools($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } /* * Menu MEMBERS */ if ($mainmenu == 'members') { - if (!empty($conf->adherent->enabled)) { - // Load translation files required by the page - $langs->loadLangs(array("members", "compta")); - - $newmenu->add("/adherents/index.php?leftmenu=members&mainmenu=members", $langs->trans("Members"), 0, $user->rights->adherent->lire, '', $mainmenu, 'members', 0, '', '', '', img_picto('', 'member', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/adherents/card.php?leftmenu=members&action=create", $langs->trans("NewMember"), 1, $user->rights->adherent->creer); - $newmenu->add("/adherents/list.php?leftmenu=members", $langs->trans("List"), 1, $user->rights->adherent->lire); - $newmenu->add("/adherents/list.php?leftmenu=members&statut=-1", $langs->trans("MenuMembersToValidate"), 2, $user->rights->adherent->lire); - $newmenu->add("/adherents/list.php?leftmenu=members&statut=1", $langs->trans("MenuMembersValidated"), 2, $user->rights->adherent->lire); - $newmenu->add("/adherents/list.php?leftmenu=members&statut=1&filter=withoutsubscription", $langs->trans("WithoutSubscription"), 3, $user->rights->adherent->lire); - $newmenu->add("/adherents/list.php?leftmenu=members&statut=1&filter=uptodate", $langs->trans("UpToDate"), 3, $user->rights->adherent->lire); - $newmenu->add("/adherents/list.php?leftmenu=members&statut=1&filter=outofdate", $langs->trans("OutOfDate"), 3, $user->rights->adherent->lire); - $newmenu->add("/adherents/list.php?leftmenu=members&statut=0", $langs->trans("MenuMembersResiliated"), 2, $user->rights->adherent->lire); - $newmenu->add("/adherents/stats/index.php?leftmenu=members", $langs->trans("MenuMembersStats"), 1, $user->rights->adherent->lire); - - $newmenu->add("/adherents/cartes/carte.php?leftmenu=export", $langs->trans("MembersCards"), 1, $user->rights->adherent->export); - if (!empty($conf->global->MEMBER_LINK_TO_HTPASSWDFILE) && ($usemenuhider || empty($leftmenu) || $leftmenu == 'none' || $leftmenu == "members" || $leftmenu == "export")) { - $newmenu->add("/adherents/htpasswd.php?leftmenu=export", $langs->trans("Filehtpasswd"), 1, $user->rights->adherent->export); - } - - if (!empty($conf->categorie->enabled)) { - $langs->load("categories"); - $newmenu->add("/categories/index.php?leftmenu=cat&type=3", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); - } - - $newmenu->add("/adherents/index.php?leftmenu=members&mainmenu=members", $langs->trans("Subscriptions"), 0, $user->rights->adherent->cotisation->lire, '', $mainmenu, 'members', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/adherents/list.php?leftmenu=members&statut=-1,1&mainmenu=members", $langs->trans("NewSubscription"), 1, $user->rights->adherent->cotisation->creer); - $newmenu->add("/adherents/subscription/list.php?leftmenu=members", $langs->trans("List"), 1, $user->rights->adherent->cotisation->lire); - $newmenu->add("/adherents/stats/index.php?leftmenu=members", $langs->trans("MenuMembersStats"), 1, $user->rights->adherent->lire); - - //$newmenu->add("/adherents/index.php?leftmenu=export&mainmenu=members",$langs->trans("Tools"),0,$user->rights->adherent->export, '', $mainmenu, 'export'); - //if (! empty($conf->export->enabled) && ($usemenuhider || empty($leftmenu) || $leftmenu=="export")) $newmenu->add("/exports/index.php?leftmenu=export",$langs->trans("Datas"),1,$user->rights->adherent->export); - - // Type - $newmenu->add("/adherents/type.php?leftmenu=setup&mainmenu=members", $langs->trans("MembersTypes"), 0, $user->rights->adherent->configurer, '', $mainmenu, 'setup', 0, '', '', '', img_picto('', 'members', 'class="paddingright pictofixedwidth"')); - $newmenu->add("/adherents/type.php?leftmenu=setup&mainmenu=members&action=create", $langs->trans("New"), 1, $user->rights->adherent->configurer); - $newmenu->add("/adherents/type.php?leftmenu=setup&mainmenu=members", $langs->trans("List"), 1, $user->rights->adherent->configurer); - } + get_left_menu_members($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user); } // Add personalized menus and modules menus @@ -2022,13 +881,13 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM // TODO Use the position property in menu_array to reorder the $menu_array //var_dump($menu_array); /*$new_menu_array = array(); - $level=0; $cusor=0; $position=0; - $nbentry = count($menu_array); - while (findNextEntryForLevel($menu_array, $cursor, $position, $level)) - { + $level=0; $cusor=0; $position=0; + $nbentry = count($menu_array); + while (findNextEntryForLevel($menu_array, $cursor, $position, $level)) + { - $cursor++; - }*/ + $cursor++; + }*/ // Show menu $invert = empty($conf->global->MAIN_MENU_INVERT) ? "" : "invert"; @@ -2182,3 +1041,1368 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM return count($menu_array); } + + +/** + * Get left Menu HOME + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of user + * @return void + */ +function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'home') { + $langs->load("users"); + + // Home - dashboard + $newmenu->add("/index.php?mainmenu=home&leftmenu=home", $langs->trans("MyDashboard"), 0, 1, '', $mainmenu, 'home', 0, '', '', '', ''); + + // Setup + $newmenu->add("/admin/index.php?mainmenu=home&leftmenu=setup", $langs->trans("Setup"), 0, $user->admin, '', $mainmenu, 'setup', 0, '', '', '', ''); + + if ($usemenuhider || empty($leftmenu) || $leftmenu == "setup") { + // Load translation files required by the page + $langs->loadLangs(array("admin", "help")); + + $warnpicto = ''; + if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY)) { + $langs->load("errors"); + $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete")); + } + $newmenu->add("/admin/company.php?mainmenu=home", $langs->trans("MenuCompanySetup").$warnpicto, 1); + + $warnpicto = ''; + if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only user module enabled + $langs->load("errors"); + $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete")); + } + $newmenu->add("/admin/modules.php?mainmenu=home", $langs->trans("Modules").$warnpicto, 1); + $newmenu->add("/admin/ihm.php?mainmenu=home", $langs->trans("GUISetup"), 1); + $newmenu->add("/admin/menus.php?mainmenu=home", $langs->trans("Menus"), 1); + + $newmenu->add("/admin/translation.php?mainmenu=home", $langs->trans("Translation"), 1); + $newmenu->add("/admin/defaultvalues.php?mainmenu=home", $langs->trans("DefaultValues"), 1); + $newmenu->add("/admin/boxes.php?mainmenu=home", $langs->trans("Boxes"), 1); + $newmenu->add("/admin/delais.php?mainmenu=home", $langs->trans("MenuWarnings"), 1); + $newmenu->add("/admin/security_other.php?mainmenu=home", $langs->trans("Security"), 1); + $newmenu->add("/admin/limits.php?mainmenu=home", $langs->trans("MenuLimits"), 1); + $newmenu->add("/admin/pdf.php?mainmenu=home", $langs->trans("PDF"), 1); + + $warnpicto = ''; + if (!empty($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'mail' && empty($conf->global->MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP)) { + $langs->load("errors"); + $warnpicto = img_warning($langs->trans("WarningPHPMailD")); + } + if (!empty($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmail')) && empty($conf->global->MAIN_MAIL_SMTP_SERVER)) { + $langs->load("errors"); + $warnpicto = img_warning($langs->trans("ErrorSetupOfEmailsNotComplete")); + } + + $newmenu->add("/admin/mails.php?mainmenu=home", $langs->trans("Emails").$warnpicto, 1); + $newmenu->add("/admin/sms.php?mainmenu=home", $langs->trans("SMS"), 1); + $newmenu->add("/admin/dict.php?mainmenu=home", $langs->trans("Dictionary"), 1); + $newmenu->add("/admin/const.php?mainmenu=home", $langs->trans("OtherSetup"), 1); + } + + // System tools + $newmenu->add("/admin/tools/index.php?mainmenu=home&leftmenu=admintools", $langs->trans("AdminTools"), 0, $user->admin, '', $mainmenu, 'admintools', 0, '', '', '', ''); + if ($usemenuhider || empty($leftmenu) || preg_match('/^admintools/', $leftmenu)) { + // Load translation files required by the page + $langs->loadLangs(array('admin', 'help')); + + $newmenu->add('/admin/system/dolibarr.php?mainmenu=home&leftmenu=admintools_info', $langs->trans('InfoDolibarr'), 1); + if ($usemenuhider || empty($leftmenu) || $leftmenu == 'admintools_info') { + $newmenu->add('/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', $langs->trans('Modules'), 2); + $newmenu->add('/admin/triggers.php?mainmenu=home&leftmenu=admintools_info', $langs->trans('Triggers'), 2); + $newmenu->add('/admin/system/filecheck.php?mainmenu=home&leftmenu=admintools_info', $langs->trans('FileCheck'), 2); + } + $newmenu->add('/admin/system/browser.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoBrowser'), 1); + $newmenu->add('/admin/system/os.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoOS'), 1); + $newmenu->add('/admin/system/web.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoWebServer'), 1); + $newmenu->add('/admin/system/phpinfo.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoPHP'), 1); + $newmenu->add('/admin/system/database.php?mainmenu=home&leftmenu=admintools', $langs->trans('InfoDatabase'), 1); + $newmenu->add("/admin/system/perf.php?mainmenu=home&leftmenu=admintools", $langs->trans("InfoPerf"), 1); + $newmenu->add("/admin/system/security.php?mainmenu=home&leftmenu=admintools", $langs->trans("InfoSecurity"), 1); + $newmenu->add("/admin/tools/dolibarr_export.php?mainmenu=home&leftmenu=admintools", $langs->trans("Backup"), 1); + $newmenu->add("/admin/tools/dolibarr_import.php?mainmenu=home&leftmenu=admintools", $langs->trans("Restore"), 1); + $newmenu->add("/admin/tools/update.php?mainmenu=home&leftmenu=admintools", $langs->trans("MenuUpgrade"), 1); + $newmenu->add("/admin/tools/purge.php?mainmenu=home&leftmenu=admintools", $langs->trans("Purge"), 1); + $newmenu->add("/admin/tools/listevents.php?mainmenu=home&leftmenu=admintools", $langs->trans("Audit"), 1); + $newmenu->add("/admin/tools/listsessions.php?mainmenu=home&leftmenu=admintools", $langs->trans("Sessions"), 1); + $newmenu->add('/admin/system/about.php?mainmenu=home&leftmenu=admintools', $langs->trans('ExternalResources'), 1); + + if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { + $langs->load("products"); + $newmenu->add("/product/admin/product_tools.php?mainmenu=home&leftmenu=admintools", $langs->trans("ProductVatMassChange"), 1, $user->admin); + } + } + + $newmenu->add("/user/home.php?leftmenu=users", $langs->trans("MenuUsersAndGroups"), 0, $user->rights->user->user->lire, '', $mainmenu, 'users', 0, '', '', '', img_picto('', 'user', 'class="paddingright pictofixedwidth"')); + if ($user->rights->user->user->lire) { + if ($usemenuhider || empty($leftmenu) || $leftmenu == "users") { + $newmenu->add("", $langs->trans("Users"), 1, $user->rights->user->user->lire || $user->admin); + $newmenu->add("/user/card.php?leftmenu=users&action=create", $langs->trans("NewUser"), 2, ($user->rights->user->user->creer || $user->admin) && !(!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE), '', 'home'); + $newmenu->add("/user/list.php?leftmenu=users", $langs->trans("ListOfUsers"), 2, $user->rights->user->user->lire || $user->admin); + $newmenu->add("/user/hierarchy.php?leftmenu=users", $langs->trans("HierarchicView"), 2, $user->rights->user->user->lire || $user->admin); + if (!empty($conf->categorie->enabled)) { + $langs->load("categories"); + $newmenu->add("/categories/index.php?leftmenu=users&type=7", $langs->trans("UsersCategoriesShort"), 2, $user->rights->categorie->lire, '', $mainmenu, 'cat'); + } + $newmenu->add("", $langs->trans("Groups"), 1, ($user->rights->user->user->lire || $user->admin) && !(!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); + $newmenu->add("/user/group/card.php?leftmenu=users&action=create", $langs->trans("NewGroup"), 2, ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) ? $user->rights->user->group_advance->write : $user->rights->user->user->creer) || $user->admin) && !(!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); + $newmenu->add("/user/group/list.php?leftmenu=users", $langs->trans("ListOfGroups"), 2, ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) ? $user->rights->user->group_advance->read : $user->rights->user->user->lire) || $user->admin) && !(!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)); + } + } + } +} + +/** + * Get left Menu THIRDPARTIES + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_thridparties($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'companies') { + // Societes + if (!empty($conf->societe->enabled)) { + $langs->load("companies"); + $newmenu->add("/societe/index.php?leftmenu=thirdparties", $langs->trans("ThirdParty"), 0, $user->rights->societe->lire, '', $mainmenu, 'thirdparties', 0, '', '', '', img_picto('', 'company', 'class="paddingright pictofixedwidth"')); + + if ($user->rights->societe->creer) { + $newmenu->add("/societe/card.php?action=create", $langs->trans("MenuNewThirdParty"), 1); + if (!$conf->use_javascript_ajax) { + $newmenu->add("/societe/card.php?action=create&private=1", $langs->trans("MenuNewPrivateIndividual"), 1); + } + } + } + + $newmenu->add("/societe/list.php?leftmenu=thirdparties", $langs->trans("List"), 1); + + // Prospects + if (!empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { + $langs->load("commercial"); + $newmenu->add("/societe/list.php?type=p&leftmenu=prospects", $langs->trans("ListProspectsShort"), 2, $user->rights->societe->lire, '', $mainmenu, 'prospects'); + /* no more required, there is a filter that can do more + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=-1", $langs->trans("LastProspectDoNotContact"), 2, $user->rights->societe->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=0", $langs->trans("LastProspectNeverContacted"), 2, $user->rights->societe->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=1", $langs->trans("LastProspectToContact"), 2, $user->rights->societe->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=2", $langs->trans("LastProspectContactInProcess"), 2, $user->rights->societe->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&sortfield=s.datec&sortorder=desc&begin=&search_stcomm=3", $langs->trans("LastProspectContactDone"), 2, $user->rights->societe->lire); + */ + $newmenu->add("/societe/card.php?leftmenu=prospects&action=create&type=p", $langs->trans("MenuNewProspect"), 3, $user->rights->societe->creer); + } + + // Customers/Prospects + if (!empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { + $langs->load("commercial"); + $newmenu->add("/societe/list.php?type=c&leftmenu=customers", $langs->trans("ListCustomersShort"), 2, $user->rights->societe->lire, '', $mainmenu, 'customers'); + + $newmenu->add("/societe/card.php?leftmenu=customers&action=create&type=c", $langs->trans("MenuNewCustomer"), 3, $user->rights->societe->creer); + } + + // Suppliers + if (!empty($conf->societe->enabled) && (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) || !empty($conf->supplier_proposal->enabled))) { + $langs->load("suppliers"); + $newmenu->add("/societe/list.php?type=f&leftmenu=suppliers", $langs->trans("ListSuppliersShort"), 2, ($user->rights->fournisseur->lire || $user->rights->supplier_order->lire || $user->rights->supplier_invoice->lire || $user->rights->supplier_proposal->lire), '', $mainmenu, 'suppliers'); + $newmenu->add("/societe/card.php?leftmenu=suppliers&action=create&type=f", $langs->trans("MenuNewSupplier"), 3, $user->rights->societe->creer && ($user->rights->fournisseur->lire || $user->rights->supplier_order->lire || $user->rights->supplier_invoice->lire || $user->rights->supplier_proposal->lire)); + } + + // Categories + if (!empty($conf->categorie->enabled)) { + $langs->load("categories"); + if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { + // Categories prospects/customers + $menutoshow = $langs->trans("CustomersProspectsCategoriesShort"); + if (!empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { + $menutoshow = $langs->trans("CustomersCategoriesShort"); + } + if (!empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { + $menutoshow = $langs->trans("ProspectsCategoriesShort"); + } + $newmenu->add("/categories/index.php?leftmenu=cat&type=2", $menutoshow, 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); + } + // Categories suppliers + if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { + $newmenu->add("/categories/index.php?leftmenu=catfournish&type=1", $langs->trans("SuppliersCategoriesShort"), 1, $user->rights->categorie->lire); + } + } + + // Contacts + $newmenu->add("/societe/index.php?leftmenu=thirdparties", (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")), 0, $user->rights->societe->contact->lire, '', $mainmenu, 'contacts', 0, '', '', '', img_picto('', 'contact', 'class="paddingright pictofixedwidth"')); + + $newmenu->add("/contact/card.php?leftmenu=contacts&action=create", (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("NewContact") : $langs->trans("NewContactAddress")), 1, $user->rights->societe->contact->creer); + $newmenu->add("/contact/list.php?leftmenu=contacts", $langs->trans("List"), 1, $user->rights->societe->contact->lire); + if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) { + $newmenu->add("/contact/list.php?leftmenu=contacts&type=p", $langs->trans("Prospects"), 2, $user->rights->societe->contact->lire); + } + if (empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { + $newmenu->add("/contact/list.php?leftmenu=contacts&type=c", $langs->trans("Customers"), 2, $user->rights->societe->contact->lire); + } + if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { + $newmenu->add("/contact/list.php?leftmenu=contacts&type=f", $langs->trans("Suppliers"), 2, $user->rights->societe->contact->lire); + } + $newmenu->add("/contact/list.php?leftmenu=contacts&type=o", $langs->trans("ContactOthers"), 2, $user->rights->societe->contact->lire); + //$newmenu->add("/contact/list.php?userid=$user->id", $langs->trans("MyContacts"), 1, $user->rights->societe->contact->lire); + + // Categories + if (!empty($conf->categorie->enabled)) { + $langs->load("categories"); + // Categories Contact + $newmenu->add("/categories/index.php?leftmenu=catcontact&type=4", $langs->trans("ContactCategoriesShort"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); + } + } +} + +/** + * Get left Menu COMMERCIAL (propal, commande, supplier_proposal, supplier_order, contrat, ficheinter) + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_commercial($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'commercial') { + $langs->load("companies"); + + // Customer proposal + if (!empty($conf->propal->enabled)) { + $langs->load("propal"); + $newmenu->add("/comm/propal/index.php?leftmenu=propals", $langs->trans("Proposals"), 0, $user->rights->propale->lire, '', $mainmenu, 'propals', 100, '', '', '', img_picto('', 'propal', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/comm/propal/card.php?action=create&leftmenu=propals", $langs->trans("NewPropal"), 1, $user->rights->propale->creer); + $newmenu->add("/comm/propal/list.php?leftmenu=propals", $langs->trans("List"), 1, $user->rights->propale->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "propals") { + $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=0", $langs->trans("PropalsDraft"), 2, $user->rights->propale->lire); + $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=1", $langs->trans("PropalsOpened"), 2, $user->rights->propale->lire); + $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=2", $langs->trans("PropalStatusSigned"), 2, $user->rights->propale->lire); + $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=3", $langs->trans("PropalStatusNotSigned"), 2, $user->rights->propale->lire); + $newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=4", $langs->trans("PropalStatusBilled"), 2, $user->rights->propale->lire); + //$newmenu->add("/comm/propal/list.php?leftmenu=propals&search_status=2,3,4", $langs->trans("PropalStatusClosedShort"), 2, $user->rights->propale->lire); + } + $newmenu->add("/comm/propal/stats/index.php?leftmenu=propals", $langs->trans("Statistics"), 1, $user->rights->propale->lire); + } + + // Customers orders + if (!empty($conf->commande->enabled)) { + $langs->load("orders"); + $newmenu->add("/commande/index.php?leftmenu=orders", $langs->trans("CustomersOrders"), 0, $user->rights->commande->lire, '', $mainmenu, 'orders', 200, '', '', '', img_picto('', 'order', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/commande/card.php?action=create&leftmenu=orders", $langs->trans("NewOrder"), 1, $user->rights->commande->creer); + $newmenu->add("/commande/list.php?leftmenu=orders", $langs->trans("List"), 1, $user->rights->commande->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "orders") { + $newmenu->add("/commande/list.php?leftmenu=orders&search_status=0", $langs->trans("StatusOrderDraftShort"), 2, $user->rights->commande->lire); + $newmenu->add("/commande/list.php?leftmenu=orders&search_status=1", $langs->trans("StatusOrderValidated"), 2, $user->rights->commande->lire); + if (!empty($conf->expedition->enabled)) { + $newmenu->add("/commande/list.php?leftmenu=orders&search_status=2", $langs->trans("StatusOrderSentShort"), 2, $user->rights->commande->lire); + } + $newmenu->add("/commande/list.php?leftmenu=orders&search_status=3", $langs->trans("StatusOrderDelivered"), 2, $user->rights->commande->lire); + //$newmenu->add("/commande/list.php?leftmenu=orders&search_status=4", $langs->trans("StatusOrderProcessed"), 2, $user->rights->commande->lire); + $newmenu->add("/commande/list.php?leftmenu=orders&search_status=-1", $langs->trans("StatusOrderCanceledShort"), 2, $user->rights->commande->lire); + } + $newmenu->add("/commande/stats/index.php?leftmenu=orders", $langs->trans("Statistics"), 1, $user->rights->commande->lire); + } + + // Supplier proposal + if (!empty($conf->supplier_proposal->enabled)) { + $langs->load("supplier_proposal"); + $newmenu->add("/supplier_proposal/index.php?leftmenu=propals_supplier", $langs->trans("SupplierProposalsShort"), 0, $user->rights->supplier_proposal->lire, '', $mainmenu, 'propals_supplier', 300, '', '', '', img_picto('', 'supplier_proposal', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/supplier_proposal/card.php?action=create&leftmenu=supplier_proposals", $langs->trans("SupplierProposalNew"), 1, $user->rights->supplier_proposal->creer); + $newmenu->add("/supplier_proposal/list.php?leftmenu=supplier_proposals", $langs->trans("List"), 1, $user->rights->supplier_proposal->lire); + $newmenu->add("/comm/propal/stats/index.php?leftmenu=supplier_proposals&mode=supplier", $langs->trans("Statistics"), 1, $user->rights->supplier_proposal->lire); + } + + // Suppliers orders + if (!empty($conf->supplier_order->enabled)) { + $langs->load("orders"); + $newmenu->add("/fourn/commande/index.php?leftmenu=orders_suppliers", $langs->trans("SuppliersOrders"), 0, $user->rights->fournisseur->commande->lire, '', $mainmenu, 'orders_suppliers', 400, '', '', '', img_picto('', 'supplier_order', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/fourn/commande/card.php?action=create&leftmenu=orders_suppliers", $langs->trans("NewSupplierOrderShort"), 1, $user->rights->fournisseur->commande->creer); + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers", $langs->trans("List"), 1, $user->rights->fournisseur->commande->lire); + + if ($usemenuhider || empty($leftmenu) || $leftmenu == "orders_suppliers") { + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=0", $langs->trans("StatusSupplierOrderDraftShort"), 2, $user->rights->fournisseur->commande->lire); + if (empty($conf->global->SUPPLIER_ORDER_HIDE_VALIDATED)) { + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=1", $langs->trans("StatusSupplierOrderValidated"), 2, $user->rights->fournisseur->commande->lire); + } + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=2", $langs->trans("StatusSupplierOrderApprovedShort"), 2, $user->rights->fournisseur->commande->lire); + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=3", $langs->trans("StatusSupplierOrderOnProcessShort"), 2, $user->rights->fournisseur->commande->lire); + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=4", $langs->trans("StatusSupplierOrderReceivedPartiallyShort"), 2, $user->rights->fournisseur->commande->lire); + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=5", $langs->trans("StatusSupplierOrderReceivedAll"), 2, $user->rights->fournisseur->commande->lire); + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=6,7", $langs->trans("StatusSupplierOrderCanceled"), 2, $user->rights->fournisseur->commande->lire); + $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&statut=9", $langs->trans("StatusSupplierOrderRefused"), 2, $user->rights->fournisseur->commande->lire); + } + // Billed is another field. We should add instead a dedicated filter on list. if ($usemenuhider || empty($leftmenu) || $leftmenu=="orders_suppliers") $newmenu->add("/fourn/commande/list.php?leftmenu=orders_suppliers&billed=1", $langs->trans("Billed"), 2, $user->rights->fournisseur->commande->lire); + + + $newmenu->add("/commande/stats/index.php?leftmenu=orders_suppliers&mode=supplier", $langs->trans("Statistics"), 1, $user->rights->fournisseur->commande->lire); + } + + // Contrat + if (!empty($conf->contrat->enabled)) { + $langs->load("contracts"); + $newmenu->add("/contrat/index.php?leftmenu=contracts", $langs->trans("ContractsSubscriptions"), 0, $user->rights->contrat->lire, '', $mainmenu, 'contracts', 2000, '', '', '', img_picto('', 'contract', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/contrat/card.php?action=create&leftmenu=contracts", $langs->trans("NewContractSubscription"), 1, $user->rights->contrat->creer); + $newmenu->add("/contrat/list.php?leftmenu=contracts", $langs->trans("List"), 1, $user->rights->contrat->lire); + $newmenu->add("/contrat/services_list.php?leftmenu=contracts", $langs->trans("MenuServices"), 1, $user->rights->contrat->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "contracts") { + $newmenu->add("/contrat/services_list.php?leftmenu=contracts&mode=0", $langs->trans("MenuInactiveServices"), 2, $user->rights->contrat->lire); + $newmenu->add("/contrat/services_list.php?leftmenu=contracts&mode=4", $langs->trans("MenuRunningServices"), 2, $user->rights->contrat->lire); + $newmenu->add("/contrat/services_list.php?leftmenu=contracts&mode=4&filter=expired", $langs->trans("MenuExpiredServices"), 2, $user->rights->contrat->lire); + $newmenu->add("/contrat/services_list.php?leftmenu=contracts&mode=5", $langs->trans("MenuClosedServices"), 2, $user->rights->contrat->lire); + } + } + + // Interventions + if (!empty($conf->ficheinter->enabled)) { + $langs->load("interventions"); + $newmenu->add("/fichinter/index.php?leftmenu=ficheinter", $langs->trans("Interventions"), 0, $user->rights->ficheinter->lire, '', $mainmenu, 'ficheinter', 2200, '', '', '', img_picto('', 'intervention', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/fichinter/card.php?action=create&leftmenu=ficheinter", $langs->trans("NewIntervention"), 1, $user->rights->ficheinter->creer, '', '', '', 201); + $newmenu->add("/fichinter/list.php?leftmenu=ficheinter", $langs->trans("List"), 1, $user->rights->ficheinter->lire, '', '', '', 202); + if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { + $newmenu->add("/fichinter/card-rec.php?leftmenu=ficheinter", $langs->trans("ListOfTemplates"), 1, $user->rights->ficheinter->lire, '', '', '', 203); + } + $newmenu->add("/fichinter/stats/index.php?leftmenu=ficheinter", $langs->trans("Statistics"), 1, $user->rights->ficheinter->lire); + } + } +} + +/** + * Get left COMPTA-FINANCIAL + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_billing($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'billing') { + $langs->load("companies"); + + // Customers invoices + if (!empty($conf->facture->enabled)) { + $langs->load("bills"); + $newmenu->add("/compta/facture/index.php?leftmenu=customers_bills", $langs->trans("BillsCustomers"), 0, $user->rights->facture->lire, '', $mainmenu, 'customers_bills', 0, '', '', '', img_picto('', 'bill', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/compta/facture/card.php?action=create", $langs->trans("NewBill"), 1, $user->rights->facture->creer); + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills", $langs->trans("List"), 1, $user->rights->facture->lire, '', $mainmenu, 'customers_bills_list'); + + if ($usemenuhider || empty($leftmenu) || preg_match('/customers_bills(|_draft|_notpaid|_paid|_canceled)$/', $leftmenu)) { + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_draft&search_status=0", $langs->trans("BillShortStatusDraft"), 2, $user->rights->facture->lire); + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_notpaid&search_status=1", $langs->trans("BillShortStatusNotPaid"), 2, $user->rights->facture->lire); + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_paid&search_status=2", $langs->trans("BillShortStatusPaid"), 2, $user->rights->facture->lire); + $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_canceled&search_status=3", $langs->trans("BillShortStatusCanceled"), 2, $user->rights->facture->lire); + } + $newmenu->add("/compta/facture/invoicetemplate_list.php?leftmenu=customers_bills_templates", $langs->trans("ListOfTemplates"), 1, $user->rights->facture->creer, '', $mainmenu, 'customers_bills_templates'); // No need to see recurring invoices, if user has no permission to create invoice. + + $newmenu->add("/compta/paiement/list.php?leftmenu=customers_bills_payment", $langs->trans("Payments"), 1, $user->rights->facture->lire, '', $mainmenu, 'customers_bills_payment'); + + if (!empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) { + $newmenu->add("/compta/paiement/tovalidate.php?leftmenu=customers_bills_tovalid", $langs->trans("MenuToValid"), 2, $user->rights->facture->lire, '', $mainmenu, 'customer_bills_tovalid'); + } + if ($usemenuhider || empty($leftmenu) || preg_match('/customers_bills/', $leftmenu)) { + $newmenu->add("/compta/paiement/rapport.php?leftmenu=customers_bills_payment_report", $langs->trans("Reportings"), 2, $user->rights->facture->lire, '', $mainmenu, 'customers_bills_payment_report'); + } + + $newmenu->add("/compta/facture/stats/index.php?leftmenu=customers_bills_stats", $langs->trans("Statistics"), 1, $user->rights->facture->lire, '', $mainmenu, 'customers_bills_stats'); + } + + // Suppliers invoices + if (!empty($conf->societe->enabled) && !empty($conf->supplier_invoice->enabled)) { + $langs->load("bills"); + $newmenu->add("/fourn/facture/index.php?leftmenu=suppliers_bills", $langs->trans("BillsSuppliers"), 0, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills', 0, '', '', '', img_picto('', 'supplier_invoice', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/fourn/facture/card.php?leftmenu=suppliers_bills&action=create", $langs->trans("NewBill"), 1, ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer), '', $mainmenu, 'suppliers_bills_create'); + $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills", $langs->trans("List"), 1, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_list'); + + if ($usemenuhider || empty($leftmenu) || preg_match('/suppliers_bills/', $leftmenu)) { + $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_draft&search_status=0", $langs->trans("BillShortStatusDraft"), 2, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_draft'); + $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_notpaid&search_status=1", $langs->trans("BillShortStatusNotPaid"), 2, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_notpaid'); + $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_paid&search_status=2", $langs->trans("BillShortStatusPaid"), 2, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_paid'); + } + + $newmenu->add("/fourn/facture/list-rec.php?leftmenu=supplierinvoicestemplate_list", $langs->trans("ListOfTemplates"), 1, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'supplierinvoicestemplate_list'); + + $newmenu->add("/fourn/paiement/list.php?leftmenu=suppliers_bills_payment", $langs->trans("Payments"), 1, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_payment'); + + if ($usemenuhider || empty($leftmenu) || preg_match('/suppliers_bills/', $leftmenu)) { + $newmenu->add("/fourn/facture/rapport.php?leftmenu=suppliers_bills_payment_report", $langs->trans("Reportings"), 2, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_payment_report'); + } + + $newmenu->add("/compta/facture/stats/index.php?mode=supplier&leftmenu=suppliers_bills_stats", $langs->trans("Statistics"), 1, $user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills_stats'); + } + + // Orders + if (!empty($conf->commande->enabled)) { + $langs->load("orders"); + if (!empty($conf->facture->enabled)) { + $newmenu->add("/commande/list.php?leftmenu=orders&search_status=-3&billed=0&contextpage=billableorders", $langs->trans("MenuOrdersToBill2"), 0, $user->rights->commande->lire, '', $mainmenu, 'orders', 0, '', '', '', img_picto('', 'order', 'class="paddingright pictofixedwidth"')); + } + //if ($usemenuhider || empty($leftmenu) || $leftmenu=="orders") $newmenu->add("/commande/", $langs->trans("StatusOrderToBill"), 1, $user->rights->commande->lire); + } + + // Supplier Orders to bill + if (!empty($conf->supplier_invoice->enabled)) { + if (!empty($conf->global->SUPPLIER_MENU_ORDER_RECEIVED_INTO_INVOICE)) { + $langs->load("supplier"); + $newmenu->add("/fourn/commande/list.php?leftmenu=orders&search_status=5&billed=0", $langs->trans("MenuOrdersSupplierToBill"), 0, $user->rights->commande->lire, '', $mainmenu, 'orders', 0, '', '', '', img_picto('', 'supplier_order', 'class="paddingright pictofixedwidth"')); + //if ($usemenuhider || empty($leftmenu) || $leftmenu=="orders") $newmenu->add("/commande/", $langs->trans("StatusOrderToBill"), 1, $user->rights->commande->lire); + } + } + + + // Donations + if (!empty($conf->don->enabled)) { + $langs->load("donations"); + $newmenu->add("/don/index.php?leftmenu=donations&mainmenu=billing", $langs->trans("Donations"), 0, $user->rights->don->lire, '', $mainmenu, 'donations', 0, '', '', '', img_picto('', 'donation', 'class="paddingright pictofixedwidth"')); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "donations") { + $newmenu->add("/don/card.php?leftmenu=donations&action=create", $langs->trans("NewDonation"), 1, $user->rights->don->creer); + $newmenu->add("/don/list.php?leftmenu=donations", $langs->trans("List"), 1, $user->rights->don->lire); + } + // if ($leftmenu=="donations") $newmenu->add("/don/stats/index.php",$langs->trans("Statistics"), 1, $user->rights->don->lire); + } + + // Taxes and social contributions + if (!empty($conf->tax->enabled)) { + $newmenu->add("/compta/charges/index.php?leftmenu=tax&mainmenu=billing", $langs->trans("MenuTaxesAndSpecialExpenses"), 0, $user->rights->tax->charges->lire, '', $mainmenu, 'tax', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); + + $newmenu->add("/compta/sociales/list.php?leftmenu=tax_social", $langs->trans("MenuSocialContributions"), 1, $user->rights->tax->charges->lire); + if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_social/i', $leftmenu)) { + $newmenu->add("/compta/sociales/card.php?leftmenu=tax_social&action=create", $langs->trans("MenuNewSocialContribution"), 2, $user->rights->tax->charges->creer); + $newmenu->add("/compta/sociales/list.php?leftmenu=tax_social", $langs->trans("List"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/sociales/payments.php?leftmenu=tax_social&mainmenu=billing", $langs->trans("Payments"), 2, $user->rights->tax->charges->lire); + } + // VAT + if (empty($conf->global->TAX_DISABLE_VAT_MENUS)) { + global $mysoc; + + $newmenu->add("/compta/tva/list.php?leftmenu=tax_vat&mainmenu=billing", $langs->transcountry("VAT", $mysoc->country_code), 1, $user->rights->tax->charges->lire, '', $mainmenu, 'tax_vat'); + if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_vat/i', $leftmenu)) { + $newmenu->add("/compta/tva/card.php?leftmenu=tax_vat&action=create", $langs->trans("New"), 2, $user->rights->tax->charges->creer); + $newmenu->add("/compta/tva/list.php?leftmenu=tax_vat", $langs->trans("List"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/tva/payments.php?mode=tvaonly&leftmenu=tax_vat", $langs->trans("Payments"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/tva/index.php?leftmenu=tax_vat", $langs->trans("ReportByMonth"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/tva/clients.php?leftmenu=tax_vat", $langs->trans("ReportByThirdparties"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/tva/quadri_detail.php?leftmenu=tax_vat", $langs->trans("ReportByQuarter"), 2, $user->rights->tax->charges->lire); + } + + //Local Taxes 1 + if ($mysoc->useLocalTax(1) && (isset($mysoc->localtax1_assuj) && $mysoc->localtax1_assuj == "1")) { + $newmenu->add("/compta/localtax/list.php?leftmenu=tax_1_vat&mainmenu=billing&localTaxType=1", $langs->transcountry("LT1", $mysoc->country_code), 1, $user->rights->tax->charges->lire); + if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_1_vat/i', $leftmenu)) { + $newmenu->add("/compta/localtax/card.php?leftmenu=tax_1_vat&action=create&localTaxType=1", $langs->trans("New"), 2, $user->rights->tax->charges->creer); + $newmenu->add("/compta/localtax/list.php?leftmenu=tax_1_vat&localTaxType=1", $langs->trans("List"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/localtax/index.php?leftmenu=tax_1_vat&localTaxType=1", $langs->trans("ReportByMonth"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/localtax/clients.php?leftmenu=tax_1_vat&localTaxType=1", $langs->trans("ReportByThirdparties"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/localtax/quadri_detail.php?leftmenu=tax_1_vat&localTaxType=1", $langs->trans("ReportByQuarter"), 2, $user->rights->tax->charges->lire); + } + } + //Local Taxes 2 + if ($mysoc->useLocalTax(2) && (isset($mysoc->localtax2_assuj) && $mysoc->localtax2_assuj == "1")) { + $newmenu->add("/compta/localtax/list.php?leftmenu=tax_2_vat&mainmenu=billing&localTaxType=2", $langs->transcountry("LT2", $mysoc->country_code), 1, $user->rights->tax->charges->lire); + if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_2_vat/i', $leftmenu)) { + $newmenu->add("/compta/localtax/card.php?leftmenu=tax_2_vat&action=create&localTaxType=2", $langs->trans("New"), 2, $user->rights->tax->charges->creer); + $newmenu->add("/compta/localtax/list.php?leftmenu=tax_2_vat&localTaxType=2", $langs->trans("List"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/localtax/index.php?leftmenu=tax_2_vat&localTaxType=2", $langs->trans("ReportByMonth"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/localtax/clients.php?leftmenu=tax_2_vat&localTaxType=2", $langs->trans("ReportByThirdparties"), 2, $user->rights->tax->charges->lire); + $newmenu->add("/compta/localtax/quadri_detail.php?leftmenu=tax_2_vat&localTaxType=2", $langs->trans("ReportByQuarter"), 2, $user->rights->tax->charges->lire); + } + } + } + } + + // Salaries + if (!empty($conf->salaries->enabled)) { + $langs->load("salaries"); + $newmenu->add("/salaries/list.php?leftmenu=tax_salary&mainmenu=billing", $langs->trans("Salaries"), 0, $user->rights->salaries->read, '', $mainmenu, 'tax_salary', 0, '', '', '', img_picto('', 'salary', 'class="paddingright pictofixedwidth"')); + if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_salary/i', $leftmenu)) { + $newmenu->add("/salaries/card.php?leftmenu=tax_salary&action=create", $langs->trans("New"), 1, $user->rights->salaries->write); + $newmenu->add("/salaries/list.php?leftmenu=tax_salary", $langs->trans("List"), 1, $user->rights->salaries->read); + $newmenu->add("/salaries/payments.php?leftmenu=tax_salary", $langs->trans("Payments"), 1, $user->rights->salaries->read); + $newmenu->add("/salaries/stats/index.php?leftmenu=tax_salary", $langs->trans("Statistics"), 1, $user->rights->salaries->read); + } + } + + // Loan + if (!empty($conf->loan->enabled)) { + $langs->load("loan"); + $newmenu->add("/loan/list.php?leftmenu=tax_loan&mainmenu=billing", $langs->trans("Loans"), 0, $user->rights->loan->read, '', $mainmenu, 'tax_loan', 0, '', '', '', img_picto('', 'loan', 'class="paddingright pictofixedwidth"')); + if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_loan/i', $leftmenu)) { + $newmenu->add("/loan/card.php?leftmenu=tax_loan&action=create", $langs->trans("NewLoan"), 1, $user->rights->loan->write); + //$newmenu->add("/loan/payment/list.php?leftmenu=tax_loan",$langs->trans("Payments"),2,$user->rights->loan->read); + } + } + + // Various payment + if (!empty($conf->banque->enabled) && empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)) { + $langs->load("banks"); + $newmenu->add("/compta/bank/various_payment/list.php?leftmenu=tax_various&mainmenu=billing", $langs->trans("MenuVariousPayment"), 0, $user->rights->banque->lire, '', $mainmenu, 'tax_various', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); + if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_various/i', $leftmenu)) { + $newmenu->add("/compta/bank/various_payment/card.php?leftmenu=tax_various&action=create", $langs->trans("New"), 1, $user->rights->banque->modifier); + $newmenu->add("/compta/bank/various_payment/list.php?leftmenu=tax_various", $langs->trans("List"), 1, $user->rights->banque->lire); + } + } + } +} + +/** + * Get left COMPTA-FINANCIAL (accountancy) + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + global $db; + + if ($mainmenu == 'accountancy') { + $langs->load("companies"); + + // Accounting (Double entries) + if (!empty($conf->accounting->enabled)) { + //$permtoshowmenu = (!empty($conf->accounting->enabled) || $user->rights->accounting->bind->write || $user->rights->compta->resultat->lire); + //$newmenu->add("/accountancy/index.php?leftmenu=accountancy", $langs->trans("MenuAccountancy"), 0, $permtoshowmenu, '', $mainmenu, 'accountancy'); + + // Configuration + $newmenu->add("/accountancy/index.php?leftmenu=accountancy_admin", $langs->trans("Setup"), 0, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin', 1, '', '', '', img_picto('', 'technic', 'class="paddingright pictofixedwidth"')); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/', $leftmenu)) { + global $mysoc; + $newmenu->add("/accountancy/admin/index.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("General"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_general', 10); + + // Fiscal year - Not really yet used. In a future will lock some periods. + if ($conf->global->MAIN_FEATURES_LEVEL > 1) { + $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("FiscalPeriod"), 1, $user->rights->accounting->fiscalyear->write, '', $mainmenu, 'fiscalyear', 20); + } + + $newmenu->add("/accountancy/admin/journals_list.php?id=35&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingJournals"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_journal', 30); + $newmenu->add("/accountancy/admin/accountmodel.php?id=31&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Pcg_version"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chartmodel', 40); + $newmenu->add("/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Chartofaccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 41); + $newmenu->add("/accountancy/admin/subaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("ChartOfSubaccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 41); + $newmenu->add("/accountancy/admin/categories_list.php?id=32&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingCategory"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 50); + $newmenu->add("/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDefaultAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 60); + if (!empty($conf->banque->enabled)) { + $newmenu->add("/compta/bank/list.php?mainmenu=accountancy&leftmenu=accountancy_admin&search_status=-1", $langs->trans("MenuBankAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_bank', 70); + } + if (!empty($conf->facture->enabled) || ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled))) { + $newmenu->add("/admin/dict.php?id=10&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuVatAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 80); + } + if (!empty($conf->tax->enabled)) { + $newmenu->add("/admin/dict.php?id=7&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuTaxAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 90); + } + if (!empty($conf->expensereport->enabled)) { + $newmenu->add("/admin/dict.php?id=17&from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuExpenseReportAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 100); + } + $newmenu->add("/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuProductsAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_product', 110); + if ($conf->global->MAIN_FEATURES_LEVEL > 1) { + $newmenu->add("/accountancy/admin/closure.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuClosureAccounts"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_closure', 120); + } + $newmenu->add("/accountancy/admin/export.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("ExportOptions"), 1, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_export', 130); + } + + // Transfer in accounting + $newmenu->add("/accountancy/index.php?leftmenu=accountancy_transfer", $langs->trans("TransferInAccounting"), 0, $user->rights->accounting->bind->write, '', $mainmenu, 'transfer', 1, '', '', '', img_picto('', 'long-arrow-alt-right', 'class="paddingright pictofixedwidth"')); + + // Binding + // $newmenu->add("", $langs->trans("Binding"), 0, $user->rights->accounting->bind->write, '', $mainmenu, 'dispatch'); + if (!empty($conf->facture->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_SALES)) { + $newmenu->add("/accountancy/customer/index.php?leftmenu=accountancy_dispatch_customer&mainmenu=accountancy", $langs->trans("CustomersVentilation"), 1, $user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_customer'); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_dispatch_customer/', $leftmenu)) { + $newmenu->add("/accountancy/customer/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer", $langs->trans("ToBind"), 2, $user->rights->accounting->bind->write); + $newmenu->add("/accountancy/customer/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer", $langs->trans("Binded"), 2, $user->rights->accounting->bind->write); + } + } + if (!empty($conf->supplier_invoice->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_PURCHASES)) { + $newmenu->add("/accountancy/supplier/index.php?leftmenu=accountancy_dispatch_supplier&mainmenu=accountancy", $langs->trans("SuppliersVentilation"), 1, $user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_supplier'); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_dispatch_supplier/', $leftmenu)) { + $newmenu->add("/accountancy/supplier/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_supplier", $langs->trans("ToBind"), 2, $user->rights->accounting->bind->write); + $newmenu->add("/accountancy/supplier/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_supplier", $langs->trans("Binded"), 2, $user->rights->accounting->bind->write); + } + } + if (!empty($conf->expensereport->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS)) { + $newmenu->add("/accountancy/expensereport/index.php?leftmenu=accountancy_dispatch_expensereport&mainmenu=accountancy", $langs->trans("ExpenseReportsVentilation"), 1, $user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_expensereport'); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_dispatch_expensereport/', $leftmenu)) { + $newmenu->add("/accountancy/expensereport/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_expensereport", $langs->trans("ToBind"), 2, $user->rights->accounting->bind->write); + $newmenu->add("/accountancy/expensereport/lines.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_expensereport", $langs->trans("Binded"), 2, $user->rights->accounting->bind->write); + } + } + + // Journals + if (!empty($conf->accounting->enabled) && !empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { + $newmenu->add('', $langs->trans("RegistrationInAccounting"), 1, $user->rights->accounting->comptarapport->lire, '', '', ''); + + // Multi journal + $sql = "SELECT rowid, code, label, nature"; + $sql .= " FROM ".MAIN_DB_PREFIX."accounting_journal"; + $sql .= " WHERE entity = ".$conf->entity; + $sql .= " AND active = 1"; + $sql .= " ORDER BY nature ASC, label DESC"; + + $resql = $db->query($sql); + if ($resql) { + $numr = $db->num_rows($resql); + $i = 0; + + if ($numr > 0) { + while ($i < $numr) { + $objp = $db->fetch_object($resql); + + $nature = ''; + + // Must match array $sourceList defined into journals_list.php + if ($objp->nature == 2 && !empty($conf->facture->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_SALES)) { + $nature = "sells"; + } + if ($objp->nature == 3 + && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled)) + && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_PURCHASES)) { + $nature = "purchases"; + } + if ($objp->nature == 4 && !empty($conf->banque->enabled)) { + $nature = "bank"; + } + if ($objp->nature == 5 && !empty($conf->expensereport->enabled) && empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS)) { + $nature = "expensereports"; + } + if ($objp->nature == 1 && !empty($conf->asset->enabled)) { + $nature = "various"; // Warning: The page /accountancy/journal/variousjournal.php is bugged. It read tables that does not exists. + } + if ($objp->nature == 8) { + $nature = "inventory"; + } + if ($objp->nature == 9) { + $nature = "hasnew"; + } + + // To enable when page exists + if (empty($conf->global->ACCOUNTANCY_SHOW_DEVELOP_JOURNAL)) { + if ($nature == 'hasnew' || $nature == 'inventory') { + $nature = ''; + } + } + + if ($nature) { + $langs->load('accountancy'); + $journallabel = $langs->transnoentities($objp->label); // Labels in this table are set by loading llx_accounting_abc.sql. Label can be 'ACCOUNTING_SELL_JOURNAL', 'InventoryJournal', ... + $newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal='.$objp->rowid, $journallabel, 2, $user->rights->accounting->comptarapport->lire); + } + $i++; + } + } else { + // Should not happend. Entries are added + $newmenu->add('', $langs->trans("NoJournalDefined"), 2, $user->rights->accounting->comptarapport->lire); + } + } else { + dol_print_error($db); + } + $db->free($resql); + } + + // Files + if (empty($conf->global->ACCOUNTANCY_HIDE_EXPORT_FILES_MENU)) { + $newmenu->add("/compta/accounting-files.php?mainmenu=accountancy&leftmenu=accountancy_files", $langs->trans("AccountantFiles"), 1, $user->rights->accounting->mouvements->lire); + } + + + // Accounting + $newmenu->add("/accountancy/index.php?leftmenu=accountancy_accountancy", $langs->trans("MenuAccountancy"), 0, $user->rights->accounting->mouvements->lire || $user->rights->accounting->comptarapport->lire, '', $mainmenu, 'accountancy', 1, '', '', '', img_picto('', 'accountancy', 'class="paddingright pictofixedwidth"')); + + // General Ledger + $newmenu->add("/accountancy/bookkeeping/listbyaccount.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("Bookkeeping"), 1, $user->rights->accounting->mouvements->lire); + + // Journals + $newmenu->add("/accountancy/bookkeeping/list.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("Journals"), 1, $user->rights->accounting->mouvements->lire); + + // Account Balance + $newmenu->add("/accountancy/bookkeeping/balance.php?mainmenu=accountancy&leftmenu=accountancy_accountancy", $langs->trans("AccountBalance"), 1, $user->rights->accounting->mouvements->lire); + + // Closure + $newmenu->add("/accountancy/closure/index.php?mainmenu=accountancy&leftmenu=accountancy_closure", $langs->trans("MenuAccountancyClosure"), 1, $user->rights->accounting->fiscalyear->write, '', $mainmenu, 'closure'); + + // Reports + $newmenu->add("/accountancy/index.php?leftmenu=accountancy_report", $langs->trans("Reportings"), 1, $user->rights->accounting->comptarapport->lire, '', $mainmenu, 'ca'); + + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { + $newmenu->add("/compta/resultat/index.php?leftmenu=accountancy_report", $langs->trans("MenuReportInOut"), 2, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=accountancy_report", $langs->trans("ByPredefinedAccountGroups"), 3, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/resultat/result.php?leftmenu=accountancy_report", $langs->trans("ByPersonalizedAccountGroups"), 3, $user->rights->accounting->comptarapport->lire); + } + + $modecompta = 'CREANCES-DETTES'; + if (!empty($conf->accounting->enabled) && !empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { + $modecompta = 'BOOKKEEPING'; // Not yet implemented. Should be BOOKKEEPINGCOLLECTED + } + if ($modecompta) { + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { + $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportTurnover"), 2, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 3, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 3, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 3, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/byratecountry.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByVatRate"), 3, $user->rights->accounting->comptarapport->lire); + } + } + + $modecompta = 'RECETTES-DEPENSES'; + //if (! empty($conf->accounting->enabled) && ! empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') $modecompta=''; // Not yet implemented. Should be BOOKKEEPINGCOLLECTED + if ($modecompta) { + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { + $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportTurnoverCollected"), 2, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 3, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 3, $user->rights->accounting->comptarapport->lire); + //$newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"),3,$user->rights->accounting->comptarapport->lire); + //$newmenu->add("/compta/stats/byratecountry.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByVatRate"),3,$user->rights->accounting->comptarapport->lire); + } + } + + $modecompta = 'CREANCES-DETTES'; + if (!empty($conf->accounting->enabled) && !empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { + $modecompta = 'BOOKKEEPING'; // Not yet implemented. + } + if ($modecompta && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled))) { + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { + $newmenu->add("/compta/stats/supplier_turnover.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnover"), 2, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/supplier_turnover_by_thirdparty.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 3, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/supplier_turnover_by_prodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 3, $user->rights->accounting->comptarapport->lire); + } + } + + $modecompta = 'RECETTES-DEPENSES'; + if (!empty($conf->accounting->enabled) && !empty($user->rights->accounting->comptarapport->lire) && $mainmenu == 'accountancy') { + $modecompta = 'BOOKKEEPINGCOLLECTED'; // Not yet implemented. + } + if ($modecompta && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled))) { + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_report/', $leftmenu)) { + $newmenu->add("/compta/stats/supplier_turnover.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnoverCollected"), 2, $user->rights->accounting->comptarapport->lire); + $newmenu->add("/compta/stats/supplier_turnover_by_thirdparty.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 3, $user->rights->accounting->comptarapport->lire); + } + } + } + + // Accountancy (simple) + if (!empty($conf->comptabilite->enabled)) { + // Files + if (empty($conf->global->ACCOUNTANCY_HIDE_EXPORT_FILES_MENU)) { + $newmenu->add("/compta/accounting-files.php?mainmenu=accountancy&leftmenu=accountancy_files", $langs->trans("AccountantFiles"), 0, $user->rights->compta->resultat->lire, '', $mainmenu, 'files'); + } + + // Bilan, resultats + $newmenu->add("/compta/resultat/index.php?leftmenu=report&mainmenu=accountancy", $langs->trans("Reportings"), 0, $user->rights->compta->resultat->lire, '', $mainmenu, 'ca'); + + if ($usemenuhider || empty($leftmenu) || preg_match('/report/', $leftmenu)) { + $newmenu->add("/compta/resultat/index.php?leftmenu=report", $langs->trans("MenuReportInOut"), 1, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/resultat/clientfourn.php?leftmenu=report", $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); + /* On verra ca avec module compabilite expert + $newmenu->add("/compta/resultat/compteres.php?leftmenu=report","Compte de resultat",2,$user->rights->compta->resultat->lire); + $newmenu->add("/compta/resultat/bilan.php?leftmenu=report","Bilan",2,$user->rights->compta->resultat->lire); + */ + + /* + $newmenu->add("/compta/stats/cumul.php?leftmenu=report","Cumule",2,$user->rights->compta->resultat->lire); + if (! empty($conf->propal->enabled)) { + $newmenu->add("/compta/stats/prev.php?leftmenu=report","Previsionnel",2,$user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/comp.php?leftmenu=report","Transforme",2,$user->rights->compta->resultat->lire); + } + */ + + $modecompta = 'CREANCES-DETTES'; + $newmenu->add("/compta/stats/index.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ReportTurnover"), 1, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/casoc.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/cabyuser.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 2, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/byratecountry.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ByVatRate"), 2, $user->rights->compta->resultat->lire); + + $modecompta = 'RECETTES-DEPENSES'; + $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportTurnoverCollected"), 1, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire); + + //Achats + $modecompta = 'CREANCES-DETTES'; + $newmenu->add("/compta/stats/supplier_turnover.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnover"), 1, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/supplier_turnover_by_thirdparty.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/supplier_turnover_by_prodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 2, $user->rights->compta->resultat->lire); + + /* + $modecompta = 'RECETTES-DEPENSES'; + $newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnoverCollected"), 1, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire); + $newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire); + */ + + // Journals + $newmenu->add("/compta/journal/sellsjournal.php?leftmenu=report", $langs->trans("SellsJournal"), 1, $user->rights->compta->resultat->lire, '', '', '', 50); + $newmenu->add("/compta/journal/purchasesjournal.php?leftmenu=report", $langs->trans("PurchasesJournal"), 1, $user->rights->compta->resultat->lire, '', '', '', 51); + } + //if ($leftmenu=="ca") $newmenu->add("/compta/journaux/index.php?leftmenu=ca",$langs->trans("Journals"),1,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); + } + + // Intracomm report + if (!empty($conf->intracommreport->enabled)) { + $newmenu->add("/intracommreport/list.php?leftmenu=intracommreport", $langs->trans("MenuIntracommReport"), 0, $user->rights->intracommreport->read, '', $mainmenu, 'intracommreport', 60, '', '', '', img_picto('', 'intracommreport', 'class="paddingright pictofixedwidth"')); + if ($usemenuhider || empty($leftmenu) || preg_match('/intracommreport/', $leftmenu)) { + // DEB / DES + $newmenu->add("/intracommreport/card.php?action=create&leftmenu=intracommreport", $langs->trans("MenuIntracommReportNew"), 1, $user->rights->intracommreport->write, '', $mainmenu, 'intracommreport', 1); + $newmenu->add("/intracommreport/list.php?leftmenu=intracommreport", $langs->trans("MenuIntracommReportList"), 1, $user->rights->intracommreport->read, '', $mainmenu, 'intracommreport', 1); + } + } + + // Assets + if (!empty($conf->asset->enabled)) { + $newmenu->add("/asset/list.php?leftmenu=asset&mainmenu=accountancy", $langs->trans("MenuAssets"), 0, $user->rights->asset->read, '', $mainmenu, 'asset', 100, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/asset/card.php?leftmenu=asset&action=create", $langs->trans("MenuNewAsset"), 1, $user->rights->asset->write); + $newmenu->add("/asset/list.php?leftmenu=asset&mainmenu=accountancy", $langs->trans("MenuListAssets"), 1, $user->rights->asset->read); + $newmenu->add("/asset/model/list.php?leftmenu=asset_model", $langs->trans("MenuAssetModels"), 1, (empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->read)), '', $mainmenu, 'asset_model'); + if ($usemenuhider || empty($leftmenu) || preg_match('/asset_model/', $leftmenu)) { + $newmenu->add("/asset/model/card.php?leftmenu=asset_model&action=create", $langs->trans("MenuNewAssetModel"), 2, (empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->write))); + $newmenu->add("/asset/model/list.php?leftmenu=asset_model", $langs->trans("MenuListAssetModels"), 2, (empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->setup_advance->read))); + } + } + } +} + +/** + * Get left Menu BANK + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_bank($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'bank') { + // Load translation files required by the page + $langs->loadLangs(array("withdrawals", "banks", "bills", "categories")); + + // Bank-Cash account + if (!empty($conf->banque->enabled)) { + $newmenu->add("/compta/bank/list.php?leftmenu=bank&mainmenu=bank", $langs->trans("MenuBankCash"), 0, $user->rights->banque->lire, '', $mainmenu, 'bank', 0, '', '', '', img_picto('', 'bank_account', 'class="paddingright pictofixedwidth"')); + + $newmenu->add("/compta/bank/card.php?action=create", $langs->trans("MenuNewFinancialAccount"), 1, $user->rights->banque->configurer); + $newmenu->add("/compta/bank/list.php?leftmenu=bank&mainmenu=bank", $langs->trans("List"), 1, $user->rights->banque->lire, '', $mainmenu, 'bank'); + $newmenu->add("/compta/bank/bankentries_list.php", $langs->trans("ListTransactions"), 1, $user->rights->banque->lire); + $newmenu->add("/compta/bank/budget.php", $langs->trans("ListTransactionsByCategory"), 1, $user->rights->banque->lire); + + $newmenu->add("/compta/bank/transfer.php", $langs->trans("MenuBankInternalTransfer"), 1, $user->rights->banque->transfer); + } + + if (!empty($conf->categorie->enabled)) { + $langs->load("categories"); + $newmenu->add("/categories/index.php?type=5", $langs->trans("Rubriques"), 1, $user->rights->categorie->creer, '', $mainmenu, 'tags'); + $newmenu->add("/compta/bank/categ.php", $langs->trans("RubriquesTransactions"), 1, $user->rights->banque->configurer, '', $mainmenu, 'tags'); + } + + // Direct debit order + if (!empty($conf->prelevement->enabled)) { + $newmenu->add("/compta/prelevement/index.php?leftmenu=withdraw&mainmenu=bank", $langs->trans("PaymentByDirectDebit"), 0, $user->rights->prelevement->bons->lire, '', $mainmenu, 'withdraw', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); + + if ($usemenuhider || empty($leftmenu) || $leftmenu == "withdraw") { + $newmenu->add("/compta/prelevement/create.php?mainmenu=bank", $langs->trans("NewStandingOrder"), 1, $user->rights->prelevement->bons->creer); + + $newmenu->add("/compta/prelevement/orders_list.php?mainmenu=bank", $langs->trans("WithdrawalsReceipts"), 1, $user->rights->prelevement->bons->lire); + $newmenu->add("/compta/prelevement/list.php?mainmenu=bank", $langs->trans("WithdrawalsLines"), 1, $user->rights->prelevement->bons->lire); + $newmenu->add("/compta/prelevement/rejets.php?mainmenu=bank", $langs->trans("Rejects"), 1, $user->rights->prelevement->bons->lire); + $newmenu->add("/compta/prelevement/stats.php?mainmenu=bank", $langs->trans("Statistics"), 1, $user->rights->prelevement->bons->lire); + } + } + + // Bank transfer order + if (!empty($conf->paymentbybanktransfer->enabled)) { + $newmenu->add("/compta/paymentbybanktransfer/index.php?leftmenu=banktransfer&mainmenu=bank", $langs->trans("PaymentByBankTransfer"), 0, $user->rights->paymentbybanktransfer->read, '', $mainmenu, 'banktransfer', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); + + if ($usemenuhider || empty($leftmenu) || $leftmenu == "banktransfer") { + $newmenu->add("/compta/prelevement/create.php?type=bank-transfer&mainmenu=bank", $langs->trans("NewPaymentByBankTransfer"), 1, $user->rights->paymentbybanktransfer->create); + + $newmenu->add("/compta/prelevement/orders_list.php?type=bank-transfer&mainmenu=bank", $langs->trans("PaymentByBankTransferReceipts"), 1, $user->rights->paymentbybanktransfer->read); + $newmenu->add("/compta/prelevement/list.php?type=bank-transfer&mainmenu=bank", $langs->trans("PaymentByBankTransferLines"), 1, $user->rights->paymentbybanktransfer->read); + $newmenu->add("/compta/prelevement/rejets.php?type=bank-transfer&mainmenu=bank", $langs->trans("Rejects"), 1, $user->rights->paymentbybanktransfer->read); + $newmenu->add("/compta/prelevement/stats.php?type=bank-transfer&mainmenu=bank", $langs->trans("Statistics"), 1, $user->rights->paymentbybanktransfer->read); + } + } + + // Management of checks + if (empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT) && !empty($conf->banque->enabled) && (!empty($conf->facture->enabled) || !empty($conf->global->MAIN_MENU_CHEQUE_DEPOSIT_ON))) { + $newmenu->add("/compta/paiement/cheque/index.php?leftmenu=checks&mainmenu=bank", $langs->trans("MenuChequeDeposits"), 0, $user->rights->banque->cheque, '', $mainmenu, 'checks', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); + if (preg_match('/checks/', $leftmenu)) { + $newmenu->add("/compta/paiement/cheque/card.php?leftmenu=checks_bis&action=new&mainmenu=bank", $langs->trans("NewChequeDeposit"), 1, $user->rights->banque->cheque); + $newmenu->add("/compta/paiement/cheque/list.php?leftmenu=checks_bis&mainmenu=bank", $langs->trans("List"), 1, $user->rights->banque->cheque); + } + } + + // Cash Control + if (!empty($conf->takepos->enabled) || !empty($conf->cashdesk->enabled)) { + $permtomakecashfence = ($user->hasRight('cashdesk', 'run')|| $user->hasRight('takepos', 'run')); + $newmenu->add("/compta/cashcontrol/cashcontrol_list.php?action=list", $langs->trans("POS"), 0, $permtomakecashfence, '', $mainmenu, 'cashcontrol', 0, '', '', '', img_picto('', 'pos', 'class="pictofixedwidth"')); + $newmenu->add("/compta/cashcontrol/cashcontrol_card.php?action=create", $langs->trans("NewCashFence"), 1, $permtomakecashfence); + $newmenu->add("/compta/cashcontrol/cashcontrol_list.php?action=list", $langs->trans("List"), 1, $permtomakecashfence); + } + } +} + +/** + * Get left Menu PRODUCTS-SERVICES + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_products($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'products') { + // Products + if (!empty($conf->product->enabled)) { + $newmenu->add("/product/index.php?leftmenu=product&type=0", $langs->trans("Products"), 0, $user->rights->produit->lire, '', $mainmenu, 'product', 0, '', '', '', img_picto('', 'product', 'class="pictofixedwidth"')); + $newmenu->add("/product/card.php?leftmenu=product&action=create&type=0", $langs->trans("NewProduct"), 1, $user->rights->produit->creer); + $newmenu->add("/product/list.php?leftmenu=product&type=0", $langs->trans("List"), 1, $user->rights->produit->lire); + if (!empty($conf->stock->enabled)) { + $newmenu->add("/product/reassort.php?type=0", $langs->trans("MenuStocks"), 1, $user->rights->produit->lire && $user->rights->stock->lire); + } + if (!empty($conf->productbatch->enabled)) { + $langs->load("stocks"); + $newmenu->add("/product/reassortlot.php?type=0", $langs->trans("StocksByLotSerial"), 1, $user->rights->produit->lire && $user->rights->stock->lire); + $newmenu->add("/product/stock/productlot_list.php", $langs->trans("LotSerial"), 1, $user->rights->produit->lire && $user->rights->stock->lire); + } + if (!empty($conf->variants->enabled)) { + $newmenu->add("/variants/list.php", $langs->trans("VariantAttributes"), 1, $user->rights->produit->lire); + } + if (!empty($conf->propal->enabled) || (!empty($conf->commande->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->facture->enabled) || !empty($conf->fournisseur->enabled) || !empty($conf->supplier_proposal->enabled) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) { + $newmenu->add("/product/stats/card.php?id=all&leftmenu=stats&type=0", $langs->trans("Statistics"), 1, $user->rights->produit->lire && $user->rights->propale->lire); + } + + // Categories + if (!empty($conf->categorie->enabled)) { + $langs->load("categories"); + $newmenu->add("/categories/index.php?leftmenu=cat&type=0", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); + //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire); + } + } + + // Services + if (!empty($conf->service->enabled)) { + $newmenu->add("/product/index.php?leftmenu=service&type=1", $langs->trans("Services"), 0, $user->rights->service->lire, '', $mainmenu, 'service', 0, '', '', '', img_picto('', 'service', 'class="pictofixedwidth"')); + $newmenu->add("/product/card.php?leftmenu=service&action=create&type=1", $langs->trans("NewService"), 1, $user->rights->service->creer); + $newmenu->add("/product/list.php?leftmenu=service&type=1", $langs->trans("List"), 1, $user->rights->service->lire); + if (!empty($conf->propal->enabled) || !empty($conf->commande->enabled) || !empty($conf->facture->enabled) || (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_proposal->enabled) || !empty($conf->supplier_oder->enabled) || !empty($conf->supplier_invoice->enabled)) { + $newmenu->add("/product/stats/card.php?id=all&leftmenu=stats&type=1", $langs->trans("Statistics"), 1, $user->rights->service->lire || $user->rights->product->lire); + } + // Categories + if (!empty($conf->categorie->enabled)) { + $langs->load("categories"); + $newmenu->add("/categories/index.php?leftmenu=cat&type=0", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); + //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire); + } + } + + // Warehouse + if (!empty($conf->stock->enabled)) { + $langs->load("stocks"); + $newmenu->add("/product/stock/index.php?leftmenu=stock", $langs->trans("Warehouses"), 0, $user->rights->stock->lire, '', $mainmenu, 'stock', 0, '', '', '', img_picto('', 'stock', 'class="pictofixedwidth"')); + $newmenu->add("/product/stock/card.php?action=create", $langs->trans("MenuNewWarehouse"), 1, $user->rights->stock->creer); + $newmenu->add("/product/stock/list.php", $langs->trans("List"), 1, $user->rights->stock->lire); + $newmenu->add("/product/stock/movement_list.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire); + + $newmenu->add("/product/stock/massstockmove.php", $langs->trans("MassStockTransferShort"), 1, $user->rights->stock->mouvement->creer); + if ($conf->supplier_order->enabled) { + $newmenu->add("/product/stock/replenish.php", $langs->trans("Replenishment"), 1, $user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire); + } + $newmenu->add("/product/stock/stockatdate.php", $langs->trans("StockAtDate"), 1, $user->rights->produit->lire && $user->rights->stock->lire); + + // Categories for warehouses + if (!empty($conf->categorie->enabled)) { + $newmenu->add("/categories/index.php?leftmenu=stock&type=9", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); + } + } + + // Inventory + if (!empty($conf->stock->enabled)) { + $langs->load("stocks"); + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { + $newmenu->add("/product/inventory/list.php?leftmenu=stock_inventories", $langs->trans("Inventories"), 0, $user->rights->stock->lire, '', $mainmenu, 'stock', 0, '', '', '', img_picto('', 'inventory', 'class="pictofixedwidth"')); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "stock_inventories") { + $newmenu->add("/product/inventory/card.php?action=create&leftmenu=stock_inventories", $langs->trans("NewInventory"), 1, $user->rights->stock->creer); + $newmenu->add("/product/inventory/list.php?leftmenu=stock_inventories", $langs->trans("List"), 1, $user->rights->stock->lire); + } + } else { + $newmenu->add("/product/inventory/list.php?leftmenu=stock_inventories", $langs->trans("Inventories"), 0, $user->rights->stock->inventory_advance->read, '', $mainmenu, 'stock', 0, '', '', '', img_picto('', 'inventory', 'class="pictofixedwidth"')); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "stock_inventories") { + $newmenu->add("/product/inventory/card.php?action=create&leftmenu=stock_inventories", $langs->trans("NewInventory"), 1, $user->rights->stock->inventory_advance->write); + $newmenu->add("/product/inventory/list.php?leftmenu=stock_inventories", $langs->trans("List"), 1, $user->rights->stock->inventory_advance->read); + } + } + } + + // Shipments + if (!empty($conf->expedition->enabled)) { + $langs->load("sendings"); + $newmenu->add("/expedition/index.php?leftmenu=sendings", $langs->trans("Shipments"), 0, $user->rights->expedition->lire, '', $mainmenu, 'sendings', 0, '', '', '', img_picto('', 'shipment', 'class="pictofixedwidth"')); + $newmenu->add("/expedition/card.php?action=create2&leftmenu=sendings", $langs->trans("NewSending"), 1, $user->rights->expedition->creer); + $newmenu->add("/expedition/list.php?leftmenu=sendings", $langs->trans("List"), 1, $user->rights->expedition->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "sendings") { + $newmenu->add("/expedition/list.php?leftmenu=sendings&search_status=0", $langs->trans("StatusSendingDraftShort"), 2, $user->rights->expedition->lire); + $newmenu->add("/expedition/list.php?leftmenu=sendings&search_status=1", $langs->trans("StatusSendingValidatedShort"), 2, $user->rights->expedition->lire); + $newmenu->add("/expedition/list.php?leftmenu=sendings&search_status=2", $langs->trans("StatusSendingProcessedShort"), 2, $user->rights->expedition->lire); + } + $newmenu->add("/expedition/stats/index.php?leftmenu=sendings", $langs->trans("Statistics"), 1, $user->rights->expedition->lire); + } + + // Receptions + if (!empty($conf->reception->enabled)) { + $langs->load("receptions"); + $newmenu->add("/reception/index.php?leftmenu=receptions", $langs->trans("Receptions"), 0, $user->rights->reception->lire, '', $mainmenu, 'receptions', 0, '', '', '', img_picto('', 'dollyrevert', 'class="pictofixedwidth"')); + $newmenu->add("/reception/card.php?action=create2&leftmenu=receptions", $langs->trans("NewReception"), 1, $user->rights->reception->creer); + $newmenu->add("/reception/list.php?leftmenu=receptions", $langs->trans("List"), 1, $user->rights->reception->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "receptions") { + $newmenu->add("/reception/list.php?leftmenu=receptions&search_status=0", $langs->trans("StatusReceptionDraftShort"), 2, $user->rights->reception->lire); + } + if ($usemenuhider || empty($leftmenu) || $leftmenu == "receptions") { + $newmenu->add("/reception/list.php?leftmenu=receptions&search_status=1", $langs->trans("StatusReceptionValidatedShort"), 2, $user->rights->reception->lire); + } + if ($usemenuhider || empty($leftmenu) || $leftmenu == "receptions") { + $newmenu->add("/reception/list.php?leftmenu=receptions&search_status=2", $langs->trans("StatusReceptionProcessedShort"), 2, $user->rights->reception->lire); + } + $newmenu->add("/reception/stats/index.php?leftmenu=receptions", $langs->trans("Statistics"), 1, $user->rights->reception->lire); + } + } +} + +/** + * Get left Menu PRODUCTS-SERVICES MRP - GPAO + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_mrp($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'mrp') { + // BOM + if (!empty($conf->bom->enabled) || !empty($conf->mrp->enabled)) { + $langs->load("mrp"); + + $newmenu->add("", $langs->trans("MenuBOM"), 0, $user->rights->bom->read, '', $mainmenu, 'bom', 0, '', '', '', img_picto('', 'bom', 'class="paddingrightonly pictofixedwidth"')); + $newmenu->add("/bom/bom_card.php?leftmenu=bom&action=create", $langs->trans("NewBOM"), 1, $user->rights->bom->write, '', $mainmenu, 'bom'); + $newmenu->add("/bom/bom_list.php?leftmenu=bom", $langs->trans("List"), 1, $user->rights->bom->read, '', $mainmenu, 'bom'); + } + + if (!empty($conf->mrp->enabled)) { + $langs->load("mrp"); + + $newmenu->add("", $langs->trans("MenuMRP"), 0, $user->rights->mrp->read, '', $mainmenu, 'mo', 0, '', '', '', img_picto('', 'mrp', 'class="paddingrightonly pictofixedwidth"')); + $newmenu->add("/mrp/mo_card.php?leftmenu=mo&action=create", $langs->trans("NewMO"), 1, $user->rights->mrp->write, '', $mainmenu, 'mo'); + $newmenu->add("/mrp/mo_list.php?leftmenu=mo", $langs->trans("List"), 1, $user->rights->mrp->read, '', $mainmenu, 'mo'); + } + } +} + +/** + * Get left Menu PROJECTS + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_projects($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'project') { + if (!empty($conf->projet->enabled)) { + $langs->load("projects"); + + $search_project_user = GETPOST('search_project_user', 'int'); + + $tmpentry = array( + 'enabled'=>(!empty($conf->projet->enabled)), + 'perms'=>(!empty($user->rights->projet->lire)), + 'module'=>'projet' + ); + $listofmodulesforexternal = explode(',', $conf->global->MAIN_MODULES_FOR_EXTERNAL); + $showmode = isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); + + $titleboth = $langs->trans("LeadsOrProjects"); + $titlenew = $langs->trans("NewLeadOrProject"); // Leads and opportunities by default + if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { + $titleboth = $langs->trans("Projects"); + $titlenew = $langs->trans("NewProject"); + } + if (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only + $titleboth = $langs->trans("Leads"); + $titlenew = $langs->trans("NewLead"); + } + + // Project assigned to user + $newmenu->add("/projet/index.php?leftmenu=projects".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titleboth, 0, $user->rights->projet->lire, '', $mainmenu, 'projects', 0, '', '', '', img_picto('', 'project', 'class="pictofixedwidth"')); + $newmenu->add("/projet/card.php?leftmenu=projects&action=create".($search_project_user ? '&search_project_user='.$search_project_user : ''), $titlenew, 1, $user->rights->projet->creer); + + if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { + $newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user ? '&search_project_user='.$search_project_user : '').'&search_status=99', $langs->trans("List"), 1, $showmode, '', 'project', 'list'); + } elseif (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 1) { + $newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $showmode, '', 'project', 'list'); + $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_usage_opportunity=1&search_status=99&search_opp_status=openedopp&contextpage=lead', $langs->trans("ListOpenLeads"), 2, $showmode); + $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_opp_status=notopenedopp&search_status=99&contextpage=project', $langs->trans("ListOpenProjects"), 2, $showmode); + } elseif (isset($conf->global->PROJECT_USE_OPPORTUNITIES) && $conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only + $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_usage_opportunity=1&search_status=99', $langs->trans("List"), 2, $showmode); + } + + $newmenu->add("/projet/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); + + // Categories + if (!empty($conf->categorie->enabled)) { + $langs->load("categories"); + $newmenu->add("/categories/index.php?leftmenu=cat&type=6", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); + } + + if (empty($conf->global->PROJECT_HIDE_TASKS)) { + // Project affected to user + $newmenu->add("/projet/activity/index.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("Activities"), 0, $user->rights->projet->lire, '', 'project', 'tasks', 0, '', '', '', img_picto('', 'projecttask', 'class="pictofixedwidth"')); + $newmenu->add("/projet/tasks.php?leftmenu=tasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); + $newmenu->add("/projet/tasks/list.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $user->rights->projet->lire); + $newmenu->add("/projet/tasks/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); + + $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', 'project', 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="pictofixedwidth"')); + } + } + } +} + +/** + * Get left Menu HRM + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'hrm') { + // HRM module + if (!empty($conf->hrm->enabled)) { + $langs->load("hrm"); + + $newmenu->add("/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee", $langs->trans("Employees"), 0, $user->rights->user->user->lire, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); + $newmenu->add("/user/card.php?mainmenu=hrm&leftmenu=hrm&action=create&employee=1", $langs->trans("NewEmployee"), 1, $user->rights->user->user->creer); + $newmenu->add("/user/list.php?mainmenu=hrm&leftmenu=hrm&mode=employee&contextpage=employeelist", $langs->trans("List"), 1, $user->rights->user->user->lire); + + $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("SkillsManagement"), 0, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); + + // Skills + $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("Skills"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'shapes', 'class="pictofixedwidth"')); + //$newmenu->add("/hrm/skill_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->trans("NewSkill"), 1, $user->rights->hrm->all->write); + //$newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); + + // Job (Description of work to do and skills required) + $newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("JobsPosition"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'technic', 'class="pictofixedwidth"')); + //$newmenu->add("/hrm/job_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->transnoentities("NewObject", $langs->trans("Job")), 1, $user->rights->hrm->all->write); + //$newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); + + // Position = Link job - user + $newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("EmployeePositions"), 1, $user->rights->hrm->all->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user-cog', 'class="pictofixedwidth"')); + //$newmenu->add("/hrm/position.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->transnoentities("NewObject", $langs->trans("Position")), 1, $user->rights->hrm->all->write); + //$newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->all->read); + + // Evaluation + $newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("Evals"), 1, $user->rights->hrm->evaluation->read, '', $mainmenu, 'hrm_sm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); + //$newmenu->add("/hrm/evaluation_card.php?mainmenu=hrm&leftmenu=hrm_sm&action=create", $langs->trans("NewEval"), 1, $user->rights->hrm->evaluation->write); + //$newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("List"), 1, $user->rights->hrm->evaluation->read); + $newmenu->add("/hrm/compare.php?mainmenu=hrm&leftmenu=hrm_sm", $langs->trans("SkillComparison"), 1, $user->rights->hrm->evaluation->read || $user->rights->hrm->compare_advance->read); + } + + // Leave/Holiday/Vacation module + if (!empty($conf->holiday->enabled)) { + // Load translation files required by the page + $langs->loadLangs(array("holiday", "trips")); + + $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("CPTitreMenu"), 0, $user->rights->holiday->read, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'holiday', 'class="pictofixedwidth"')); + $newmenu->add("/holiday/card.php?mainmenu=hrm&leftmenu=holiday&action=create", $langs->trans("New"), 1, $user->rights->holiday->write); + $newmenu->add("/holiday/list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("List"), 1, $user->rights->holiday->read); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "hrm") { + $newmenu->add("/holiday/list.php?search_status=1&mainmenu=hrm&leftmenu=hrm", $langs->trans("DraftCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=2&mainmenu=hrm&leftmenu=hrm", $langs->trans("ToReviewCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=3&mainmenu=hrm&leftmenu=hrm", $langs->trans("ApprovedCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=4&mainmenu=hrm&leftmenu=hrm", $langs->trans("CancelCP"), 2, $user->rights->holiday->read); + $newmenu->add("/holiday/list.php?search_status=5&mainmenu=hrm&leftmenu=hrm", $langs->trans("RefuseCP"), 2, $user->rights->holiday->read); + } + $newmenu->add("/holiday/define_holiday.php?mainmenu=hrm&action=request", $langs->trans("MenuConfCP"), 1, $user->rights->holiday->read); + $newmenu->add("/holiday/month_report.php?mainmenu=hrm&leftmenu=holiday", $langs->trans("MenuReportMonth"), 1, $user->rights->holiday->readall); + $newmenu->add("/holiday/view_log.php?mainmenu=hrm&leftmenu=holiday&action=request", $langs->trans("MenuLogCP"), 1, $user->rights->holiday->define_holiday); + } + + // Trips and expenses (old module) + if (!empty($conf->deplacement->enabled)) { + $langs->load("trips"); + $newmenu->add("/compta/deplacement/index.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->deplacement->lire, '', $mainmenu, 'tripsandexpenses', 0, '', '', '', img_picto('', 'trip', 'class="pictofixedwidth"')); + $newmenu->add("/compta/deplacement/card.php?action=create&leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("New"), 1, $user->rights->deplacement->creer); + $newmenu->add("/compta/deplacement/list.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("List"), 1, $user->rights->deplacement->lire); + $newmenu->add("/compta/deplacement/stats/index.php?leftmenu=tripsandexpenses&mainmenu=hrm", $langs->trans("Statistics"), 1, $user->rights->deplacement->lire); + } + + // Expense report + if (!empty($conf->expensereport->enabled)) { + $langs->load("trips"); + $newmenu->add("/expensereport/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->expensereport->lire, '', $mainmenu, 'expensereport', 0, '', '', '', img_picto('', 'trip', 'class="pictofixedwidth"')); + $newmenu->add("/expensereport/card.php?action=create&leftmenu=expensereport&mainmenu=hrm", $langs->trans("New"), 1, $user->rights->expensereport->creer); + $newmenu->add("/expensereport/list.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("List"), 1, $user->rights->expensereport->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu == "expensereport") { + $newmenu->add("/expensereport/list.php?search_status=0&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Draft"), 2, $user->rights->expensereport->lire); + $newmenu->add("/expensereport/list.php?search_status=2&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Validated"), 2, $user->rights->expensereport->lire); + $newmenu->add("/expensereport/list.php?search_status=5&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Approved"), 2, $user->rights->expensereport->lire); + $newmenu->add("/expensereport/list.php?search_status=6&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Paid"), 2, $user->rights->expensereport->lire); + $newmenu->add("/expensereport/list.php?search_status=4&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Canceled"), 2, $user->rights->expensereport->lire); + $newmenu->add("/expensereport/list.php?search_status=99&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Refused"), 2, $user->rights->expensereport->lire); + } + $newmenu->add("/expensereport/stats/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("Statistics"), 1, $user->rights->expensereport->lire); + } + + if (!empty($conf->projet->enabled)) { + if (empty($conf->global->PROJECT_HIDE_TASKS)) { + $langs->load("projects"); + + $search_project_user = GETPOST('search_project_user', 'int'); + + $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', $mainmenu, 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="pictofixedwidth"')); + } + } + } +} + +/** + * Get left Menu TOOLS + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_tools($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'tools') { + if (empty($user->socid)) { // limit to internal users + $langs->load("mails"); + $newmenu->add("/admin/mails_templates.php?leftmenu=email_templates", $langs->trans("EMailTemplates"), 0, 1, '', $mainmenu, 'email_templates', 0, '', '', '', img_picto('', 'email', 'class="paddingright pictofixedwidth"')); + } + + if (!empty($conf->mailing->enabled)) { + $newmenu->add("/comm/mailing/index.php?leftmenu=mailing", $langs->trans("EMailings"), 0, $user->rights->mailing->lire, '', $mainmenu, 'mailing', 0, '', '', '', img_picto('', 'email', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/comm/mailing/card.php?leftmenu=mailing&action=create", $langs->trans("NewMailing"), 1, $user->rights->mailing->creer); + $newmenu->add("/comm/mailing/list.php?leftmenu=mailing", $langs->trans("List"), 1, $user->rights->mailing->lire); + } + + if (!empty($conf->export->enabled)) { + $langs->load("exports"); + $newmenu->add("/exports/index.php?leftmenu=export", $langs->trans("FormatedExport"), 0, $user->rights->export->lire, '', $mainmenu, 'export', 0, '', '', '', img_picto('', 'technic', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/exports/export.php?leftmenu=export", $langs->trans("NewExport"), 1, $user->rights->export->creer); + //$newmenu->add("/exports/export.php?leftmenu=export",$langs->trans("List"),1, $user->rights->export->lire); + } + + if (!empty($conf->import->enabled)) { + $langs->load("exports"); + $newmenu->add("/imports/index.php?leftmenu=import", $langs->trans("FormatedImport"), 0, $user->rights->import->run, '', $mainmenu, 'import', 0, '', '', '', img_picto('', 'technic', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/imports/import.php?leftmenu=import", $langs->trans("NewImport"), 1, $user->rights->import->run); + } + } +} + +/** + * Get left Menu MEMBERS + * + * @param string $mainmenu Main menu + * @param Menu $newmenu Object Menu to return back list of menu entries + * @param string $usemenuhider Use menu hider + * @param string $leftmenu Left menu + * @param int $type_user Type of targeted user for menu + * @return void + */ +function get_left_menu_members($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0) +{ + global $user, $conf, $langs; + + if ($mainmenu == 'members') { + if (!empty($conf->adherent->enabled)) { + // Load translation files required by the page + $langs->loadLangs(array("members", "compta")); + + $newmenu->add("/adherents/index.php?leftmenu=members&mainmenu=members", $langs->trans("Members"), 0, $user->rights->adherent->lire, '', $mainmenu, 'members', 0, '', '', '', img_picto('', 'member', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/adherents/card.php?leftmenu=members&action=create", $langs->trans("NewMember"), 1, $user->rights->adherent->creer); + $newmenu->add("/adherents/list.php?leftmenu=members", $langs->trans("List"), 1, $user->rights->adherent->lire); + $newmenu->add("/adherents/list.php?leftmenu=members&statut=-1", $langs->trans("MenuMembersToValidate"), 2, $user->rights->adherent->lire); + $newmenu->add("/adherents/list.php?leftmenu=members&statut=1", $langs->trans("MenuMembersValidated"), 2, $user->rights->adherent->lire); + $newmenu->add("/adherents/list.php?leftmenu=members&statut=1&filter=withoutsubscription", $langs->trans("WithoutSubscription"), 3, $user->rights->adherent->lire); + $newmenu->add("/adherents/list.php?leftmenu=members&statut=1&filter=uptodate", $langs->trans("UpToDate"), 3, $user->rights->adherent->lire); + $newmenu->add("/adherents/list.php?leftmenu=members&statut=1&filter=outofdate", $langs->trans("OutOfDate"), 3, $user->rights->adherent->lire); + $newmenu->add("/adherents/list.php?leftmenu=members&statut=0", $langs->trans("MenuMembersResiliated"), 2, $user->rights->adherent->lire); + $newmenu->add("/adherents/stats/index.php?leftmenu=members", $langs->trans("MenuMembersStats"), 1, $user->rights->adherent->lire); + + $newmenu->add("/adherents/cartes/carte.php?leftmenu=export", $langs->trans("MembersCards"), 1, $user->rights->adherent->export); + if (!empty($conf->global->MEMBER_LINK_TO_HTPASSWDFILE) && ($usemenuhider || empty($leftmenu) || $leftmenu == 'none' || $leftmenu == "members" || $leftmenu == "export")) { + $newmenu->add("/adherents/htpasswd.php?leftmenu=export", $langs->trans("Filehtpasswd"), 1, $user->rights->adherent->export); + } + + if (!empty($conf->categorie->enabled)) { + $langs->load("categories"); + $newmenu->add("/categories/index.php?leftmenu=cat&type=3", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat'); + } + + $newmenu->add("/adherents/index.php?leftmenu=members&mainmenu=members", $langs->trans("Subscriptions"), 0, $user->rights->adherent->cotisation->lire, '', $mainmenu, 'members', 0, '', '', '', img_picto('', 'payment', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/adherents/list.php?leftmenu=members&statut=-1,1&mainmenu=members", $langs->trans("NewSubscription"), 1, $user->rights->adherent->cotisation->creer); + $newmenu->add("/adherents/subscription/list.php?leftmenu=members", $langs->trans("List"), 1, $user->rights->adherent->cotisation->lire); + $newmenu->add("/adherents/stats/index.php?leftmenu=members", $langs->trans("MenuMembersStats"), 1, $user->rights->adherent->lire); + + //$newmenu->add("/adherents/index.php?leftmenu=export&mainmenu=members",$langs->trans("Tools"),0,$user->rights->adherent->export, '', $mainmenu, 'export'); + //if (! empty($conf->export->enabled) && ($usemenuhider || empty($leftmenu) || $leftmenu=="export")) $newmenu->add("/exports/index.php?leftmenu=export",$langs->trans("Datas"),1,$user->rights->adherent->export); + + // Type + $newmenu->add("/adherents/type.php?leftmenu=setup&mainmenu=members", $langs->trans("MembersTypes"), 0, $user->rights->adherent->configurer, '', $mainmenu, 'setup', 0, '', '', '', img_picto('', 'members', 'class="paddingright pictofixedwidth"')); + $newmenu->add("/adherents/type.php?leftmenu=setup&mainmenu=members&action=create", $langs->trans("New"), 1, $user->rights->adherent->configurer); + $newmenu->add("/adherents/type.php?leftmenu=setup&mainmenu=members", $langs->trans("List"), 1, $user->rights->adherent->configurer); + } + } +} diff --git a/htdocs/core/modules/action/rapport.pdf.php b/htdocs/core/modules/action/rapport.pdf.php index 8b80492685d..1ee7ff94998 100644 --- a/htdocs/core/modules/action/rapport.pdf.php +++ b/htdocs/core/modules/action/rapport.pdf.php @@ -261,7 +261,7 @@ class CommActionRapport if (!preg_match('/^'.preg_quote($obj->label, '/').'/', $obj->note)) { $text = $obj->label."\n"; } - $text .= dolGetFirstLineOfText(dol_string_nohtmltag($obj->note), 2); + $text .= dolGetFirstLineOfText(dol_string_nohtmltag($obj->note), 1); // Add status to text $text .= "\n"; $status = $outputlangs->trans("Status").': '.dol_htmlentitiesbr_decode($eventstatic->getLibStatut(1, 1)); diff --git a/htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php b/htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php new file mode 100644 index 00000000000..7fe684c9da1 --- /dev/null +++ b/htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php @@ -0,0 +1,499 @@ + + * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2014 Marcos García + * Copyright (C) 2016 Charlie Benke + * Copyright (C) 2018-2021 Philippe Grand + * Copyright (C) 2018 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/asset/doc/doc_generic_asset_odt.modules.php + * \ingroup asset + * \brief File of class to build ODT documents for assets + */ + +dol_include_once('/asset/core/modules/asset/modules_asset.php'); +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_asset_odt extends ModelePDFAsset +{ + /** + * Issuer + * @var Societe + */ + public $emetteur; + + /** + * @var array Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.6 = array(5, 6) + */ + public $phpmin = array(5, 6); + + /** + * @var string Dolibarr version of the loaded document + */ + public $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf, $langs, $mysoc; + + // Load translation files required by the page + $langs->loadLangs(array("main", "companies")); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'ASSET_ASSET_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Page size for A4 format + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur, $this->page_hauteur); + $this->marge_gauche = 0; + $this->marge_droite = 0; + $this->marge_haute = 0; + $this->marge_basse = 0; + + $this->option_logo = 1; // Display logo + $this->option_tva = 0; // Manage the vat option FACTURE_TVAOPTION + $this->option_modereg = 0; // Display payment mode + $this->option_condreg = 0; // Display payment terms + $this->option_codeproduitservice = 0; // Display product-service code + $this->option_multilang = 1; // Available in several languages + $this->option_escompte = 0; // Displays if there has been a discount + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Get source company + $this->emetteur = $mysoc; + if (!$this->emetteur->country_code) { + $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined + } + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + public function info($langs) + { + global $conf, $langs; + + // Load translation files required by the page + $langs->loadLangs(array("errors", "companies")); + + $form = new Form($this->db); + + $texte = $this->description.".
    \n"; + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= '
    '; print ''.img_edit().''; // id= is included into $param if ($permissiontodelete) { - print '   '.img_delete().''; // id= is included into $param + print '   '.img_delete().''; // id= is included into $param } else { print ' '; } @@ -2144,7 +2144,7 @@ class FormFile * @param array $file Array with data of file. Example: array('name'=>...) * @param string $modulepart propal, facture, facture_fourn, ... * @param string $relativepath Relative path of docs - * @param integer $ruleforpicto Rule for picto: 0=Use the generic preview picto, 1=Use the picto of mime type of file) + * @param integer $ruleforpicto Rule for picto: 0=Use the generic preview picto, 1=Use the picto of mime type of file). Use a negative value to show a generic picto even if preview not available. * @param string $param More param on http links * @return string $out Output string with HTML */ @@ -2160,11 +2160,15 @@ class FormFile //$out.= ''; if (empty($ruleforpicto)) { //$out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail'); - $out .= ''; + $out .= ''; } else { - $out .= img_mime($relativepath, $langs->trans('Preview').' '.$file['name']); + $out .= img_mime($relativepath, $langs->trans('Preview').' '.$file['name'], 'pictofixedwidth'); } $out .= ''; + } else { + if ($ruleforpicto < 0) { + $out .= img_picto('', 'generic', '', false, 0, 0, '', 'paddingright pictofixedwidth'); + } } } return $out; diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 752f57dfdf9..0c9a1b2531a 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -1250,7 +1250,7 @@ class FormMail extends Form * Return templates of email with type = $type_template or type = 'all'. * This search into table c_email_templates. Used by the get_form function. * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param string $type_template Get message for model/type=$type_template, type='all' also included. * @param User $user Get template public or limited to this user * @param Translate $outputlangs Output lang object @@ -1259,7 +1259,7 @@ class FormMail extends Form * @param string $label Label of template * @return ModelMail|integer One instance of ModelMail or -1 if error */ - public function getEMailTemplate($db, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '') + public function getEMailTemplate($dbs, $type_template, $user, $outputlangs, $id = 0, $active = 1, $label = '') { global $conf, $langs; @@ -1279,18 +1279,18 @@ class FormMail extends Form } $sql = "SELECT rowid, module, label, type_template, topic, joinfiles, content, content_lines, lang"; - $sql .= " FROM ".$db->prefix().'c_email_templates'; - $sql .= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')"; + $sql .= " FROM ".$dbs->prefix().'c_email_templates'; + $sql .= " WHERE (type_template='".$dbs->escape($type_template)."' OR type_template='all')"; $sql .= " AND entity IN (".getEntity('c_email_templates').")"; $sql .= " AND (private = 0 OR fk_user = ".((int) $user->id).")"; // Get all public or private owned if ($active >= 0) { $sql .= " AND active = ".((int) $active); } if ($label) { - $sql .= " AND label = '".$db->escape($label)."'"; + $sql .= " AND label = '".$dbs->escape($label)."'"; } if (!($id > 0) && $languagetosearch) { - $sql .= " AND (lang = '".$db->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$db->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')"; + $sql .= " AND (lang = '".$dbs->escape($languagetosearch)."'".($languagetosearchmain ? " OR lang = '".$dbs->escape($languagetosearchmain)."'" : "")." OR lang IS NULL OR lang = '')"; } if ($id > 0) { $sql .= " AND rowid=".(int) $id; @@ -1299,22 +1299,22 @@ class FormMail extends Form $sql .= " AND position=0"; } if ($languagetosearch) { - $sql .= $db->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or '' + $sql .= $dbs->order("position,lang,label", "ASC,DESC,ASC"); // We want line with lang set first, then with lang null or '' } else { - $sql .= $db->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined + $sql .= $dbs->order("position,lang,label", "ASC,ASC,ASC"); // If no language provided, we give priority to lang not defined } - //$sql .= $db->plimit(1); + //$sql .= $dbs->plimit(1); //print $sql; - $resql = $db->query($sql); + $resql = $dbs->query($sql); if (!$resql) { - dol_print_error($db); + dol_print_error($dbs); return -1; } // Get first found while (1) { - $obj = $db->fetch_object($resql); + $obj = $dbs->fetch_object($resql); if ($obj) { // If template is for a module, check module is enabled; if not, take next template @@ -1386,7 +1386,8 @@ class FormMail extends Form } } - $db->free($resql); + $dbs->free($resql); + return $ret; } diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 0c55a1fd853..23881c0c9eb 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -88,7 +88,7 @@ class FormOther $stringaddbarcode = str_replace("tmphtml", $htmltoreplaceby, $stringaddbarcode); $out .= $stringaddbarcode.'
    '; $out .= '
    '; - $out .= ''; + $out .= ''; /*print '
    '.$langs->trans("or").'
    '; @@ -110,7 +110,7 @@ class FormOther $out .= 'jQuery("#scantoolmessage").text("");'; $out .= '});'."\n"; $out .= '$("#exec'.dol_escape_js($jstoexecuteonadd).'").click(function(){ - console.log("We call js to execute '.dol_escape_js($jstoexecuteonadd).'"); + console.log("We call js to execute \''.dol_escape_js($jstoexecuteonadd).'\'"); '.dol_escape_js($jstoexecuteonadd).'(); return false; /* We want to stay on the scan tool */ })'; @@ -473,15 +473,6 @@ class FormOther $langs->load('users'); $out = ''; - // Enhance with select2 - if ($conf->use_javascript_ajax) { - include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; - - $comboenhancement = ajax_combobox($htmlname); - if ($comboenhancement) { - $out .= $comboenhancement; - } - } $reshook = $hookmanager->executeHooks('addSQLWhereFilterOnSelectSalesRep', array(), $this, $action); @@ -622,6 +613,16 @@ class FormOther $out .= ''; + // Enhance with select2 + if ($conf->use_javascript_ajax) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + + $comboenhancement = ajax_combobox($htmlname); + if ($comboenhancement) { + $out .= $comboenhancement; + } + } + return $out; } diff --git a/htdocs/core/class/menu.class.php b/htdocs/core/class/menu.class.php index e88ec701320..eab31288cca 100644 --- a/htdocs/core/class/menu.class.php +++ b/htdocs/core/class/menu.class.php @@ -119,7 +119,7 @@ class Menu { $nb = 0; foreach ($this->liste as $val) { - //if (dol_eval($val['enabled'], 1)) $nb++; + //if (dol_eval($val['enabled'], 1, 1, '1')) $nb++; if (!empty($val['enabled'])) { $nb++; // $val['enabled'] is already evaluated to 0 or 1, no need for dol_eval() } diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 853de6d0a41..452d066886e 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -4,6 +4,7 @@ * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2018 Philippe Grand * Copyright (C) 2021 Thibault FOUCART + * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -355,17 +356,26 @@ class Notify global $dolibarr_main_url_root; global $action; - if (!in_array($notifcode, Notify::$arrayofnotifsupported)) { - return 0; - } - - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } $hookmanager->initHooks(array('notification')); + $parameters = array('notifcode' => $notifcode); + $reshook = $hookmanager->executeHooks('notifsupported', $parameters, $object, $action); + if (empty($reshook)) { + if (!empty($hookmanager->resArray['arrayofnotifsupported'])) { + Notify::$arrayofnotifsupported = array_merge(Notify::$arrayofnotifsupported, $hookmanager->resArray['arrayofnotifsupported']); + } + } + + if (!in_array($notifcode, Notify::$arrayofnotifsupported)) { + return 0; + } + + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + dol_syslog(get_class($this)."::send notifcode=".$notifcode.", object=".$object->id); $langs->load("other"); @@ -577,6 +587,13 @@ class Notify $labeltouse = $conf->global->ACTION_CREATE_TEMPLATE; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextActionAdded", $link); break; + default: + $object_type = $object->element; + $dir_output = $conf->$object_type->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, $object_type); + $template = $notifcode.'_TEMPLATE'; + $labeltouse = $conf->global->$template; + $mesg = $outputlangs->transnoentitiesnoconv('Notify_'.$notifcode).' '.$newref.' '.$dir_output; + break; } include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; @@ -608,7 +625,7 @@ class Notify $mimefilename_list[] = $ref.".pdf"; } - $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list); + $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list, 'outputlangs'=>$outputlangs, 'labeltouse'=>$labeltouse); if (!isset($action)) { $action = ''; } @@ -812,6 +829,11 @@ class Notify $object_type = 'action'; $mesg = $langs->transnoentitiesnoconv("EMailTextActionAdded", $link); break; + default: + $object_type = $object->element; + $dir_output = $conf->$object_type->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, $object_type); + $mesg = $langs->transnoentitiesnoconv('Notify_'.$notifcode).' '.$newref; + break; } $ref = dol_sanitizeFileName($newref); $pdf_path = $dir_output."/".$ref."/".$ref.".pdf"; diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index 8be6f77251c..27f3ca1c836 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -656,7 +656,7 @@ class Translate return $str; } else { // Translation is not available - //if ($key[0] == '$') { return dol_eval($key,1); } + //if ($key[0] == '$') { return dol_eval($key, 1, 1, '1'); } return $this->getTradFromKey($key); } } @@ -722,7 +722,7 @@ class Translate return $str; } else { if ($key[0] == '$') { - return dol_eval($key, 1); + return dol_eval($key, 1, 1, '1'); } return $this->getTradFromKey($key); } diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 2fa329406fb..f3d46e09f30 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2021 Regis Houssin + * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -188,7 +189,7 @@ class Utils * @param int $usedefault 1=Use default backup profile (Set this to 1 when used as cron) * @param string $file 'auto' or filename to build * @param int $keeplastnfiles Keep only last n files (not used yet) - * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method + * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec' - need size of dump in memory, but low memory method is used if GETPOST('lowmemorydump') is set, 2=Use the 'popen' method (low memory method) * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ public function dumpDatabase($compression = 'none', $type = 'auto', $usedefault = 1, $file = 'auto', $keeplastnfiles = 0, $execmethod = 0) @@ -277,8 +278,8 @@ class Utils if (!empty($dolibarr_main_db_port)) { $param .= " -P ".$dolibarr_main_db_port; } - if (!GETPOST("use_transaction", "alpha")) { - $param .= " -l --single-transaction"; + if (GETPOST("use_transaction", "alpha")) { + $param .= " --single-transaction"; } if (GETPOST("disable_fk", "alpha") || $usedefault) { $param .= " -K"; @@ -341,17 +342,42 @@ class Utils $handle = ''; + $lowmemorydump = GETPOSTISSET("lowmemorydump", "alpha") ? GETPOST("lowmemorydump") : getDolGlobalString('MAIN_LOW_MEMORY_DUMP'); + // Start call method to execute dump $fullcommandcrypted = $command." ".$paramcrypted." 2>&1"; $fullcommandclear = $command." ".$paramclear." 2>&1"; - if ($compression == 'none') { - $handle = fopen($outputfile, 'w'); - } elseif ($compression == 'gz') { - $handle = gzopen($outputfile, 'w'); - } elseif ($compression == 'bz') { - $handle = bzopen($outputfile, 'w'); - } elseif ($compression == 'zstd') { - $handle = fopen($outputfile, 'w'); + if (!$lowmemorydump) { + if ($compression == 'none') { + $handle = fopen($outputfile, 'w'); + } elseif ($compression == 'gz') { + $handle = gzopen($outputfile, 'w'); + } elseif ($compression == 'bz') { + $handle = bzopen($outputfile, 'w'); + } elseif ($compression == 'zstd') { + $handle = fopen($outputfile, 'w'); + } + } else { + if ($compression == 'none') { + $fullcommandclear .= " > ".$outputfile; + $fullcommandcrypted .= " > ".$outputfile; + $handle = 1; + } elseif ($compression == 'gz') { + $fullcommandclear .= " | gzip > ".$outputfile; + $fullcommandcrypted .= " | gzip > ".$outputfile; + $paramcrypted.=" | gzip"; + $handle = 1; + } elseif ($compression == 'bz') { + $fullcommandclear .= " | bzip2 > ".$outputfile; + $fullcommandcrypted .= " | bzip2 > ".$outputfile; + $paramcrypted.=" | bzip2"; + $handle = 1; + } elseif ($compression == 'zstd') { + $fullcommandclear .= " | zstd > ".$outputfile; + $fullcommandcrypted .= " | zstd > ".$outputfile; + $paramcrypted.=" | zstd"; + $handle = 1; + } } $ok = 0; @@ -373,7 +399,8 @@ class Utils } - // TODO Replace with executeCLI function + // TODO Replace with executeCLI function but + // we must first introduce a low memory mode if ($execmethod == 1) { $output_arr = array(); $retval = null; @@ -393,16 +420,23 @@ class Utils if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) { continue; } - fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); - if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) { - $ok = 1; - } elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) { - $ok = 1; + if (!$lowmemorydump) { + fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); + if (preg_match('/'.preg_quote('-- Dump completed', '/').'/i', $read)) { + $ok = 1; + } elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES', '/').'/i', $read)) { + $ok = 1; + } + } else { + // If we have a result here in lowmemorydump mode, something is strange } } + } elseif ($lowmemorydump) { + $ok = 1; } } } + if ($execmethod == 2) { // With this method, there is no way to get the return code, only output $handlein = popen($fullcommandclear, 'r'); $i = 0; @@ -617,12 +651,13 @@ class Utils * Warning: The command line is sanitize so can't contains any redirection char '>'. Use param $redirectionfile if you need it. * @param string $outputfile A path for an output file (used only when method is 2). For example: $conf->admin->dir_temp.'/out.tmp'; * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method - * @param string $redirectionfile If defined, a redirection of output to this files is added. + * @param string $redirectionfile If defined, a redirection of output to this file is added. * @param int $noescapecommand 1=Do not escape command. Warning: Using this parameter need you alreay sanitized the command. if not, it will lead to security vulnerability. * This parameter is provided for backward compatibility with external modules. Always use 0 in core. + * @param string $redirectionfileerr If defined, a redirection of error is added to this file instead of to channel 1. * @return array array('result'=>...,'output'=>...,'error'=>...). result = 0 means OK. */ - public function executeCLI($command, $outputfile, $execmethod = 0, $redirectionfile = null, $noescapecommand = 0) + public function executeCLI($command, $outputfile, $execmethod = 0, $redirectionfile = null, $noescapecommand = 0, $redirectionfileerr = null) { global $conf, $langs; @@ -633,10 +668,17 @@ class Utils if (empty($noescapecommand)) { $command = escapeshellcmd($command); } + if ($redirectionfile) { $command .= " > ".dol_sanitizePathName($redirectionfile); } - $command .= " 2>&1"; + + if ($redirectionfileerr && ($redirectionfileerr != $redirectionfile)) { + // If we ask a redirect of stderr on a given file not already used for stdout + $command .= " 2> ".dol_sanitizePathName($redirectionfileerr); + } else { + $command .= " 2>&1"; + } if (!empty($conf->global->MAIN_EXEC_USE_POPEN)) { $execmethod = $conf->global->MAIN_EXEC_USE_POPEN; @@ -645,7 +687,7 @@ class Utils $execmethod = 1; } //$execmethod=1; - dol_syslog("Utils::executeCLI execmethod=".$execmethod." system:".$command, LOG_DEBUG); + dol_syslog("Utils::executeCLI execmethod=".$execmethod." command=".$command, LOG_DEBUG); $output_arr = array(); if ($execmethod == 1) { @@ -847,8 +889,13 @@ class Utils $resarray = $utils->executeCLI($command, $outfile); if ($resarray['result'] != '0') { $this->error = $resarray['error'].' '.$resarray['output']; + $this->errors[] = $this->error; } $result = ($resarray['result'] == 0) ? 1 : 0; + if ($result < 0 && empty($this->errors)) { + $this->error = $langs->trans("ErrorFailToGenerateFile", $FILENAMEDOC); + $this->errors[] = $this->error; + } // Build PDF doc $command = $conf->global->MODULEBUILDER_ASCIIDOCTORPDF.' '.$destfile.' -n -o '.$dirofmoduledoc.'/'.$FILENAMEDOCPDF; @@ -856,8 +903,13 @@ class Utils $resarray = $utils->executeCLI($command, $outfile); if ($resarray['result'] != '0') { $this->error = $resarray['error'].' '.$resarray['output']; + $this->errors[] = $this->error; } $result = ($resarray['result'] == 0) ? 1 : 0; + if ($result < 0 && empty($this->errors)) { + $this->error = $langs->trans("ErrorFailToGenerateFile", $FILENAMEDOCPDF); + $this->errors[] = $this->error; + } chdir($currentdir); } else { @@ -868,8 +920,6 @@ class Utils return 1; } else { $error++; - $langs->load("errors"); - $this->error = $langs->trans("ErrorFailToGenerateFile", $outputfiledoc); } } else { $error++; @@ -1176,4 +1226,112 @@ class Utils return 1; } + + /** + * Make a send last backup of database or fil in param + * CAN BE A CRON TASK + * + * @param string $sendto Recipients emails + * @param string $from Sender email + * @param string $subject Topic/Subject of mail + * @param string $message Message + * @param string $filename List of files to attach (full path of filename on file system) + * @param string $filter Filter file send + * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) + */ + public function sendBackup($sendto = '', $from = '', $subject = '', $message = '', $filename = '', $filter = '') + { + global $conf, $langs; + + $filepath = ''; + $output = ''; + $error = 0; + + if (!empty($from)) { + $from = dol_escape_htmltag($from); + } elseif (!empty($conf->global->MAIN_INFO_SOCIETE_MAIL)) { + $from = dol_escape_htmltag($conf->global->MAIN_INFO_SOCIETE_MAIL); + } else { + $error++; + } + + if (!empty($sendto)) { + $sendto = dol_escape_htmltag($sendto); + } elseif (!empty($conf->global->MAIN_INFO_SOCIETE_MAIL)) { + $from = dol_escape_htmltag($conf->global->MAIN_INFO_SOCIETE_MAIL); + } else { + $error++; + } + + if (!empty($subject)) { + $subject = dol_escape_htmltag($subject); + } else { + $subject = dol_escape_htmltag($langs->trans('MakeSendLocalDatabaseDumpShort')); + } + + if (empty($message)) { + $message = dol_escape_htmltag($langs->trans('MakeSendLocalDatabaseDumpShort')); + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + if ($filename) { + if (dol_is_file($conf->admin->dir_output.'/backup/'.$filename)) { + $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup', $filename); + } + } else { + $tmpfiles = dol_most_recent_file($conf->admin->dir_output.'/backup', $filter); + } + if ($tmpfiles) { + foreach ($tmpfiles as $key => $val) { + if ($key == 'fullname') { + $filepath = array($val); + $filesize = dol_filesize($val); + } + if ($key == 'type') { + $mimetype = array($val); + } + if ($key == 'relativename') { + $filename = array($val); + } + } + } + + if ($filepath) { + if ($filesize > 100000000) { + $output = 'Sorry, last backup file is too large to be send by email'; + $error++; + } + } else { + $output = 'No backup file found'; + $error++; + } + + if (!$error) { + include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1); + if ($mailfile->error) { + $error++; + $output = $mailfile->error; + } + } + + if (!$error) { + $result = $mailfile->sendfile(); + if ($result <= 0) { + $error++; + $output = $mailfile->error; + } + } + + dol_syslog(__METHOD__, LOG_DEBUG); + + $this->error = $error; + $this->output = $output; + + if ($result == true) { + return 0; + } else { + return $result; + } + } } diff --git a/htdocs/core/commonfieldsinimport.inc.php b/htdocs/core/commonfieldsinimport.inc.php new file mode 100644 index 00000000000..60716b8b109 --- /dev/null +++ b/htdocs/core/commonfieldsinimport.inc.php @@ -0,0 +1,63 @@ +db); + + // Add common fields + foreach ($tmpobject->fields as $keyfield => $valuefield) { + $fieldname = $keyforalias.'.'.$keyfield; + $fieldlabel = ucfirst($valuefield['label']); + $typeFilter = "Text"; + $typefield = preg_replace('/\(.*$/', '', $valuefield['type']); // double(24,8) -> double + switch ($typefield) { + case 'int': + case 'integer': + case 'double': + case 'price': + $typeFilter = "Numeric"; + break; + case 'date': + case 'datetime': + case 'timestamp': + $typeFilter = "Date"; + break; + case 'boolean': + $typeFilter = "Boolean"; + break; + /* + * case 'sellist': + * $tmp=''; + * $tmpparam=jsonOrUnserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + * if ($tmpparam['options'] && is_array($tmpparam['options'])) { + * $tmpkeys=array_keys($tmpparam['options']); + * $tmp=array_shift($tmpkeys); + * } + * if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; + * break; + */ + } + $helpfield = ''; + if (!empty($valuefield['help'])) { + $helpfield = preg_replace('/\(.*$/', '', $valuefield['help']); + } + if ($valuefield['enabled']) { + $this->import_fields_array[$r][$fieldname] = $fieldlabel; + $this->import_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->import_entities_array[$r][$fieldname] = $keyforelement; + $this->import_help_array[$r][$fieldname] = $helpfield; + } + } +} else { + dol_print_error($this->db, 'Failed to find class '.$keyforclass.', even after the include of '.$keyforclassfile); +} +// End add common fields diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index fd1b8069264..2d00677b20a 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -212,6 +212,29 @@ if (!defined('USE_CUSTOM_REPORT_AS_INCLUDE')) { print dol_get_fiche_head($head, 'customreports', $title, -1, $picto); } +$newarrayoftype = array(); +foreach ($arrayoftype as $key => $val) { + if (dol_eval($val['enabled'], 1, 1, '1')) { + $newarrayoftype[$key] = $arrayoftype[$key]; + } + if ($val['langs']) { + $langs->load($val['langs']); + } +} + +$count = 0; +$arrayofmesures = fillArrayOfMeasures($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofmesures, 0, $count); +$arrayofmesures = dol_sort_array($arrayofmesures, 'position', 'asc', 0, 0, 1); + +$count = 0; +$arrayofxaxis = fillArrayOfXAxis($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofxaxis, 0, $count); +$arrayofxaxis = dol_sort_array($arrayofxaxis, 'position', 'asc', 0, 0, 1); + +$count = 0; +$arrayofgroupby = fillArrayOfGroupBy($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofgroupby, 0, $count); +$arrayofgroupby = dol_sort_array($arrayofgroupby, 'position', 'asc', 0, 0, 1); + + // Check parameters if ($action == 'viewgraph') { if (!count($search_measures)) { @@ -253,10 +276,18 @@ if (is_array($search_groupby) && count($search_groupby)) { } $sql = "SELECT DISTINCT ".$fieldtocount." as val"; + if (strpos($fieldtocount, 'te.') === 0) { - $sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.'_extrafields as te'; + $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element."_extrafields as te"; } else { - $sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t'; + $tabletouse = $object->table_element; + $tablealiastouse = 't'; + if (!empty($arrayofgroupby[$gval])) { + $tmpval = explode('.', $gval); + $tabletouse = $arrayofgroupby[$gval]['table']; + $tablealiastouse = $tmpval[0]; + } + $sql .= " FROM ".MAIN_DB_PREFIX.$tabletouse." as ".$tablealiastouse; } // Add the where here @@ -272,7 +303,7 @@ if (is_array($search_groupby) && count($search_groupby)) { } }*/ - $sql .= ' LIMIT '.($MAXUNIQUEVALFORGROUP + 1); + $sql .= " LIMIT ".((int) ($MAXUNIQUEVALFORGROUP + 1)); //print $sql; $resql = $db->query($sql); @@ -319,8 +350,17 @@ if (is_array($search_groupby) && count($search_groupby)) { $arrayofvaluesforgroupby['g_'.$gkey][$keytouse] = $valuetranslated; } + // Add also the possible NULL value if field is a parent field that is not a strict join + $tmpfield = explode('.', $gval); + if ($tmpfield[0] != 't' || (is_array($object->fields[$tmpfield[1]]) && empty($object->fields[$tmpfield[1]]['notnull']))) { + dol_syslog("The group by field ".$gval." may be null (because field is null or it is a left join), so we add __NULL__ entry in list of possible values"); + //var_dump($gval); var_dump($object->fields); + $arrayofvaluesforgroupby['g_'.$gkey]['__NULL__'] = $langs->transnoentitiesnoconv("NotDefined"); + } + asort($arrayofvaluesforgroupby['g_'.$gkey]); + // Add a protection/error to refuse the request if number of differentr values for the group by is higher than $MAXUNIQUEVALFORGROUP if (count($arrayofvaluesforgroupby['g_'.$gkey]) > $MAXUNIQUEVALFORGROUP) { $langs->load("errors"); if (strpos($fieldtocount, 'te.') === 0) { @@ -380,15 +420,6 @@ print '
    '; // Select object print '
    '; print '
    '.$langs->trans("StatisticsOn").'
    '; -$newarrayoftype = array(); -foreach ($arrayoftype as $key => $val) { - if (dol_eval($val['enabled'], 1)) { - $newarrayoftype[$key] = $arrayoftype[$key]; - } - if ($val['langs']) { - $langs->load($val['langs']); - } -} print $form->selectarray('objecttype', $newarrayoftype, $objecttype, 0, 0, 0, '', 1, 0, 0, '', 'minwidth200', 1); if (empty($conf->use_javascript_ajax)) { print ''; @@ -412,17 +443,18 @@ print '
    '; // Add measures into array $count = 0; -$arrayofmesures = fillArrayOfMeasures($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofmesures, 0, $count); //var_dump($arrayofmesures); print '
    '; print '
    '; -print $form->multiselectarray('search_measures', $arrayofmesures, $search_measures, 0, 0, 'minwidth400', 1, 0, '', '', $langs->trans("Measures")); // Fill the array $arrayofmeasures with possible fields +$simplearrayofmesures = array(); +foreach ($arrayofmesures as $key => $val) { + $simplearrayofmesures[$key] = $arrayofmesures[$key]['label']; +} +print $form->multiselectarray('search_measures', $simplearrayofmesures, $search_measures, 0, 0, 'minwidth400', 1, 0, '', '', $langs->trans("Measures")); // Fill the array $arrayofmeasures with possible fields print '
    '; // XAxis $count = 0; -$arrayofxaxis = fillArrayOfXAxis($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofxaxis, 0, $count); -$arrayofxaxis = dol_sort_array($arrayofxaxis, 'position', 'asc', 0, 0, 1); print '
    '; print '
    '; //var_dump($arrayofxaxis); @@ -431,8 +463,6 @@ print '
    '; // Group by $count = 0; -$arrayofgroupby = fillArrayOfGroupBy($object, 't', $langs->trans($newarrayoftype[$objecttype]['label']), $arrayofgroupby, 0, $count); -$arrayofgroupby = dol_sort_array($arrayofgroupby, 'position', 'asc', 0, 0, 1); print '
    '; print '
    '; print $formother->selectGroupByField($object, $search_groupby, $arrayofgroupby, 'minwidth200 maxwidth250', $langs->trans("GroupBy")); // Fill the array $arrayofgroupby with possible fields @@ -443,7 +473,7 @@ if ($mode == 'grid') { // YAxis print '
    '; foreach ($object->fields as $key => $val) { - if (empty($val['measure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1))) { + if (empty($val['measure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1, 1, '1'))) { if (in_array($key, array('id', 'rowid', 'entity', 'last_main_doc', 'extraparams'))) { continue; } @@ -454,18 +484,38 @@ if ($mode == 'grid') { continue; } if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) { - $arrayofyaxis['t.'.$key.'-year'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.')', 'position' => $val['position']); - $arrayofyaxis['t.'.$key.'-month'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => $val['position']); - $arrayofyaxis['t.'.$key.'-day'] = array('label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => $val['position']); + $arrayofyaxis['t.'.$key.'-year'] = array( + 'label' => $langs->trans($val['label']).' ('.$YYYY.')', + 'position' => $val['position'], + 'table' => $object->table_element + ); + $arrayofyaxis['t.'.$key.'-month'] = array( + 'label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', + 'position' => $val['position'], + 'table' => $object->table_element + ); + $arrayofyaxis['t.'.$key.'-day'] = array( + 'label' => $langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', + 'position' => $val['position'], + 'table' => $object->table_element + ); } else { - $arrayofyaxis['t.'.$key] = array('label' => $val['label'], 'position' => (int) $val['position']); + $arrayofyaxis['t.'.$key] = array( + 'label' => $val['label'], + 'position' => (int) $val['position'], + 'table' => $object->table_element + ); } } // Add measure from extrafields if ($object->isextrafieldmanaged) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1))) { - $arrayofyaxis['te.'.$key] = array('label' => $extrafields->attributes[$object->table_element]['label'][$key], 'position' => (int) $extrafields->attributes[$object->table_element]['pos'][$key]); + if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'))) { + $arrayofyaxis['te.'.$key] = array( + 'label' => $extrafields->attributes[$object->table_element]['label'][$key], + 'position' => (int) $extrafields->attributes[$object->table_element]['pos'][$key], + 'table' => $object->table_element + ); } } } @@ -495,7 +545,7 @@ $sql = ''; if (!empty($search_measures) && !empty($search_xaxis)) { $fieldid = 'rowid'; - $sql = 'SELECT '; + $sql = "SELECT "; foreach ($search_xaxis as $key => $val) { if (preg_match('/\-year$/', $val)) { $tmpval = preg_replace('/\-year$/', '', $val); @@ -542,23 +592,72 @@ if (!empty($search_measures) && !empty($search_xaxis)) { } } $sql = preg_replace('/,\s*$/', '', $sql); - $sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t'; + $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; // Add measure from extrafields if ($object->isextrafieldmanaged) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as te ON te.fk_object = t.".$fieldid; } - if ($object->ismultientitymanaged) { + // Add table for link for multientity + if ($object->ismultientitymanaged) { // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table if ($object->ismultientitymanaged == 1) { - // Nothing here + // No table to add here } else { $tmparray = explode('@', $object->ismultientitymanaged); - $sql .= " INNER JOIN ".MAIN_DB_PREFIX.$tmparray[1]." as parenttable ON t.".$tmparray[0]." = parenttable.rowid"; - $sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')'; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX.$tmparray[1]." as parenttableforentity ON t.".$tmparray[0]." = parenttableforentity.rowid"; + $sql .= " AND parenttableforentity.entity IN (".getEntity($tmparray[1]).")"; } } - $sql .= ' WHERE 1 = 1'; - if ($object->ismultientitymanaged == 1) { - $sql .= ' AND entity IN ('.getEntity($object->element).')'; + + $listoftablesalreadyadded = array($object->table_element => $object->table_element); + + // Add LEFT JOIN for all parent tables mentionned into the Xaxis + //var_dump($arrayofxaxis); var_dump($search_xaxis); + foreach ($search_xaxis as $key => $val) { + if (!empty($arrayofxaxis[$val])) { + $tmpval = explode('.', $val); + //var_dump($arrayofxaxis[$val]['table']); + if (! in_array($arrayofxaxis[$val]['table'], $listoftablesalreadyadded)) { // We do not add join for main table already added + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$arrayofxaxis[$val]['table']." as ".$db->sanitize($tmpval[0])." ON t.".str_replace('t__', '', $db->sanitize($tmpval[0]))." = ".$db->sanitize($tmpval[0]).".rowid"; + $listoftablesalreadyadded[$arrayofxaxis[$val]['table']] = $arrayofxaxis[$val]['table']; + } + } else { + dol_print_error($db, 'Found a key into search_xaxis not found into arrayofxaxis'); + } + } + + // Add LEFT JOIN for all parent tables mentionned into the Group by + //var_dump($arrayofgroupby); var_dump($search_groupby); + foreach ($search_groupby as $key => $val) { + if (!empty($arrayofgroupby[$val])) { + $tmpval = explode('.', $val); + //var_dump($arrayofxaxis[$val]['table']); + if (! in_array($arrayofgroupby[$val]['table'], $listoftablesalreadyadded)) { // We do not add join for main table already added + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$arrayofgroupby[$val]['table']." as ".$tmpval[0]." ON t.".str_replace('t__', '', $tmpval[0])." = ".$tmpval[0].".rowid"; + $listoftablesalreadyadded[$arrayofgroupby[$val]['table']] = $arrayofgroupby[$val]['table']; + } + } else { + dol_print_error($db, 'Found a key into search_groupby not found into arrayofgroupby'); + } + } + + // Add LEFT JOIN for all parent tables mentionned into the Yaxis + //var_dump($arrayofgroupby); var_dump($search_groupby); + foreach ($search_measures as $key => $val) { + if (!empty($arrayofmesures[$val])) { + $tmpval = explode('.', $val); + //var_dump($arrayofxaxis[$val]['table']); + if (! in_array($arrayofmesures[$val]['table'], $listoftablesalreadyadded)) { // We do not add join for main table already added + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$arrayofmesures[$val]['table']." as ".$tmpval[0]." ON t.".str_replace('t__', '', $tmpval[0])." = ".$tmpval[0].".rowid"; + $listoftablesalreadyadded[$arrayofmesures[$val]['table']] = $arrayofmesures[$val]['table']; + } + } else { + dol_print_error($db, 'Found a key into search_measures not found into arrayofmesures'); + } + } + + $sql .= " WHERE 1 = 1"; + if ($object->ismultientitymanaged == 1) { // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table + $sql .= " AND t.entity IN (".getEntity($object->element).")"; } // Add the where here $sqlfilters = $search_component_params_hidden; @@ -571,7 +670,7 @@ if (!empty($search_measures) && !empty($search_xaxis)) { print $errormessage; } } - $sql .= ' GROUP BY '; + $sql .= " GROUP BY "; foreach ($search_xaxis as $key => $val) { if (preg_match('/\-year$/', $val)) { $tmpval = preg_replace('/\-year$/', '', $val); @@ -636,7 +735,7 @@ if (!empty($search_measures) && !empty($search_xaxis)) { $legend = array(); foreach ($search_measures as $key => $val) { - $legend[] = $langs->trans($arrayofmesures[$val]); + $legend[] = $langs->trans($arrayofmesures[$val]['label']); } $useagroupby = (is_array($search_groupby) && count($search_groupby)); @@ -667,7 +766,7 @@ if ($sql) { if (!empty($object->fields[$xvalwithoutprefix]['arrayofkeyval'])) { $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey]; } - $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->trans("Empty") : $langs->trans("NotDefined"))); + $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->transnoentitiesnoconv("Empty") : $langs->transnoentitiesnoconv("NotDefined"))); if ($oldlabeltouse && ($labeltouse != $oldlabeltouse)) { $xi++; // Increase $xi @@ -861,26 +960,64 @@ function fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesu if ($level == 0) { // Add the count of record only for the main/first level object. Parents are necessarly unique for each record. - $arrayofmesures[$tablealias.'.count'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': Count'; + $arrayofmesures[$tablealias.'.count'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': Count', + 'position' => 0, + 'table' => $object->table_element + ); } // Add main fields of object foreach ($object->fields as $key => $val) { - if (!empty($val['isameasure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1))) { - $arrayofmesures[$tablealias.'.'.$key.'-sum'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$langs->trans("Sum").')'; - $arrayofmesures[$tablealias.'.'.$key.'-average'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$langs->trans("Average").')'; - $arrayofmesures[$tablealias.'.'.$key.'-min'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$langs->trans("Minimum").')'; - $arrayofmesures[$tablealias.'.'.$key.'-max'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$langs->trans("Maximum").')'; + if (!empty($val['isameasure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1, 1, '1'))) { + $position = (!empty($val['position']) ? $val['position'] : 0); + $arrayofmesures[$tablealias.'.'.$key.'-sum'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$langs->trans("Sum").')', + 'position' => ($position+($count * 100000)).'.1', + 'table' => $object->table_element + ); + $arrayofmesures[$tablealias.'.'.$key.'-average'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$langs->trans("Average").')', + 'position' => ($position+($count * 100000)).'.2', + 'table' => $object->table_element + ); + $arrayofmesures[$tablealias.'.'.$key.'-min'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$langs->trans("Minimum").')', + 'position' => ($position+($count * 100000)).'.3', + 'table' => $object->table_element + ); + $arrayofmesures[$tablealias.'.'.$key.'-max'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$langs->trans("Maximum").')', + 'position' => ($position+($count * 100000)).'.4', + 'table' => $object->table_element + ); } } // Add extrafields to Measures if ($object->isextrafieldmanaged) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1))) { - $arrayofmesures[$tablealias.'e.'.$key.'-sum'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Sum").')'; - $arrayofmesures[$tablealias.'e.'.$key.'-average'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Average").')'; - $arrayofmesures[$tablealias.'e.'.$key.'-min'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Minimum").')'; - $arrayofmesures[$tablealias.'e.'.$key.'-max'] = img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Maximum").')'; + if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'))) { + $position = (!empty($val['position']) ? $val['position'] : 0); + $arrayofmesures[$tablealias.'e.'.$key.'-sum'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Sum").')', + 'position' => ($position+($count * 100000)).'.1', + 'table' => $object->table_element + ); + $arrayofmesures[$tablealias.'e.'.$key.'-average'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Average").')', + 'position' => ($position+($count * 100000)).'.2', + 'table' => $object->table_element + ); + $arrayofmesures[$tablealias.'e.'.$key.'-min'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Minimum").')', + 'position' => ($position+($count * 100000)).'.3', + 'table' => $object->table_element + ); + $arrayofmesures[$tablealias.'e.'.$key.'-max'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Maximum").')', + 'position' => ($position+($count * 100000)).'.4', + 'table' => $object->table_element + ); } } } @@ -888,19 +1025,16 @@ function fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesu foreach ($object->fields as $key => $val) { if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) { $tmptype = explode(':', $val['type'], 4); - if ($tmptype[0] = 'integer' && $tmptype[1] && $tmptype[2]) { + if ($tmptype[0] == 'integer' && $tmptype[1] && $tmptype[2]) { $newobject = $tmptype[1]; dol_include_once($tmptype[2]); if (class_exists($newobject)) { $tmpobject = new $newobject($db); - /*var_dump($val['label']); - var_dump($tmptype); - var_dump($arrayofmesures); - var_dump('t-'.$key);*/ + //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key); $count++; $arrayofmesures = fillArrayOfMeasures($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofmesures, $level + 1, $count); } else { - print 'Failed to find '.$newobject.' class for field '.$key.' of object '.$object->element."\n"; + print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."
    \n"; } } } @@ -914,7 +1048,7 @@ function fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesu * Fill arrayofmesures for an object * * @param mixed $object Any object - * @param string $tablealias Alias of table + * @param string $tablealias Alias of table ('t' for example) * @param string $labelofobject Label of object * @param array $arrayofxaxis Array of xaxis already filled * @param int $level Level @@ -948,10 +1082,10 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) { continue; } - if (isset($val['enabled']) && !dol_eval($val['enabled'], 1)) { + if (isset($val['enabled']) && !dol_eval($val['enabled'], 1, 1, '1')) { continue; } - if (isset($val['visible']) && !dol_eval($val['visible'], 1)) { + if (isset($val['visible']) && !dol_eval($val['visible'], 1, 1, '1')) { continue; } if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) { @@ -964,14 +1098,32 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, continue; } if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) { - $arrayofxaxis[$tablealias.'.'.$key.'-year'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.')', 'position' => ($val['position']+($count * 100000)).'.1'); - $arrayofxaxis[$tablealias.'.'.$key.'-month'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => ($val['position']+($count * 100000)).'.2'); - $arrayofxaxis[$tablealias.'.'.$key.'-day'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => ($val['position']+($count * 100000)).'.3'); + $position = (!empty($val['position']) ? $val['position'] : 0); + $arrayofxaxis[$tablealias.'.'.$key.'-year'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.')', + 'position' => ($position+($count * 100000)).'.1', + 'table' => $object->table_element + ); + $arrayofxaxis[$tablealias.'.'.$key.'-month'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', + 'position' => ($position+($count * 100000)).'.2', + 'table' => $object->table_element + ); + $arrayofxaxis[$tablealias.'.'.$key.'-day'] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', + 'position' => ($position+($count * 100000)).'.3', + 'table' => $object->table_element + ); } else { - $arrayofxaxis[$tablealias.'.'.$key] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']), 'position' => ($val['position']+($count * 100000))); + $arrayofxaxis[$tablealias.'.'.$key] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']), + 'position' => ($position+($count * 100000)), + 'table' => $object->table_element + ); } } } + // Add extrafields to X-Axis if ($object->isextrafieldmanaged) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { @@ -981,26 +1133,28 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis, if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) { continue; } - $arrayofxaxis[$tablealias.'e.'.$key] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000)); + $arrayofxaxis[$tablealias.'e.'.$key] = array( + 'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), + 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000), + 'table' => $object->table_element + ); } } + // Add fields for parent objects foreach ($object->fields as $key => $val) { if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) { $tmptype = explode(':', $val['type'], 4); - if ($tmptype[0] = 'integer' && $tmptype[1] && $tmptype[2]) { + if ($tmptype[0] == 'integer' && $tmptype[1] && $tmptype[2]) { $newobject = $tmptype[1]; dol_include_once($tmptype[2]); if (class_exists($newobject)) { $tmpobject = new $newobject($db); - /*var_dump($val['label']); - var_dump($tmptype); - var_dump($arrayofmesures); - var_dump('t-'.$key);*/ + //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key); $count++; $arrayofxaxis = fillArrayOfXAxis($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofxaxis, $level + 1, $count); } else { - print 'Failed to find '.$newobject.' class for field '.$key.' of object '.$object->element."\n"; + print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."
    \n"; } } } @@ -1048,10 +1202,10 @@ function fillArrayOfGroupBy($object, $tablealias, $labelofobject, &$arrayofgroup 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) { continue; } - if (isset($val['enabled']) && !dol_eval($val['enabled'], 1)) { + if (isset($val['enabled']) && !dol_eval($val['enabled'], 1, 1, '1')) { continue; } - if (isset($val['visible']) && !dol_eval($val['visible'], 1)) { + if (isset($val['visible']) && !dol_eval($val['visible'], 1, 1, '1')) { continue; } if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) { @@ -1064,14 +1218,32 @@ function fillArrayOfGroupBy($object, $tablealias, $labelofobject, &$arrayofgroup continue; } if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) { - $arrayofgroupby[$tablealias.'.'.$key.'-year'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.')', 'position' => ($val['position']+($count * 100000)).'.1'); - $arrayofgroupby[$tablealias.'.'.$key.'-month'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => ($val['position']+($count * 100000)).'.2'); - $arrayofgroupby[$tablealias.'.'.$key.'-day'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => ($val['position']+($count * 100000)).'.3'); + $position = (!empty($val['position']) ? $val['position'] : 0); + $arrayofgroupby[$tablealias.'.'.$key.'-year'] = array( + 'label' => img_picto('', $object->picto, + 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.')', 'position' => ($position+($count * 100000)).'.1', + 'table' => $object->table_element + ); + $arrayofgroupby[$tablealias.'.'.$key.'-month'] = array( + 'label' => img_picto('', $object->picto, + 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.')', 'position' => ($position+($count * 100000)).'.2', + 'table' => $object->table_element + ); + $arrayofgroupby[$tablealias.'.'.$key.'-day'] = array( + 'label' => img_picto('', $object->picto, + 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' ('.$YYYY.'-'.$MM.'-'.$DD.')', 'position' => ($position+($count * 100000)).'.3', + 'table' => $object->table_element + ); } else { - $arrayofgroupby[$tablealias.'.'.$key] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']), 'position' => ($val['position']+($count * 100000))); + $arrayofgroupby[$tablealias.'.'.$key] = array( + 'label' => img_picto('', $object->picto, + 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']), 'position' => ($position+($count * 100000)), + 'table' => $object->table_element + ); } } } + // Add extrafields to Group by if ($object->isextrafieldmanaged) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { @@ -1081,26 +1253,28 @@ function fillArrayOfGroupBy($object, $tablealias, $labelofobject, &$arrayofgroup if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) { continue; } - $arrayofgroupby[$tablealias.'e.'.$key] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000)); + $arrayofgroupby[$tablealias.'e.'.$key] = array( + 'label' => img_picto('', $object->picto, + 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000), + 'table' => $object->table_element + ); } } + // Add fields for parent objects foreach ($object->fields as $key => $val) { if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) { $tmptype = explode(':', $val['type'], 4); - if ($tmptype[0] = 'integer' && $tmptype[1] && $tmptype[2]) { + if ($tmptype[0] == 'integer' && $tmptype[1] && $tmptype[2]) { $newobject = $tmptype[1]; dol_include_once($tmptype[2]); if (class_exists($newobject)) { $tmpobject = new $newobject($db); - /*var_dump($val['label']); - var_dump($tmptype); - var_dump($arrayofmesures); - var_dump('t-'.$key);*/ + //var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key); $count++; $arrayofgroupby = fillArrayOfGroupBy($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofgroupby, $level + 1, $count); } else { - print 'Failed to find '.$newobject.' class for field '.$key.' of object '.$object->element."\n"; + print 'For property '.$object->element.'->'.$key.', type="'.$val['type'].'": Failed to find class '.$newobject." in file ".$tmptype[2]."
    \n"; } } } diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index f23a66bbee4..aae315ec992 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -96,6 +96,17 @@ abstract class DoliDB implements Database return '(CASE WHEN '.$test.' THEN '.$resok.' ELSE '.$resko.' END)'; } + /** + * Return SQL string to force an index + * + * @param string $nameofindex Name of index + * @return string SQL string + */ + public function hintindex($nameofindex) + { + return ''; + } + /** * Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field. * Function to use to build INSERT, UPDATE or WHERE predica @@ -106,7 +117,7 @@ abstract class DoliDB implements Database */ public function idate($param, $gm = 'tzserver') { - // TODO $param should be gmt, so we should add $gm to 'gmt' instead of default 'tzserver' + // TODO $param should be gmt, so we should have default $gm to 'gmt' instead of default 'tzserver' return dol_print_date($param, "%Y-%m-%d %H:%M:%S", $gm); } diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index fa24e4a70ac..582fd08811f 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -168,6 +168,18 @@ class DoliDBMysqli extends DoliDB } + /** + * Return SQL string to force an index + * + * @param string $nameofindex Name of index + * @return string SQL string + */ + public function hintindex($nameofindex) + { + return " FORCE INDEX(".preg_replace('/[^a-z0-9_]/', '', $nameofindex).")"; + } + + /** * Convert a SQL request in Mysql syntax to native syntax * @@ -180,6 +192,7 @@ class DoliDBMysqli extends DoliDB return $line; } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Select a database @@ -266,7 +279,7 @@ class DoliDBMysqli extends DoliDB * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollback to savepoint if error (this allow to have some request with errors inside global transactions). * Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints. * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) - * @param int $result_mode Result mode + * @param int $result_mode Result mode (Using 1=MYSQLI_USE_RESULT instead of 0=MYSQLI_STORE_RESULT will not buffer the result and save memory) * @return bool|mysqli_result Resultset of answer */ public function query($query, $usesavepoint = 0, $type = 'auto', $result_mode = 0) @@ -966,7 +979,7 @@ class DoliDBMysqli extends DoliDB public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name) { // phpcs:enable - $sql = "CREATE USER '".$this->escape($dolibarr_main_db_user)."'"; + $sql = "CREATE USER '".$this->escape($dolibarr_main_db_user)."' IDENTIFIED BY '".$this->escape($dolibarr_main_db_pass)."'"; dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log $resql = $this->query($sql); if (!$resql) { @@ -979,14 +992,14 @@ class DoliDBMysqli extends DoliDB } // Redo with localhost forced (sometimes user is created on %) - $sql = "CREATE USER '".$this->escape($dolibarr_main_db_user)."'@'localhost'"; + $sql = "CREATE USER '".$this->escape($dolibarr_main_db_user)."'@'localhost' IDENTIFIED BY '".$this->escape($dolibarr_main_db_pass)."'"; $resql = $this->query($sql); - $sql = "GRANT ALL PRIVILEGES ON ".$this->escape($dolibarr_main_db_name).".* TO '".$this->escape($dolibarr_main_db_user)."'@'".$this->escape($dolibarr_main_db_host)."' IDENTIFIED BY '".$this->escape($dolibarr_main_db_pass)."'"; + $sql = "GRANT ALL PRIVILEGES ON ".$this->escape($dolibarr_main_db_name).".* TO '".$this->escape($dolibarr_main_db_user)."'@'".$this->escape($dolibarr_main_db_host)."'"; dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log $resql = $this->query($sql); if (!$resql) { - $this->error = "Connected user not allowed to GRANT ALL PRIVILEGES ON ".$this->escape($dolibarr_main_db_name).".* TO '".$this->escape($dolibarr_main_db_user)."'@'".$this->escape($dolibarr_main_db_host)."' IDENTIFIED BY '*****'"; + $this->error = "Connected user not allowed to GRANT ALL PRIVILEGES ON ".$this->escape($dolibarr_main_db_name).".* TO '".$this->escape($dolibarr_main_db_user)."'@'".$this->escape($dolibarr_main_db_host)."'"; return -1; } diff --git a/htdocs/core/extrafieldsinexport.inc.php b/htdocs/core/extrafieldsinexport.inc.php index fc2210eabd8..b31b02c3460 100644 --- a/htdocs/core/extrafieldsinexport.inc.php +++ b/htdocs/core/extrafieldsinexport.inc.php @@ -12,7 +12,7 @@ if (empty($keyforselect) || empty($keyforelement) || empty($keyforaliasextra)) { // Add extra fields $sql = "SELECT name, label, type, param, fieldcomputed, fielddefault FROM ".MAIN_DB_PREFIX."extrafields"; -$sql .= " WHERE elementtype = '".$this->db->escape($keyforselect)."' AND type != 'separate' AND entity IN (0, ".$conf->entity.') ORDER BY pos ASC'; +$sql .= " WHERE elementtype = '".$this->db->escape($keyforselect)."' AND type <> 'separate' AND entity IN (0, ".((int) $conf->entity).') ORDER BY pos ASC'; //print $sql; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) diff --git a/htdocs/core/extrafieldsinimport.inc.php b/htdocs/core/extrafieldsinimport.inc.php new file mode 100644 index 00000000000..4845d9a6d44 --- /dev/null +++ b/htdocs/core/extrafieldsinimport.inc.php @@ -0,0 +1,75 @@ +db->escape($keyforselect)."' AND type <> 'separate' AND entity IN (0, ".((int) $conf->entity).') ORDER BY pos ASC'; +//print $sql; +$resql = $this->db->query($sql); +if ($resql) { // This can fail when class is used on old database (during migration for example) + while ($obj = $this->db->fetch_object($resql)) { + $fieldname = $keyforaliasextra.'.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $typeFilter = "Text"; + $typefield = preg_replace('/\(.*$/', '', $obj->type); // double(24,8) -> double + switch ($typefield) { + case 'int': + case 'integer': + case 'double': + case 'price': + $typeFilter = "Numeric"; + break; + case 'date': + case 'datetime': + case 'timestamp': + $typeFilter = "Date"; + break; + case 'boolean': + $typeFilter = "Boolean"; + break; + case 'checkbox': + case 'select': + if (!empty($conf->global->EXPORT_LABEL_FOR_SELECT)) { + $tmpparam = jsonOrUnserialize($obj->param); // $tmpparam may be array with 'options' = array(key1=>val1, key2=>val2 ...) + if ($tmpparam['options'] && is_array($tmpparam['options'])) { + $typeFilter = "Select:".$obj->param; + } + } + break; + case 'sellist': + $tmp = ''; + $tmpparam = jsonOrUnserialize($obj->param); // $tmp may be array 'options' => array 'c_currencies:code_iso:code_iso' => null + if (is_array($tmpparam) && array_key_exists('options', $tmpparam) && $tmpparam['options'] && is_array($tmpparam['options'])) { + $tmpkeys = array_keys($tmpparam['options']); + $tmp = array_shift($tmpkeys); + } + if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) { + $typeFilter = "List:".$tmp; + } + break; + } + if ($obj->type != 'separate') { + // If not a computed field + if (empty($obj->fieldcomputed)) { + $this->import_fields_array[$r][$fieldname] = $fieldlabel.($obj->fieldrequired ? '*' : ''); + $this->import_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->import_entities_array[$r][$fieldname] = $keyforelement; + } else { + // If this is a computed field + $this->import_fields_array[$r][$fieldname] = $fieldlabel.($obj->fieldrequired ? '*' : ''); + $this->import_TypeFields_array[$r][$fieldname] = $typeFilter.'Compute'; + $this->import_entities_array[$r][$fieldname] = $keyforelement; + } + } + } +} +// End add axtra fields diff --git a/htdocs/core/filemanagerdol/browser/default/browser.css b/htdocs/core/filemanagerdol/browser/default/browser.css index 0df72be1a35..d6ec1e212aa 100644 --- a/htdocs/core/filemanagerdol/browser/default/browser.css +++ b/htdocs/core/filemanagerdol/browser/default/browser.css @@ -42,8 +42,8 @@ body.FileArea body, td, input, select { - font-size: 11px; - font-family: 'Microsoft Sans Serif', Arial, Helvetica, Verdana, sans-serif; + /* font-size: 11px; */ + /* font-family: 'Microsoft Sans Serif', Arial, Helvetica, Verdana, sans-serif; */ } .ActualFolder @@ -78,4 +78,6 @@ body, td, input, select .fullHeight { height: 100%; + padding-left: 10px; + padding-right: 10px; } diff --git a/htdocs/core/filemanagerdol/browser/default/browser.php b/htdocs/core/filemanagerdol/browser/default/browser.php index 50bd538078b..b5bce100d39 100644 --- a/htdocs/core/filemanagerdol/browser/default/browser.php +++ b/htdocs/core/filemanagerdol/browser/default/browser.php @@ -25,15 +25,30 @@ require '../../connectors/php/config.php'; // This include the define('NOTOKENRE global $Config; - - ?> - + <?php echo $langs->trans("MediaBrowser").' - '.$Config['UserFilesAbsolutePathRelative']; ?> +'."\n"; +// Output style sheets (optioncss='print' or ''). Note: $conf->css looks like '/theme/eldy/style.css.php' +$themepath = dol_buildpath($conf->css, 1); +$themesubdir = ''; +if (!empty($conf->modules_parts['theme'])) { // This slow down + foreach ($conf->modules_parts['theme'] as $reldir) { + if (file_exists(dol_buildpath($reldir.$conf->css, 0))) { + $themepath = dol_buildpath($reldir.$conf->css, 1); + $themesubdir = $reldir; + break; + } + } +} + +//print 'themepath='.$themepath.' themeparam='.$themeparam;exit; +print ''."\n"; +?> - + - + - + diff --git a/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php b/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php index d2d7a0966ce..c66187ee433 100644 --- a/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php +++ b/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php @@ -22,6 +22,7 @@ define('NOTOKENRENEWAL', 1); // Disables token renewal require '../../../../main.inc.php'; + ?> '."\n"; +// Output style sheets (optioncss='print' or ''). Note: $conf->css looks like '/theme/eldy/style.css.php' +$themepath = dol_buildpath($conf->css, 1); +$themesubdir = ''; +if (!empty($conf->modules_parts['theme'])) { // This slow down + foreach ($conf->modules_parts['theme'] as $reldir) { + if (file_exists(dol_buildpath($reldir.$conf->css, 0))) { + $themepath = dol_buildpath($reldir.$conf->css, 1); + $themesubdir = $reldir; + break; + } + } +} + +//print 'themepath='.$themepath.' themeparam='.$themeparam;exit; +print ''."\n"; +?> '; exit; } diff --git a/htdocs/core/filemanagerdol/connectors/php/upload.php b/htdocs/core/filemanagerdol/connectors/php/upload.php index bd9b9218155..b9296d68bcf 100644 --- a/htdocs/core/filemanagerdol/connectors/php/upload.php +++ b/htdocs/core/filemanagerdol/connectors/php/upload.php @@ -22,11 +22,12 @@ * This is the "File Uploader" for PHP. */ -require 'config.php'; +require 'config.php'; // This include the main.inc.php require 'util.php'; require 'io.php'; require 'commands.php'; + /** * SendError * @@ -63,6 +64,7 @@ if (!IsAllowedType($sType)) { } + // @CHANGE //FileUpload( $sType, $sCurrentFolder, $sCommand ) diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index 1e9b53b1424..3fe6dee8820 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -1187,9 +1187,9 @@ $(document).ready(function() { }); -// Force to hide menus when page is inside an iFrame +// Force to hide menus when page is inside an iFrame so we can show any page into a dialog popup $(document).ready(function() { - if (window.location !== window.parent.location ) { + if (window.location && window.location.pathname.indexOf("externalsite/frametop.php") == -1 && window.location !== window.parent.location ) { console.log("Page is detected to be into an iframe, we hide by CSS the menus"); // The page is in an iframe jQuery(".side-nav-vert, .side-nav, .websitebar").hide(); @@ -1198,4 +1198,22 @@ $(document).ready(function() { } }); + +/* + * Hacky fix for a bug in select2 with jQuery 3.6.0's new nested-focus "protection" + * see: https://github.com/select2/select2/issues/5993 + * see: https://github.com/jquery/jquery/issues/4382 + * + * TODO: Recheck with the select2 GH issue and remove once this is fixed on their side + */ +$(document).on('select2:open', () => { + console.log("Execute the focus (click on combo or use space when on component"); + let allFound = document.querySelectorAll('.select2-container--open .select2-search__field'); + $(this).one('mouseup keyup',()=>{ + setTimeout(()=>{ + allFound[allFound.length - 1].focus(); + },0); + }); +}); + // End of lib_head.js.php diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index d2528f45dfa..488010609f9 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -93,7 +93,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print $form->select_dolgroups($usergroupid, 'usergroup', 1, '', !$canedit, '', '', '0', false, 'minwidth100 maxwidth500 widthcentpercentminusxx'); print '
    '; - if ($conf->resource->enabled) { + if (!empty($conf->resource->enabled)) { include_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; $formresource = new FormResource($db); @@ -105,14 +105,14 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh } } - if (!empty($conf->societe->enabled) && $user->rights->societe->lire) { + if (!empty($conf->societe->enabled) && !empty($user->rights->societe->lire)) { print '
    '; print img_picto($langs->trans("ThirdParty"), 'company', 'class="fawidth30 inline-block"'); print $form->select_company($socid, 'search_socid', '', ' ', 0, 0, null, 0, 'minwidth100 maxwidth500'); print '
    '; } - if (!empty($conf->projet->enabled) && $user->rights->projet->lire) { + if (!empty($conf->projet->enabled) && !empty($user->rights->projet->lire)) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; $formproject = new FormProjets($db); diff --git a/htdocs/core/lib/asset.lib.php b/htdocs/core/lib/asset.lib.php index 840aca1339a..9d71e2b38f1 100644 --- a/htdocs/core/lib/asset.lib.php +++ b/htdocs/core/lib/asset.lib.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2018-2022 OpenDSI * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,7 +26,7 @@ * * @return array head array with tabs */ -function asset_admin_prepare_head() +function assetAdminPrepareHead() { global $langs, $conf; @@ -43,90 +43,118 @@ function asset_admin_prepare_head() // Show more tabs from modules // Entries must be declared in modules descriptor with line //$this->tabs = array( - // 'entity:+tabname:Title:@assets:/asset/mypage.php?id=__ID__' + // 'entity:+tabname:Title:@asset:/asset/mypage.php?id=__ID__' //); // to add new tab //$this->tabs = array( - // 'entity:-tabname:Title:@assets:/asset/mypage.php?id=__ID__' + // 'entity:-tabname:Title:@asset:/asset/mypage.php?id=__ID__' //); // to remove a tab - complete_head_from_modules($conf, $langs, null, $head, $h, 'assets_admin'); + complete_head_from_modules($conf, $langs, null, $head, $h, 'asset_admin'); - $head[$h][0] = DOL_URL_ROOT.'/asset/admin/assets_extrafields.php'; + $head[$h][0] = DOL_URL_ROOT.'/asset/admin/asset_extrafields.php'; $head[$h][1] = $langs->trans("ExtraFields"); - $head[$h][2] = 'attributes'; + $head[$h][2] = 'asset_extrafields'; $h++; - $head[$h][0] = DOL_URL_ROOT.'/asset/admin/assets_type_extrafields.php'; - $head[$h][1] = $langs->trans("ExtraFieldsAssetsType"); - $head[$h][2] = 'attributes_type'; + $head[$h][0] = DOL_URL_ROOT.'/asset/admin/assetmodel_extrafields.php'; + $head[$h][1] = $langs->trans("ExtraFieldsAssetModel"); + $head[$h][2] = 'assetmodel_extrafields'; $h++; - complete_head_from_modules($conf, $langs, null, $head, $h, 'assets_admin', 'remove'); + complete_head_from_modules($conf, $langs, null, $head, $h, 'asset_admin', 'remove'); return $head; } /** - * Prepare admin pages header + * Prepare array of tabs for Asset * - * @param Contrat $object Object related to tabs - * @return array head array with tabs + * @param Asset $object Asset + * @return array Array of tabs */ -function asset_prepare_head(Asset $object) +function assetPrepareHead(Asset $object) { global $db, $langs, $conf; - $langs->load("assets"); + $langs->load("assets", "admin"); $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/asset/card.php?id='.$object->id; + $head[$h][0] = DOL_URL_ROOT . '/asset/card.php?id=' . $object->id; $head[$h][1] = $langs->trans("Card"); $head[$h][2] = 'card'; $h++; + if (empty($object->not_depreciated)) { + $head[$h][0] = DOL_URL_ROOT . '/asset/depreciation_options.php?id=' . $object->id; + $head[$h][1] = $langs->trans("AssetDepreciationOptions"); + $head[$h][2] = 'depreciation_options'; + $h++; + } + + $head[$h][0] = DOL_URL_ROOT . '/asset/accountancy_codes.php?id=' . $object->id; + $head[$h][1] = $langs->trans("AssetAccountancyCodes"); + $head[$h][2] = 'accountancy_codes'; + $h++; + + if (empty($object->not_depreciated)) { + $head[$h][0] = DOL_URL_ROOT . '/asset/depreciation.php?id=' . $object->id; + $head[$h][1] = $langs->trans("AssetDepreciation"); + $head[$h][2] = 'depreciation'; + $h++; + } + + if (isset($object->disposal_date) && $object->disposal_date !== "") { + $head[$h][0] = DOL_URL_ROOT . '/asset/disposal.php?id=' . $object->id; + $head[$h][1] = $langs->trans("AssetDisposal"); + $head[$h][2] = 'disposal'; + $h++; + } + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = DOL_URL_ROOT . '/asset/note.php?id=' . $object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? '' . $nbNote . '' : ''); + } + $head[$h][2] = 'note'; + $h++; + } + + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php'; + $upload_dir = $conf->asset->dir_output . "/asset/" . dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = DOL_URL_ROOT . '/asset/document.php?id=' . $object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) { + $head[$h][1] .= '' . ($nbFiles + $nbLinks) . ''; + } + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = DOL_URL_ROOT . '/asset/agenda.php?id=' . $object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + // Show more tabs from modules // Entries must be declared in modules descriptor with line //$this->tabs = array( - // 'entity:+tabname:Title:@assets:/asset/mypage.php?id=__ID__' + // 'entity:+tabname:Title:@asset:/asset/mypage.php?id=__ID__' //); // to add new tab //$this->tabs = array( - // 'entity:-tabname:Title:@assets:/asset/mypage.php?id=__ID__' + // 'entity:-tabname:Title:@asset:/asset/mypage.php?id=__ID__' //); // to remove a tab - complete_head_from_modules($conf, $langs, $object, $head, $h, 'assets'); - - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; - $upload_dir = $conf->assets->dir_output.'/'.dol_sanitizeFileName($object->ref); - $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); - $nbLinks = Link::count($db, $object->element, $object->id); - $head[$h][0] = DOL_URL_ROOT.'/asset/document.php?id='.$object->id; - $head[$h][1] = $langs->trans('Documents'); - if (($nbFiles + $nbLinks) > 0) { - $head[$h][1] .= ''.($nbFiles + $nbLinks).''; - } - $head[$h][2] = 'documents'; - $h++; - - $nbNote = 0; - if (!empty($object->note_private)) { - $nbNote++; - } - if (!empty($object->note_public)) { - $nbNote++; - } - $head[$h][0] = DOL_URL_ROOT.'/asset/note.php?id='.$object->id; - $head[$h][1] = $langs->trans("Notes"); - if ($nbNote > 0) { - $head[$h][1] .= ''.$nbNote.''; - } - $head[$h][2] = 'note'; - $h++; - - $head[$h][0] = DOL_URL_ROOT.'/asset/info.php?id='.$object->id; - $head[$h][1] = $langs->trans("Info"); - $head[$h][2] = 'info'; - $h++; + complete_head_from_modules($conf, $langs, $object, $head, $h, 'asset'); complete_head_from_modules($conf, $langs, $object, $head, $h, 'asset', 'remove'); @@ -134,30 +162,69 @@ function asset_prepare_head(Asset $object) } /** - * Return array head with list of tabs to view object informations + * Prepare array of tabs for AssetModel * - * @param AssetType $object Asset - * @return array head + * @param AssetModel $object AssetModel + * @return array Array of tabs */ -function asset_type_prepare_head(AssetType $object) +function assetModelPrepareHead($object) { - global $langs, $conf, $user; + global $langs, $conf; + + $langs->load("assets", "admin"); $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/asset/type.php?rowid='.$object->id; + $head[$h][0] = DOL_URL_ROOT . '/asset/model/card.php?id=' . $object->id; $head[$h][1] = $langs->trans("Card"); $head[$h][2] = 'card'; $h++; + $head[$h][0] = DOL_URL_ROOT . '/asset/model/depreciation_options.php?id=' . $object->id; + $head[$h][1] = $langs->trans("AssetDepreciationOptions"); + $head[$h][2] = 'depreciation_options'; + $h++; + + $head[$h][0] = DOL_URL_ROOT . '/asset/model/accountancy_codes.php?id=' . $object->id; + $head[$h][1] = $langs->trans("AssetAccountancyCodes"); + $head[$h][2] = 'accountancy_codes'; + $h++; + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = DOL_URL_ROOT . '/asset/model/note.php?id=' . $object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? '' . $nbNote . '' : ''); + } + $head[$h][2] = 'note'; + $h++; + } + + $head[$h][0] = DOL_URL_ROOT . '/asset/model/agenda.php?id=' . $object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + + // Show more tabs from modules // Entries must be declared in modules descriptor with line - // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab - // $this->tabs = array('entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to remove a tab - complete_head_from_modules($conf, $langs, $object, $head, $h, 'assettype'); + //$this->tabs = array( + // 'entity:+tabname:Title:@asset:/asset/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@asset:/asset/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'assetmodel'); - complete_head_from_modules($conf, $langs, $object, $head, $h, 'assettype', 'remove'); + complete_head_from_modules($conf, $langs, $object, $head, $h, 'assetmodel', 'remove'); return $head; } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 4bf8a0e7219..197a6c95687 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -42,6 +42,8 @@ function societe_prepare_head(Societe $object) { global $db, $langs, $conf, $user; + global $hookmanager; + $h = 0; $head = array(); @@ -64,7 +66,15 @@ function societe_prepare_head(Societe $object) } else { $sql = "SELECT COUNT(p.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p"; + // Add table from hooks + $parameters = array('contacttab' => true); + $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; $sql .= " WHERE p.fk_soc = ".((int) $object->id); + // Add where from hooks + $parameters = array('contacttab' => true); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); @@ -168,27 +178,9 @@ function societe_prepare_head(Societe $object) $h++; } - if (!empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { - // Tab to accountancy - if (!empty($conf->accounting->enabled) && $object->client > 0) { - $head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettering_customer.php?socid='.$object->id; - $head[$h][1] = $langs->trans("TabLetteringCustomer"); - $head[$h][2] = 'lettering_customer'; - $h++; - } - - // Tab to accountancy - if (!empty($conf->accounting->enabled) && $object->fournisseur > 0) { - $head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettering_supplier.php?socid='.$object->id; - $head[$h][1] = $langs->trans("TabLetteringSupplier"); - $head[$h][2] = 'lettering_supplier'; - $h++; - } - } - // Related items if ((!empty($conf->commande->enabled) || !empty($conf->propal->enabled) || !empty($conf->facture->enabled) || !empty($conf->ficheinter->enabled) || (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) - && empty($conf->global->THIRPARTIES_DISABLE_RELATED_OBJECT_TAB)) { + && empty($conf->global->THIRDPARTIES_DISABLE_RELATED_OBJECT_TAB)) { $head[$h][0] = DOL_URL_ROOT.'/societe/consumption.php?socid='.$object->id; $head[$h][1] = $langs->trans("Referers"); $head[$h][2] = 'consumption'; @@ -1102,6 +1094,10 @@ function show_contacts($conf, $langs, $db, $object, $backtopage = '') // Add where from extra fields $extrafieldsobjectkey = $contactstatic->table_element; include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; + // Add where from hooks + $parameters = array('socid' => $object->id); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; if ($sortfield == "t.name") { $sql .= " ORDER BY t.lastname $sortorder, t.firstname $sortorder"; } else { diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index efde963d077..2cf0beb013f 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2083,65 +2083,115 @@ function dol_compress_file($inputfile, $outputfile, $mode = "gz", &$errorstring */ function dol_uncompress($inputfile, $outputdir) { - global $conf, $langs; + global $conf, $langs, $db; - if (defined('ODTPHP_PATHTOPCLZIP') && empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_UNCOMPRESS)) { - dol_syslog("Constant ODTPHP_PATHTOPCLZIP for pclzip library is set to ".ODTPHP_PATHTOPCLZIP.", so we use Pclzip to unzip into ".$outputdir); - include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; - $archive = new PclZip($inputfile); + $fileinfo = pathinfo($inputfile); + $fileinfo["extension"] = strtolower($fileinfo["extension"]); - // Extract into outputdir, but only files that match the regex '/^((?!\.\.).)*$/' that means "does not include .." - $result = $archive->extract(PCLZIP_OPT_PATH, $outputdir, PCLZIP_OPT_BY_PREG, '/^((?!\.\.).)*$/'); + if ($fileinfo["extension"] == "zip") { + if (defined('ODTPHP_PATHTOPCLZIP') && empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_UNCOMPRESS)) { + dol_syslog("Constant ODTPHP_PATHTOPCLZIP for pclzip library is set to ".ODTPHP_PATHTOPCLZIP.", so we use Pclzip to unzip into ".$outputdir); + include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; + $archive = new PclZip($inputfile); - if (!is_array($result) && $result <= 0) { - return array('error'=>$archive->errorInfo(true)); - } else { - $ok = 1; - $errmsg = ''; - // Loop on each file to check result for unzipping file - foreach ($result as $key => $val) { - if ($val['status'] == 'path_creation_fail') { - $langs->load("errors"); - $ok = 0; - $errmsg = $langs->trans("ErrorFailToCreateDir", $val['filename']); - break; + // We create output dir manually, so it uses the correct permission (When created by the archive->extract, dir is rwx for everybody). + dol_mkdir(dol_sanitizePathName($outputdir)); + + // Extract into outputdir, but only files that match the regex '/^((?!\.\.).)*$/' that means "does not include .." + $result = $archive->extract(PCLZIP_OPT_PATH, $outputdir, PCLZIP_OPT_BY_PREG, '/^((?!\.\.).)*$/'); + + if (!is_array($result) && $result <= 0) { + return array('error'=>$archive->errorInfo(true)); + } else { + $ok = 1; + $errmsg = ''; + // Loop on each file to check result for unzipping file + foreach ($result as $key => $val) { + if ($val['status'] == 'path_creation_fail') { + $langs->load("errors"); + $ok = 0; + $errmsg = $langs->trans("ErrorFailToCreateDir", $val['filename']); + break; + } + } + + if ($ok) { + return array(); + } else { + return array('error'=>$errmsg); } } + } - if ($ok) { + if (class_exists('ZipArchive')) { // Must install php-zip to have it + dol_syslog("Class ZipArchive is set so we unzip using ZipArchive to unzip into ".$outputdir); + $zip = new ZipArchive; + $res = $zip->open($inputfile); + if ($res === true) { + //$zip->extractTo($outputdir.'/'); + // We must extract one file at time so we can check that file name does not contains '..' to avoid transversal path of zip built for example using + // python3 path_traversal_archiver.py test.zip -l 10 -p tmp/ + // with -l is the range of dot to go back in path. + // and path_traversal_archiver.py found at https://github.com/Alamot/code-snippets/blob/master/path_traversal/path_traversal_archiver.py + for ($i = 0; $i < $zip->numFiles; $i++) { + if (preg_match('/\.\./', $zip->getNameIndex($i))) { + dol_syslog("Warning: Try to unzip a file with a transversal path ".$zip->getNameIndex($i), LOG_WARNING); + continue; // Discard the file + } + $zip->extractTo($outputdir.'/', array($zip->getNameIndex($i))); + } + + $zip->close(); return array(); } else { - return array('error'=>$errmsg); + return array('error'=>'ErrUnzipFails'); } } - } - if (class_exists('ZipArchive')) { // Must install php-zip to have it - dol_syslog("Class ZipArchive is set so we unzip using ZipArchive to unzip into ".$outputdir); - $zip = new ZipArchive; - $res = $zip->open($inputfile); - if ($res === true) { - //$zip->extractTo($outputdir.'/'); - // We must extract one file at time so we can check that file name does not contains '..' to avoid transversal path of zip built for example using - // python3 path_traversal_archiver.py test.zip -l 10 -p tmp/ - // with -l is the range of dot to go back in path. - // and path_traversal_archiver.py found at https://github.com/Alamot/code-snippets/blob/master/path_traversal/path_traversal_archiver.py - for ($i = 0; $i < $zip->numFiles; $i++) { - if (preg_match('/\.\./', $zip->getNameIndex($i))) { - dol_syslog("Warning: Try to unzip a file with a transversal path ".$zip->getNameIndex($i), LOG_WARNING); - continue; // Discard the file - } - $zip->extractTo($outputdir.'/', array($zip->getNameIndex($i))); + return array('error'=>'ErrNoZipEngine'); + } elseif (in_array($fileinfo["extension"], array('gz', 'bz2', 'zst'))) { + include_once DOL_DOCUMENT_ROOT."/core/class/utils.class.php"; + $utils = new Utils($db); + + dol_mkdir(dol_sanitizePathName($outputdir)); + $outputfilename = escapeshellcmd(dol_sanitizePathName($outputdir).'/'.dol_sanitizeFileName($fileinfo["filename"])); + dol_delete_file($outputfilename.'.tmp'); + dol_delete_file($outputfilename.'.err'); + + $extension = strtolower(pathinfo($fileinfo["filename"], PATHINFO_EXTENSION)); + if ($extension == "tar") { + $cmd = 'tar -C '.escapeshellcmd(dol_sanitizePathName($outputdir)).' -xvf '.escapeshellcmd(dol_sanitizePathName($fileinfo["dirname"]).'/'.dol_sanitizeFileName($fileinfo["basename"])); + + $resarray = $utils->executeCLI($cmd, $outputfilename.'.tmp', 0, $outputfilename.'.err', 0); + if ($resarray["result"] != 0) { + $resarray["error"] .= file_get_contents($outputfilename.'.err'); } - - $zip->close(); - return array(); } else { - return array('error'=>'ErrUnzipFails'); + $program = ""; + if ($fileinfo["extension"] == "gz") { + $program = 'gzip'; + } elseif ($fileinfo["extension"] == "bz2") { + $program = 'bzip2'; + } elseif ($fileinfo["extension"] == "zst") { + $program = 'zstd'; + } else { + return array('error'=>'ErrorBadFileExtension'); + } + $cmd = $program.' -dc '.escapeshellcmd(dol_sanitizePathName($fileinfo["dirname"]).'/'.dol_sanitizeFileName($fileinfo["basename"])); + $cmd .= ' > '.$outputfilename; + + $resarray = $utils->executeCLI($cmd, $outputfilename.'.tmp', 0, null, 1, $outputfilename.'.err'); + if ($resarray["result"] != 0) { + $errfilecontent = @file_get_contents($outputfilename.'.err'); + if ($errfilecontent) { + $resarray["error"] .= " - ".$errfilecontent; + } + } } + return $resarray["result"] != 0 ? array('error' => $resarray["error"]) : array(); } - return array('error'=>'ErrNoZipEngine'); + return array('error'=>'ErrorBadFileExtension'); } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 3b0e90c9013..50d0e8ee9e3 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -378,7 +378,7 @@ function GETPOSTISSET($paramname) * @param string $paramname Name of parameter to found * @param string $check Type of check * ''=no check (deprecated) - * 'none'=no check (only for param that should have very rich content) + * 'none'=no check (only for param that should have very rich content like passwords) * 'array', 'array:restricthtml' or 'array:aZ09' to check it's an array * 'int'=check it's numeric (integer or float) * 'intcomma'=check it's integer+comma ('1,2,3,4...') @@ -3465,14 +3465,18 @@ function dol_print_address($address, $htmlid, $element, $id, $noprint = 0, $char * * @param string $address email (Ex: "toto@examle.com". Long form "John Do " will be false) * @param int $acceptsupervisorkey If 1, the special string '__SUPERVISOREMAIL__' is also accepted as valid + * @param int $acceptuserkey If 1, the special string '__USER_EMAIL__' is also accepted as valid * @return boolean true if email syntax is OK, false if KO or empty string * @see isValidMXRecord() */ -function isValidEmail($address, $acceptsupervisorkey = 0) +function isValidEmail($address, $acceptsupervisorkey = 0, $acceptuserkey = 0) { if ($acceptsupervisorkey && $address == '__SUPERVISOREMAIL__') { return true; } + if ($acceptuserkey && $address == '__USER_EMAIL__') { + return true; + } if (filter_var($address, FILTER_VALIDATE_EMAIL)) { return true; } @@ -5434,11 +5438,16 @@ function price2num($amount, $rounding = '', $option = 0) // Decimal delimiter for PHP and database SQL requests must be '.' $dec = ','; $thousand = ' '; - if ($langs->transnoentitiesnoconv("SeparatorDecimal") != "SeparatorDecimal") { - $dec = $langs->transnoentitiesnoconv("SeparatorDecimal"); - } - if ($langs->transnoentitiesnoconv("SeparatorThousand") != "SeparatorThousand") { - $thousand = $langs->transnoentitiesnoconv("SeparatorThousand"); + if (is_null($langs)) { // $langs is not defined, we use english values. + $dec = '.'; + $thousand = ','; + } else { + if ($langs->transnoentitiesnoconv("SeparatorDecimal") != "SeparatorDecimal") { + $dec = $langs->transnoentitiesnoconv("SeparatorDecimal"); + } + if ($langs->transnoentitiesnoconv("SeparatorThousand") != "SeparatorThousand") { + $thousand = $langs->transnoentitiesnoconv("SeparatorThousand"); + } } if ($thousand == 'None') { $thousand = ''; @@ -7461,13 +7470,23 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__DATE_YMD__'] = is_object($object) ? (isset($object->date) ? dol_print_date($object->date, 'day', 0, $outputlangs) : null) : ''; $substitutionarray['__DATE_DUE_YMD__'] = is_object($object) ? (isset($object->date_lim_reglement) ? dol_print_date($object->date_lim_reglement, 'day', 0, $outputlangs) : null) : ''; + $already_payed_all = 0; + if (is_object($object) && ($object instanceof Facture)) { + $already_payed_all = $object->sumpayed + $object->sumdeposit + $object->sumcreditnote; + } + + $substitutionarray['__AMOUNT_EXCL_TAX__'] = is_object($object) ? $object->total_ht : ''; + $substitutionarray['__AMOUNT__'] = is_object($object) ? $object->total_ttc : ''; $substitutionarray['__AMOUNT_TEXT__'] = is_object($object) ? dol_convertToWord($object->total_ttc, $outputlangs, '', true) : ''; $substitutionarray['__AMOUNT_TEXTCURRENCY__'] = is_object($object) ? dol_convertToWord($object->total_ttc, $outputlangs, $conf->currency, true) : ''; - $substitutionarray['__AMOUNT_EXCL_TAX__'] = is_object($object) ? $object->total_ht : ''; + + $substitutionarray['__AMOUNT_REMAIN__'] = is_object($object) ? $object->total_ttc - $already_payed_all : ''; + $substitutionarray['__AMOUNT_VAT__'] = is_object($object) ? (isset($object->total_vat) ? $object->total_vat : $object->total_tva) : ''; $substitutionarray['__AMOUNT_VAT_TEXT__'] = is_object($object) ? (isset($object->total_vat) ? dol_convertToWord($object->total_vat, $outputlangs, '', true) : dol_convertToWord($object->total_tva, $outputlangs, '', true)) : ''; $substitutionarray['__AMOUNT_VAT_TEXTCURRENCY__'] = is_object($object) ? (isset($object->total_vat) ? dol_convertToWord($object->total_vat, $outputlangs, $conf->currency, true) : dol_convertToWord($object->total_tva, $outputlangs, $conf->currency, true)) : ''; + if ($onlykey != 2 || $mysoc->useLocalTax(1)) { $substitutionarray['__AMOUNT_TAX2__'] = is_object($object) ? $object->total_localtax1 : ''; } @@ -7475,8 +7494,10 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__AMOUNT_TAX3__'] = is_object($object) ? $object->total_localtax2 : ''; } - $substitutionarray['__AMOUNT_FORMATED__'] = is_object($object) ? ($object->total_ttc ? price($object->total_ttc, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; + // Amount keys formated in a currency $substitutionarray['__AMOUNT_EXCL_TAX_FORMATED__'] = is_object($object) ? ($object->total_ht ? price($object->total_ht, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; + $substitutionarray['__AMOUNT_FORMATED__'] = is_object($object) ? ($object->total_ttc ? price($object->total_ttc, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; + $substitutionarray['__AMOUNT_REMAIN_FORMATED__'] = is_object($object) ? ($object->total_ttc ? price($object->total_ttc - $already_payed_all, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; $substitutionarray['__AMOUNT_VAT_FORMATED__'] = is_object($object) ? (isset($object->total_vat) ? price($object->total_vat, 0, $outputlangs, 0, -1, -1, $conf->currency) : ($object->total_tva ? price($object->total_tva, 0, $outputlangs, 0, -1, -1, $conf->currency) : null)) : ''; if ($onlykey != 2 || $mysoc->useLocalTax(1)) { $substitutionarray['__AMOUNT_TAX2_FORMATED__'] = is_object($object) ? ($object->total_localtax1 ? price($object->total_localtax1, 0, $outputlangs, 0, -1, -1, $conf->currency) : null) : ''; @@ -7900,7 +7921,6 @@ function dol_htmloutput_events($disabledoutputofmessages = 0) } unset($_SESSION['dol_events']['mesgs']); } - // Show errors if (isset($_SESSION['dol_events']['errors'])) { if (empty($disabledoutputofmessages)) { @@ -8297,7 +8317,7 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = * Verify if condition in string is ok or not * * @param string $strToEvaluate String with condition to check - * @return boolean True or False. Note: It returns True if $strToEvaluate is '' + * @return boolean True or False. Note: It returns also True if $strToEvaluate is ''. False if error */ function verifCond($strToEvaluate) { @@ -8308,8 +8328,12 @@ function verifCond($strToEvaluate) //print $strToEvaluate."
    \n"; $rights = true; if (isset($strToEvaluate) && $strToEvaluate !== '') { - $str = 'if(!('.$strToEvaluate.')) { $rights = false; }'; - dol_eval($str); // The dol_eval must contains all the global $xxx used into a condition + //$str = 'if(!('.$strToEvaluate.')) $rights = false;'; + //dol_eval($str, 0, 1, '2'); // The dol_eval must contains all the global $xxx used into a condition + //var_dump($strToEvaluate); + $rep = dol_eval($strToEvaluate, 1, 1, '1'); // The dol_eval must contains all the global $xxx for all variables $xxx found into the string condition + $rights = (($rep && strpos($rep, 'Bad string syntax to evaluate') === false) ? true : false); + //var_dump($rights); } return $rights; } @@ -8318,12 +8342,13 @@ function verifCond($strToEvaluate) * Replace eval function to add more security. * This function is called by verifCond() or trans() and transnoentitiesnoconv(). * - * @param string $s String to evaluate - * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). - * @param int $hideerrors 1=Hide errors - * @return mixed Nothing or return result of eval + * @param string $s String to evaluate + * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). + * @param int $hideerrors 1=Hide errors + * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s^$_->&|=!?():"\',/' and restrict use of (, 2=Accept also ';' and no restriction on (. + * @return mixed Nothing or return result of eval */ -function dol_eval($s, $returnvalue = 0, $hideerrors = 1) +function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1') { // Only global variables can be changed by eval function and returned to caller global $db, $langs, $user, $conf, $website, $websitepage; @@ -8335,17 +8360,62 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1) global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object global $soc; // For backward compatibility - // Replace dangerous char (used for RCE), we allow only PHP variable testing. + // Test on dangerous char (used for RCE), we allow only characters to make PHP variable testing + if ($onlysimplestring == '1') { + // We must accept: '1 && getDolGlobalInt("doesnotexist1") && $conf->global->MAIN_FEATURES_LEVEL' + // We must accept: '$conf->barcode->enabled && preg_match(\'/^(AAA|BBB)/\',$leftmenu)' + if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-*>&|=!?():"\',/', '/').']/i', $s)) { + if ($returnvalue) { + return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s); + return ''; + } + // TODO We can exclude all () that is not '($db)' and 'getDolGlobalInt(' and 'getDolGlobalString(' and 'preg_match(' + // ... + } + } elseif ($onlysimplestring == '2') { + // We must accept: (($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : "Parent project not found" + if (preg_match('/[^a-z0-9\s'.preg_quote('^$_+-*>&|=!?():"\',/;[]', '/').']/i', $s)) { + if ($returnvalue) { + return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s); + return ''; + } + } + } + if (strpos($s, '::') !== false) { + if ($returnvalue) { + return 'Bad string syntax to evaluate (double : char is forbidden): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (double : char is forbidden): '.$s); + return ''; + } + } if (strpos($s, '`') !== false) { - return 'Bad string syntax to evaluate: '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate (backtick char is forbidden): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (backtick char is forbidden): '.$s); + return ''; + } + } + if (strpos($s, '.') !== false) { + if ($returnvalue) { + return 'Bad string syntax to evaluate (dot char is forbidden): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (dot char is forbidden): '.$s); + return ''; + } } // We block use of php exec or php file functions $forbiddenphpstrings = array('$$'); $forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST')); - $forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI"); - $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "unlink", "mkdir", "rmdir", "symlink", "touch", "umask")); + $forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI", 'verifCond'); + $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "require", "include", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func")); $forbiddenphpregex = 'global\s+\$|\b('.implode('|', $forbiddenphpfunctions).')\b'; @@ -8359,7 +8429,12 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1) if (strpos($s, '__forbiddenstring__') !== false) { dol_syslog('Bad string syntax to evaluate: '.$s, LOG_WARNING); - return 'Bad string syntax to evaluate: '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate: '.$s; + } else { + dol_syslog('Bad string syntax to evaluate: '.$s); + return ''; + } } //print $s."
    \n"; @@ -8695,7 +8770,7 @@ function getLanguageCodeFromCountryCode($countrycode) */ function complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode = 'add') { - global $hookmanager; + global $hookmanager, $db; if (isset($conf->modules_parts['tabs'][$type]) && is_array($conf->modules_parts['tabs'][$type])) { foreach ($conf->modules_parts['tabs'][$type] as $value) { @@ -8716,7 +8791,20 @@ function complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, complete_substitutions_array($substitutionarray, $langs, $object, array('needforkey'=>$values[2])); $label = make_substitutions($reg[1], $substitutionarray); } else { - $label = $langs->trans($values[2]); + $labeltemp = explode(':', $values[2]); + $label = $langs->trans($labeltemp[0]); + if (!empty($labeltemp[1]) && is_object($object) && !empty($object->id)) { + dol_include_once($labeltemp[2]); + $classtoload = $labeltemp[1]; + if (class_exists($classtoload)) { + $obj = new $classtoload($db); + $function = $labeltemp[3]; + if ($obj && $function && method_exists($obj, $function)) { + $nbrec = $obj->$function($object->id, $obj); + $label .= ''.$nbrec.''; + } + } + } } $head[$h][0] = dol_buildpath(preg_replace('/__ID__/i', ((is_object($object) && !empty($object->id)) ? $object->id : ''), $values[5]), 1); @@ -9052,6 +9140,7 @@ function dol_getmypid() * 3=value is list of string separated with comma (Example 'text 1,text 2'), 4=value is a list of ID separated with comma (Example '2,7') to be used to search into a multiselect string '1,2,3,4' * @param integer $nofirstand 1=Do not output the first 'AND' * @return string $res The statement to append to the SQL query + * @see dolSqlDateFilter() */ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) { @@ -10063,19 +10152,19 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st * @param int $userRight user action right * // phpcs:disable * @param array $params = [ // Various params for future : recommended rather than adding more function arguments - * 'attr' => [ // to add or override button attributes - * 'xxxxx' => '', // your xxxxx attribute you want - * 'class' => '', // to add more css class to the button class attribute - * 'classOverride' => '' // to replace class attribute of the button - * ], - * 'confirm' => [ - * 'url' => 'http://', // Overide Url to go when user click on action btn, if empty default url is $url.?confirm=yes, for no js compatibility use $url for fallback confirm. - * 'title' => '', // Overide title of modal, if empty default title use "ConfirmBtnCommonTitle" lang key - * 'action-btn-label' => '', // Overide label of action button, if empty default label use "Confirm" lang key - * 'cancel-btn-label' => '', // Overide label of cancel button, if empty default label use "CloseDialog" lang key - * 'content' => '', // Overide text of content, if empty default content use "ConfirmBtnCommonContent" lang key - * 'modal' => true, // true|false to display dialog as a modal (with dark background) - * ], + * 'attr' => [ // to add or override button attributes + * 'xxxxx' => '', // your xxxxx attribute you want + * 'class' => '', // to add more css class to the button class attribute + * 'classOverride' => '' // to replace class attribute of the button + * ], + * 'confirm' => [ + * 'url' => 'http://', // Overide Url to go when user click on action btn, if empty default url is $url.?confirm=yes, for no js compatibility use $url for fallback confirm. + * 'title' => '', // Overide title of modal, if empty default title use "ConfirmBtnCommonTitle" lang key + * 'action-btn-label' => '', // Overide label of action button, if empty default label use "Confirm" lang key + * 'cancel-btn-label' => '', // Overide label of cancel button, if empty default label use "CloseDialog" lang key + * 'content' => '', // Overide text of content, if empty default content use "ConfirmBtnCommonContent" lang key + * 'modal' => true, // true|false to display dialog as a modal (with dark background) + * ], * ] * // phpcs:enable * @return string html button @@ -10087,7 +10176,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = $class = 'butAction'; if ($actionType == 'danger' || $actionType == 'delete') { $class = 'butActionDelete'; - if (strpos($url, 'token=') === false) $url .= '&token='.newToken(); + if (!empty($url) && strpos($url, 'token=') === false) $url .= '&token='.newToken(); } $attr = array( @@ -10098,6 +10187,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = if (empty($html)) { $html = $label; + $attr['title'] = ''; // if html not set, leave label on title is redundant } else { $attr['aria-label'] = $label; } @@ -10111,6 +10201,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = $attr['id'] = $id; } + // Override attr if (!empty($params['attr']) && is_array($params['attr'])) { foreach ($params['attr'] as $key => $value) { @@ -10124,6 +10215,11 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = } } + // automatic add tooltip when title is detected + if (!empty($attr['title']) && !empty($attr['class']) && strpos($attr['class'], 'classfortooltip') === false) { + $attr['class'].= ' classfortooltip'; + } + // Js Confirm button if ($userRight && !empty($params['confirm'])) { if (!is_array($params['confirm'])) { @@ -10501,7 +10597,7 @@ function isAFileWithExecutableContent($filename) */ function newToken() { - return $_SESSION['newtoken']; + return empty($_SESSION['newtoken']) ? '' : $_SESSION['newtoken']; } /** @@ -10817,6 +10913,9 @@ function dolForgeCriteriaCallback($matches) $operand = preg_replace('/[^a-z0-9\._]/i', '', trim($tmp[0])); $operator = strtoupper(preg_replace('/[^a-z<>=]/i', '', trim($tmp[1]))); + if ($operator == 'NOTLIKE') { + $operator = 'NOT LIKE'; + } $tmpescaped = trim($tmp[2]); $regbis = array(); diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 3a0b077be6b..8c419eec3c9 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -628,7 +628,7 @@ function dol_print_object_info($object, $usetable = 0) if ($usetable) { print '
    '; } - print $langs->trans("ConciliatedBy"); + print $langs->trans("ReconciledBy"); if ($usetable) { print ''; } else { @@ -1451,14 +1451,17 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $ // Now we replace the counter $maskbefore = '{'.$masktri.'}'; $maskafter = str_pad($counter, dol_strlen($maskcounter), "0", STR_PAD_LEFT); - //print 'x'.$maskbefore.'-'.$maskafter.'y'; + //print 'x'.$numFinal.' - '.$maskbefore.' - '.$maskafter.'y';exit; $numFinal = str_replace($maskbefore, $maskafter, $numFinal); // Now we replace the refclient if ($maskrefclient) { - //print "maskrefclient=".$maskrefclient." maskwithonlyymcode=".$maskwithonlyymcode." maskwithnocode=".$maskwithnocode." maskrefclient_clientcode=".$maskrefclient_clientcode."\n
    ";exit; + //print "maskrefclient=".$maskrefclient." maskrefclient_counter=".$maskrefclient_counter." maskwithonlyymcode=".$maskwithonlyymcode." maskwithnocode=".$maskwithnocode." maskrefclient_clientcode=".$maskrefclient_clientcode." maskrefclient_maskcounter=".$maskrefclient_maskcounter."\n
    ";exit; $maskrefclient_maskbefore = '{'.$maskrefclient.'}'; - $maskrefclient_maskafter = $maskrefclient_clientcode.str_pad($maskrefclient_counter, dol_strlen($maskrefclient_maskcounter), "0", STR_PAD_LEFT); + $maskrefclient_maskafter = $maskrefclient_clientcode; + if (dol_strlen($maskrefclient_maskcounter) > 0) { + $maskrefclient_maskafter .= str_pad($maskrefclient_counter, dol_strlen($maskrefclient_maskcounter), "0", STR_PAD_LEFT); + } $numFinal = str_replace($maskrefclient_maskbefore, $maskrefclient_maskafter, $numFinal); } diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index 8d992250cbb..64cc4388718 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -225,7 +225,14 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation = } // Common check on ip (local and external) - $arrayofmetadataserver = array('100.100.100.200' => 'Alibaba', '192.0.0.192'=> 'Oracle', '192.80.8.124'=>'Packet'); + // See list on https://tagmerge.com/gist/a7b9d57ff8ec11d63642f8778609a0b8 + // Not evasive url that ar enot IP are excluded by test on IP v4/v6 validity. + $arrayofmetadataserver = array( + '100.100.100.200' => 'Alibaba', + '192.0.0.192' => 'Oracle', + '192.80.8.124' => 'Packet', + '100.88.222.5' => 'Tencent cloud', + ); foreach ($arrayofmetadataserver as $ipofmetadataserver => $nameofmetadataserver) { if ($iptocheck == $ipofmetadataserver) { $info['http_code'] = 400; diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index 6b973d89887..b8202b8e361 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -590,6 +590,7 @@ function vignette($file, $maxWidth = 160, $maxHeight = 120, $extName = '_small', break; } + // Before PHP8, img was a resource, With PHP8, it is a GdImage if (!is_resource($img) && !($img instanceof \GdImage)) { dol_syslog('Failed to detect type of image. We found infoImg[2]='.$infoImg[2], LOG_WARNING); return 0; diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index c6f972f46c8..7c24d17d61e 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -546,7 +546,7 @@ function getNumberInvoicesPieChart($mode) ,array($langs->trans('InvoiceNotLate15Days'), $obj->nbnotlate15 - $obj->nbnotlate30) ,array($langs->trans('InvoiceNotLate30Days'), $obj->nbnotlate30)); */ - $dataseries[$i]=array($langs->trans('NbOfOpenInvoices'), $obj->nblate30, $obj->nblate15 - $obj->nblate30, $obj->nblatenow - $obj->nblate15, $obj->nbnotlatenow - $obj->nbnotlate15, $obj->nbnotlate15 - $obj->nbnotlate30, $obj->nbnotlate30); + $dataseries[$i]=array($langs->transnoentitiesnoconv('NbOfOpenInvoices'), $obj->nblate30, $obj->nblate15 - $obj->nblate30, $obj->nblatenow - $obj->nblate15, $obj->nbnotlatenow - $obj->nbnotlate15, $obj->nbnotlate15 - $obj->nbnotlate30, $obj->nbnotlate30); $i++; } if (!empty($dataseries[0])) { diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index a0c6bcfd054..37223701ff7 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1130,6 +1130,11 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $pdf->SetFont('', '', 7); $pdf->SetDrawColor(224, 224, 224); + // Option for footer text color + if (!empty($conf->global->PDF_FOOTER_TEXT_COLOR)) { + list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d'); + $pdf->SetTextColor($r, $g, $b); + } // The start of the bottom of this page footer is positioned according to # of lines $freetextheight = 0; @@ -1161,9 +1166,17 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $marginwithfooter = $marge_basse + $freetextheight + $mycustomfooterheight; $posy = $marginwithfooter + 0; + // Option for footer background color (without freetext zone) + if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) { + list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d'); + $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak + $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b)); + $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak + } + if ($line) { // Free text $pdf->SetXY($dims['lm'], -$posy); - if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { // by default + if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default $pdf->MultiCell(0, 3, $line, 0, $align, 0); } else { $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); @@ -1172,10 +1185,23 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ } $pdf->SetY(-$posy); - $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); - $posy--; - $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $freetextheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0)); + // Hide footer line if footer background color is set + if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) { + $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); + } + + // Option for set top margin height of footer after freetext + if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalString('PDF_FOOTER_TOP_MARGIN') === '0') { + // TODO Remove this case. Height should be good automatically, only $posy-- should be required. + $posy -= getDolGlobalInt('PDF_FOOTER_TOP_MARGIN'); + } else { + $posy--; + } + + if (getDolGlobalString('PDF_FOOTER_DISABLE_PAGEBREAK') === '1') { $pdf->SetAutoPageBreak(0, 0); } // Option for disable auto pagebreak + $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $mycustomfooterheight, $dims['lm'], $dims['hk'] - $posy, dol_htmlentitiesbr($mycustomfooter, 1, 'UTF-8', 0)); + if (getDolGlobalString('PDF_FOOTER_DISABLE_PAGEBREAK') === '1') { $pdf->SetAutoPageBreak(1, 0); } // Restore pagebreak $posy -= $mycustomfooterheight - 3; } else { @@ -1183,9 +1209,17 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $marginwithfooter = $marge_basse + $freetextheight + (!empty($line1) ? 3 : 0) + (!empty($line2) ? 3 : 0) + (!empty($line3) ? 3 : 0) + (!empty($line4) ? 3 : 0); $posy = $marginwithfooter + 0; + // Option for footer background color (without freetext zone) + if (getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) { + list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_BACKGROUND_COLOR, '%d, %d, %d'); + $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak + $pdf->Rect(0, $dims['hk'] - $posy + $freetextheight, $dims['wk'] + 1, $marginwithfooter + 1, 'F', '', $fill_color = array($r, $g, $b)); + $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak + } + if ($line) { // Free text $pdf->SetXY($dims['lm'], -$posy); - if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { // by default + if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) { // by default $pdf->MultiCell(0, 3, $line, 0, $align, 0); } else { $pdf->writeHTMLCell($pdf->page_largeur - $pdf->margin_left - $pdf->margin_right, $freetextheight, $dims['lm'], $dims['hk'] - $marginwithfooter, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); @@ -1194,8 +1228,19 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ } $pdf->SetY(-$posy); - $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); - $posy--; + + // Hide footer line if footer background color is set + if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) { + $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); + } + + // Option for set top margin height of footer after freetext + if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalString('PDF_FOOTER_TOP_MARGIN') === '0') { + // TODO Remove this case. Height should be good automatically, only $posy-- should be required. + $posy -= getDolGlobalString('PDF_FOOTER_TOP_MARGIN'); + } else { + $posy--; + } if (!empty($line1)) { $pdf->SetFont('', 'B', 7); @@ -1393,7 +1438,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $note = $prodser->multilangs[$outputlangs->defaultlang]["other"]; } } - } elseif ($object->element == 'facture' || $object->element == 'facturefourn') { + } elseif (($object->element == 'facture' || $object->element == 'facturefourn') && preg_match('/^\(DEPOSIT\).+/', $desc)) { // We must not replace '(DEPOSIT)' when it is alone, it will be translated and detailed later $desc = str_replace('(DEPOSIT)', $outputlangs->trans('Deposit'), $desc); } diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 90a67991413..15162c8b273 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -1561,8 +1561,8 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $disabledtask = 1; } - // Form to add new time - print '
    '; + // Select hour + print ''; $tableCell = $form->selectDate($preselectedday, $lines[$i]->id, 1, 1, 2, "addtime", 0, 0, $disabledtask); print $tableCell; print '
    '; + + // List of directories area + $texte .= ''; + + $texte .= ''; + $texte .= ''; + + $texte .= '
    '; + $texttitle = $langs->trans("ListOfDirectories"); + $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->ASSET_ASSET_ADDON_PDF_ODT_PATH))); + $listoffiles = array(); + foreach ($listofdir as $key => $tmpdir) { + $tmpdir = trim($tmpdir); + $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir); + if (!$tmpdir) { + unset($listofdir[$key]); + continue; + } + if (!is_dir($tmpdir)) { + $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0); + } else { + $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)'); + if (count($tmpfiles)) { + $listoffiles = array_merge($listoffiles, $tmpfiles); + } + } + } + $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp .= '
    '.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
    '; + $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1); + $texte .= '
    '; + $texte .= ''; + $texte .= '
    '; + $texte .= ''; + $texte .= '
    '; + + // Scan directories + $nbofiles = count($listoffiles); + if (!empty($conf->global->ASSET_ASSET_ADDON_PDF_ODT_PATH)) { + $texte .= $langs->trans("NumberOfModelFilesFound").': '; + //$texte.=$nbofiles?'':''; + $texte .= count($listoffiles); + //$texte.=$nbofiles?'':''; + $texte .= ''; + } + + if ($nbofiles) { + $texte .= ''; + } + + $texte .= '
    '; + $texte .= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte .= '
    '; + $texte .= ''; + + return $texte; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Function to build a document on disk using the generic odt module. + * + * @param Asset $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1 if OK, <=0 if KO + */ + public function write_file($object, $outputlangs, $srctemplatepath, $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + // phpcs:enable + global $user, $langs, $conf, $mysoc, $hookmanager; + + if (empty($srctemplatepath)) { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + // Add odtgeneration hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + + if (!is_object($outputlangs)) { + $outputlangs = $langs; + } + $sav_charset_output = $outputlangs->charset_output; + $outputlangs->charset_output = 'UTF-8'; + + $outputlangs->loadLangs(array("main", "dict", "companies", "bills")); + + if ($conf->asset->dir_output) { + // If $object is id instead of object + if (!is_object($object)) { + $id = $object; + $object = new Asset($this->db); + $result = $object->fetch($id); + if ($result < 0) { + dol_print_error($this->db, $object->error); + return -1; + } + } + + $object->fetch_thirdparty(); + + $dir = $conf->asset->multidir_output[isset($object->entity) ? $object->entity : 1]; + $objectref = dol_sanitizeFileName($object->ref); + if (!preg_match('/specimen/i', $objectref)) { + $dir .= "/".$objectref; + } + $file = $dir."/".$objectref.".odt"; + + if (!file_exists($dir)) { + if (dol_mkdir($dir) < 0) { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return -1; + } + } + + if (file_exists($dir)) { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile = basename($srctemplatepath); + $newfiletmp = preg_replace('/\.od(t|s)/i', '', $newfile); + $newfiletmp = preg_replace('/template_/i', '', $newfiletmp); + $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp); + $newfiletmp = $objectref.'_'.$newfiletmp; + //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + // Get extension (ods or odt) + $newfileformat = substr($newfile, strrpos($newfile, '.') + 1); + if (!empty($conf->global->MAIN_DOC_USE_TIMING)) { + $format = $conf->global->MAIN_DOC_USE_TIMING; + if ($format == '1') { + $format = '%Y%m%d%H%M%S'; + } + $filename = $newfiletmp.'-'.dol_print_date(dol_now(), $format).'.'.$newfileformat; + } else { + $filename = $newfiletmp.'.'.$newfileformat; + } + $file = $dir.'/'.$filename; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + + dol_mkdir($conf->asset->dir_temp); + if (!is_writable($conf->asset->dir_temp)) { + $this->error = "Failed to write in temp directory ".$conf->asset->dir_temp; + dol_syslog('Error in write_file: '.$this->error, LOG_ERR); + return -1; + } + + // If CUSTOMER contact defined on order, we use it + $usecontact = false; + $arrayidcontact = $object->getIdContact('external', 'CUSTOMER'); + if (count($arrayidcontact) > 0) { + $usecontact = true; + $result = $object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + $contactobject = null; + if (!empty($usecontact)) { + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; + } else { + $socobject = $object->thirdparty; + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use + $contactobject = $object->contact; + } + } else { + $socobject = $object->thirdparty; + } + + // Make substitution + $substitutionarray = array( + '__FROM_NAME__' => $this->emetteur->name, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_tva + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$substitutionarray); + $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + // Line of free text + $newfreetext = ''; + $paramfreetext = 'ORDER_FREE_TEXT'; + if (!empty($conf->global->$paramfreetext)) { + $newfreetext = make_substitutions($conf->global->$paramfreetext, $substitutionarray); + } + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + try { + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->asset->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + } catch (Exception $e) { + $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); + return -1; + } + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + // Make substitutions into odt of freetext + try { + $odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8'); + } catch (OdfException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } + + // Define substitution array + $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object); + $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs); + $array_objet = $this->get_substitutionarray_object($object, $outputlangs); + $array_user = $this->get_substitutionarray_user($user, $outputlangs); + $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs); + $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs); + $array_other = $this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in object as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact && is_object($contactobject)) { + $array_thirdparty_contact = $this->get_substitutionarray_contact($contactobject, $outputlangs, 'contact'); + } + + $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other, $array_thirdparty_contact); + complete_substitutions_array($tmparray, $outputlangs, $object); + + // Call the ODTSubstitution hook + $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray); + $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + foreach ($tmparray as $key => $value) { + try { + if (preg_match('/logo$/', $key)) { + // Image + if (file_exists($value)) { + $odfHandler->setImage($key, $value); + } else { + $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + } else { + // Text + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } catch (OdfException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } + } + // Replace tags of lines + try { + $foundtagforlines = 1; + try { + $listlines = $odfHandler->setSegment('lines'); + } catch (OdfException $e) { + // We may arrive here if tags for lines not present into template + $foundtagforlines = 0; + dol_syslog($e->getMessage(), LOG_INFO); + } + if ($foundtagforlines) { + $linenumber = 0; + foreach ($object->lines as $line) { + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); + complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); + $reshook = $hookmanager->executeHooks('ODTSubstitutionLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + foreach ($tmparray as $key => $val) { + try { + $listlines->setVars($key, $val, true, 'UTF-8'); + } catch (OdfException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } catch (SegmentException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + } catch (OdfException $e) { + $this->error = $e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace labels translated + $tmparray = $outputlangs->get_translations_for_substitutions(); + foreach ($tmparray as $key => $value) { + try { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } catch (OdfException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } + } + + // Call the beforeODTSave hook + + $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray); + $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + // Write new file + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + try { + $odfHandler->exportAsAttachedPDF($file); + } catch (Exception $e) { + $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); + return -1; + } + } else { + try { + $odfHandler->saveToDisk($file); + } catch (Exception $e) { + $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); + return -1; + } + } + + $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray); + $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + if (!empty($conf->global->MAIN_UMASK)) { + @chmod($file, octdec($conf->global->MAIN_UMASK)); + } + + $odfHandler = null; // Destroy object + + $this->result = array('fullpath'=>$file); + + return 1; // Success + } else { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return -1; + } + } + + return -1; + } +} diff --git a/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php b/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php new file mode 100644 index 00000000000..de378ee79a8 --- /dev/null +++ b/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php @@ -0,0 +1,1375 @@ + + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2014 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file core/modules/asset/doc/pdf_standard.modules.php + * \ingroup asset + * \brief File of class to generate document from standard template + */ + +dol_include_once('/asset/core/modules/asset/modules_asset.php'); +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; + + +/** + * Class to manage PDF template standard_asset + */ +class pdf_standard_asset extends ModelePDFAsset +{ + /** + * @var DoliDb Database handler + */ + public $db; + + /** + * @var string model name + */ + public $name; + + /** + * @var string model description (short text) + */ + public $description; + + /** + * @var int Save the name of generated file as the main doc when generating a doc with this template + */ + public $update_main_doc_field; + + /** + * @var string document type + */ + public $type; + + /** + * @var array Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.6 = array(5, 6) + */ + public $phpmin = array(5, 6); + + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; + + /** + * @var int page_largeur + */ + public $page_largeur; + + /** + * @var int page_hauteur + */ + public $page_hauteur; + + /** + * @var array format + */ + public $format; + + /** + * @var int marge_gauche + */ + public $marge_gauche; + + /** + * @var int marge_droite + */ + public $marge_droite; + + /** + * @var int marge_haute + */ + public $marge_haute; + + /** + * @var int marge_basse + */ + public $marge_basse; + + /** + * Issuer + * @var Societe Object that emits + */ + public $emetteur; + + /** + * @var bool Situation invoice type + */ + public $situationinvoice; + + + /** + * @var array of document table columns + */ + public $cols; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf, $langs, $mysoc; + + // Translations + $langs->loadLangs(array("main", "bills")); + + $this->db = $db; + $this->name = "standard"; + $this->description = $langs->trans('DocumentModelStandardPDF'); + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + + // Dimension page + $this->type = 'pdf'; + $formatarray = pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur, $this->page_hauteur); + $this->marge_gauche = isset($conf->global->MAIN_PDF_MARGIN_LEFT) ? $conf->global->MAIN_PDF_MARGIN_LEFT : 10; + $this->marge_droite = isset($conf->global->MAIN_PDF_MARGIN_RIGHT) ? $conf->global->MAIN_PDF_MARGIN_RIGHT : 10; + $this->marge_haute = isset($conf->global->MAIN_PDF_MARGIN_TOP) ? $conf->global->MAIN_PDF_MARGIN_TOP : 10; + $this->marge_basse = isset($conf->global->MAIN_PDF_MARGIN_BOTTOM) ? $conf->global->MAIN_PDF_MARGIN_BOTTOM : 10; + + // Get source company + $this->emetteur = $mysoc; + if (empty($this->emetteur->country_code)) { + $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined + } + + // Define position of columns + $this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff + + + $this->tabTitleHeight = 5; // default height + + // Use new system for position of columns, view $this->defineColumnField() + + $this->tva = array(); + $this->localtax1 = array(); + $this->localtax2 = array(); + $this->atleastoneratenotnull = 0; + $this->atleastonediscount = 0; + $this->situationinvoice = false; + } + + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Function to build pdf onto disk + * + * @param Object $object Object to generate + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO + */ + public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + // phpcs:enable + global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines; + + dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null')); + + if (!is_object($outputlangs)) { + $outputlangs = $langs; + } + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (!empty($conf->global->MAIN_USE_FPDF)) { + $outputlangs->charset_output = 'ISO-8859-1'; + } + + // Load translation files required by the page + $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies")); + + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) { + global $outputlangsbis; + $outputlangsbis = new Translate('', $conf); + $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE); + $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies")); + } + + $nblines = (is_array($object->lines) ? count($object->lines) : 0); + + $hidetop = 0; + if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) { + $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE; + } + + // Loop on each lines to detect if there is at least one image to show + $realpatharray = array(); + $this->atleastonephoto = false; + /* + if (!empty($conf->global->MAIN_GENERATE_ASSET_WITH_PICTURE)) + { + $objphoto = new Product($this->db); + + for ($i = 0; $i < $nblines; $i++) + { + if (empty($object->lines[$i]->fk_product)) continue; + + //var_dump($objphoto->ref);exit; + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { + $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; + $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/'; + } else { + $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default + $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative + } + + $arephoto = false; + foreach ($pdir as $midir) + { + if (!$arephoto) + { + $dir = $conf->product->dir_output.'/'.$midir; + + foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) + { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + { + if ($obj['photo_vignette']) + { + $filename = $obj['photo_vignette']; + } else { + $filename = $obj['photo']; + } + } else { + $filename = $obj['photo']; + } + + $realpath = $dir.$filename; + $arephoto = true; + $this->atleastonephoto = true; + } + } + } + + if ($realpath && $arephoto) $realpatharray[$i] = $realpath; + } + } + */ + + //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva; + + if ($conf->asset->dir_output.'/asset') { + $object->fetch_thirdparty(); + + // Definition of $dir and $file + if ($object->specimen) { + $dir = $conf->asset->dir_output.'/asset'; + $file = $dir."/SPECIMEN.pdf"; + } else { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->asset->dir_output.'/asset/'.$objectref; + $file = $dir."/".$objectref.".pdf"; + } + if (!file_exists($dir)) { + if (dol_mkdir($dir) < 0) { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + } + + if (file_exists($dir)) { + // Add pdfgeneration hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + + // Set nblines with the new facture lines content after hook + $nblines = (is_array($object->lines) ? count($object->lines) : 0); + + // Create pdf instance + $pdf = pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance + $pdf->SetAutoPageBreak(1, 0); + + $heightforinfotot = 50; // Height reserved to output the info and total part and payment part + $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin) + + if (class_exists('TCPDF')) { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + + // Set path to the background PDF File + if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { + $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb = 0; + $pdf->SetDrawColor(128, 128, 128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("PdfTitle")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) { + $pdf->SetCompression(false); + } + + // Set certificate + $cert = empty($user->conf->CERTIFICATE_CRT) ? '' : $user->conf->CERTIFICATE_CRT; + // If user has no certificate, we try to take the company one + if (!$cert) { + $cert = empty($conf->global->CERTIFICATE_CRT) ? '' : $conf->global->CERTIFICATE_CRT; + } + // If a certificate is found + if ($cert) { + $info = array( + 'Name' => $this->emetteur->name, + 'Location' => getCountry($this->emetteur->country_code, 0), + 'Reason' => 'ASSET', + 'ContactInfo' => $this->emetteur->email + ); + $pdf->setSignature($cert, $cert, $this->emetteur->name, '', 2, $info); + } + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + // New page + $pdf->AddPage(); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + $pagenb++; + + $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0, 0, 0); + + $tab_top = 90 + $top_shift; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10); + $tab_height = 130 - $top_shift; + $tab_height_newpage = 150; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { + $tab_height_newpage -= $top_shift; + } + + $nexY = $tab_top - 1; + + // Display notes + $notetoshow = empty($object->note_public) ? '' : $object->note_public; + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + + $pagenb = $pdf->getPage(); + if ($notetoshow) { + $tab_top -= 2; + + $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite; + $pageposbeforenote = $pagenb; + + $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs); + $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow); + + $pdf->startTransaction(); + + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + // Description + $pageposafternote = $pdf->getPage(); + $posyafter = $pdf->GetY(); + + if ($pageposafternote > $pageposbeforenote) { + $pdf->rollbackTransaction(true); + + // prepare pages to receive notes + while ($pagenb < $pageposafternote) { + $pdf->AddPage(); + $pagenb++; + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { + $this->_pagehead($pdf, $object, 0, $outputlangs); + } + // $this->_pagefoot($pdf,$object,$outputlangs,1); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + } + + // back to start + $pdf->setPage($pageposbeforenote); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + $pageposafternote = $pdf->getPage(); + + $posyafter = $pdf->GetY(); + + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { // There is no space left for total+free text + $pdf->AddPage('', '', true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + //$posyafter = $tab_top_newpage; + } + + + // apply note frame to previous pages + $i = $pageposbeforenote; + while ($i < $pageposafternote) { + $pdf->setPage($i); + + + $pdf->SetDrawColor(128, 128, 128); + // Draw note frame + if ($i > $pageposbeforenote) { + $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); + } else { + $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); + } + + // Add footer + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $this->_pagefoot($pdf, $object, $outputlangs, 1); + + $i++; + } + + // apply note frame to last page + $pdf->setPage($pageposafternote); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { + $this->_pagehead($pdf, $object, 0, $outputlangs); + } + $height_note = $posyafter - $tab_top_newpage; + $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); + } else // No pagebreak + { + $pdf->commitTransaction(); + $posyafter = $pdf->GetY(); + $height_note = $posyafter - $tab_top; + $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1); + + + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) { + // not enough space, need to add page + $pdf->AddPage('', '', true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { + $this->_pagehead($pdf, $object, 0, $outputlangs); + } + + $posyafter = $tab_top_newpage; + } + } + + $tab_height = $tab_height - $height_note; + $tab_top = $posyafter + 6; + } else { + $height_note = 0; + } + + // Use new auto column system + $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref); + + // Table simulation to know the height of the title line + $pdf->startTransaction(); + $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop); + $pdf->rollbackTransaction(true); + + $nexY = $tab_top + $this->tabTitleHeight; + + // Loop on each lines + $pageposbeforeprintlines = $pdf->getPage(); + $pagenb = $pageposbeforeprintlines; + for ($i = 0; $i < $nblines; $i++) { + $curY = $nexY; + $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0, 0, 0); + + // Define size of image if we need it + $imglinesize = array(); + if (!empty($realpatharray[$i])) { + $imglinesize = pdf_getSizeForImage($realpatharray[$i]); + } + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore = $pdf->getPage(); + + $showpricebeforepagebreak = 1; + $posYAfterImage = 0; + + if ($this->getColumnStatus('photo')) { + // We start with Photo of product line + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page + $pdf->AddPage('', '', true); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + $pdf->setPage($pageposbefore + 1); + + $curY = $tab_top_newpage; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) { + $showpricebeforepagebreak = 1; + } else { + $showpricebeforepagebreak = 0; + } + } + + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + // $pdf->Image does not increase value return by getY, so we save it manually + $posYAfterImage = $curY + $imglinesize['height']; + } + } + + // Description of product line + if ($this->getColumnStatus('desc')) { + $pdf->startTransaction(); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); + $pageposafter = $pdf->getPage(); + + if ($pageposafter > $pageposbefore) { // There is a pagebreak + $pdf->rollbackTransaction(true); + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); + + $pageposafter = $pdf->getPage(); + $posyafter = $pdf->GetY(); + //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; + if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text + if ($i == ($nblines - 1)) { // No more lines, and no space left to show total, so we create a new page + $pdf->AddPage('', '', true); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + $pdf->setPage($pageposafter + 1); + } + } else { + // We found a page break + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) { + $showpricebeforepagebreak = 1; + } else { + $showpricebeforepagebreak = 0; + } + } + } else // No pagebreak + { + $pdf->commitTransaction(); + } + } + + $nexY = $pdf->GetY(); + $pageposafter = $pdf->getPage(); + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description or photo were moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut + + // Quantity + // Enough for 6 chars + if ($this->getColumnStatus('qty')) { + $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'qty', $qty); + $nexY = max($pdf->GetY(), $nexY); + } + + // Extrafields + if (!empty($object->lines[$i]->array_options)) { + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) { + if ($this->getColumnStatus($extrafieldColKey)) { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } + + + $parameters = array( + 'object' => $object, + 'i' => $i, + 'pdf' =>& $pdf, + 'curY' =>& $curY, + 'nexY' =>& $nexY, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails + ); + $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook + + + $sign = 1; + // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva + $prev_progress = $object->lines[$i]->get_prev_progress($object->id); + if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) { // Compute progress from previous situation + if (!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) { + $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent; + } else { + $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent; + } + } else { + if (!empty($conf->multicurrency->enabled) && $object->multicurrency_tx != 1) { + $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva; + } else { + $tvaligne = $sign * $object->lines[$i]->total_tva; + } + } + + $localtax1ligne = $object->lines[$i]->total_localtax1; + $localtax2ligne = $object->lines[$i]->total_localtax2; + $localtax1_rate = $object->lines[$i]->localtax1_tx; + $localtax2_rate = $object->lines[$i]->localtax2_tx; + $localtax1_type = $object->lines[$i]->localtax1_type; + $localtax2_type = $object->lines[$i]->localtax2_type; + + if ($object->remise_percent) { + $tvaligne -= ($tvaligne * $object->remise_percent) / 100; + } + if ($object->remise_percent) { + $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100; + } + if ($object->remise_percent) { + $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100; + } + + $vatrate = (string) $object->lines[$i]->tva_tx; + + // Retrieve type from database for backward compatibility with old records + if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined + && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax + $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); + $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : ''; + $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : ''; + } + + // retrieve global local tax + if ($localtax1_type && $localtax1ligne != 0) { + $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne; + } + if ($localtax2_type && $localtax2ligne != 0) { + $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne; + } + + if (($object->lines[$i]->info_bits & 0x01) == 0x01) { + $vatrate .= '*'; + } + if (!isset($this->tva[$vatrate])) { + $this->tva[$vatrate] = 0; + } + $this->tva[$vatrate] += $tvaligne; + + $nexY = max($nexY, $posYAfterImage); + + // Add line + if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); + $pdf->SetLineStyle(array('dash'=>0)); + } + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) { + $pdf->setPage($pagenb); + if ($pagenb == $pageposbeforeprintlines) { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); + } else { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); + } + $this->_pagefoot($pdf, $object, $outputlangs, 1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { + $this->_pagehead($pdf, $object, 0, $outputlangs); + } + } + + if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { + if ($pagenb == $pageposafter) { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); + } else { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); + } + $this->_pagefoot($pdf, $object, $outputlangs, 1); + // New page + $pdf->AddPage(); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { + $this->_pagehead($pdf, $object, 0, $outputlangs); + } + } + } + + // Show square + if ($pagenb == $pageposbeforeprintlines) { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis); + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } else { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis); + $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } + + // Display infos area + //$posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs); + + // Display total zone + //$posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); + + // Display payment area + /* + if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS)) + { + $posy = $this->drawPaymentsTable($pdf, $object, $posy, $outputlangs); + } + */ + + // Pagefoot + $this->_pagefoot($pdf, $object, $outputlangs); + if (method_exists($pdf, 'AliasNbPages')) { + $pdf->AliasNbPages(); + } + + $pdf->Close(); + + $pdf->Output($file, 'F'); + + // Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + } + + if (!empty($conf->global->MAIN_UMASK)) { + @chmod($file, octdec($conf->global->MAIN_UMASK)); + } + + $this->result = array('fullpath'=>$file); + + return 1; // No error + } else { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return 0; + } + } else { + $this->error = $langs->transnoentities("ErrorConstantNotDefined", "FAC_OUTPUTDIR"); + return 0; + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + public static function liste_modeles($db, $maxfilenamelength = 0) + { + // phpcs:enable + return parent::liste_modeles($db, $maxfilenamelength); // TODO: Change the autogenerated stub + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show table for lines + * + * @param tcpdf $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y (not used) + * @param Translate $outputlangs Langs object + * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title + * @param int $hidebottom Hide bottom bar of array + * @param string $currency Currency code + * @param Translate $outputlangsbis Langs object bis + * @return void + */ + protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null) + { + global $conf; + + // Force to disable hidetop and hidebottom + $hidebottom = 0; + if ($hidetop) { + $hidetop = -1; + } + + $currency = !empty($currency) ? $currency : $conf->currency; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + + if (empty($hidetop)) { + $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency)); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency)); + } + + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; + if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) { + $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)); + } + } + + $pdf->SetDrawColor(128, 128, 128); + $pdf->SetFont('', '', $default_font_size - 1); + + // Output Rect + $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter + + + $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop); + + if (empty($hidetop)) { + $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show top header of page. + * + * @param Tcpdf $pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @param Translate $outputlangsbis Object lang for output bis + * @return void + */ + protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null) + { + global $conf, $langs; + + // Load traductions files required by page + $outputlangs->loadLangs(array("main", "bills", "propal", "companies")); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf, $outputlangs, $this->page_hauteur); + + // Show Draft Watermark + if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK))) { + pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK); + } + + $pdf->SetTextColor(0, 0, 60); + $pdf->SetFont('', 'B', $default_font_size + 3); + + $w = 110; + + $posy = $this->marge_haute; + $posx = $this->page_largeur - $this->marge_droite - $w; + + $pdf->SetXY($this->marge_gauche, $posy); + + // Logo + if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) { + if ($this->emetteur->logo) { + $logodir = $conf->mycompany->dir_output; + if (!empty($conf->mycompany->multidir_output[$object->entity])) { + $logodir = $conf->mycompany->multidir_output[$object->entity]; + } + if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) { + $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; + } else { + $logo = $logodir.'/logos/'.$this->emetteur->logo; + } + if (is_readable($logo)) { + $height = pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } else { + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L'); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } else { + $text = $this->emetteur->name; + $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + } + + $pdf->SetFont('', 'B', $default_font_size + 3); + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $title = $outputlangs->transnoentities("PdfTitle"); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title .= ' - '; + $title .= $outputlangsbis->transnoentities("PdfTitle"); + } + $pdf->MultiCell($w, 3, $title, '', 'R'); + + $pdf->SetFont('', 'B', $default_font_size); + + $posy += 5; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref); + if ($object->statut == $object::STATUS_DRAFT) { + $pdf->SetTextColor(128, 0, 0); + $textref .= ' - '.$outputlangs->transnoentities("NotValidated"); + } + $pdf->MultiCell($w, 4, $textref, '', 'R'); + + $posy += 1; + $pdf->SetFont('', '', $default_font_size - 2); + + if ($object->ref_client) { + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); + } + + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) { + $object->fetch_projet(); + if (!empty($object->project->ref)) { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R'); + } + } + + if (!empty($conf->global->PDF_SHOW_PROJECT)) { + $object->fetch_projet(); + if (!empty($object->project->ref)) { + $outputlangs->load("projects"); + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R'); + } + } + + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + + $title = $outputlangs->transnoentities("Date"); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title .= ' - '.$outputlangsbis->transnoentities("Date"); + } + $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date, "day", false, $outputlangs), '', 'R'); + + if ($object->thirdparty->code_client) { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R'); + } + + // Get contact + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) { + $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL'); + if (count($arrayidcontact) > 0) { + $usertmp = new User($this->db); + $usertmp->fetch($arrayidcontact[0]); + $posy += 4; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R'); + } + } + + $posy += 1; + + $top_shift = 0; + // Show list of linked objects + $current_y = $pdf->getY(); + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size); + if ($current_y < $pdf->getY()) { + $top_shift = $pdf->getY() - $current_y; + } + + if ($showaddress) { + // Sender properties + $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); + + // Show sender + $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posy += $top_shift; + $posx = $this->marge_gauche; + if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) { + $posx = $this->page_largeur - $this->marge_droite - 80; + } + + $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40; + $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82; + + + // Show sender frame + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posx, $posy - 5); + $pdf->MultiCell(66, 5, $outputlangs->transnoentities("BillFrom").":", 0, 'L'); + $pdf->SetXY($posx, $posy); + $pdf->SetFillColor(230, 230, 230); + $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0, 0, 60); + + // Show sender name + $pdf->SetXY($posx + 2, $posy + 3); + $pdf->SetFont('', 'B', $default_font_size); + $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + $posy = $pdf->getY(); + + // Show sender information + $pdf->SetXY($posx + 2, $posy); + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L'); + + // If BILLING contact defined on invoice, we use it + $usecontact = false; + $arrayidcontact = $object->getIdContact('external', 'BILLING'); + if (count($arrayidcontact) > 0) { + $usecontact = true; + $result = $object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $thirdparty = $object->contact; + } else { + $thirdparty = $object->thirdparty; + } + + if (is_object($thirdparty)) { + $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); + } + + $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object); + + // Show recipient + $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100; + if ($this->page_largeur < 210) { + $widthrecbox = 84; // To work with US executive format + } + $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posy += $top_shift; + $posx = $this->page_largeur - $this->marge_droite - $widthrecbox; + if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) { + $posx = $this->marge_gauche; + } + + // Show recipient frame + $pdf->SetTextColor(0, 0, 0); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posx + 2, $posy - 5); + $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L'); + $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); + + // Show recipient name + $pdf->SetXY($posx + 2, $posy + 3); + $pdf->SetFont('', 'B', $default_font_size); + $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); + + // Show recipient information + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->SetXY($posx + 2, $posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + } + + $pdf->SetTextColor(0, 0, 0); + return $top_shift; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Show footer of page. Need this->emetteur object + * + * @param TCPDF $pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0) + { + global $conf; + $showdetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 0 : $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf, $outputlangs, 'INVOICE_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext); + } + + /** + * Define Array Column Field + * + * @param object $object common object + * @param Translate $outputlangs langs + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return null + */ + public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) + { + global $conf, $hookmanager; + + // Default field style for content + $this->defaultContentsFieldsStyle = array( + 'align' => 'R', // R,C,L + 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + // Default field style for content + $this->defaultTitlesFieldsStyle = array( + 'align' => 'C', // R,C,L + 'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + /* + * For exemple + $this->cols['theColKey'] = array( + 'rank' => $rank, // int : use for ordering columns + 'width' => 20, // the column width in mm + 'title' => array( + 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + 'label' => ' ', // the final label : used fore final generated text + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + */ + + $rank = 0; // do not use negative rank + $this->cols['desc'] = array( + 'rank' => $rank, + 'width' => false, // only for desc + 'status' => true, + 'title' => array( + 'textkey' => 'Designation', // use lang key is usefull in somme case with module + 'align' => 'L', + // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + // 'label' => ' ', // the final label + 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', + 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + + // PHOTO + $rank = $rank + 10; + $this->cols['photo'] = array( + 'rank' => $rank, + 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Photo', + 'label' => ' ' + ), + 'content' => array( + 'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'border-left' => false, // remove left line separator + ); + + if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto)) { + $this->cols['photo']['status'] = true; + } + + + $rank = $rank + 10; + $this->cols['vat'] = array( + 'rank' => $rank, + 'status' => false, + 'width' => 16, // in mm + 'title' => array( + 'textkey' => 'VAT' + ), + 'border-left' => true, // add left line separator + ); + + if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) { + $this->cols['vat']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['subprice'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'PriceUHT' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['qty'] = array( + 'rank' => $rank, + 'width' => 16, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'Qty' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['progress'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Progress' + ), + 'border-left' => true, // add left line separator + ); + + if ($this->situationinvoice) { + $this->cols['progress']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['unit'] = array( + 'rank' => $rank, + 'width' => 11, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Unit' + ), + 'border-left' => true, // add left line separator + ); + if (!empty($conf->global->PRODUCT_USE_UNITS)) { + $this->cols['unit']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['discount'] = array( + 'rank' => $rank, + 'width' => 13, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'ReductionShort' + ), + 'border-left' => true, // add left line separator + ); + if ($this->atleastonediscount) { + $this->cols['discount']['status'] = true; + } + + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 + $this->cols['totalexcltax'] = array( + 'rank' => $rank, + 'width' => 26, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'TotalHT' + ), + 'border-left' => true, // add left line separator + ); + + // Add extrafields cols + if (!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } + + $parameters = array( + 'object' => $object, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails, + 'hidedesc' => $hidedesc, + 'hideref' => $hideref + ); + + $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } elseif (empty($reshook)) { + $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys + } else { + $this->cols = $hookmanager->resArray; + } + } +} diff --git a/htdocs/core/modules/asset/mod_asset_advanced.php b/htdocs/core/modules/asset/mod_asset_advanced.php new file mode 100644 index 00000000000..0942604466c --- /dev/null +++ b/htdocs/core/modules/asset/mod_asset_advanced.php @@ -0,0 +1,147 @@ + + * Copyright (C) 2004-2007 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2019 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/asset/mod_asset_advanced.php + * \ingroup asset + * \brief File containing class for advanced numbering model of Asset + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/asset/modules_asset.php'; + +/** + * Class to manage customer Bom numbering rules advanced + */ +class mod_asset_advanced extends ModeleNumRefAsset +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + /** + * @var string Error message + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'advanced'; + + + /** + * Returns the description of the numbering model + * + * @return string Texte descripif + */ + public function info() + { + global $conf, $langs, $db; + + $langs->load("bills"); + + $form = new Form($db); + + $texte = $langs->trans('GenericNumRefModelDesc')."
    \n"; + $texte .= '
    '; + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= ''; + + $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Asset"), $langs->transnoentities("Asset")); + $tooltip .= $langs->trans("GenericMaskCodes2"); + $tooltip .= $langs->trans("GenericMaskCodes3"); + $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("Asset"), $langs->transnoentities("Asset")); + $tooltip .= $langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix + $texte .= ''; + $texte .= ''; + + $texte .= ''; + + $texte .= ''; + + $texte .= '
    '.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).' 
    '; + $texte .= '
    '; + + return $texte; + } + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $conf, $db, $langs, $mysoc; + + $object = new Asset($db); + $object->initAsSpecimen(); + + /*$old_code_client = $mysoc->code_client; + $old_code_type = $mysoc->typent_code; + $mysoc->code_client = 'CCCCCCCCCC'; + $mysoc->typent_code = 'TTTTTTTTTT';*/ + + $numExample = $this->getNextValue($object); + + /*$mysoc->code_client = $old_code_client; + $mysoc->typent_code = $old_code_type;*/ + + if (!$numExample) { + $numExample = $langs->trans('NotConfigured'); + } + return $numExample; + } + + /** + * Return next free value + * + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($object) + { + global $db, $conf; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + + // We get cursor rule + $mask = $conf->global->ASSET_ASSET_ADVANCED_MASK; + + if (!$mask) { + $this->error = 'NotConfigured'; + return 0; + } + + $date = $object->date; + + $numFinal = get_next_value($db, $mask, 'asset_asset', 'ref', '', null, $date); + + return $numFinal; + } +} diff --git a/htdocs/core/modules/asset/mod_asset_standard.php b/htdocs/core/modules/asset/mod_asset_standard.php new file mode 100644 index 00000000000..af28c0f9c5b --- /dev/null +++ b/htdocs/core/modules/asset/mod_asset_standard.php @@ -0,0 +1,161 @@ + + * Copyright (C) 2005-2009 Regis Houssin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/asset/mod_asset_standard.php + * \ingroup asset + * \brief File of class to manage Asset numbering rules standard + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/asset/modules_asset.php'; + +/** + * Class to manage customer order numbering rules standard + */ +class mod_asset_standard extends ModeleNumRefAsset +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + public $prefix = 'ASSET'; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'standard'; + + + /** + * Return description of numbering module + * + * @return string Text with description + */ + public function info() + { + global $langs; + return $langs->trans("SimpleNumRefModelDesc", $this->prefix); + } + + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + return $this->prefix."0501-0001"; + } + + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @param Object $object Object we need next value for + * @return boolean false if conflict, true if ok + */ + public function canBeActivated($object) + { + global $conf, $langs, $db; + + $coyymm = ''; $max = ''; + + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."asset_asset"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + if ($object->ismultientitymanaged == 1) { + $sql .= " AND entity = ".$conf->entity; + } elseif ($object->ismultientitymanaged == 2) { + // TODO + } + + $resql = $db->query($sql); + if ($resql) { + $row = $db->fetch_row($resql); + if ($row) { + $coyymm = substr($row[0], 0, 6); $max = $row[0]; + } + } + if ($coyymm && !preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm)) { + $langs->load("errors"); + $this->error = $langs->trans('ErrorNumRefModel', $max); + return false; + } + + return true; + } + + /** + * Return next free value + * + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($object) + { + global $db, $conf; + + // first we get the max value + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."asset_asset"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + if ($object->ismultientitymanaged == 1) { + $sql .= " AND entity = ".$conf->entity; + } elseif ($object->ismultientitymanaged == 2) { + // TODO + } + + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj) { + $max = intval($obj->max); + } else { + $max = 0; + } + } else { + dol_syslog("mod_asset_standard::getNextValue", LOG_DEBUG); + return -1; + } + + //$date=time(); + $date = $object->date_creation; + $yymm = strftime("%y%m", $date); + + if ($max >= (pow(10, 4) - 1)) { + $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is + } else { + $num = sprintf("%04s", $max + 1); + } + + dol_syslog("mod_asset_standard::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + } +} diff --git a/htdocs/core/modules/asset/modules_asset.php b/htdocs/core/modules/asset/modules_asset.php new file mode 100644 index 00000000000..e158b5bdfe9 --- /dev/null +++ b/htdocs/core/modules/asset/modules_asset.php @@ -0,0 +1,158 @@ + + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2014 Marcos García + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/asset/modules_asset.php + * \ingroup asset + * \brief File that contains parent class for assets document models and parent class for assets numbering models + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // required for use by classes that inherit + + +/** + * Parent class for documents models + */ +abstract class ModelePDFAsset extends CommonDocGenerator +{ + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + public static function liste_modeles($db, $maxfilenamelength = 0) + { + // phpcs:enable + global $conf; + + $type = 'asset'; + $list = array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $list = getListOfModels($db, $type, $maxfilenamelength); + + return $list; + } +} + + + +/** + * Parent class to manage numbering of Asset + */ +abstract class ModeleNumRefAsset +{ + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * Return if a module can be used or not + * + * @return boolean true if module can be used + */ + public function isEnabled() + { + return true; + } + + /** + * Returns the default description of the numbering template + * + * @return string Texte descripif + */ + public function info() + { + global $langs; + $langs->load("asset@asset"); + return $langs->trans("NoDescription"); + } + + /** + * Returns an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $langs; + $langs->load("asset@asset"); + return $langs->trans("NoExample"); + } + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @param Object $object Object we need next value for + * @return boolean false if conflict, true if ok + */ + public function canBeActivated($object) + { + return true; + } + + /** + * Returns next assigned value + * + * @param Object $object Object we need next value for + * @return string Valeur + */ + public function getNextValue($object) + { + global $langs; + return $langs->trans("NotAvailable"); + } + + /** + * Returns version of numbering module + * + * @return string Valeur + */ + public function getVersion() + { + global $langs; + $langs->load("admin"); + + if ($this->version == 'development') { + return $langs->trans("VersionDevelopment"); + } + if ($this->version == 'experimental') { + return $langs->trans("VersionExperimental"); + } + if ($this->version == 'dolibarr') { + return DOL_VERSION; + } + if ($this->version) { + return $this->version; + } + return $langs->trans("NotAvailable"); + } +} diff --git a/htdocs/core/modules/barcode/mod_barcode_product_standard.php b/htdocs/core/modules/barcode/mod_barcode_product_standard.php index c101001af4c..17b5a9bb16a 100644 --- a/htdocs/core/modules/barcode/mod_barcode_product_standard.php +++ b/htdocs/core/modules/barcode/mod_barcode_product_standard.php @@ -176,7 +176,7 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode * @param string $type Type of barcode (EAN, ISBN, ...) * @return string Value if OK, '' if module not configured, <0 if KO */ - public function getNextValue($objproduct = null, $type = '') + public function getNextValue($objproduct, $type = '') { global $db, $conf; diff --git a/htdocs/core/modules/cheque/modules_chequereceipts.php b/htdocs/core/modules/cheque/modules_chequereceipts.php index dfdf0fbe363..e50a6877848 100644 --- a/htdocs/core/modules/cheque/modules_chequereceipts.php +++ b/htdocs/core/modules/cheque/modules_chequereceipts.php @@ -126,8 +126,7 @@ abstract class ModeleNumRefChequeReceipts } /** - * \class ModeleChequeReceipts - * \brief Classe mere des modeles de + * Class parent for templates of document generation */ abstract class ModeleChequeReceipts extends CommonDocGenerator { diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index d30107fcbfb..3b946d1f3ce 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -609,7 +609,7 @@ class pdf_eratosthene extends ModelePDFCommandes } if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { - $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } diff --git a/htdocs/core/modules/contract/doc/pdf_strato.modules.php b/htdocs/core/modules/contract/doc/pdf_strato.modules.php index 69a4d5ce96e..085f7bee190 100644 --- a/htdocs/core/modules/contract/doc/pdf_strato.modules.php +++ b/htdocs/core/modules/contract/doc/pdf_strato.modules.php @@ -321,28 +321,28 @@ class pdf_strato extends ModelePDFContract // Description of product line - if ($objectligne->date_ouverture_prevue) { - $datei = dol_print_date($objectligne->date_ouverture_prevue, 'day', false, $outputlangs, true); + if (!empty($objectligne->date_start)) { + $datei = dol_print_date((int) $objectligne->date_start, 'day', false, $outputlangs, true); } else { $datei = $langs->trans("Unknown"); } - if ($objectligne->date_fin_validite) { - $durationi = convertSecondToTime($objectligne->date_fin_validite - $objectligne->date_ouverture_prevue, 'allwithouthour'); - $datee = dol_print_date($objectligne->date_fin_validite, 'day', false, $outputlangs, true); + if (!empty($objectligne->date_end)) { + $durationi = convertSecondToTime((int) $objectligne->date_end - (int) $objectligne->date_start, 'allwithouthour'); + $datee = dol_print_date($objectligne->date_end, 'day', false, $outputlangs, true); } else { $durationi = $langs->trans("Unknown"); $datee = $langs->trans("Unknown"); } - if ($objectligne->date_ouverture) { - $daters = dol_print_date($objectligne->date_ouverture, 'day', false, $outputlangs, true); + if (!empty($objectligne->date_start_real)) { + $daters = dol_print_date((int) $objectligne->date_start_real, 'day', false, $outputlangs, true); } else { $daters = $langs->trans("Unknown"); } - if ($objectligne->date_cloture) { - $datere = dol_print_date($objectligne->date_cloture, 'day', false, $outputlangs, true); + if (!empty($objectligne->date_end_real)) { + $datere = dol_print_date((int) $objectligne->date_end_real, 'day', false, $outputlangs, true); } else { $datere = $langs->trans("Unknown"); } @@ -355,7 +355,12 @@ class pdf_strato extends ModelePDFContract $desc = dol_htmlentitiesbr($objectligne->desc, 1); // Desc (not empty for free lines) $txt = ''; - $txt .= $outputlangs->transnoentities("Quantity").' : '.$objectligne->qty.' - '.$outputlangs->transnoentities("UnitPrice").' : '.price($objectligne->subprice).''; // Desc (not empty for free lines) + if (empty($conf->global->CONTRACT_HIDE_QTY_ON_PDF)) { + $txt .= $outputlangs->transnoentities("Quantity") . ' : ' . $objectligne->qty . ''; + } + if (empty($conf->global->CONTRACT_HIDE_PRICE_ON_PDF)) { + $txt .= ' - ' . $outputlangs->transnoentities("UnitPrice") . ' : ' . price($objectligne->subprice) . ''; + } if (empty($conf->global->CONTRACT_HIDE_PLANNED_DATE_ON_PDF)) { $txt .= '
    '; $txt .= $outputlangs->transnoentities("DateStartPlannedShort")." : ".$datei." - ".$outputlangs->transnoentities("DateEndPlanned")." : ".$datee.''; @@ -363,7 +368,7 @@ class pdf_strato extends ModelePDFContract if (empty($conf->global->CONTRACT_HIDE_REAL_DATE_ON_PDF)) { $txt .= '
    '; $txt .= $outputlangs->transnoentities("DateStartRealShort")." : ".$daters.''; - if ($objectligne->date_cloture) { + if (!empty($objectligne->date_end_real)) { $txt .= " - ".$outputlangs->transnoentities("DateEndRealShort")." : ''".$datere.''; } } diff --git a/htdocs/core/modules/delivery/doc/pdf_storm.modules.php b/htdocs/core/modules/delivery/doc/pdf_storm.modules.php index 742d06e2e34..65912a8b9a0 100644 --- a/htdocs/core/modules/delivery/doc/pdf_storm.modules.php +++ b/htdocs/core/modules/delivery/doc/pdf_storm.modules.php @@ -461,7 +461,7 @@ class pdf_storm extends ModelePDFDeliveryOrder if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { - $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index fc1094ea949..efc061b9e67 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -562,7 +562,7 @@ class pdf_espadon extends ModelePdfExpedition if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { - $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index 9c0088bd398..e9b985ee151 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -383,10 +383,10 @@ class doc_generic_invoice_odt extends ModelePDFFactures } // Define substitution array - $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object); + $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object); // Set tags __...__ $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs); - $array_objet = $this->get_substitutionarray_object($object, $outputlangs); - $array_user = $this->get_substitutionarray_user($user, $outputlangs); + $array_objet = $this->get_substitutionarray_object($object, $outputlangs); // Set tags object_... + $array_user = $this->get_substitutionarray_user($user, $outputlangs); // Set tags myuser_... $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs); $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs); $array_propal = is_object($propal_object) ? $this->get_substitutionarray_object($propal_object, $outputlangs, 'propal') : array(); diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 63a68f7b802..8046347e881 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -299,11 +299,11 @@ class pdf_crabe extends ModelePDFFactures // Definition of $dir and $file if ($object->specimen) { - $dir = $conf->facture->dir_output; + $dir = empty($conf->facture->multidir_output[$conf->entity]) ? $conf->facture->dir_output : $conf->facture->multidir_output[$conf->entity]; $file = $dir."/SPECIMEN.pdf"; } else { $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->facture->dir_output."/".$objectref; + $dir = (empty($conf->facture->multidir_output[$conf->entity]) ? $conf->facture->dir_output : $conf->facture->multidir_output[$conf->entity])."/".$objectref; $file = $dir."/".$objectref.".pdf"; } if (!file_exists($dir)) { @@ -477,7 +477,7 @@ class pdf_crabe extends ModelePDFFactures } $tab_top += $extra_under_address_shift; - $tab_top_newpage += $extra_under_address_shift; + $tab_top_newpage += 0; // Incoterm $height_incoterms = 0; @@ -897,7 +897,7 @@ class pdf_crabe extends ModelePDFFactures $tab3_width = 80; $tab3_height = 4; if ($this->page_largeur < 210) { // To work with US executive format - $tab3_posx -= 20; + $tab3_posx -= 15; } $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -1289,7 +1289,8 @@ class pdf_crabe extends ModelePDFFactures $col1x = 120; $col2x = 170; if ($this->page_largeur < 210) { // To work with US executive format - $col2x -= 20; + $col1x -= 15; + $col2x -= 10; } $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 7f3b543ebba..39c76e780c8 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -460,7 +460,7 @@ class pdf_sponge extends ModelePDFFactures } $tab_top += $extra_under_address_shift; - $tab_top_newpage += $extra_under_address_shift; + $tab_top_newpage += 0; // Define heigth of table for lines (for first page) @@ -540,7 +540,7 @@ class pdf_sponge extends ModelePDFFactures $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } // $this->_pagefoot($pdf,$object,$outputlangs,1); $pdf->setTopMargin($tab_top_newpage); @@ -598,7 +598,7 @@ class pdf_sponge extends ModelePDFFactures $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } $height_note = $posyafter - $tab_top_newpage; $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1); @@ -620,7 +620,7 @@ class pdf_sponge extends ModelePDFFactures $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } $posyafter = $tab_top_newpage; @@ -685,7 +685,7 @@ class pdf_sponge extends ModelePDFFactures } if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { - $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } @@ -870,9 +870,9 @@ class pdf_sponge extends ModelePDFFactures // Retrieve type from database for backward compatibility with old records if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax - $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); - $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : ''; - $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : ''; + $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); + $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : ''; + $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : ''; } // retrieve global local tax @@ -922,7 +922,7 @@ class pdf_sponge extends ModelePDFFactures $pdf->setPage($pagenb); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } } @@ -940,7 +940,7 @@ class pdf_sponge extends ModelePDFFactures } $pagenb++; if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); + $this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis); } } } @@ -989,9 +989,9 @@ class pdf_sponge extends ModelePDFFactures @chmod($file, octdec($conf->global->MAIN_UMASK)); } - $this->result = array('fullpath'=>$file); + $this->result = array('fullpath'=>$file); - return 1; // No error + return 1; // No error } else { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; @@ -1026,7 +1026,7 @@ class pdf_sponge extends ModelePDFFactures $tab3_width = 80; $tab3_height = 4; if ($this->page_largeur < 210) { // To work with US executive format - $tab3_posx -= 20; + $tab3_posx -= 15; } $default_font_size = pdf_getPDFFontSize($outputlangs); @@ -1177,20 +1177,24 @@ class pdf_sponge extends ModelePDFFactures $posy = $pdf->GetY() + 4; } - $posxval = 52; + $posxval = 52; // Position of values of properties shown on left side + $posxend = 110; // End of x for text on left side + if ($this->page_largeur < 210) { // To work with US executive format + $posxend -= 10; + } // Show payments conditions if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement)) { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $titre = $outputlangs->transnoentities("PaymentConditions").':'; - $pdf->MultiCell(43, 4, $titre, 0, 'L'); + $pdf->MultiCell($posxval - $this->marge_gauche, 4, $titre, 0, 'L'); $pdf->SetFont('', '', $default_font_size - 2); $pdf->SetXY($posxval, $posy); $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label); $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement); - $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L'); + $pdf->MultiCell($posxend - $posxval, 4, $lib_condition_paiement, 0, 'L'); $posy = $pdf->GetY() + 3; // We need spaces for 2 lines payment conditions } @@ -1198,42 +1202,42 @@ class pdf_sponge extends ModelePDFFactures if ($object->type != 2) { // Check a payment mode is defined if (empty($object->mode_reglement_code) - && empty($conf->global->FACTURE_CHQ_NUMBER) - && empty($conf->global->FACTURE_RIB_NUMBER)) { - $this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"); + && empty($conf->global->FACTURE_CHQ_NUMBER) + && empty($conf->global->FACTURE_RIB_NUMBER)) { + $this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"); } elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank)) - || ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))) { - // Avoid having any valid PDF with setup that is not complete - $outputlangs->load("errors"); + || ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))) { + // Avoid having any valid PDF with setup that is not complete + $outputlangs->load("errors"); - $pdf->SetXY($this->marge_gauche, $posy); - $pdf->SetTextColor(200, 0, 0); - $pdf->SetFont('', 'B', $default_font_size - 2); - $this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code); - $pdf->MultiCell(80, 3, $this->error, 0, 'L', 0); - $pdf->SetTextColor(0, 0, 0); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200, 0, 0); + $pdf->SetFont('', 'B', $default_font_size - 2); + $this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $this->error, 0, 'L', 0); + $pdf->SetTextColor(0, 0, 0); - $posy = $pdf->GetY() + 1; + $posy = $pdf->GetY() + 1; } - // Show payment mode + // Show payment mode if (!empty($object->mode_reglement_code) - && $object->mode_reglement_code != 'CHQ' - && $object->mode_reglement_code != 'VIR') { - $pdf->SetFont('', 'B', $default_font_size - 2); - $pdf->SetXY($this->marge_gauche, $posy); - $titre = $outputlangs->transnoentities("PaymentMode").':'; - $pdf->MultiCell(80, 5, $titre, 0, 'L'); + && $object->mode_reglement_code != 'CHQ' + && $object->mode_reglement_code != 'VIR') { + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentMode").':'; + $pdf->MultiCell($posxend - $this->marge_gauche, 5, $titre, 0, 'L'); - $pdf->SetFont('', '', $default_font_size - 2); - $pdf->SetXY($posxval, $posy); - $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement); - $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L'); + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement); + $pdf->MultiCell($posxend - $posxval, 5, $lib_mode_reg, 0, 'L'); - $posy = $pdf->GetY(); + $posy = $pdf->GetY(); } - // Show online payment link + // Show online payment link if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') { $useonlinepayment = 0; if (!empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT)) { @@ -1258,13 +1262,13 @@ class pdf_sponge extends ModelePDFFactures $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").''; $pdf->SetXY($this->marge_gauche, $posy); - $pdf->writeHTMLCell(80, 5, '', '', dol_htmlentitiesbr($linktopay), 0, 1); + $pdf->writeHTMLCell($posxend - $this->marge_gauche, 5, '', '', dol_htmlentitiesbr($linktopay), 0, 1); $posy = $pdf->GetY() + 1; } } - // Show payment mode CHQ + // Show payment mode CHQ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') { // If payment mode unregulated or payment mode forced to CHQ if (!empty($conf->global->FACTURE_CHQ_NUMBER)) { @@ -1276,33 +1280,33 @@ class pdf_sponge extends ModelePDFFactures $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0); $posy = $pdf->GetY() + 1; if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - $diffsizetitle); - $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); $posy = $pdf->GetY() + 2; } } if ($conf->global->FACTURE_CHQ_NUMBER == -1) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0); $posy = $pdf->GetY() + 1; if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) { $pdf->SetXY($this->marge_gauche, $posy); $pdf->SetFont('', '', $default_font_size - $diffsizetitle); - $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); + $pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); $posy = $pdf->GetY() + 2; } } } } - // If payment mode not forced or forced to VIR, show payment with BAN + // If payment mode not forced or forced to VIR, show payment with BAN if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') { if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) { $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); @@ -1350,13 +1354,18 @@ class pdf_sponge extends ModelePDFFactures $tab2_top = $posy; $tab2_hl = 4; - $pdf->SetFont('', '', $default_font_size - 1); + if (is_object($outputlangsbis)) { // When we show 2 languages we need more room for text, so we use a smaller font. + $pdf->SetFont('', '', $default_font_size - 2); + } else { + $pdf->SetFont('', '', $default_font_size - 1); + } // Total table $col1x = 120; $col2x = 170; if ($this->page_largeur < 210) { // To work with US executive format - $col2x -= 20; + $col1x -= 15; + $col2x -= 10; } $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); @@ -1481,9 +1490,10 @@ class pdf_sponge extends ModelePDFFactures $tab2_top = $posy; $index = 0; + + $tab2_top += 3; } - $tab2_top += 3; // Get Total HT $total_ht = (!empty($conf->multicurrency->enabled) && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); @@ -1795,7 +1805,7 @@ class pdf_sponge extends ModelePDFFactures // Credit note if ($creditnoteamount) { $labeltouse = ($outputlangs->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangs->transnoentities("CreditNotesOrExcessReceived") : $outputlangs->transnoentities("CreditNotes"); - $labeltouse .= (is_object($outputlangsbis) ? ' / '.($outputlangsbis->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangsbis->transnoentities("CreditNotesOrExcessReceived") : $outputlangsbis->transnoentities("CreditNotes") : ''); + $labeltouse .= (is_object($outputlangsbis) ? (' / '.($outputlangsbis->transnoentities("CreditNotesOrExcessReceived") != "CreditNotesOrExcessReceived") ? $outputlangsbis->transnoentities("CreditNotesOrExcessReceived") : $outputlangsbis->transnoentities("CreditNotes")) : ''); $index++; $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($col2x - $col1x, $tab2_hl, $labeltouse, 0, 'L', 0); @@ -1804,19 +1814,19 @@ class pdf_sponge extends ModelePDFFactures } /* - if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT) - { - $index++; - $pdf->SetFillColor(255, 255, 255); + if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT) + { + $index++; + $pdf->SetFillColor(255, 255, 255); - $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1); - $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); - $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1); - $resteapayer = 0; - } - */ + $resteapayer = 0; + } + */ $index++; $pdf->SetTextColor(0, 0, 60); @@ -1936,7 +1946,7 @@ class pdf_sponge extends ModelePDFFactures // Show Draft Watermark if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK))) { - pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK); + pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK); } $pdf->SetTextColor(0, 0, 60); @@ -2023,15 +2033,15 @@ class pdf_sponge extends ModelePDFFactures $pdf->SetFont('', 'B', $default_font_size); /* - $posy += 5; - $pdf->SetXY($posx, $posy); - $pdf->SetTextColor(0, 0, 60); - $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref); - if ($object->statut == $object::STATUS_DRAFT) { - $pdf->SetTextColor(128, 0, 0); - $textref .= ' - '.$outputlangs->transnoentities("NotValidated"); - } - $pdf->MultiCell($w, 4, $textref, '', 'R');*/ + $posy += 5; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref); + if ($object->statut == $object::STATUS_DRAFT) { + $pdf->SetTextColor(128, 0, 0); + $textref .= ' - '.$outputlangs->transnoentities("NotValidated"); + } + $pdf->MultiCell($w, 4, $textref, '', 'R');*/ $posy += 3; $pdf->SetFont('', '', $default_font_size - 2); @@ -2295,21 +2305,21 @@ class pdf_sponge extends ModelePDFFactures /* * For exemple - $this->cols['theColKey'] = array( - 'rank' => $rank, // int : use for ordering columns - 'width' => 20, // the column width in mm - 'title' => array( - 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label - 'label' => ' ', // the final label : used fore final generated text - 'align' => 'L', // text alignement : R,C,L - 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left - ), - 'content' => array( - 'align' => 'L', // text alignement : R,C,L - 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left - ), - ); - */ + $this->cols['theColKey'] = array( + 'rank' => $rank, // int : use for ordering columns + 'width' => 20, // the column width in mm + 'title' => array( + 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + 'label' => ' ', // the final label : used fore final generated text + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + */ $rank = 0; // do not use negative rank $this->cols['desc'] = array( diff --git a/htdocs/core/modules/facture/mod_facture_mars.php b/htdocs/core/modules/facture/mod_facture_mars.php index c7a69a82caa..ef34b145e52 100644 --- a/htdocs/core/modules/facture/mod_facture_mars.php +++ b/htdocs/core/modules/facture/mod_facture_mars.php @@ -150,7 +150,7 @@ class mod_facture_mars extends ModeleNumRefFactures * @param Societe $objsoc Object third party * @param Facture $invoice Object invoice * @param string $mode 'next' for next value or 'last' for last value - * @return string Value + * @return string Value if OK, 0 if KO */ public function getNextValue($objsoc, $invoice, $mode = 'next') { diff --git a/htdocs/core/modules/facture/mod_facture_mercure.php b/htdocs/core/modules/facture/mod_facture_mercure.php index 621bb8e6d2d..7a572615a21 100644 --- a/htdocs/core/modules/facture/mod_facture_mercure.php +++ b/htdocs/core/modules/facture/mod_facture_mercure.php @@ -171,7 +171,7 @@ class mod_facture_mercure extends ModeleNumRefFactures $this->error = $numFinal; } - return $numFinal; + return $numFinal; } diff --git a/htdocs/core/modules/facture/mod_facture_terre.php b/htdocs/core/modules/facture/mod_facture_terre.php index 55f6dd816d1..9660be93266 100644 --- a/htdocs/core/modules/facture/mod_facture_terre.php +++ b/htdocs/core/modules/facture/mod_facture_terre.php @@ -185,7 +185,7 @@ class mod_facture_terre extends ModeleNumRefFactures * @param Societe $objsoc Object third party * @param Facture $invoice Object invoice * @param string $mode 'next' for next value or 'last' for last value - * @return string Next ref value or last ref if $mode is 'last' + * @return string Next ref value or last ref if $mode is 'last', <= 0 if KO */ public function getNextValue($objsoc, $invoice, $mode = 'next') { @@ -259,6 +259,8 @@ class mod_facture_terre extends ModeleNumRefFactures } else { dol_print_error('', 'Bad parameter for getNextValue'); } + + return 0; } /** diff --git a/htdocs/core/modules/facture/modules_facture.php b/htdocs/core/modules/facture/modules_facture.php index e188f66b1ad..480c532cc1f 100644 --- a/htdocs/core/modules/facture/modules_facture.php +++ b/htdocs/core/modules/facture/modules_facture.php @@ -132,10 +132,11 @@ abstract class ModeleNumRefFactures * Renvoi prochaine valeur attribuee * * @param Societe $objsoc Objet societe - * @param Facture $facture Objet facture + * @param Facture $invoice Objet facture + * @param string $mode 'next' for next value or 'last' for last value * @return string Value */ - public function getNextValue($objsoc, $facture) + public function getNextValue($objsoc, $invoice, $mode = 'next') { global $langs; return $langs->trans("NotAvailable"); diff --git a/htdocs/core/modules/fichinter/modules_fichinter.php b/htdocs/core/modules/fichinter/modules_fichinter.php index 8cf79227d4f..185ef4cf73b 100644 --- a/htdocs/core/modules/fichinter/modules_fichinter.php +++ b/htdocs/core/modules/fichinter/modules_fichinter.php @@ -122,9 +122,11 @@ abstract class ModeleNumRefFicheinter /** * Return the next assigned value * - * @return string Value + * @param Societe $objsoc Object thirdparty + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO */ - public function getNextValue() + public function getNextValue($objsoc = 0, $object = '') { global $langs; return $langs->trans("NotAvailable"); diff --git a/htdocs/core/modules/holiday/mod_holiday_immaculate.php b/htdocs/core/modules/holiday/mod_holiday_immaculate.php index 84d6638a27e..a1647a67953 100644 --- a/htdocs/core/modules/holiday/mod_holiday_immaculate.php +++ b/htdocs/core/modules/holiday/mod_holiday_immaculate.php @@ -117,11 +117,11 @@ class mod_holiday_immaculate extends ModelNumRefHolidays /** * Return next value * - * @param Societe $user user object + * @param Societe $objsoc third party object * @param Object $holiday holiday object * @return string Value if OK, 0 if KO */ - public function getNextValue($user, $holiday) + public function getNextValue($objsoc, $holiday) { global $db, $conf; @@ -134,7 +134,7 @@ class mod_holiday_immaculate extends ModelNumRefHolidays return 0; } - $numFinal = get_next_value($db, $mask, 'holiday', 'ref', '', $user, $holiday->date_create); + $numFinal = get_next_value($db, $mask, 'holiday', 'ref', '', $objsoc, $holiday->date_create); return $numFinal; } diff --git a/htdocs/core/modules/holiday/modules_holiday.php b/htdocs/core/modules/holiday/modules_holiday.php index 65b08f4bba8..7b6e13ea992 100644 --- a/htdocs/core/modules/holiday/modules_holiday.php +++ b/htdocs/core/modules/holiday/modules_holiday.php @@ -126,10 +126,10 @@ class ModelNumRefHolidays * Return next value * * @param Societe $objsoc third party object - * @param Object $contract contract object - * @return string Value + * @param Object $holiday Holiday object + * @return string Value if OK, 0 if KO */ - public function getNextValue($objsoc, $contract) + public function getNextValue($objsoc, $holiday) { global $langs; return $langs->trans("NotAvailable"); diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 781c22ce7e3..e45630df298 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -324,7 +324,8 @@ class ImportCsv extends ModeleImports //dol_syslog("import_csv.modules maxfields=".$maxfields." importid=".$importid); //var_dump($array_match_file_to_database); - //var_dump($arrayrecord); + //var_dump($arrayrecord); exit; + $array_match_database_to_file = array_flip($array_match_file_to_database); $sort_array_match_file_to_database = $array_match_file_to_database; ksort($sort_array_match_file_to_database); @@ -367,12 +368,15 @@ class ImportCsv extends ModeleImports //dol_syslog("Table ".$tablename." check for entity into cache is ".$tablewithentity_cache[$tablename]); } - // array of fields to column index + // Define array to convert fields ('c.ref', ...) into column index (1, ...) $arrayfield = array(); foreach ($sort_array_match_file_to_database as $key => $val) { $arrayfield[$val] = ($key - 1); } + // $arrayrecord start at key 0 + // $sort_array_match_file_to_database start at key 1 + // Loop on each fields in the match array: $key = 1..n, $val=alias of field (s.nom) foreach ($sort_array_match_file_to_database as $key => $val) { $fieldalias = preg_replace('/\..*$/i', '', $val); @@ -595,9 +599,24 @@ class ImportCsv extends ModeleImports if (!empty($classModForNumber) && !empty($pathModForNumber) && is_readable(DOL_DOCUMENT_ROOT.$pathModForNumber)) { require_once DOL_DOCUMENT_ROOT.$pathModForNumber; $modForNumber = new $classModForNumber; - $defaultref = $modForNumber->getNextValue(null, null); + + $tmpobject = null; + // Set the object when we can + if (!empty($objimport->array_import_convertvalue[0][$val]['classobject'])) { + $pathForObject = $objimport->array_import_convertvalue[0][$val]['pathobject']; + require_once DOL_DOCUMENT_ROOT.$pathForObject; + $tmpclassobject = $objimport->array_import_convertvalue[0][$val]['classobject']; + $tmpobject = new $tmpclassobject($this->db); + foreach ($arrayfield as $tmpkey => $tmpval) { // $arrayfield is array('c.ref'=>0, ...) + if (in_array($tmpkey, array('t.date', 'c.date_commande'))) { + $tmpobject->date = dol_stringtotime($arrayrecord[$arrayfield[$tmpkey]]['val'], 1); + } + } + } + + $defaultref = $modForNumber->getNextValue(null, $tmpobject); } - if (is_numeric($defaultref) && $defaultref <= 0) { + if (is_numeric($defaultref) && $defaultref <= 0) { // If error $defaultref = ''; } $newval = $defaultref; @@ -612,19 +631,8 @@ class ImportCsv extends ModeleImports break; } $classinstance = new $class($this->db); - $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord)); - if ($res < 0) { - if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) { - $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); - } else { - $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn'; - } - $this->errors[$error]['type'] = 'FOREIGNKEY'; - $errorforthistable++; - $error++; - } else { - $newval = $arrayrecord[($key - 1)]['val']; //We get new value computed. - } + $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $listfields, ($key - 1))); + $newval = $res; // We get new value computed. } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'numeric') { $newval = price2num($newval); } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'accountingaccount') { @@ -716,6 +724,8 @@ class ImportCsv extends ModeleImports } // We add hidden fields (but only if there is at least one field to add into table) + // We process here all the fields that were declared into the array ->import_fieldshidden_array of the descriptor file. + // Previously we processed the ->import_fields_array. if (!empty($listfields) && is_array($objimport->array_import_fieldshidden[0])) { // Loop on each hidden fields to add them into listfields/listvalues foreach ($objimport->array_import_fieldshidden[0] as $key => $val) { @@ -749,14 +759,13 @@ class ImportCsv extends ModeleImports break; } $classinstance = new $class($this->db); - $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $fieldname, &$listfields, &$listvalues)); - if ($res < 0) { - if (!empty($objimport->array_import_convertvalue[0][$fieldname]['dict'])) $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, end($listvalues), 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$fieldname]['dict'])); - else $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn'; - $this->errors[$error]['type'] = 'FOREIGNKEY'; - $errorforthistable++; - $error++; + $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $listfields, ($key - 1))); + $fieldArr = explode('.', $fieldname); + if (count($fieldArr) > 0) { + $fieldname = $fieldArr[1]; } + $listfields[] = $fieldname; + $listvalues[] = $res; } } } else { diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 1c38f52cbfc..9fa5cbf2c44 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -367,7 +367,8 @@ class ImportXlsx extends ModeleImports //dol_syslog("import_csv.modules maxfields=".$maxfields." importid=".$importid); //var_dump($array_match_file_to_database); - //var_dump($arrayrecord); + //var_dump($arrayrecord); exit; + $array_match_database_to_file = array_flip($array_match_file_to_database); $sort_array_match_file_to_database = $array_match_file_to_database; ksort($sort_array_match_file_to_database); @@ -410,12 +411,15 @@ class ImportXlsx extends ModeleImports //dol_syslog("Table ".$tablename." check for entity into cache is ".$tablewithentity_cache[$tablename]); } - // array of fields to column index + // Define array to convert fields ('c.ref', ...) into column index (1, ...) $arrayfield = array(); foreach ($sort_array_match_file_to_database as $key => $val) { - $arrayfield[$val] = ($key - 1); + $arrayfield[$val] = ($key); } + // $arrayrecord start at key 1 + // $sort_array_match_file_to_database start at key 1 + // Loop on each fields in the match array: $key = 1..n, $val=alias of field (s.nom) foreach ($sort_array_match_file_to_database as $key => $val) { $fieldalias = preg_replace('/\..*$/i', '', $val); @@ -619,7 +623,7 @@ class ImportXlsx extends ModeleImports $this->thirpartyobject->get_codecompta('supplier'); $newval = $this->thirpartyobject->code_compta_fournisseur; if (empty($newval)) { - $arrayrecord[($key - 1)]['type'] = -1; // If we get empty value, we will use "null" + $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null" } //print 'code_compta_fournisseur='.$newval; } @@ -636,9 +640,24 @@ class ImportXlsx extends ModeleImports if (!empty($classModForNumber) && !empty($pathModForNumber) && is_readable(DOL_DOCUMENT_ROOT.$pathModForNumber)) { require_once DOL_DOCUMENT_ROOT.$pathModForNumber; $modForNumber = new $classModForNumber; - $defaultref = $modForNumber->getNextValue(null, null); + + $tmpobject = null; + // Set the object with the date property when we can + if (!empty($objimport->array_import_convertvalue[0][$val]['classobject'])) { + $pathForObject = $objimport->array_import_convertvalue[0][$val]['pathobject']; + require_once DOL_DOCUMENT_ROOT.$pathForObject; + $tmpclassobject = $objimport->array_import_convertvalue[0][$val]['classobject']; + $tmpobject = new $tmpclassobject($this->db); + foreach ($arrayfield as $tmpkey => $tmpval) { // $arrayfield is array('c.ref'=>1, ...) + if (in_array($tmpkey, array('t.date', 'c.date_commande'))) { + $tmpobject->date = dol_stringtotime($arrayrecord[$arrayfield[$tmpkey]]['val'], 1); + } + } + } + + $defaultref = $modForNumber->getNextValue(null, $tmpobject); } - if (is_numeric($defaultref) && $defaultref <= 0) { + if (is_numeric($defaultref) && $defaultref <= 0) { // If error $defaultref = ''; } $newval = $defaultref; @@ -654,18 +673,7 @@ class ImportXlsx extends ModeleImports } $classinstance = new $class($this->db); $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord)); - if ($res < 0) { - if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) { - $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict'])); - } else { - $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn'; - } - $this->errors[$error]['type'] = 'FOREIGNKEY'; - $errorforthistable++; - $error++; - } else { - $newval = $arrayrecord[($key)]['val']; //We get new value computed. - } + $newval = $res; // We get new value computed. } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'numeric') { $newval = price2num($newval); } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'accountingaccount') { @@ -757,6 +765,8 @@ class ImportXlsx extends ModeleImports } // We add hidden fields (but only if there is at least one field to add into table) + // We process here all the fields that were declared into the array $this->import_fieldshidden_array of the descriptor file. + // Previously we processed the ->import_fields_array. if (!empty($listfields) && is_array($objimport->array_import_fieldshidden[0])) { // Loop on each hidden fields to add them into listfields/listvalues foreach ($objimport->array_import_fieldshidden[0] as $key => $val) { @@ -791,13 +801,12 @@ class ImportXlsx extends ModeleImports } $classinstance = new $class($this->db); $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $fieldname, &$listfields, &$listvalues)); - if ($res < 0) { - if (!empty($objimport->array_import_convertvalue[0][$fieldname]['dict'])) $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, end($listvalues), 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$fieldname]['dict'])); - else $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn'; - $this->errors[$error]['type'] = 'FOREIGNKEY'; - $errorforthistable++; - $error++; + $fieldArr = explode('.', $fieldname); + if (count($fieldArr) > 0) { + $fieldname = $fieldArr[1]; } + $listfields[] = $fieldname; + $listvalues[] = $res; } } } else { diff --git a/htdocs/core/modules/mailings/advthirdparties.modules.php b/htdocs/core/modules/mailings/advthirdparties.modules.php index cbf668b6c67..538e5389727 100644 --- a/htdocs/core/modules/mailings/advthirdparties.modules.php +++ b/htdocs/core/modules/mailings/advthirdparties.modules.php @@ -123,7 +123,7 @@ class mailing_advthirdparties extends MailingTargets if (count($socid) > 0 || count($contactid) > 0) { $sql = "SELECT socp.rowid as id, socp.email as email, socp.lastname as lastname, socp.firstname as firstname"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as socp"; - $sql .= " WHERE socp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE socp.entity IN (".getEntity('contact').")"; if (count($contactid) > 0) { $sql .= " AND socp.rowid IN (".$this->db->sanitize(implode(',', $contactid)).")"; } diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 4b928d8af07..d43c95720d3 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -78,7 +78,7 @@ class mailing_contacts1 extends MailingTargets $statssql[0] = "SELECT '".$this->db->escape($langs->trans("NbOfCompaniesContacts"))."' as label,"; $statssql[0] .= " count(distinct(c.email)) as nb"; $statssql[0] .= " FROM ".MAIN_DB_PREFIX."socpeople as c"; - $statssql[0] .= " WHERE c.entity IN (".getEntity('socpeople').")"; + $statssql[0] .= " WHERE c.entity IN (".getEntity('contact').")"; $statssql[0] .= " AND c.email <> ''"; // Note that null != '' is false $statssql[0] .= " AND (SELECT count(*) FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = c.email) = 0"; $statssql[0] .= " AND c.statut = 1"; @@ -102,7 +102,7 @@ class mailing_contacts1 extends MailingTargets $sql = "SELECT count(distinct(c.email)) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc"; - $sql .= " WHERE c.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE c.entity IN (".getEntity('contact').")"; $sql .= " AND c.email <> ''"; // Note that null != '' is false $sql .= " AND (SELECT count(*) FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = c.email) = 0"; // exclude unsubscribed users @@ -130,7 +130,7 @@ class mailing_contacts1 extends MailingTargets // Add filter on job position $sql = "SELECT sp.poste, count(distinct(sp.email)) AS nb"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; - $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; $sql .= " AND sp.email <> ''"; // Note that null != '' is false $sql .= " AND sp.statut = 1"; $sql .= " AND (sp.poste IS NOT NULL AND sp.poste <> '')"; @@ -165,7 +165,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; $sql .= " ".MAIN_DB_PREFIX."categorie as c,"; $sql .= " ".MAIN_DB_PREFIX."categorie_contact as cs"; - $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; $sql .= " AND sp.email <> ''"; // Note that null != '' is false $sql .= " AND sp.statut = 1"; $sql .= " AND cs.fk_categorie = c.rowid"; @@ -238,7 +238,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; $sql .= " ".MAIN_DB_PREFIX."categorie as c,"; $sql .= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; $sql .= " AND sp.email <> ''"; // Note that null != '' is false $sql .= " AND sp.statut = 1"; $sql .= " AND cs.fk_categorie = c.rowid"; @@ -275,7 +275,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; $sql .= " ".MAIN_DB_PREFIX."categorie as c,"; $sql .= " ".MAIN_DB_PREFIX."categorie_fournisseur as cs"; - $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; $sql .= " AND sp.email <> ''"; // Note that null != '' is false $sql .= " AND sp.statut = 1"; $sql .= " AND cs.fk_categorie = c.rowid"; @@ -375,7 +375,7 @@ class mailing_contacts1 extends MailingTargets $sql .= ", ".MAIN_DB_PREFIX."categorie as c3"; $sql .= ", ".MAIN_DB_PREFIX."categorie_fournisseur as c3s"; } - $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; $sql .= " AND sp.email <> ''"; $sql .= " AND (SELECT count(*) FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = sp.email) = 0"; // Exclude unsubscribed email adresses diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index 2a78baa00c9..5e30978693e 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -256,7 +256,7 @@ class modAccounting extends DolibarrModules $r++; $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = 'Chartofaccounts'; - $this->export_icon[$r] = 'accounting'; + $this->export_icon[$r] = $this->picto; $this->export_permission[$r] = array(array("accounting", "chartofaccount")); $this->export_fields_array[$r] = array('ac.rowid'=>'ChartofaccountsId', 'ac.pcg_version'=>'Chartofaccounts', 'aa.rowid'=>'ID', 'aa.account_number'=>"AccountAccounting", 'aa.label'=>"Label", 'aa.account_parent'=>"Accountparent", 'aa.pcg_type'=>"Pcgtype", 'aa.active'=>'Status'); $this->export_TypeFields_array[$r] = array('ac.rowid'=>'List:accounting_system:pcg_version', 'ac.pcg_version'=>'Text', 'aa.rowid'=>'Numeric', 'aa.account_number'=>"Text", 'aa.label'=>"Text", 'aa.account_parent'=>"Text", 'aa.pcg_type'=>'Text', 'aa.active'=>'Status'); @@ -354,8 +354,12 @@ class modAccounting extends DolibarrModules 'b.sens'=>'rule-computeDirection' ); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) $this->import_convertvalue_array[$r]=array( + 'b.piece_num' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanValue', 'element' => 'Accountancy'), 'b.numero_compte'=>array('rule'=>'accountingaccount'), 'b.subledger_account'=>array('rule'=>'accountingaccount'), + 'b.debit' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'), + 'b.credit' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'), + 'b.multicurrency_amount' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'cleanAmount', 'element' => 'Accountancy'), 'b.montant' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'computeAmount', 'element' => 'Accountancy'), 'b.sens' => array('rule' => 'compute', 'classfile' => '/accountancy/class/accountancyimport.class.php', 'class' => 'AccountancyImport', 'method' => 'computeDirection', 'element' => 'Accountancy'), ); diff --git a/htdocs/core/modules/modAsset.class.php b/htdocs/core/modules/modAsset.class.php index b275f38debe..2146de367e1 100644 --- a/htdocs/core/modules/modAsset.class.php +++ b/htdocs/core/modules/modAsset.class.php @@ -58,9 +58,9 @@ class modAsset extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleAssetsName' not found (MyModue is name of module). $this->name = preg_replace('/^mod/i', '', get_class($this)); // Module description, used if translation string 'ModuleAssetsDesc' not found (MyModue is name of module). - $this->description = "Assets module"; + $this->description = "Asset module"; // Used only if file README.md and README-LL.md not found. - $this->descriptionlong = "Assets module to manage assets module and depreciation charge on Dolibarr"; + $this->descriptionlong = "Asset module to manage assets module and depreciation charge on Dolibarr"; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' $this->version = 'development'; @@ -103,6 +103,15 @@ class modAsset extends DolibarrModules // 1=>array('ASSETS_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1) // ); $this->const = array(); + $this->const[1] = array( + "ASSET_DEPRECIATION_DURATION_PER_YEAR", + "chaine", + "365", + "Duration per year to calculate depreciation. In some case, can be 360 days", + 0, + 'current', + 1 + ); if (!isset($conf->asset) || !isset($conf->asset->enabled)) { @@ -192,13 +201,29 @@ class modAsset extends DolibarrModules $this->rights[$r][4] = 'delete'; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) $this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) + $r++; + $this->rights[$r][0] = 51004; // Permission id (must not be already used) + $this->rights[$r][1] = 'Read asset models'; // Permission label + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'model_advance'; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) + $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) + $r++; $this->rights[$r][0] = 51005; // Permission id (must not be already used) - $this->rights[$r][1] = 'Setup types of asset'; // Permission label + $this->rights[$r][1] = 'Create/Update asset models'; // Permission label $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; // Permission by default for new user (0/1) - $this->rights[$r][4] = 'setup_advance'; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) - $this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) + $this->rights[$r][4] = 'model_advance'; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) + $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) + + $r++; + $this->rights[$r][0] = 51006; // Permission id (must not be already used) + $this->rights[$r][1] = 'Delete asset models'; // Permission label + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'model_advance'; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) + $this->rights[$r][5] = 'delete'; // In php code, permission will be checked by test if ($user->rights->asset->level1->level2) // Menus //------- diff --git a/htdocs/core/modules/modBanque.class.php b/htdocs/core/modules/modBanque.class.php index b4135294293..e44d8b59374 100644 --- a/htdocs/core/modules/modBanque.class.php +++ b/htdocs/core/modules/modBanque.class.php @@ -151,7 +151,7 @@ class modBanque extends DolibarrModules $this->export_fields_array[$r] = array( 'b.rowid'=>'IdTransaction', 'ba.ref'=>'AccountRef', 'ba.label'=>'AccountLabel', 'b.datev'=>'DateValue', 'b.dateo'=>'DateOperation', 'b.label'=>'Label', 'b.num_chq'=>'ChequeOrTransferNumber', 'b.fk_bordereau'=>'ChequeBordereau', '-b.amount'=>'Debit', 'b.amount'=>'Credit', - 'b.num_releve'=>'AccountStatement', 'b.rappro'=>'Conciliated', 'b.datec'=>"DateCreation", "bu.url_id"=>"IdThirdParty", + 'b.num_releve'=>'AccountStatement', 'b.rappro'=>'BankLineReconciled', 'b.datec'=>"DateCreation", "bu.url_id"=>"IdThirdParty", "s.nom"=>"ThirdParty", "s.code_compta"=>"CustomerAccountancyCode", "s.code_compta_fournisseur"=>"SupplierAccountancyCode" ); $this->export_TypeFields_array[$r] = array('ba.ref'=>'Text', 'ba.label'=>'Text', 'b.datev'=>'Date', 'b.dateo'=>'Date', 'b.label'=>'Text', 'b.num_chq'=>'Text', 'b.fk_bordereau'=>'Text', '-b.amount'=>'Numeric', 'b.amount'=>'Numeric', 'b.num_releve'=>'Text', 'b.rappro'=>'Boolean', 'b.datec'=>"Date", "bu.url_id"=>"Text", "s.nom"=>"Text", "s.code_compta"=>"Text", "s.code_compta_fournisseur"=>"Text"); diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index 877dca880f7..ced58f9b6c4 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -33,7 +33,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; */ class modBarcode extends DolibarrModules { - /** * Constructor. Define names, constants, directories, boxes, permissions * @@ -94,6 +93,7 @@ class modBarcode extends DolibarrModules // Main menu entries $r = 0; + // A menu entry for the Tools top menu $this->menu[$r] = array( 'fk_menu'=>'fk_mainmenu=tools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'mainmenu'=>'tools', @@ -111,6 +111,7 @@ class modBarcode extends DolibarrModules ); $r++; + // A menu entry for the left menu $this->menu[$r] = array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=admintools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Left menu entry diff --git a/htdocs/core/modules/modCommande.class.php b/htdocs/core/modules/modCommande.class.php index d8ba1f98146..9aac30fe8a5 100644 --- a/htdocs/core/modules/modCommande.class.php +++ b/htdocs/core/modules/modCommande.class.php @@ -196,10 +196,10 @@ class modCommande extends DolibarrModules 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 'ps.nom'=>'ParentCompany', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'd.nom'=>'State', 'co.label'=>'Country', 'co.code'=>"CountryCode", 's.phone'=>'Phone', 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 'c.rowid'=>"Id", 'c.ref'=>"Ref", 'c.ref_client'=>"RefCustomer", 'c.fk_soc'=>"IdCompany", 'c.date_creation'=>"DateCreation", 'c.date_commande'=>"OrderDate", - 'c.date_livraison'=>"DateDeliveryPlanned", 'c.amount_ht'=>"Amount", 'c.remise_percent'=>"GlobalDiscount", 'c.total_ht'=>"TotalHT", + 'c.date_livraison'=>"DateDeliveryPlanned", 'c.amount_ht'=>"Amount", 'c.total_ht'=>"TotalHT", 'c.total_ttc'=>"TotalTTC", 'c.facture'=>"Billed", 'c.fk_statut'=>'Status', 'c.note_public'=>"Note", 'c.date_livraison'=>'DeliveryDate', 'c.fk_user_author'=>'CreatedById', 'uc.login'=>'CreatedByLogin', 'c.fk_user_valid'=>'ValidatedById', 'uv.login'=>'ValidatedByLogin', - 'pj.ref'=>'ProjectRef', 'cd.rowid'=>'LineId', 'cd.label'=>"Label", 'cd.description'=>"LineDescription", 'cd.product_type'=>'TypeOfLineServiceOrProduct', + 'pj.ref'=>'ProjectRef', 'cd.rowid'=>'LineId', 'cd.description'=>"LineDescription", 'cd.product_type'=>'TypeOfLineServiceOrProduct', 'cd.tva_tx'=>"LineVATRate", 'cd.qty'=>"LineQty", 'cd.total_ht'=>"LineTotalHT", 'cd.total_tva'=>"LineTotalVAT", 'cd.total_ttc'=>"LineTotalTTC", 'p.rowid'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel' ); @@ -220,7 +220,7 @@ class modCommande extends DolibarrModules //$this->export_TypeFields_array[$r]=array( // 's.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','co.label'=>'List:c_country:label:label', // 'co.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','c.ref'=>"Text",'c.ref_client'=>"Text", - // 'c.date_creation'=>"Date",'c.date_commande'=>"Date",'c.amount_ht'=>"Numeric",'c.remise_percent'=>"Numeric",'c.total_ht'=>"Numeric", + // 'c.date_creation'=>"Date",'c.date_commande'=>"Date",'c.amount_ht'=>"Numeric",'c.total_ht'=>"Numeric", // 'c.total_ttc'=>"Numeric",'c.facture'=>"Boolean",'c.fk_statut'=>'Status','c.note_public'=>"Text",'c.date_livraison'=>'Date','cd.description'=>"Text", // 'cd.product_type'=>'Boolean','cd.tva_tx'=>"Numeric",'cd.qty'=>"Numeric",'cd.total_ht'=>"Numeric",'cd.total_tva'=>"Numeric",'cd.total_ttc'=>"Numeric", // 'p.rowid'=>'List:product:ref','p.ref'=>'Text','p.label'=>'Text' @@ -228,7 +228,7 @@ class modCommande extends DolibarrModules $this->export_TypeFields_array[$r] = array( 's.nom'=>'Text', 'ps.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'co.label'=>'List:c_country:label:label', 'co.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 'c.ref'=>"Text", 'c.ref_client'=>"Text", 'c.date_creation'=>"Date", - 'c.date_commande'=>"Date", 'c.date_livraison'=>"Date", 'c.amount_ht'=>"Numeric", 'c.remise_percent'=>"Numeric", 'c.total_ht'=>"Numeric", + 'c.date_commande'=>"Date", 'c.date_livraison'=>"Date", 'c.amount_ht'=>"Numeric", 'c.total_ht'=>"Numeric", 'c.total_ttc'=>"Numeric", 'c.facture'=>"Boolean", 'c.fk_statut'=>'Status', 'c.note_public'=>"Text", 'c.date_livraison'=>'Date', 'pj.ref'=>'Text', 'cd.description'=>"Text", 'cd.product_type'=>'Boolean', 'cd.tva_tx'=>"Numeric", 'cd.qty'=>"Numeric", 'cd.total_ht'=>"Numeric", 'cd.total_tva'=>"Numeric", 'cd.total_ttc'=>"Numeric", 'p.rowid'=>'List:product:ref::product', 'p.ref'=>'Text', 'p.label'=>'Text', 'd.nom'=>'Text', @@ -238,8 +238,8 @@ class modCommande extends DolibarrModules 's.rowid'=>"company", 's.nom'=>'company', 'ps.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'd.nom'=>'company', 'co.label'=>'company', 'co.code'=>'company', 's.phone'=>'company', 's.siren'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.siret'=>'company', 'c.rowid'=>"order", 'c.ref'=>"order", 'c.ref_client'=>"order", 'c.fk_soc'=>"order", 'c.date_creation'=>"order", 'c.date_commande'=>"order", 'c.amount_ht'=>"order", - 'c.remise_percent'=>"order", 'c.total_ht'=>"order", 'c.total_ttc'=>"order", 'c.facture'=>"order", 'c.fk_statut'=>"order", 'c.note'=>"order", - 'c.date_livraison'=>"order", 'pj.ref'=>'project', 'cd.rowid'=>'order_line', 'cd.label'=>"order_line", 'cd.description'=>"order_line", + 'c.total_ht'=>"order", 'c.total_ttc'=>"order", 'c.facture'=>"order", 'c.fk_statut'=>"order", 'c.note'=>"order", + 'c.date_livraison'=>"order", 'pj.ref'=>'project', 'cd.rowid'=>'order_line', 'cd.description'=>"order_line", 'cd.product_type'=>'order_line', 'cd.tva_tx'=>"order_line", 'cd.qty'=>"order_line", 'cd.total_ht'=>"order_line", 'cd.total_tva'=>"order_line", 'cd.total_ttc'=>"order_line", 'p.rowid'=>'product', 'p.ref'=>'product', 'p.label'=>'product' ); @@ -296,18 +296,17 @@ class modCommande extends DolibarrModules $this->import_entities_array[$r] = array(); $this->import_tables_array[$r] = array('c' => MAIN_DB_PREFIX.'commande', 'extra' => MAIN_DB_PREFIX.'commande_extrafields'); $this->import_tables_creator_array[$r] = array('c' => 'fk_user_author'); // Fields to store import user id + $import_sample = array(); $this->import_fields_array[$r] = array( 'c.ref' => 'Ref*', 'c.ref_client' => 'RefCustomer', 'c.fk_soc' => 'ThirdPartyName*', 'c.fk_projet' => 'ProjectId', 'c.date_creation' => 'DateCreation', - 'c.date_valid' => 'DateValid', - 'c.date_commande' => 'DateOrder', + 'c.date_valid' => 'DateValidation', + 'c.date_commande' => 'OrderDate*', 'c.fk_user_modif' => 'ModifiedById', 'c.fk_user_valid' => 'ValidatedById', - 'c.fk_statut' => 'Status*', - 'c.remise_percent' => 'GlobalDiscount', 'c.total_tva' => 'TotalTVA', 'c.total_ht' => 'TotalHT', 'c.total_ttc' => 'TotalTTC', @@ -317,7 +316,8 @@ class modCommande extends DolibarrModules 'c.date_livraison' => 'DeliveryDate', 'c.fk_cond_reglement' => 'Payment Condition', 'c.fk_mode_reglement' => 'Payment Mode', - 'c.model_pdf' => 'Model' + 'c.model_pdf' => 'Model', + 'c.fk_statut' => 'Status*' ); if (!empty($conf->multicurrency->enabled)) { @@ -327,51 +327,48 @@ class modCommande extends DolibarrModules $this->import_fields_array[$r]['c.multicurrency_total_tva'] = 'MulticurrencyAmountVAT'; $this->import_fields_array[$r]['c.multicurrency_total_ttc'] = 'MulticurrencyAmountTTC'; } - - // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'commande' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); + $keyforselect = 'commande'; + $keyforelement = 'order'; + $keyforaliasextra = 'extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinimport.inc.php'; - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { - $fieldname = 'extra.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $this->import_fields_array[$r][$fieldname] = $fieldlabel.($obj->fieldrequired ? '*' : ''); - $import_extrafield_sample[$fieldname] = $fieldlabel; - } - } - // End add extra fields - - $this->import_fieldshidden_array[$r] = ['extra.fk_object' => 'lastrowid-'.MAIN_DB_PREFIX.'commande']; - $this->import_regex_array[$r] = [ + $this->import_fieldshidden_array[$r] = array('extra.fk_object' => 'lastrowid-'.MAIN_DB_PREFIX.'commande'); + $this->import_regex_array[$r] = array( 'c.multicurrency_code' => 'code@'.MAIN_DB_PREFIX.'multicurrency' - ]; - - $this->import_updatekeys_array[$r] = ['c.ref' => 'Ref']; - $this->import_convertvalue_array[$r] = [ - 'c.fk_soc' => [ + ); + $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample); + $this->import_updatekeys_array[$r] = array('c.ref' => 'Ref'); + $this->import_convertvalue_array[$r] = array( + 'c.ref' => array( + 'rule'=>'getrefifauto', + 'class'=>(empty($conf->global->COMMANDE_ADDON) ? 'mod_commande_marbre' : $conf->global->COMMANDE_ADDON), + 'path'=>"/core/modules/commande/".(empty($conf->global->COMMANDE_ADDON) ? 'mod_commande_marbre' : $conf->global->COMMANDE_ADDON).'.php', + 'classobject'=>'Commande', + 'pathobject'=>'/commande/class/commande.class.php', + ), + 'c.fk_soc' => array( 'rule' => 'fetchidfromref', 'file' => '/societe/class/societe.class.php', 'class' => 'Societe', 'method' => 'fetch', 'element' => 'ThirdParty' - ], - 'c.fk_user_valid' => [ + ), + 'c.fk_user_valid' => array( 'rule' => 'fetchidfromref', 'file' => '/user/class/user.class.php', 'class' => 'User', 'method' => 'fetch', 'element' => 'user' - ], - 'c.fk_mode_reglement' => [ + ), + 'c.fk_mode_reglement' => array( 'rule' => 'fetchidfromcodeorlabel', 'file' => '/compta/paiement/class/cpaiement.class.php', 'class' => 'Cpaiement', 'method' => 'fetch', 'element' => 'cpayment' - ], - ]; + ), + ); //Import CPV Lines $r++; @@ -381,15 +378,13 @@ class modCommande extends DolibarrModules $this->import_entities_array[$r] = array(); $this->import_tables_array[$r] = array('cd' => MAIN_DB_PREFIX.'commandedet', 'extra' => MAIN_DB_PREFIX.'commandedet_extrafields'); $this->import_fields_array[$r] = array( - 'cd.fk_commande' => 'SalesOrder*', - 'cd.fk_parent_line' => 'PrParentLine', + 'cd.fk_commande' => 'CustomerOrder*', + 'cd.fk_parent_line' => 'ParentLine', 'cd.fk_product' => 'IdProduct', - 'cd.label' => 'Label', 'cd.description' => 'LineDescription', 'cd.tva_tx' => 'LineVATRate', 'cd.qty' => 'LineQty', 'cd.remise_percent' => 'Reduc. Percent', - 'cd.remise' => 'Reduc.', 'cd.price' => 'Price', 'cd.subprice' => 'Sub Price', 'cd.total_ht' => 'LineTotalHT', @@ -410,17 +405,11 @@ class modCommande extends DolibarrModules $this->import_fields_array[$r]['cd.multicurrency_total_ttc'] = 'MulticurrencyAmountTTC'; } - // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'commandedet' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { - $fieldname = 'extra.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $this->import_fields_array[$r][$fieldname] = $fieldlabel.($obj->fieldrequired ? '*' : ''); - } - } - // End add extra fields + $import_extrafield_sample = array(); + $keyforselect = 'commandedet'; + $keyforelement = 'orderline'; + $keyforaliasextra = 'extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinimport.inc.php'; $this->import_fieldshidden_array[$r] = ['extra.fk_object' => 'lastrowid-'.MAIN_DB_PREFIX.'commandedet']; $this->import_regex_array[$r] = [ diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index 60d713d5fc4..290eea449f5 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -1,6 +1,7 @@ + * Copyright (C) 2022 Anthony Berton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -98,7 +99,8 @@ class modCron extends DolibarrModules // Cronjobs $this->cronjobs = array( 0=>array('entity'=>0, 'label'=>'PurgeDeleteTemporaryFilesShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'purgeFiles', 'parameters'=>'tempfilesold+logfiles', 'comment'=>'PurgeDeleteTemporaryFiles', 'frequency'=>2, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>50, 'status'=>1, 'test'=>true), - 1=>array('entity'=>0, 'label'=>'MakeLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'dumpDatabase', 'parameters'=>'none,auto,1,auto,10', 'comment'=>'MakeLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>90, 'status'=>0, 'test'=>in_array($this->db->type, array('mysql', 'mysqli'))), + 1=>array('entity'=>0, 'label'=>'MakeLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'dumpDatabase', 'parameters'=>'none,auto,1,auto,10', 'comment'=>'MakeLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>90, 'status'=>0, 'test'=>'in_array($conf->db->type, array(\'mysql\', \'mysqli\'))'), + 2=>array('entity'=>0, 'label'=>'MakeSendLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'sendDumpDatabase', 'parameters'=>',,,,,sql', 'comment'=>'MakeSendLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>604800, 'priority'=>91, 'status'=>0, 'test'=>'!empty($conf->global->MAIN_ALLOW_BACKUP_BY_EMAIL) && in_array($conf->db->type, array(\'mysql\', \'mysqli\'))'), // 1=>array('entity'=>0, 'label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24) ); diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index fac768b9c60..817fa1b53cf 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -99,14 +99,6 @@ class modFacture extends DolibarrModules $this->const[$r][4] = 0; $r++; - /*$this->const[$r][0] = "FACTURE_DRAFT_WATERMARK"; - $this->const[$r][1] = "chaine"; - $this->const[$r][2] = "__(Draft)__"; - $this->const[$r][3] = 'Watermark to show on draft invoices'; - $this->const[$r][4] = 0; - $r++;*/ - - // Boxes //$this->boxes = array(0=>array(1=>'box_factures_imp.php'),1=>array(1=>'box_factures.php')); $this->boxes = array( @@ -121,7 +113,7 @@ class modFacture extends DolibarrModules $datestart = dol_mktime(23, 0, 0, $arraydate['mon'], $arraydate['mday'], $arraydate['year']); $this->cronjobs = array( 0 => array( - 'label'=>'RecurringInvoices', + 'label'=>'RecurringInvoicesJob', 'jobtype'=>'method', 'class'=>'compta/facture/class/facture-rec.class.php', 'objectname'=>'FactureRec', @@ -130,7 +122,7 @@ class modFacture extends DolibarrModules 'comment'=>'Generate recurring invoices', 'frequency'=>1, 'unitfrequency'=>3600 * 24, - 'priority'=>50, + 'priority'=>51, 'status'=>1, 'test'=>'$conf->facture->enabled', 'datestart'=>$datestart @@ -284,7 +276,7 @@ class modFacture extends DolibarrModules 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.localtax1'=>'Numeric', 'f.localtax2'=>'Numeric', 'f.paye'=>"Boolean", 'f.fk_statut'=>'Numeric', 'f.close_code'=>'Text', 'f.close_note'=>'Text', 'none.rest'=>"NumericCompute", 'f.note_private'=>"Text", 'f.note_public'=>"Text", 'f.fk_user_author'=>'Numeric', 'uc.login'=>'Text', 'f.fk_user_valid'=>'Numeric', 'uv.login'=>'Text', - 'pj.ref'=>'Text', 'pj.title'=>'Text', 'fd.rowid'=>'Numeric', 'fd.label'=>'Text', 'fd.description'=>"Text", 'fd.subprice'=>"Numeric", 'fd.tva_tx'=>"Numeric", + 'pj.ref'=>'Text', 'pj.title'=>'Text', 'fd.rowid'=>'Numeric', 'fd.description'=>"Text", 'fd.subprice'=>"Numeric", 'fd.tva_tx'=>"Numeric", 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_tva'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.date_start'=>"Date", 'fd.date_end'=>"Date", 'fd.special_code'=>'Numeric', 'fd.product_type'=>"Numeric", 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text', $alias_product_perentity . '.accountancy_code_sell'=>'Text', @@ -297,7 +289,7 @@ class modFacture extends DolibarrModules $this->export_entities_array[$r] = array( 's.rowid'=>"company", 's.nom'=>'company', 'ps.nom'=>'company', 's.code_client'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 'cd.nom'=>'company', 's.phone'=>'company', 's.siren'=>'company', 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', - 's.tva_intra'=>'company', 'pj.ref'=>'project', 'pj.title'=>'project', 'fd.rowid'=>'invoice_line', 'fd.label'=>"invoice_line", 'fd.description'=>"invoice_line", + 's.tva_intra'=>'company', 'pj.ref'=>'project', 'pj.title'=>'project', 'fd.rowid'=>'invoice_line', 'fd.description'=>"invoice_line", 'fd.subprice'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_tva'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva_tx'=>"invoice_line", 'fd.qty'=>"invoice_line", 'fd.date_start'=>"invoice_line", 'fd.date_end'=>"invoice_line", 'fd.special_code'=>'invoice_line', 'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product', 'p.ref'=>'product', 'p.label'=>'product', $alias_product_perentity . '.accountancy_code_sell'=>'product', diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 8bd801e0daa..aef28514c61 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -133,7 +133,7 @@ class modFournisseur extends DolibarrModules $datestart = dol_mktime(23, 0, 0, $arraydate['mon'], $arraydate['mday'], $arraydate['year']); $this->cronjobs = array( 0 => array( - 'label'=>'RecurringSupplierInvoices', + 'label'=>'RecurringSupplierInvoicesJob', 'jobtype'=>'method', 'class'=>'fourn/class/fournisseur.facture-rec.class.php', 'objectname'=>'FactureFournisseurRec', @@ -142,7 +142,7 @@ class modFournisseur extends DolibarrModules 'comment'=>'Generate recurring supplier invoices', 'frequency'=>1, 'unitfrequency'=>3600 * 24, - 'priority'=>50, + 'priority'=>51, 'status'=>1, 'datestart'=>$datestart )); @@ -312,7 +312,8 @@ class modFournisseur extends DolibarrModules 'f.rowid'=>"InvoiceId", 'f.ref'=>"InvoiceRef", 'f.ref_supplier'=>"RefSupplier", 'f.datec'=>"InvoiceDateCreation", 'f.datef'=>"DateInvoice", 'f.date_lim_reglement'=>'DateMaxPayment', 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.paye'=>"InvoicePaid", 'f.fk_statut'=>'InvoiceStatus', 'f.note_public'=>"InvoiceNote", 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", - 'fd.total_ttc'=>"LineTotalTTC", 'fd.tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.fk_product'=>'ProductId', + 'fd.total_ttc'=>"LineTotalTTC", 'fd.tva'=>"LineTotalVAT", 'fd.date_start'=>"DateStart", 'fd.date_end'=>"DateEnd", 'fd.special_code'=>'SpecialCode', + 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.fk_product'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'p.accountancy_code_buy'=>'ProductAccountancyBuyCode', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' ); @@ -333,7 +334,8 @@ class modFournisseur extends DolibarrModules 's.nom'=>'Text', 'ps.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.idprof5'=>'Text', 's.idprof6'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>'Date', 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', 'f.note_public'=>"Text", 'fd.description'=>"Text", 'fd.tva_tx'=>"Text", - 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.tva'=>"Numeric", 'fd.product_type'=>'Numeric', 'fd.fk_product'=>'List:product:label', + 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.tva'=>"Numeric", 'fd.date_start'=>"Date", 'fd.date_end'=>"Date", 'fd.special_code'=>"Numeric", + 'fd.product_type'=>'Numeric', 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text' ); $this->export_entities_array[$r] = array( @@ -341,7 +343,8 @@ class modFournisseur extends DolibarrModules 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', 's.tva_intra'=>'company', 'f.rowid'=>"invoice", 'f.ref'=>"invoice", 'f.ref_supplier'=>"invoice", 'f.datec'=>"invoice", 'f.datef'=>"invoice", 'f.date_lim_reglement'=>'invoice', 'f.total_ht'=>"invoice", 'f.total_ttc'=>"invoice", 'f.total_tva'=>"invoice", 'f.paye'=>"invoice", 'f.fk_statut'=>'invoice', 'f.note_public'=>"invoice", 'fd.rowid'=>'invoice_line', 'fd.description'=>"invoice_line", 'fd.tva_tx'=>"invoice_line", 'fd.qty'=>"invoice_line", - 'fd.remise_percent'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva'=>"invoice_line", 'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product', + 'fd.remise_percent'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva'=>"invoice_line", 'fd.date_start'=>"invoice_line", 'fd.date_end'=>"invoice_line", 'fd.special_code'=>"invoice_line", + 'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product', 'p.ref'=>'product', 'p.label'=>'product', 'p.accountancy_code_buy'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' ); $this->export_dependencies_array[$r] = array('invoice_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them @@ -451,7 +454,8 @@ class modFournisseur extends DolibarrModules 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.fk_statut'=>'Status', 'f.date_valid'=>'DateValidation', 'f.date_approve'=>'DateApprove', 'f.date_approve2'=>'DateApprove2', 'f.note_public'=>"NotePublic", 'f.note_private'=>"NotePrivate", 'uv.login'=>'UserValidation', 'ua1.login'=>'ApprovedBy', 'ua2.login'=>'ApprovedBy2', 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", 'fd.total_ttc'=>"LineTotalTTC", - 'fd.total_tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.ref'=>'RefSupplier', 'fd.fk_product'=>'ProductId', + 'fd.total_tva'=>"LineTotalVAT", 'fd.date_start'=>"DateStart", 'fd.date_end'=>"DateEnd", 'fd.special_code'=>'SpecialCode', + 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.ref'=>'RefSupplier', 'fd.fk_product'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' ); if (!empty($conf->multicurrency->enabled)) { @@ -471,13 +475,15 @@ class modFournisseur extends DolibarrModules 'f.date_creation'=>"Date", 'f.date_commande'=>"Date", 'f.date_livraison'=>"Date", 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.fk_statut'=>'Status', 'f.date_valid'=>'Date', 'f.date_approve'=>'Date', 'f.date_approve2'=>'Date', 'f.note_public'=>"Text", 'f.note_private'=>"Text", 'fd.description'=>"Text", 'fd.tva_tx'=>"Numeric", 'fd.qty'=>"Numeric", 'fd.remise_percent'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.total_tva'=>"Numeric", + 'fd.date_start'=>"Date", 'fd.date_end'=>"Date", 'fd.special_code'=>"Numeric", 'fd.product_type'=>'Numeric', 'fd.ref'=>'Text', 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text' ); $this->export_entities_array[$r] = array( 's.rowid'=>"company", 's.nom'=>'company', 'ps.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 's.phone'=>'company', 's.siren'=>'company', 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company', 's.tva_intra'=>'company', 'uv.login'=>'user', 'ua1.login'=>'user', 'ua2.login'=>'user', 'fd.rowid'=>'order_line', 'fd.description'=>"order_line", 'fd.tva_tx'=>"order_line", 'fd.qty'=>"order_line", 'fd.remise_percent'=>"order_line", - 'fd.total_ht'=>"order_line", 'fd.total_ttc'=>"order_line", 'fd.total_tva'=>"order_line", 'fd.product_type'=>'order_line', 'fd.ref'=>'order_line', 'fd.fk_product'=>'product', + 'fd.total_ht'=>"order_line", 'fd.total_ttc'=>"order_line", 'fd.total_tva'=>"order_line", 'fd.date_start'=>"order_line", 'fd.date_end'=>"order_line", 'fd.special_code'=>"order_line", + 'fd.product_type'=>'order_line', 'fd.ref'=>'order_line', 'fd.fk_product'=>'product', 'p.ref'=>'product', 'p.label'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' ); $this->export_dependencies_array[$r] = array('order_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them @@ -606,7 +612,13 @@ class modFournisseur extends DolibarrModules $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample); $this->import_updatekeys_array[$r] = array('f.ref' => 'Ref'); $this->import_convertvalue_array[$r] = array( - //'c.ref'=>array('rule'=>'getrefifauto'), + 'f.ref' => array( + 'rule'=>'getrefifauto', + 'class'=>(empty($conf->global->INVOICE_SUPPLIER_ADDON_NUMBER) ? 'mod_facture_fournisseur_cactus' : $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER), + 'path'=>"/core/modules/supplier_invoice/".(empty($conf->global->INVOICE_SUPPLIER_ADDON_NUMBER) ? 'mod_facture_fournisseur_cactus' : $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER).'.php', + 'classobject'=>'FactureFournisseur', + 'pathobject'=>'/fourn/class/fournisseur.facture.class.php', + ), 'f.fk_soc' => array('rule' => 'fetchidfromref', 'file' => '/societe/class/societe.class.php', 'class' => 'Societe', 'method' => 'fetch', 'element' => 'ThirdParty'), 'f.fk_account' => array('rule' => 'fetchidfromref', 'file' => '/compta/bank/class/account.class.php', 'class' => 'Account', 'method' => 'fetch', 'element' => 'bank_account'), ); @@ -620,9 +632,8 @@ class modFournisseur extends DolibarrModules $this->import_tables_array[$r] = array('fd' => MAIN_DB_PREFIX.'facture_fourn_det', 'extra' => MAIN_DB_PREFIX.'facture_fourn_det_extrafields'); $this->import_fields_array[$r] = array( 'fd.fk_facture_fourn' => 'InvoiceRef*', - 'fd.fk_parent_line' => 'FacParentLine', + 'fd.fk_parent_line' => 'ParentLine', 'fd.fk_product' => 'IdProduct', - 'fd.label' => 'Label', 'fd.description' => 'LineDescription', 'fd.pu_ht' => 'PriceUHT', 'fd.pu_ttc' => 'PriceUTTC', @@ -664,7 +675,6 @@ class modFournisseur extends DolibarrModules 'fd.fk_facture_fourn' => '(PROV001)', 'fd.fk_parent_line' => '', 'fd.fk_product' => '', - 'fd.label' => '', 'fd.description' => 'Test Product', 'fd.pu_ht' => '50000', 'fd.pu_ttc' => '50000', @@ -714,7 +724,6 @@ class modFournisseur extends DolibarrModules 'c.source' => 'Source', 'c.fk_statut' => 'Status*', 'c.billed' => 'Billed(0/1)', - 'c.remise_percent' => 'GlobalDiscount', 'c.total_tva' => 'TotalTVA', 'c.total_ht' => 'TotalHT', 'c.total_ttc' => 'TotalTTC', @@ -756,6 +765,13 @@ class modFournisseur extends DolibarrModules $this->import_updatekeys_array[$r] = array('c.ref' => 'Ref'); $this->import_convertvalue_array[$r] = array( + 'c.ref' => array( + 'rule'=>'getrefifauto', + 'class'=>(empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER) ? 'mod_commande_fournisseur_muguet' : $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER), + 'path'=>"/core/modules/supplier_order/".(empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER) ? 'mod_commande_fournisseur_muguet' : $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER).'.php', + 'classobject'=>'CommandeFournisseur', + 'pathobject'=>'/fourn/class/fournisseur.commande.class.php', + ), 'c.fk_soc' => array( 'rule' => 'fetchidfromref', 'file' => '/societe/class/societe.class.php', @@ -782,14 +798,12 @@ class modFournisseur extends DolibarrModules $this->import_tables_array[$r] = array('cd' => MAIN_DB_PREFIX.'commande_fournisseurdet', 'extra' => MAIN_DB_PREFIX.'commande_fournisseurdet_extrafields'); $this->import_fields_array[$r] = array( 'cd.fk_commande' => 'PurchaseOrder*', - 'cd.fk_parent_line' => 'PrParentLine', + 'cd.fk_parent_line' => 'ParentLine', 'cd.fk_product' => 'IdProduct', - 'cd.label' => 'Label', 'cd.description' => 'LineDescription', 'cd.tva_tx' => 'LineVATRate', 'cd.qty' => 'LineQty', 'cd.remise_percent' => 'Reduc. Percent', - 'cd.remise' => 'Reduc.', 'cd.subprice' => 'Sub Price', 'cd.total_ht' => 'LineTotalHT', 'cd.total_tva' => 'LineTotalVAT', diff --git a/htdocs/core/modules/modHRM.class.php b/htdocs/core/modules/modHRM.class.php index 3e75f8efcd5..bd81f06dae7 100644 --- a/htdocs/core/modules/modHRM.class.php +++ b/htdocs/core/modules/modHRM.class.php @@ -214,28 +214,28 @@ class modHRM extends DolibarrModules $r++; // Evaluation - $this->rights[$r][0] = 4020; // Permission id (must not be already used) + $this->rights[$r][0] = 4021; // Permission id (must not be already used) $this->rights[$r][1] = 'Read evaluations'; // Permission label $this->rights[$r][3] = 0; // Permission by default for new user (0/1) $this->rights[$r][4] = 'evaluation'; $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->hrm->evaluation->read) $r++; - $this->rights[$r][0] = 4021; // Permission id (must not be already used) + $this->rights[$r][0] = 4022; // Permission id (must not be already used) $this->rights[$r][1] = 'Create/modify your evaluation'; // Permission label $this->rights[$r][3] = 0; // Permission by default for new user (0/1) $this->rights[$r][4] = 'evaluation'; $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->hrm->evaluation->write) $r++; - $this->rights[$r][0] = 4022; // Permission id (must not be already used) + $this->rights[$r][0] = 4023; // Permission id (must not be already used) $this->rights[$r][1] = 'Validate evaluation'; // Permission label $this->rights[$r][3] = 0; // Permission by default for new user (0/1) $this->rights[$r][4] = 'evaluation_advance'; $this->rights[$r][5] = 'validate'; // In php code, permission will be checked by test if ($user->rights->hrm->evaluation->validate) $r++; - $this->rights[$r][0] = 4023; // Permission id (must not be already used) + $this->rights[$r][0] = 4025; // Permission id (must not be already used) $this->rights[$r][1] = 'Delete evaluations'; // Permission label $this->rights[$r][3] = 0; // Permission by default for new user (0/1) $this->rights[$r][4] = 'evaluation'; @@ -243,12 +243,28 @@ class modHRM extends DolibarrModules $r++; // Comparison - $this->rights[$r][0] = 4030; // Permission id (must not be already used) + $this->rights[$r][0] = 4028; // Permission id (must not be already used) $this->rights[$r][1] = 'See comparison menu'; // Permission label $this->rights[$r][3] = 0; // Permission by default for new user (0/1) $this->rights[$r][4] = 'compare_advance'; $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->hrm->compare_advance->read) $r++; + + // Read employee + $this->rights[$r][0] = 4031; // Permission id (must not be already used) + $this->rights[$r][1] = 'Read personal information'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'read_personal_information'; + $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->hrm->read_personal_information->read) + $r++; + + // Write employee + $this->rights[$r][0] = 4032; // Permission id (must not be already used) + $this->rights[$r][1] = 'Write personal information'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'write_personal_information'; + $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->hrm->write_personal_information->write) + $r++; } /** diff --git a/htdocs/core/modules/modOpenSurvey.class.php b/htdocs/core/modules/modOpenSurvey.class.php index 87a4f453801..9cc9310cd19 100644 --- a/htdocs/core/modules/modOpenSurvey.class.php +++ b/htdocs/core/modules/modOpenSurvey.class.php @@ -182,6 +182,13 @@ class modOpenSurvey extends DolibarrModules */ public function init($options = '') { + global $conf, $langs; + + $result = $this->_load_tables('/install/mysql/tables/', 'opensurvey'); + if ($result < 0) { + return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') + } + // Permissions $this->remove($options); diff --git a/htdocs/core/modules/modPartnership.class.php b/htdocs/core/modules/modPartnership.class.php index 516c2b41e13..3bec23d0d37 100644 --- a/htdocs/core/modules/modPartnership.class.php +++ b/htdocs/core/modules/modPartnership.class.php @@ -75,7 +75,7 @@ class modPartnership extends DolibarrModules // $this->editor_url = 'https://www.example.com'; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = 'development'; + $this->version = 'experimental'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index d1c1906d4a6..b18d10a29b1 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -857,7 +857,7 @@ class modProduct extends DolibarrModules } if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { $this->import_examplevalues_array[$r] = array_merge($this->import_examplevalues_array[$r], array( - 'sp.packagning'=>'1', + 'sp.packaging'=>'10', )); } diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php index 4f0633cd578..3419d4c866e 100644 --- a/htdocs/core/modules/modPropale.class.php +++ b/htdocs/core/modules/modPropale.class.php @@ -190,10 +190,10 @@ class modPropale extends DolibarrModules $this->export_fields_array[$r] = array( 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 'ps.nom'=>'ParentCompany', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'co.code'=>'CountryCode', 's.phone'=>'Phone', 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 'c.rowid'=>"Id", 'c.ref'=>"Ref", 'c.ref_client'=>"RefCustomer", - 'c.fk_soc'=>"IdCompany", 'c.datec'=>"DateCreation", 'c.datep'=>"DatePropal", 'c.fin_validite'=>"DateEndPropal", 'c.remise_percent'=>"GlobalDiscount", + 'c.fk_soc'=>"IdCompany", 'c.datec'=>"DateCreation", 'c.datep'=>"DatePropal", 'c.fin_validite'=>"DateEndPropal", 'c.total_ht'=>"TotalHT", 'c.total_ttc'=>"TotalTTC", 'c.fk_statut'=>'Status', 'c.note_public'=>"Note", 'c.date_livraison'=>'DeliveryDate', 'c.fk_user_author'=>'CreatedById', 'uc.login'=>'CreatedByLogin', 'c.fk_user_valid'=>'ValidatedById', 'uv.login'=>'ValidatedByLogin', - 'pj.ref'=>'ProjectRef', 'cd.rowid'=>'LineId', 'cd.label'=>"Label", 'cd.description'=>"LineDescription", 'cd.product_type'=>'TypeOfLineServiceOrProduct', + 'pj.ref'=>'ProjectRef', 'cd.rowid'=>'LineId', 'cd.description'=>"LineDescription", 'cd.product_type'=>'TypeOfLineServiceOrProduct', 'cd.tva_tx'=>"LineVATRate", 'cd.qty'=>"LineQty", 'cd.total_ht'=>"LineTotalHT", 'cd.total_tva'=>"LineTotalVAT", 'cd.total_ttc'=>"LineTotalTTC", 'p.rowid'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel' ); @@ -214,14 +214,14 @@ class modPropale extends DolibarrModules //$this->export_TypeFields_array[$r]=array( // 's.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','co.code'=>'Text','s.phone'=>'Text', // 's.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','c.ref'=>"Text",'c.ref_client'=>"Text",'c.datec'=>"Date",'c.datep'=>"Date", - // 'c.fin_validite'=>"Date",'c.remise_percent'=>"Numeric",'c.total_ht'=>"Numeric",'c.total_ttc'=>"Numeric",'c.fk_statut'=>'Status','c.note_public'=>"Text", + // 'c.fin_validite'=>"Date",'c.total_ht'=>"Numeric",'c.total_ttc'=>"Numeric",'c.fk_statut'=>'Status','c.note_public'=>"Text", // 'c.date_livraison'=>'Date','cd.description'=>"Text",'cd.product_type'=>'Boolean','cd.tva_tx'=>"Numeric",'cd.qty'=>"Numeric",'cd.total_ht'=>"Numeric", // 'cd.total_tva'=>"Numeric",'cd.total_ttc'=>"Numeric",'p.rowid'=>'List:product:label','p.ref'=>'Text','p.label'=>'Text' //); $this->export_TypeFields_array[$r] = array( 's.nom'=>'Text', 'ps.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'co.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 'c.ref'=>"Text", 'c.ref_client'=>"Text", 'c.datec'=>"Date", 'c.datep'=>"Date", 'c.fin_validite'=>"Date", - 'c.remise_percent'=>"Numeric", 'c.total_ht'=>"Numeric", 'c.total_ttc'=>"Numeric", 'c.fk_statut'=>'Status', 'c.note_public'=>"Text", 'c.date_livraison'=>'Date', + 'c.total_ht'=>"Numeric", 'c.total_ttc'=>"Numeric", 'c.fk_statut'=>'Status', 'c.note_public'=>"Text", 'c.date_livraison'=>'Date', 'pj.ref'=>'Text', 'cd.description'=>"Text", 'cd.product_type'=>'Boolean', 'cd.tva_tx'=>"Numeric", 'cd.qty'=>"Numeric", 'cd.total_ht'=>"Numeric", 'cd.total_tva'=>"Numeric", 'cd.total_ttc'=>"Numeric", 'p.ref'=>'Text', 'p.label'=>'Text', 'c.entity'=>'List:entity:label:rowid', @@ -229,9 +229,9 @@ class modPropale extends DolibarrModules $this->export_entities_array[$r] = array( 's.rowid'=>"company", 's.nom'=>'company', 'ps.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'co.code'=>'company', 's.phone'=>'company', 's.siren'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.siret'=>'company', 'c.rowid'=>"propal", 'c.ref'=>"propal", 'c.ref_client'=>"propal", - 'c.fk_soc'=>"propal", 'c.datec'=>"propal", 'c.datep'=>"propal", 'c.fin_validite'=>"propal", 'c.remise_percent'=>"propal", 'c.total_ht'=>"propal", + 'c.fk_soc'=>"propal", 'c.datec'=>"propal", 'c.datep'=>"propal", 'c.fin_validite'=>"propal", 'c.total_ht'=>"propal", 'c.total_ttc'=>"propal", 'c.fk_statut'=>"propal", 'c.note_public'=>"propal", 'c.date_livraison'=>"propal", 'pj.ref'=>'project', 'cd.rowid'=>'propal_line', - 'cd.label'=>"propal_line", 'cd.description'=>"propal_line", 'cd.product_type'=>'propal_line', 'cd.tva_tx'=>"propal_line", 'cd.qty'=>"propal_line", + 'cd.description'=>"propal_line", 'cd.product_type'=>'propal_line', 'cd.tva_tx'=>"propal_line", 'cd.qty'=>"propal_line", 'cd.total_ht'=>"propal_line", 'cd.total_tva'=>"propal_line", 'cd.total_ttc'=>"propal_line", 'p.rowid'=>'product', 'p.ref'=>'product', 'p.label'=>'product' ); $this->export_dependencies_array[$r] = array('propal_line'=>'cd.rowid', 'product'=>'cd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them @@ -293,7 +293,6 @@ class modPropale extends DolibarrModules 'c.datec' => 'DateCreation', 'c.datep' => 'DatePropal', 'c.fin_validite' => 'DateEndPropal', - 'c.remise_percent' => 'GlobalDiscount', 'c.total_ht' => 'TotalHT', 'c.total_ttc' => 'TotalTTC', 'c.fk_statut' => 'Status*', @@ -330,7 +329,6 @@ class modPropale extends DolibarrModules 'c.datec' => '2020-01-01', 'c.datep' => '2020-01-01', 'c.fin_validite' => '2020-01-01', - 'c.remise_percent' => '', 'c.total_ht' => '0', 'c.total_ttc' => '0', 'c.fk_statut' => '1', @@ -344,16 +342,23 @@ class modPropale extends DolibarrModules 'c.multicurrency_total_ttc' => '0' ]; $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample); - $this->import_updatekeys_array[$r] = ['c.ref'=>'Ref']; - $this->import_convertvalue_array[$r] = [ - 'c.fk_soc' => [ + $this->import_updatekeys_array[$r] = array('c.ref'=>'Ref'); + $this->import_convertvalue_array[$r] = array( + 'c.ref' => array( + 'rule'=>'getrefifauto', + 'class'=>(empty($conf->global->PROPALE_ADDON) ? 'mod_propale_marbre' : $conf->global->PROPALE_ADDON), + 'path'=>"/core/modules/propale/".(empty($conf->global->PROPALE_ADDON) ? 'mod_propale_marbre' : $conf->global->PROPALE_ADDON).'.php', + 'classobject'=>'Propal', + 'pathobject'=>'/comm/propal/class/propal.class.php', + ), + 'c.fk_soc' => array( 'rule' => 'fetchidfromref', 'file' => '/societe/class/societe.class.php', 'class' => 'Societe', 'method' => 'fetch', 'element' => 'ThirdParty' - ] - ]; + ) + ); //Import Proposal Lines $r++; @@ -367,15 +372,13 @@ class modPropale extends DolibarrModules ); $this->import_fields_array[$r] = array( 'cd.fk_propal' => 'Proposal*', - 'cd.fk_parent_line' => 'PrParentLine', + 'cd.fk_parent_line' => 'ParentLine', 'cd.fk_product' => 'IdProduct', - 'cd.label' => 'Label', 'cd.description' => 'LineDescription', 'cd.product_type' => 'TypeOfLineServiceOrProduct', 'cd.tva_tx' => 'LineVATRate', 'cd.qty' => 'LineQty', 'cd.remise_percent' => 'Reduc. Percent', - 'cd.remise' => 'Reduc.', 'cd.price' => 'Price', 'cd.subprice' => 'Sub Price', 'cd.total_ht' => 'LineTotalHT', @@ -411,13 +414,11 @@ class modPropale extends DolibarrModules 'cd.fk_propal' => 'PROV(0001)', 'cd.fk_parent_line' => '', 'cd.fk_product' => '', - 'cd.label' => '', 'cd.description' => 'Line description', 'cd.product_type' => '1', 'cd.tva_tx' => '0', 'cd.qty' => '2', 'cd.remise_percent' => '0', - 'cd.remise' => '0', 'cd.price' => '', 'cd.subprice' => '5000', 'cd.total_ht' => '10000', diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php index 51117868e35..da1fdcbf016 100644 --- a/htdocs/core/modules/modResource.class.php +++ b/htdocs/core/modules/modResource.class.php @@ -252,7 +252,7 @@ class modResource extends DolibarrModules $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'resource as r'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_resource as c ON c.rowid=r.fk_code_type_resource'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'resource_extrafields as extra ON extra.fk_object = r.rowid'; - $this->export_sql_end[$r] .= ' AND r.entity IN ('.getEntity('resource').')'; + $this->export_sql_end[$r] .= ' WHERE r.entity IN ('.getEntity('resource').')'; // Imports diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 0390a23cc83..bdc3388da5c 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -786,7 +786,7 @@ class modService extends DolibarrModules } if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { $this->import_examplevalues_array[$r] = array_merge($this->import_examplevalues_array[$r], array( - 'sp.packagning'=>'1', + 'sp.packagning'=>'10', )); } diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index a733484d043..09089d57563 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -5,6 +5,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2012-2014 Juanjo Menent + * Copyright (C) 2022 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -379,7 +380,7 @@ class modSociete extends DolibarrModules // Add multicompany field if (! empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED)) { if (!empty($conf->multicompany->enabled)) { - $nbofallowedentities = count(explode(',', getEntity('socpeople'))); + $nbofallowedentities = count(explode(',', getEntity('contact'))); if ($nbofallowedentities > 1) { $this->export_fields_array[$r]['c.entity'] = 'Entity'; } @@ -436,7 +437,7 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON c.fk_pays = co.rowid'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = c.rowid'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id'; - $this->export_sql_end[$r] .= ' WHERE c.entity IN ('.getEntity('socpeople').')'; + $this->export_sql_end[$r] .= ' WHERE c.entity IN ('.getEntity('contact').')'; if (is_object($user) && empty($user->rights->societe->client->voir)) { $this->export_sql_end[$r] .= ' AND (sc.fk_user = '.((int) $user->id).' '; if (!empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) { @@ -480,7 +481,6 @@ class modSociete extends DolibarrModules 's.fax' => "Fax", 's.url' => "Url", 's.email' => "Email", - 's.skype' => "Skype", 's.fk_effectif' => "Staff", 's.fk_typent' => "ThirdPartyType", "s.fk_forme_juridique" => "JuridicalStatus", @@ -621,7 +621,6 @@ class modSociete extends DolibarrModules 's.fax' => "eg. +34987654321", 's.url' => "e.g. https://www.mybigcompany.com", 's.email' => "e.g. test@mybigcompany.com", - 's.skype' => "Skype name", 's.fk_effectif' => "1/2/3/5: represents one of the five ranges of employees", 's.fk_typent' => 'matches field "id" (1-9 etc.) OR "code" (TE_SMALL etc.) in table "'.MAIN_DB_PREFIX.'c_typent"', 's.fk_forme_juridique' => '1/2/3 etc...matches field "code" in table "'.MAIN_DB_PREFIX.'c_forme_juridique"', @@ -693,7 +692,6 @@ class modSociete extends DolibarrModules 's.phone_mobile' => "PhoneMobile", 's.fax' => "Fax", 's.email' => "Email", - 's.skype' => "Skype", 's.note_private' => "NotePrivate", 's.note_public' => "NotePublic" ); @@ -759,7 +757,6 @@ class modSociete extends DolibarrModules 's.phone_mobile' => "5551144", 's.fax' => "5551155", 's.email' => "johnsmith@email.com", - 's.skype' => "skype username", 's.note_private' => "My private note", 's.note_public' => "My public note" ); diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 0ae6b00b1c3..ff7eb1ee18f 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -109,7 +109,9 @@ class modTicket extends DolibarrModules 3 => array('TICKET_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/tickets', 'Ticket templates ODT/ODS directory for templates', 0), 4 => array('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND', 'chaine', 0, 'Automatically mark ticket as read when created from backend', 0), 5 => array('TICKET_DELAY_BEFORE_FIRST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time before a first answer to a ticket (in hours). Display a warning in tickets list if not respected.', 0), - 6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0) + 6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0), + 7 => array('TICKET_NOTIFY_AT_CLOSING', 'chaine', '0', 'Default notify contacts when closing a module', 0), + 8 => array('TICKET_PRODUCT_CATEGORY', 'chaine', 0, 'The category of product that is being used for ticket accounting', 0) ); diff --git a/htdocs/core/modules/modVariants.class.php b/htdocs/core/modules/modVariants.class.php index a6c88afc03d..e1364fd845e 100644 --- a/htdocs/core/modules/modVariants.class.php +++ b/htdocs/core/modules/modVariants.class.php @@ -73,10 +73,10 @@ class modVariants extends DolibarrModules $this->module_parts = array(); // Data directories to create when module is enabled. - // Example: this->dirs = array("/mymodule/temp"); + // Example: this->dirs = array("/variants/temp"); $this->dirs = array(); - // Config pages. Put here list of php page, stored into mymodule/admin directory, to use to setup module. + // Config pages. Put here list of php page, stored into variants/admin directory, to use to setup module. $this->config_page_url = array('admin.php@variants'); // Dependencies @@ -97,9 +97,9 @@ class modVariants extends DolibarrModules ); // Dictionaries - if (!isset($conf->mymodule->enabled)) { - $conf->mymodule = new stdClass(); - $conf->mymodule->enabled = 0; + if (!isset($conf->variants->enabled)) { + $conf->variants = new stdClass(); + $conf->variants->enabled = 0; } $this->dictionaries = array(); @@ -109,5 +109,19 @@ class modVariants extends DolibarrModules // Permissions $this->rights = array(); // Permission array used by this module + $r = 0; + + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = 'Read attributes of variants'; // Permission label + $this->rights[$r][4] = 'read'; // In php code, permission will be checked by test if ($user->rights->eventorganization->level1) + $r++; + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = 'Create/Update attributes of variants'; // Permission label + $this->rights[$r][4] = 'write'; // In php code, permission will be checked by test if ($user->rights->eventorganization->level1) + $r++; + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = 'Delete attributes of variants'; // Permission label + $this->rights[$r][4] = 'delete'; // In php code, permission will be checked by test if ($user->rights->eventorganization->level1) + $r++; } } diff --git a/htdocs/core/modules/modWorkflow.class.php b/htdocs/core/modules/modWorkflow.class.php index 4122f347664..248d3c006ce 100644 --- a/htdocs/core/modules/modWorkflow.class.php +++ b/htdocs/core/modules/modWorkflow.class.php @@ -93,7 +93,10 @@ class modWorkflow extends DolibarrModules 6=>array('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION', 0, 'current', 0), 7=>array('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED', 0, 'current', 0), 8=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 0, 'current', 0), - 9=>array('WORKFLOW_BILL_ON_RECEPTION', 'chaine', '1', 'WORKFLOW_BILL_ON_RECEPTION', 0, 'current', 0) + 9=>array('WORKFLOW_BILL_ON_RECEPTION', 'chaine', '1', 'WORKFLOW_BILL_ON_RECEPTION', 0, 'current', 0), + 10=>array('WORKFLOW_TICKET_LINK_CONTRACT', 'chaine', '0', 'Automatically link a ticket to available contracts', 0, 'current', 0), + 11=>array('WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS', 'chaine', '0', 'Search among parent companies contracts when automatically linking a ticket to available contracts', 0, 'current', 0), + 11=>array('WORKFLOW_TICKET_CREATE_INTERVENTION', 'chaine', '1', 'WORKFLOW_TICKET_CREATE_INTERVENTION', 0, 'current', 0) ); // Boxes diff --git a/htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php b/htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php index 079b46003c4..bf1da990923 100644 --- a/htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php +++ b/htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php @@ -135,7 +135,7 @@ class pdf_standardlabel extends CommonStickerGenerator $widthtouse = $maxwidthtouse; $heighttouse = 0; // old value for image $tmp = dol_getImageSize($photo, false); - if ($tmp['height']) { + if (!empty($tmp['height'])) { $imgratio = $tmp['width'] / $tmp['height']; if ($imgratio >= $defaultratio) { $widthtouse = $maxwidthtouse; diff --git a/htdocs/core/modules/product/modules_product.class.php b/htdocs/core/modules/product/modules_product.class.php index fef12717e3b..4b00cbe132e 100644 --- a/htdocs/core/modules/product/modules_product.class.php +++ b/htdocs/core/modules/product/modules_product.class.php @@ -43,20 +43,18 @@ abstract class ModelePDFProduct extends CommonDocGenerator /** * Return list of active generation modules * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param integer $maxfilenamelength Max length of value to show * @return array List of templates */ - public static function liste_modeles($db, $maxfilenamelength = 0) + public static function liste_modeles($dbs, $maxfilenamelength = 0) { // phpcs:enable - global $conf; - $type = 'product'; $list = array(); include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $list = getListOfModels($db, $type, $maxfilenamelength); + $list = getListOfModels($dbs, $type, $maxfilenamelength); return $list; } } @@ -156,22 +154,22 @@ abstract class ModeleProductCode /** * Renvoi la liste des modeles de numérotation * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param integer $maxfilenamelength Max length of value to show * @return array List of numbers */ - public static function liste_modeles($db, $maxfilenamelength = 0) + public static function liste_modeles($dbs, $maxfilenamelength = 0) { // phpcs:enable $list = array(); $sql = ""; - $resql = $db->query($sql); + $resql = $dbs->query($sql); if ($resql) { - $num = $db->num_rows($resql); + $num = $dbs->num_rows($resql); $i = 0; while ($i < $num) { - $row = $db->fetch_row($resql); + $row = $dbs->fetch_row($resql); $list[$row[0]] = $row[1]; $i++; } diff --git a/htdocs/core/modules/product_batch/mod_lot_advanced.php b/htdocs/core/modules/product_batch/mod_lot_advanced.php index d44a261a16b..d56178697f5 100644 --- a/htdocs/core/modules/product_batch/mod_lot_advanced.php +++ b/htdocs/core/modules/product_batch/mod_lot_advanced.php @@ -128,7 +128,7 @@ class mod_lot_advanced extends ModeleNumRefBatch /** * Return next free value * - * @param Societe $objsoc Object Societe + * @param Societe $objsoc Object thirdparty * @param Object $object Object we need next value for * @return string Value if KO, <0 if KO */ diff --git a/htdocs/core/modules/product_batch/mod_lot_free.php b/htdocs/core/modules/product_batch/mod_lot_free.php index def14bd37b3..d6b24945ab0 100644 --- a/htdocs/core/modules/product_batch/mod_lot_free.php +++ b/htdocs/core/modules/product_batch/mod_lot_free.php @@ -93,11 +93,11 @@ class mod_lot_free extends ModeleNumRefBatch /** * Return an example of result returned by getNextValue * - * @param product $objproduct Object product - * @param int $type Type of third party (1:customer, 2:supplier, -1:autodetect) + * @param Societe $objsoc Object thirdparty + * @param Object $object Object we need next value for * @return string Return next value */ - public function getNextValue($objproduct = 0, $type = -1) + public function getNextValue($objsoc, $object) { global $langs; return ''; diff --git a/htdocs/core/modules/product_batch/mod_lot_standard.php b/htdocs/core/modules/product_batch/mod_lot_standard.php index 59de1965a6e..fc8d1389a00 100644 --- a/htdocs/core/modules/product_batch/mod_lot_standard.php +++ b/htdocs/core/modules/product_batch/mod_lot_standard.php @@ -111,11 +111,11 @@ class mod_lot_standard extends ModeleNumRefBatch /** * Return next free value * - * @param Product $objprod Object product + * @param Societe $objsoc Object thirdparty * @param Object $object Object we need next value for * @return string Value if KO, <0 if KO */ - public function getNextValue($objprod, $object) + public function getNextValue($objsoc, $object) { global $db, $conf; diff --git a/htdocs/core/modules/product_batch/mod_sn_advanced.php b/htdocs/core/modules/product_batch/mod_sn_advanced.php index abe094220d2..6ee931d51a9 100644 --- a/htdocs/core/modules/product_batch/mod_sn_advanced.php +++ b/htdocs/core/modules/product_batch/mod_sn_advanced.php @@ -128,11 +128,11 @@ class mod_sn_advanced extends ModeleNumRefBatch /** * Return next free value * - * @param Product $objprod Object product + * @param Societe $objsoc Object thirdparty * @param Object $object Object we need next value for * @return string Value if KO, <0 if KO */ - public function getNextValue($objprod, $object) + public function getNextValue($objsoc, $object) { global $db, $conf; diff --git a/htdocs/core/modules/product_batch/mod_sn_free.php b/htdocs/core/modules/product_batch/mod_sn_free.php index 67d39ec085a..f6b2417d34b 100644 --- a/htdocs/core/modules/product_batch/mod_sn_free.php +++ b/htdocs/core/modules/product_batch/mod_sn_free.php @@ -92,11 +92,11 @@ class mod_sn_free extends ModeleNumRefBatch /** * Return an example of result returned by getNextValue * - * @param product $objproduct Object product - * @param int $type Type of third party (1:customer, 2:supplier, -1:autodetect) + * @param Societe $objsoc Object thirdparty + * @param Object $object Object we need next value for * @return string Return next value */ - public function getNextValue($objproduct = 0, $type = -1) + public function getNextValue($objsoc, $object) { global $langs; return ''; diff --git a/htdocs/core/modules/product_batch/mod_sn_standard.php b/htdocs/core/modules/product_batch/mod_sn_standard.php index 845044c39f3..d6c109cff81 100644 --- a/htdocs/core/modules/product_batch/mod_sn_standard.php +++ b/htdocs/core/modules/product_batch/mod_sn_standard.php @@ -111,7 +111,7 @@ class mod_sn_standard extends ModeleNumRefBatch /** * Return next free value * - * @param Societe $objsoc Object product + * @param Societe $objsoc Object thirdparty * @param Object $object Object we need next value for * @return string Value if KO, <0 if KO */ diff --git a/htdocs/core/modules/project/doc/pdf_baleine.modules.php b/htdocs/core/modules/project/doc/pdf_baleine.modules.php index 716c88e1f92..776f2f9d1e6 100644 --- a/htdocs/core/modules/project/doc/pdf_baleine.modules.php +++ b/htdocs/core/modules/project/doc/pdf_baleine.modules.php @@ -432,10 +432,12 @@ class pdf_baleine extends ModelePDFProjects $pdf->MultiCell($this->posxlabel - $this->posxref, 3, $outputlangs->convToOutputCharset($ref), 0, 'L'); // Workload $pdf->SetXY($this->posxworkload, $curY); + $pdf->SetFont('', '', $default_font_size - 2); // We use a smaller font $pdf->MultiCell($this->posxprogress - $this->posxworkload, 3, $planned_workload ? $planned_workload : '', 0, 'R'); // Progress $pdf->SetXY($this->posxprogress, $curY); $pdf->MultiCell($this->posxdatestart - $this->posxprogress, 3, $progress, 0, 'R'); + $pdf->SetFont('', '', $default_font_size - 1); // We restore font // Date start and end $pdf->SetXY($this->posxdatestart, $curY); @@ -640,9 +642,11 @@ class pdf_baleine extends ModelePDFProjects $pdf->SetTextColor(0, 0, 60); $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateStart")." : ".dol_print_date($object->date_start, 'day', false, $outputlangs, true), '', 'R'); - $posy += 6; - $pdf->SetXY($posx, $posy); - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateEnd")." : ".dol_print_date($object->date_end, 'day', false, $outputlangs, true), '', 'R'); + if ($object->date_end) { + $posy += 6; + $pdf->SetXY($posx, $posy); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateEnd")." : ".dol_print_date($object->date_end, 'day', false, $outputlangs, true), '', 'R'); + } if (is_object($object->thirdparty)) { $posy += 6; diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index 1e48a826257..66882166722 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -622,7 +622,7 @@ class pdf_cyan extends ModelePDFPropales if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { - $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } diff --git a/htdocs/core/modules/reception/mod_reception_beryl.php b/htdocs/core/modules/reception/mod_reception_beryl.php index bbfc0daee45..6570f2c864a 100644 --- a/htdocs/core/modules/reception/mod_reception_beryl.php +++ b/htdocs/core/modules/reception/mod_reception_beryl.php @@ -96,10 +96,10 @@ class mod_reception_beryl extends ModelNumRefReception * Return next value * * @param Societe $objsoc Third party object - * @param Object $shipment Shipment object + * @param Object $reception Reception object * @return string Value if OK, 0 if KO */ - public function getNextValue($objsoc, $shipment) + public function getNextValue($objsoc, $reception) { global $db, $conf; diff --git a/htdocs/core/modules/reception/modules_reception.php b/htdocs/core/modules/reception/modules_reception.php index 145a04fbd31..f519974382b 100644 --- a/htdocs/core/modules/reception/modules_reception.php +++ b/htdocs/core/modules/reception/modules_reception.php @@ -110,10 +110,10 @@ abstract class ModelNumRefReception * Returns next value assigned * * @param Societe $objsoc Third party object - * @param Object $shipment Shipment object + * @param Object $reception Reception object * @return string Value */ - public function getNextValue($objsoc, $shipment) + public function getNextValue($objsoc, $reception) { global $langs; return $langs->trans("NotAvailable"); diff --git a/htdocs/core/modules/societe/modules_societe.class.php b/htdocs/core/modules/societe/modules_societe.class.php index 09f6cb9c29d..e8b0fbe9193 100644 --- a/htdocs/core/modules/societe/modules_societe.class.php +++ b/htdocs/core/modules/societe/modules_societe.class.php @@ -41,20 +41,19 @@ abstract class ModeleThirdPartyDoc extends CommonDocGenerator /** * Return list of active generation modules * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param integer $maxfilenamelength Max length of value to show * @return array List of templates */ - public static function liste_modeles($db, $maxfilenamelength = 0) + public static function liste_modeles($dbs, $maxfilenamelength = 0) { // phpcs:enable - global $conf; $type = 'company'; $list = array(); include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $list = getListOfModels($db, $type, $maxfilenamelength); + $list = getListOfModels($dbs, $type, $maxfilenamelength); return $list; } @@ -161,22 +160,22 @@ abstract class ModeleThirdPartyCode /** * Renvoie la liste des modeles de numérotation * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param integer $maxfilenamelength Max length of value to show * @return array|int List of numbers */ - public static function liste_modeles($db, $maxfilenamelength = 0) + public static function liste_modeles($dbs, $maxfilenamelength = 0) { // phpcs:enable $list = array(); $sql = ""; - $resql = $db->query($sql); + $resql = $dbs->query($sql); if ($resql) { - $num = $db->num_rows($resql); + $num = $dbs->num_rows($resql); $i = 0; while ($i < $num) { - $row = $db->fetch_row($resql); + $row = $dbs->fetch_row($resql); $list[$row[0]] = $row[1]; $i++; } @@ -401,26 +400,3 @@ abstract class ModeleAccountancyCode return $langs->trans("NotAvailable"); } } - - -/** - * Create a document onto disk according to template module. - * - * @param DoliDB $db Database handler - * @param Facture $object Object invoice - * @param string $message Message (not used, deprecated) - * @param string $modele Force template to use ('' to not force) - * @param Translate $outputlangs objet lang a utiliser pour traduction - * @param int $hidedetails Hide details of lines - * @param int $hidedesc Hide description - * @param int $hideref Hide ref - * @return int <0 if KO, >0 if OK - * @deprecated Use the new function generateDocument of Objects class - * @see Societe::generateDocument() - */ -function thirdparty_doc_create(DoliDB $db, Societe $object, $message, $modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) -{ - dol_syslog(__METHOD__." is deprecated", LOG_WARNING); - - return $object->generateDocument($modele, $outputlangs, $hidedetails, $hidedesc, $hideref); -} diff --git a/htdocs/core/modules/supplier_invoice/modules_facturefournisseur.php b/htdocs/core/modules/supplier_invoice/modules_facturefournisseur.php index acb3ad8fa2a..546596ab640 100644 --- a/htdocs/core/modules/supplier_invoice/modules_facturefournisseur.php +++ b/htdocs/core/modules/supplier_invoice/modules_facturefournisseur.php @@ -120,7 +120,7 @@ abstract class ModeleNumRefSuppliersInvoices * @param string $mode 'next' for next value or 'last' for last value * @return string Value if OK, 0 if KO */ - public function getNextValue($objsoc, $object, $mode) + public function getNextValue($objsoc, $object, $mode = 'next') { global $langs; return $langs->trans("NotAvailable"); diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php index 5fcd0ee20de..2be12805685 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php @@ -546,31 +546,30 @@ class pdf_cornas extends ModelePDFSuppliersOrders $posYAfterDescription = 0; // We start with Photo of product line - if (!empty($imglinesize['width']) && !empty($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page - $pdf->AddPage('', '', true); - if (!empty($tplidx)) { - $pdf->useTemplate($tplidx); - } - if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { - $this->_pagehead($pdf, $object, 0, $outputlangs); - } - $pdf->setPage($pageposbefore + 1); + if ($this->getColumnStatus('photo')) { + // We start with Photo of product line + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // If photo too high, we moved completely on new page + $pdf->AddPage('', '', true); + if (!empty($tplidx)) { + $pdf->useTemplate($tplidx); + } + $pdf->setPage($pageposbefore + 1); - $curY = $tab_top_newpage; + $curY = $tab_top_newpage; - // Allows data in the first page if description is long enough to break in multiples pages - if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) { - $showpricebeforepagebreak = 1; - } else { - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) { + $showpricebeforepagebreak = 1; + } else { + $showpricebeforepagebreak = 0; + } } - } - if (!empty($imglinesize['width']) && !empty($imglinesize['height'])) { - $curX = $this->posxpicture - 1; - $pdf->Image($realpatharray[$i], $curX + (($this->posxtva - $this->posxpicture - $imglinesize['width']) / 2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi - // $pdf->Image does not increase value return by getY, so we save it manually - $posYAfterImage = $curY + $imglinesize['height']; + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) { + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + // $pdf->Image does not increase value return by getY, so we save it manually + $posYAfterImage = $curY + $imglinesize['height']; + } } // Description of product line $curX = $this->posxdesc - 1; diff --git a/htdocs/core/modules/supplier_order/modules_commandefournisseur.php b/htdocs/core/modules/supplier_order/modules_commandefournisseur.php index 6fe3cb8883d..51c4e5f07d3 100644 --- a/htdocs/core/modules/supplier_order/modules_commandefournisseur.php +++ b/htdocs/core/modules/supplier_order/modules_commandefournisseur.php @@ -120,9 +120,11 @@ abstract class ModeleNumRefSuppliersOrders /** Returns next value assigned * - * @return string Valeur + * @param Societe $objsoc Object third party + * @param Object $object Object + * @return string Valeur */ - public function getNextValue() + public function getNextValue($objsoc = 0, $object = '') { global $langs; return $langs->trans("NotAvailable"); diff --git a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php index 608d765b1c5..003cd999cde 100644 --- a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php @@ -2,6 +2,7 @@ /* Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2010-2014 Laurent Destailleur * Copyright (C) 2015 Marcos García + * Copyright (C) 2022 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -132,7 +133,7 @@ class pdf_standard extends ModelePDFSuppliersPayments $this->db = $db; $this->name = "standard"; $this->description = $langs->trans('DocumentModelStandardPDF'); - $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + $this->update_main_doc_field = 0; // Save the name of generated file as the main doc when generating a doc with this template // Page size for A4 format $this->type = 'pdf'; diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php index b225899cef2..2e618b3ece3 100644 --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php @@ -120,9 +120,9 @@ class mod_supplier_proposal_marbre extends ModeleNumRefSupplierProposal /** * Return next value * - * @param Societe $objsoc Object third party - * @param Propal $supplier_proposal Object commercial proposal - * @return string Next value + * @param Societe $objsoc Object third party + * @param SupplierProposal $supplier_proposal Object commercial proposal + * @return string Next value */ public function getNextValue($objsoc, $supplier_proposal) { diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php index e7db54062cb..57cba16c01b 100644 --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php @@ -120,9 +120,9 @@ class mod_supplier_proposal_saphir extends ModeleNumRefSupplierProposal /** * Return next value * - * @param Societe $objsoc Object third party - * @param Propal $supplier_proposal Object supplier_proposal - * @return string Value if OK, 0 if KO + * @param Societe $objsoc Object third party + * @param SupplierProposal $supplier_proposal Object commercial proposal + * @return string Value if OK, 0 if KO */ public function getNextValue($objsoc, $supplier_proposal) { diff --git a/htdocs/core/modules/supplier_proposal/modules_supplier_proposal.php b/htdocs/core/modules/supplier_proposal/modules_supplier_proposal.php index 0b6f0b3725d..5a3d9e2280a 100644 --- a/htdocs/core/modules/supplier_proposal/modules_supplier_proposal.php +++ b/htdocs/core/modules/supplier_proposal/modules_supplier_proposal.php @@ -124,11 +124,11 @@ abstract class ModeleNumRefSupplierProposal /** * Renvoi prochaine valeur attribuee * - * @param Societe $objsoc Object third party - * @param Propal $propal Object commercial proposal - * @return string Valeur + * @param Societe $objsoc Object third party + * @param SupplierProposal $supplier_proposal Object commercial proposal + * @return string Valeur */ - public function getNextValue($objsoc, $propal) + public function getNextValue($objsoc, $supplier_proposal) { global $langs; return $langs->trans("NotAvailable"); diff --git a/htdocs/core/modules/takepos/mod_takepos_ref_universal.php b/htdocs/core/modules/takepos/mod_takepos_ref_universal.php index b3d26b39511..7e46c10a341 100644 --- a/htdocs/core/modules/takepos/mod_takepos_ref_universal.php +++ b/htdocs/core/modules/takepos/mod_takepos_ref_universal.php @@ -119,7 +119,7 @@ class mod_takepos_ref_universal extends ModeleNumRefTakepos * @param string $mode 'next' for next value or 'last' for last value * @return string Value if KO, <0 if KO */ - public function getNextValue($objsoc = 0, $invoice = null, $mode = 'next') + public function getNextValue($objsoc = null, $invoice = null, $mode = 'next') { global $db, $conf; diff --git a/htdocs/core/modules/takepos/modules_takepos.php b/htdocs/core/modules/takepos/modules_takepos.php index b9fae565647..24fa70b7f28 100644 --- a/htdocs/core/modules/takepos/modules_takepos.php +++ b/htdocs/core/modules/takepos/modules_takepos.php @@ -89,9 +89,12 @@ abstract class ModeleNumRefTakepos /** * Renvoi prochaine valeur attribuee * - * @return string Valeur + * @param Societe $objsoc Object thirdparty + * @param Facture $invoice Object invoice + * @param string $mode 'next' for next value or 'last' for last value + * @return string Value if KO, <0 if KO */ - public function getNextValue() + public function getNextValue($objsoc = null, $invoice = null, $mode = 'next') { global $langs; return $langs->trans('NotAvailable'); diff --git a/htdocs/core/modules/ticket/modules_ticket.php b/htdocs/core/modules/ticket/modules_ticket.php index 1d2bc944022..c8561382436 100644 --- a/htdocs/core/modules/ticket/modules_ticket.php +++ b/htdocs/core/modules/ticket/modules_ticket.php @@ -115,11 +115,11 @@ abstract class ModeleNumRefTicket /** * Renvoi prochaine valeur attribuee * - * @param Societe $objsoc Object third party - * @param Project $project Object project - * @return string Valeur + * @param Societe $objsoc Object third party + * @param Ticket $ticket Object ticket + * @return string Valeur */ - public function getNextValue($objsoc, $project) + public function getNextValue($objsoc, $ticket) { global $langs; return $langs->trans("NotAvailable"); diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php index d1145229db7..369f60ea201 100644 --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php @@ -73,7 +73,7 @@ print "
    '; - if ($totalarray['type'][$i] == 'duration') { + if (isset($totalarray['type']) && $totalarray['type'][$i] == 'duration') { print (!empty($totalarray['val'][$totalarray['pos'][$i]])?convertSecondToTime($totalarray['val'][$totalarray['pos'][$i]], 'allhourmin'):0); } else { print price(!empty($totalarray['val'][$totalarray['pos'][$i]])?$totalarray['val'][$totalarray['pos'][$i]]:0); diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index b3a40ba3582..de034f652d3 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -212,14 +212,14 @@ if ($massaction == 'presend') { } if ($massaction == 'preenable') { - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassEnabling"), $langs->trans("ConfirmMassEnablingQuestion", count($toselect)), "enable", null, '', 0, 200, 500, 1); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassEnabling"), $langs->trans("ConfirmMassEnablingQuestion", count($toselect)), "enable", null, 'yes', 0, 200, 500, 1); } if ($massaction == 'predisable') { print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDisabling"), $langs->trans("ConfirmMassDisablingQuestion", count($toselect)), "disable", null, '', 0, 200, 500, 1); } if ($massaction == 'preapproveleave') { - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassLeaveApproval"), $langs->trans("ConfirmMassLeaveApprovalQuestion", count($toselect)), "approveleave", null, '', 0, 200, 500, 1); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassLeaveApproval"), $langs->trans("ConfirmMassLeaveApprovalQuestion", count($toselect)), "approveleave", null, 'yes', 0, 200, 500, 1); } // Allow Pre-Mass-Action hook (eg for confirmation dialog) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 335754a8168..f009b80301e 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -6,9 +6,11 @@ * Copyright (C) 2014 Florian Henry * Copyright (C) 2014 Raphaël Doursenaud * Copyright (C) 2015-2016 Marcos García - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018 Frédéric France * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2019 Nicolas ZABOURI + * Copyright (C) 2022 OpenDSI + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -68,6 +70,9 @@ if (!empty($conf->multicurrency->enabled) && $this->multicurrency_code != $conf- if (in_array($object->element, array('propal', 'commande', 'order', 'facture', 'facturerec', 'invoice', 'supplier_proposal', 'order_supplier', 'invoice_supplier', 'invoice_supplier_rec'))) { $colspan++; // With this, there is a column move button } +if (!empty($conf->asset->enabled) && $object->element == 'invoice_supplier') { + $colspan++; +} //print $object->element; // Lines for extrafield @@ -311,6 +316,11 @@ if ($nolinesbefore) { echo ''; echo ''; } + + if (!empty($conf->global->MAIN_ADD_LINE_AT_POSITION)) { + echo '
    '.$langs->trans('AddLineOnPosition').' : '; + } + if (is_object($hookmanager) && empty($senderissupplier)) { $parameters = array('fk_parent_line'=>GETPOST('fk_parent_line', 'int')); $reshook = $hookmanager->executeHooks('formCreateProductOptions', $parameters, $object, $action); @@ -356,7 +366,7 @@ if ($nolinesbefore) { } if (is_object($objectline)) { $temps = $objectline->showOptionals($extrafields, 'create', array(), '', '', 1, 'line'); - ; + if (!empty($temps)) { print '
    '; print $temps; @@ -367,7 +377,7 @@ if ($nolinesbefore) { if ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier' || $object->element == 'invoice_supplier_rec') { // We must have same test in printObjectLines $coldisplay++; ?> -
    ">"> +
    @@ -190,7 +196,7 @@ $coldisplay++; if ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier' || $object->element == 'invoice_supplier_rec') { // We must have same test in printObjectLines $coldisplay++; ?> -
    + info_bits & 2) != 2) { print ' * Copyright (C) 2013 Florian Henry * Copyright (C) 2017 Juanjo Menent + * Copyright (C) 2022 OpenDSI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -70,7 +71,9 @@ if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) || !empty($conf->global->FA if (in_array($object->element, array('propal', 'commande', 'facture')) && $object->status == $object::STATUS_DRAFT) { global $mysoc; - print 'id.'">'.img_edit($langs->trans("UpdateForAllLines"), 0, 'class="clickvatforalllines opacitymedium paddingleft cursorpointer"').''; + if (empty($disableedit)) { + print 'id.'">'.img_edit($langs->trans("UpdateForAllLines"), 0, 'class="clickvatforalllines opacitymedium paddingleft cursorpointer"').''; + } //print ''; if (GETPOST('mode', 'aZ09') == 'vatforalllines') { print '
    '; @@ -140,6 +143,10 @@ if ($outputalsopricetotalwithtax) { print '
    '.$langs->trans('TotalTTCShort').''; + $coldisplay++; + if (!empty($product_static->accountancy_code_buy) || + !empty($product_static->accountancy_code_buy_intra) || + !empty($product_static->accountancy_code_buy_export) + ) { + $accountancy_category_asset = $conf->global->ASSET_ACCOUNTANCY_CATEGORY; + $filters = array(); + if (!empty($product_static->accountancy_code_buy)) $filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy) . "'"; + if (!empty($product_static->accountancy_code_buy_intra)) $filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy_intra) . "'"; + if (!empty($product_static->accountancy_code_buy_export)) $filters[] = "account_number = '" . $this->db->escape($product_static->accountancy_code_buy_export) . "'"; + $sql = "SELECT COUNT(*) AS found"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account"; + $sql .= " WHERE pcg_type = '" . $this->db->escape($conf->global->ASSET_ACCOUNTANCY_CATEGORY) . "'"; + $sql .= " AND (" . implode(' OR ', $filters). ")"; + $resql_asset = $this->db->query($sql); + if (!$resql_asset) { + print 'Error SQL: ' . $this->db->lasterror(); + } elseif ($obj = $this->db->fetch_object($resql_asset)) { + if (!empty($obj->found)) { + print ''; + print img_edit_add() . ''; + } + } + } + print ''; $coldisplay++; if (($line->info_bits & 2) == 2 || !empty($disableedit)) { diff --git a/htdocs/core/tpl/originproductline.tpl.php b/htdocs/core/tpl/originproductline.tpl.php index 7e56611a282..55d385fcd50 100644 --- a/htdocs/core/tpl/originproductline.tpl.php +++ b/htdocs/core/tpl/originproductline.tpl.php @@ -1,6 +1,7 @@ * Copyright (C) 2017 Charlie Benke + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,7 +27,7 @@ if (empty($conf) || !is_object($conf)) { tpl['strike']) ? '' : ' strikefordisabled').'">'; +print '
    '.$this->tpl['label'].''.$this->tpl['description'].''.$this->tpl['vat_rate'].''.$this->tpl['remise_percent'].''.$this->tpl['total_ht'].''; $shipment->fetch_delivery_methods(); @@ -751,8 +751,8 @@ if (!empty($arrayfields['e.weight']['checked'])) { if (!empty($arrayfields['e.date_delivery']['checked'])) { print_liste_field_titre($arrayfields['e.date_delivery']['label'], $_SERVER["PHP_SELF"], "e.date_delivery", "", $param, '', $sortfield, $sortorder, 'center '); } -if (!empty($arrayfields['e.shipping_method_id']['checked'])) { - print_liste_field_titre($arrayfields['e.shipping_method_id']['label'], $_SERVER["PHP_SELF"], "e.fk_shipping_method", "", $param, '', $sortfield, $sortorder, 'center '); +if (!empty($arrayfields['e.fk_shipping_method']['checked'])) { + print_liste_field_titre($arrayfields['e.fk_shipping_method']['label'], $_SERVER["PHP_SELF"], "e.fk_shipping_method", "", $param, '', $sortfield, $sortorder, 'center '); } if (!empty($arrayfields['e.tracking_number']['checked'])) { print_liste_field_titre($arrayfields['e.tracking_number']['label'], $_SERVER["PHP_SELF"], "e.tracking_number", "", $param, '', $sortfield, $sortorder, 'center '); @@ -901,7 +901,7 @@ while ($i < min($num, $limit)) { print dol_print_date($db->jdate($obj->delivery_date), "dayhour"); print "'; diff --git a/htdocs/expedition/tpl/linkedobjectblock.tpl.php b/htdocs/expedition/tpl/linkedobjectblock.tpl.php index 26e4ebbb47d..2305b0d4fac 100644 --- a/htdocs/expedition/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expedition/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 307294d5422..c89723af2b9 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1336,6 +1336,15 @@ if (empty($reshook)) { $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); } + + unset($qty); + unset($value_unit_ht); + unset($value_unit); + unset($vatrate); + unset($comments); + unset($fk_c_type_fees); + unset($fk_project); + unset($date); } //header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id); @@ -2042,25 +2051,25 @@ if ($action == 'create') { if (!empty($object->lines)) { $i = 0; $total = 0; - print '
    '.$langs->trans('LineNb').'
    '.$langs->trans('LineNb').''.$langs->trans('Piece').''.$langs->trans('Date').''.$langs->trans('Date').''.$langs->trans('Project').''.$langs->trans('Project').''.$langs->trans('Type').''.$langs->trans('Type').''.$langs->trans('CarCategory').''.$langs->trans('CarCategory').''.$langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUHT').''.$langs->trans('PriceUTTC').''.$langs->trans('Qty').''.$langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUHT').''.$langs->trans('PriceUTTC').''.$langs->trans('Qty').''.$langs->trans('AmountHT').''.$langs->trans('AmountTTC').''.$langs->trans('AmountHT').''.$langs->trans('AmountTTC').''; @@ -2080,19 +2089,19 @@ if ($action == 'create') { $numline = $i + 1; if ($action != 'editline' || $line->rowid != GETPOST('rowid', 'int')) { - print '
    '; + print ''; print $numline; print ''.dol_print_date($db->jdate($line->date), 'day').''.dol_print_date($db->jdate($line->date), 'day').''; + print ''; if ($line->fk_project > 0) { $projecttmp->id = $line->fk_project; $projecttmp->ref = $line->projet_ref; @@ -2118,26 +2127,26 @@ if ($action == 'create') { } // Type of fee - print ''; + print ''; $labeltype = ($langs->trans(($line->type_fees_code)) == $line->type_fees_code ? $line->type_fees_libelle : $langs->trans($line->type_fees_code)); print $labeltype; print ''; + print ''; print dol_getIdFromCode($db, $line->fk_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label'); print ''.dol_nl2br($line->comments).''.dol_nl2br($line->comments).''.vatrate($line->vatrate.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''), true).''.vatrate($line->vatrate.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''), true).''; + print ''; if (!empty($line->value_unit_ht)) { print price($line->value_unit_ht); } else { @@ -2147,17 +2156,17 @@ if ($action == 'create') { } print ''.price($line->value_unit).''.price($line->value_unit).''.dol_escape_htmltag($line->qty).''.dol_escape_htmltag($line->qty).''.price($line->total_ht).''.price($line->total_ttc).''.price($line->total_ht).''.price($line->total_ttc).''; + print ''; if ($line->fk_ecm_files > 0) { $modulepart = 'expensereport'; $maxheightmini = 32; @@ -2227,13 +2236,13 @@ if ($action == 'create') { } print ''; + print ''; print !empty($line->rule_warning_message) ? img_warning(html_entity_decode($line->rule_warning_message)) : ' '; print ''; + print ''; print 'rowid.'">'; print img_edit(); @@ -2265,7 +2274,7 @@ if ($action == 'create') { print $numline; print ''; + print ' '; print ''.$langs->trans("UploadANewFileNow"); print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly'); print ''; @@ -2420,7 +2429,7 @@ if ($action == 'create') { // Add line with link to add new file or attach to an existing file print '
    '; + print ''; print ''.$langs->trans("UploadANewFileNow"); print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly'); print ''; @@ -2473,47 +2482,46 @@ if ($action == 'create') { include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php'; include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php'; - print '
    '.$langs->trans('Date').''.$langs->trans('Date').''.$form->textwithpicto($langs->trans('Project'), $langs->trans("ClosedProjectsAreHidden")).''.$langs->trans('Type').''.$langs->trans('Type').''.$langs->trans('CarCategory').''.$langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUHT').''.$langs->trans('PriceUTTC').''.$langs->trans('Qty').''.$langs->trans('Description').''.$langs->trans('VAT').''.$langs->trans('PriceUHT').''.$langs->trans('PriceUTTC').''.$langs->trans('Qty').'
    '; + print ''; print $form->selectDate($date ? $date : -1, 'date', 0, 0, 0, '', 1, 1); print ''; + print ''; $formproject->select_projects(-1, $fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300'); print ''; + print ''; print $formexpensereport->selectTypeExpenseReport($fk_c_type_fees, 'fk_c_type_fees', 1); print ''; + print ''; print ''; print ''; + print ''; $defaultvat = -1; if (!empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) { $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none'; @@ -2539,17 +2547,17 @@ if ($action == 'create') { print ''; + print ''; print ''; print ''; + print ''; print ''; print ''; + print ''; print ''; // We must be able to enter decimal qty print ''; + print ''; print $form->buttonsSaveCancel("Add", '', '', 1); print '
    '; $objectsrc->printOriginLinesList(empty($conf->global->FICHINTER_PRINT_PRODUCTS) ? 'services' : ''); // Show only service, except if option FICHINTER_PRINT_PRODUCTS is on print '
    '; + print '
    '; } print ''; @@ -1342,6 +1344,23 @@ if ($action == 'create') { print ''; // ancre pour retourner sur la ligne print dol_htmlentitiesbr($objp->description); + $objectline = new FichinterLigne($db); + $objectline->fetch($objp->rowid); + $objectline->fetch_optionals(); + + $extrafields->fetch_name_optionals_label($objectline->table_element); + + if (!empty($extrafields)) { + $temps = $objectline->showOptionals($extrafields, 'view', array(), '', '', 1, 'line'); + if (!empty($temps)) { + print '
    '; + print $temps; + print '
    '; + } + } + + print ''; + // Date print ''.(empty($conf->global->FICHINTER_DATE_WITHOUT_HOUR) ?dol_print_date($db->jdate($objp->date_intervention), 'dayhour') : dol_print_date($db->jdate($objp->date_intervention), 'day')).''; @@ -1378,15 +1397,6 @@ if ($action == 'create') { } print ''; - - $line = new FichinterLigne($db); - $line->fetch($objp->rowid); - - $extrafields->fetch_name_optionals_label($line->table_element); - - $line->fetch_optionals(); - - print $line->showOptionals($extrafields, 'view', array('colspan'=>5)); } // Line in update mode @@ -1405,6 +1415,22 @@ if ($action == 'create') { require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor = new DolEditor('np_desc', $objp->description, '', 164, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_DETAILS, ROWS_2, '90%'); $doleditor->Create(); + + $objectline = new FichinterLigne($db); + $objectline->fetch($objp->rowid); + $objectline->fetch_optionals(); + + $extrafields->fetch_name_optionals_label($objectline->table_element); + + if (!empty($extrafields)) { + $temps = $objectline->showOptionals($extrafields, 'edit', array(), '', '', 1, 'line'); + if (!empty($temps)) { + print '
    '; + print $temps; + print '
    '; + } + } + print ''; // Date d'intervention @@ -1431,14 +1457,6 @@ if ($action == 'create') { print ''; print ''; print ''."\n"; - - $line = new FichinterLigne($db); - $line->fetch($objp->rowid); - - $extrafields->fetch_name_optionals_label($line->table_element); - $line->fetch_optionals(); - - print $line->showOptionals($extrafields, 'edit', array('colspan'=>5)); } $i++; @@ -1481,6 +1499,20 @@ if ($action == 'create') { $doleditor = new DolEditor('np_desc', GETPOST('np_desc', 'restricthtml'), '', 100, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_DETAILS, ROWS_2, '90%'); $doleditor->Create(); } + + $objectline = new FichinterLigne($db); + $extrafields->fetch_name_optionals_label($objectline->table_element); + + if (is_object($objectline)) { + $temps = $objectline->showOptionals($extrafields, 'create', array(), '', '', 1, 'line'); + + if (!empty($temps)) { + print '
    '; + print $temps; + print '
    '; + } + } + print ''; // Date intervention @@ -1513,14 +1545,6 @@ if ($action == 'create') { print ''; print ''; - //Line extrafield - - $lineadd = new FichinterLigne($db); - - $extrafields->fetch_name_optionals_label($lineadd->table_element); - - print $lineadd->showOptionals($extrafields, 'edit', array('colspan'=>5)); - if (!$num) { print ''; } diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index b6505aa1ecf..ee2bf9269ce 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -255,7 +255,7 @@ class Fichinter extends CommonObject } if ($this->socid <= 0) { - $this->error = 'ErrorBadParameterForFunc'; + $this->error = 'ErrorFicheinterCompanyDoesNotExist'; dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); return -1; } @@ -1320,11 +1320,13 @@ class Fichinter extends CommonObject // phpcs:enable $this->lines = array(); - $sql = 'SELECT rowid, fk_fichinter, description, duree, date, rang'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'fichinterdet'; - $sql .= ' WHERE fk_fichinter = '.((int) $this->id).' ORDER BY rang ASC, date ASC'; + $sql = "SELECT rowid, fk_fichinter, description, duree, date, rang"; + $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet"; + $sql .= " WHERE fk_fichinter = ".((int) $this->id); + $sql .= " ORDER BY rang ASC, date ASC"; dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -1584,7 +1586,7 @@ class FichinterLigne extends CommonObjectLine if ($result > 0) { if (!$notrigger) { // Call trigger - $result = $this->call_trigger('LINEFICHINTER_UPDATE', $user); + $result = $this->call_trigger('LINEFICHINTER_MODIFY', $user); if ($result < 0) { $error++; } diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index fa97cf3e8a5..4488b4643b8 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -40,7 +40,7 @@ class FichinterRec extends Fichinter { public $element = 'fichinterrec'; public $table_element = 'fichinter_rec'; - public $table_element_line = 'fichinter_rec'; + public $table_element_line = 'fichinterdet_rec'; /** * @var string Fieldname with ID of parent key if this field has a parent @@ -348,6 +348,8 @@ class FichinterRec extends Fichinter public function fetch_lines($sall = 0) { // phpcs:enable + $this->lines = array(); + $sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.label as custom_label, l.description, '; $sql .= ' l.price, l.qty, l.tva_tx, l.remise, l.remise_percent, l.subprice, l.duree, '; $sql .= ' l.total_ht, l.total_tva, l.total_ttc,'; @@ -358,13 +360,15 @@ class FichinterRec extends Fichinter $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; $sql .= ' WHERE l.fk_fichinter = '.((int) $this->id); - dol_syslog('FichInter-rec::fetch_lines', LOG_DEBUG); + dol_syslog('FichinterRec::fetch_lines', LOG_DEBUG); + $result = $this->db->query($sql); if ($result) { $num = $this->db->num_rows($result); $i = 0; while ($i < $num) { $objp = $this->db->fetch_object($result); + $line = new FichinterLigne($this->db); $line->id = $objp->rowid; @@ -702,6 +706,22 @@ class FichinterRec extends Fichinter return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'fichinterdet_rec' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } /** * Update frequency and unit diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index c61fa4b1393..46a9f2eee3f 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -666,7 +666,7 @@ if ($resql) { } } if (!empty($arrayfields['f.description']['checked'])) { - print ''.dol_trunc(dolGetFirstLineOfText($obj->description), 48).''; + print ''.dol_trunc(dolGetFirstLineOfText(dol_string_nohtmltag($obj->description, 1)), 48).''; if (!$i) { $totalarray['nbfield']++; } @@ -723,7 +723,7 @@ if ($resql) { } // Fields of detail of line if (!empty($arrayfields['fd.description']['checked'])) { - print ''.dolGetFirstLineOfText($obj->descriptiondetail).''; + print ''.dol_trunc(dolGetFirstLineOfText(dol_string_nohtmltag($obj->descriptiondetail, 1)), 48).''; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php index e5903ee5863..8da01bb4f8f 100644 --- a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php @@ -22,7 +22,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 77932cf4e3d..9298c67ad9f 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -378,10 +378,10 @@ if ($object->id > 0) { // Nbre max d'elements des petites listes $MAXLIST = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; - print '
    '; + print '
    '; // Lien recap - $boxstat .= '
    '; + $boxstat .= '
    '; $boxstat .= ''; $boxstat .= ''; } // Project ref - if (!empty($arrayfields['p.project_ref']['checked'])) { + if (!empty($arrayfields['cf.fk_projet']['checked'])) { print ''; } // Request author @@ -1272,7 +1269,7 @@ if ($resql) { print ''; } // Thirpdarty - if (!empty($arrayfields['s.nom']['checked'])) { + if (!empty($arrayfields['cf.fk_soc']['checked'])) { print ''; } // Town @@ -1379,7 +1376,7 @@ if ($resql) { $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation - if (!empty($arrayfields['cf.datec']['checked'])) { + if (!empty($arrayfields['cf.date_creation']['checked'])) { print ''; } @@ -1438,14 +1435,14 @@ if ($resql) { if (!empty($arrayfields['cf.ref_supplier']['checked'])) { print_liste_field_titre($arrayfields['cf.ref_supplier']['label'], $_SERVER["PHP_SELF"], "cf.ref_supplier", "", $param, '', $sortfield, $sortorder, 'tdoverflowmax100imp '); } - if (!empty($arrayfields['p.project_ref']['checked'])) { - print_liste_field_titre($arrayfields['p.project_ref']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['cf.fk_projet']['checked'])) { + print_liste_field_titre($arrayfields['cf.fk_projet']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['u.login']['checked'])) { print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER["PHP_SELF"], "u.login", "", $param, '', $sortfield, $sortorder); } - if (!empty($arrayfields['s.nom']['checked'])) { - print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom", "", $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['cf.fk_soc']['checked'])) { + print_liste_field_titre($arrayfields['cf.fk_soc']['label'], $_SERVER["PHP_SELF"], "s.nom", "", $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['s.town']['checked'])) { print_liste_field_titre($arrayfields['s.town']['label'], $_SERVER["PHP_SELF"], 's.town', '', $param, '', $sortfield, $sortorder); @@ -1501,8 +1498,8 @@ if ($resql) { $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; - if (!empty($arrayfields['cf.datec']['checked'])) { - print_liste_field_titre($arrayfields['cf.datec']['label'], $_SERVER["PHP_SELF"], "cf.date_creation", "", $param, '', $sortfield, $sortorder, 'center nowrap '); + if (!empty($arrayfields['cf.date_creation']['checked'])) { + print_liste_field_titre($arrayfields['cf.date_creation']['label'], $_SERVER["PHP_SELF"], "cf.date_creation", "", $param, '', $sortfield, $sortorder, 'center nowrap '); } if (!empty($arrayfields['cf.tms']['checked'])) { print_liste_field_titre($arrayfields['cf.tms']['label'], $_SERVER["PHP_SELF"], "cf.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap '); @@ -1584,7 +1581,7 @@ if ($resql) { } } // Project - if (!empty($arrayfields['p.project_ref']['checked'])) { + if (!empty($arrayfields['cf.fk_projet']['checked'])) { $projectstatic->id = $obj->project_id; $projectstatic->ref = $obj->project_ref; $projectstatic->title = $obj->project_title; @@ -1616,7 +1613,7 @@ if ($resql) { } } // Thirdparty - if (!empty($arrayfields['s.nom']['checked'])) { + if (!empty($arrayfields['cf.fk_soc']['checked'])) { print ''; diff --git a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php index 1efd78df372..192a39c9b06 100644 --- a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index d384f3f90d2..c545762e5a4 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -11,6 +11,7 @@ * Copyright (C) 2016-2021 Alexandre Spangaro * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2019 Ferran Marcet + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -76,7 +77,8 @@ $lineid = GETPOST('lineid', 'int'); $projectid = GETPOST('projectid', 'int'); $origin = GETPOST('origin', 'alpha'); $originid = GETPOST('originid', 'int'); -$fac_rec = GETPOST('fac_rec', 'int'); +$fac_recid = GETPOST('fac_rec', 'int'); +$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1; // PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -882,10 +884,8 @@ if (empty($reshook)) { } } } - } - - // Standard invoice or Deposit invoice, created from a Predefined template invoice - if ((GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT) && GETPOST('fac_rec', 'int') > 0) { + } elseif ($fac_recid > 0 && (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)) { + // Standard invoice or Deposit invoice, created from a Predefined template invoice if (empty($dateinvoice)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); @@ -903,7 +903,7 @@ if (empty($reshook)) { $object->date = $dateinvoice; $object->note_public = trim(GETPOST('note_public', 'restricthtml')); $object->note_private = trim(GETPOST('note_private', 'restricthtml')); - $object->ref_client = GETPOST('ref_client'); + $object->ref_supplier = GETPOST('ref_supplier', 'nohtml'); $object->model_pdf = GETPOST('model'); $object->fk_project = GETPOST('projectid', 'int'); $object->cond_reglement_id = (GETPOST('type') == 3 ? 1 : GETPOST('cond_reglement_id')); @@ -918,7 +918,7 @@ if (empty($reshook)) { $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int'); // Source facture - $object->fac_rec = GETPOST('fac_rec', 'int'); + $object->fac_rec = $fac_recid; $fac_rec = new FactureFournisseurRec($db); $fac_rec->fetch($object->fac_rec); $fac_rec->fetch_lines(); @@ -926,10 +926,8 @@ if (empty($reshook)) { $id = $object->create($user); // This include recopy of links from recurring invoice and recurring invoice lines } - } - - // Standard invoice or Deposit invoice, not from a Predefined template invoice - if (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT && GETPOST('fac_rec') <= 0) { + } elseif ($fac_recid <= 0 && (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)) { + // Standard invoice or Deposit invoice, not from a Predefined template invoice if (GETPOST('socid', 'int') < 1) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors'); $action = 'create'; @@ -1447,7 +1445,7 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors'); $error++; } - if (!GETPOST('qty')) { + if (!GETPOST('qty', 'alpha')) { // 0 is NOT allowed for invoices setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } @@ -1499,12 +1497,27 @@ if (empty($reshook)) { if ($idprod > 0) { $label = $productsupplier->label; - + // Define output language + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if (empty($newlang)) { + $newlang = $object->thirdparty->default_lang; + } + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description; + } else { + $desc = $productsupplier->description; + } // if we use supplier description of the products if (!empty($productsupplier->desc_supplier) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) { $desc = $productsupplier->desc_supplier; - } else { - $desc = $productsupplier->description; } //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time @@ -1570,7 +1583,7 @@ if (empty($reshook)) { $tva_npr, $price_base_type, $type, - -1, + min($rank, count($object->lines) + 1), 0, $array_options, $productsupplier->fk_unit, @@ -2009,15 +2022,15 @@ if ($action == 'create') { $exampletemplateinvoice = new FactureFournisseurRec($db); $invoice_predefined = new FactureFournisseurRec($db); - if (empty($origin) && empty($originid) && GETPOST('fac_rec', 'int') > 0) { - $invoice_predefined->fetch(GETPOST('fac_rec', 'int')); + if (empty($origin) && empty($originid) && $fac_recid > 0) { + $invoice_predefined->fetch($fac_recid); } // Third party print ''; print ''; // Overwrite some values if creation of invoice is from a predefined invoice - if (empty($origin) && empty($originid) && GETPOST('fac_rec', 'int') > 0) { - $invoice_predefined->fetch(GETPOST('fac_rec', 'int')); + if (empty($origin) && empty($originid) && $fac_recid > 0) { + $invoice_predefined->fetch($fac_recid); $dateinvoice = $invoice_predefined->date_when; // To use next gen date by default later if (empty($projectid)) { @@ -2073,15 +2086,15 @@ if ($action == 'create') { if ($num > 0) { print ''; } @@ -2417,7 +2430,7 @@ if ($action == 'create') { // Help of substitution key $htmltext = ''; - if (GETPOST('fac_rec', 'int') > 0) { + if ($fac_recid > 0) { $dateexample = $newdateinvoice ? $newdateinvoice : $dateinvoice; if (empty($dateexample)) { $dateexample = dol_now(); @@ -2542,11 +2555,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
    '; print '
    '; @@ -837,24 +837,24 @@ if ($object->id > 0) { // modified by hook if (empty($reshook)) { if ($object->status != 1) { - print ''; + print dolGetButtonAction($langs->trans('ThirdPartyIsClosed'), $langs->trans('ThirdPartyIsClosed'), 'default', $_SERVER['PHP_SELF'].'#', '', false); } if (!empty($conf->supplier_proposal->enabled) && !empty($user->rights->supplier_proposal->creer)) { $langs->load("supplier_proposal"); if ($object->status == 1) { - print ''.$langs->trans("AddSupplierProposal").''; + print dolGetButtonAction('', $langs->trans('AddSupplierProposal'), 'default', DOL_URL_ROOT.'/supplier_proposal/card.php?action=create&socid='.$object->id, ''); } else { - print ''.$langs->trans("AddSupplierProposal").''; + print dolGetButtonAction($langs->trans('ThirdPartyIsClosed'), $langs->trans('AddSupplierProposalGR'), 'default', $_SERVER['PHP_SELF'].'#', '', false); } } if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) { $langs->load("orders"); if ($object->status == 1) { - print ''.$langs->trans("AddSupplierOrderShort").''; + print dolGetButtonAction('', $langs->trans('AddSupplierOrderShort'), 'default', DOL_URL_ROOT.'/fourn/commande/card.php?action=create&token='.newToken().'&socid='.$object->id, ''); } else { - print ''.$langs->trans("AddSupplierOrderShort").''; + print dolGetButtonAction($langs->trans('ThirdPartyIsClosed'), $langs->trans('AddSupplierOrderShort'), 'default', $_SERVER['PHP_SELF'].'#', '', false); } } @@ -862,30 +862,30 @@ if ($object->id > 0) { if (!empty($orders2invoice) && $orders2invoice > 0) { if ($object->status == 1) { // Company is open - print ''; + print dolGetButtonAction('', $langs->trans('CreateInvoiceForThisSupplierGR'), 'default', DOL_URL_ROOT.'/fourn/commande/list.php?socid='.$object->id.'&search_billed=0&autoselectall=1', ''); } else { - print ''; + print dolGetButtonAction('', $langs->trans('CreateInvoiceForThisCustomer'), 'default', $_SERVER['PHP_SELF'].'#', '', false); } } else { - print ''; + print dolGetButtonAction($langs->trans("NoOrdersToInvoice").' ('.$langs->trans("WithReceptionFinished").')', $langs->trans('CreateInvoiceForThisCustomer'), 'default', $_SERVER['PHP_SELF'].'#', '', false); } } if ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer) { $langs->load("bills"); if ($object->status == 1) { - print ''.$langs->trans("AddBill").''; + print dolGetButtonAction('', $langs->trans('AddBill'), 'default', DOL_URL_ROOT.'/fourn/facture/card.php?action=create&socid='.$object->id, ''); } else { - print ''.$langs->trans("AddBill").''; + print dolGetButtonAction($langs->trans('ThirdPartyIsClosed'), $langs->trans('AddBill'), 'default', $_SERVER['PHP_SELF'].'#', '', false); } } // Add action if (!empty($conf->agenda->enabled) && !empty($conf->global->MAIN_REPEATTASKONEACHTAB) && $object->status == 1) { if ($user->rights->agenda->myactions->create) { - print ''.$langs->trans("AddAction").''; + print dolGetButtonAction('', $langs->trans('AddAction'), 'default', DOL_URL_ROOT.'/comm/action/card.php?action=create&socid='.$object->id, ''); } else { - print ''.$langs->trans("AddAction").''; + print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('AddAction'), 'default', $_SERVER['PHP_SELF'].'#', '', false); } } } diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 06c836b4d77..35e783729ff 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -211,7 +211,7 @@ class SupplierInvoices extends DolibarrApi * @return int ID of supplier invoice * * @throws RestException 401 - * @throws RestException 500 + * @throws RestException 500 System error */ public function post($request_data = null) { @@ -283,7 +283,7 @@ class SupplierInvoices extends DolibarrApi * * @throws RestException 401 * @throws RestException 404 - * @throws RestException 500 + * @throws RestException 500 System error */ public function delete($id) { @@ -300,7 +300,7 @@ class SupplierInvoices extends DolibarrApi } if ($this->invoice->delete(DolibarrApiAccess::$user) < 0) { - throw new RestException(500); + throw new RestException(500, 'Error when deleting invoice'); } return array( @@ -326,7 +326,7 @@ class SupplierInvoices extends DolibarrApi * @throws RestException 401 * @throws RestException 404 * @throws RestException 405 - * @throws RestException 500 + * @throws RestException 500 System error */ public function validate($id, $idwarehouse = 0, $notrigger = 0) { diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index e21eb3436dc..d55a398dbd6 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -309,7 +309,7 @@ class SupplierOrders extends DolibarrApi } if ($this->order->delete(DolibarrApiAccess::$user) < 0) { - throw new RestException(500); + throw new RestException(500, 'Error when deleting order'); } return array( diff --git a/htdocs/fourn/class/fournisseur.class.php b/htdocs/fourn/class/fournisseur.class.php index b47cfa263c0..baed7051ef8 100644 --- a/htdocs/fourn/class/fournisseur.class.php +++ b/htdocs/fourn/class/fournisseur.class.php @@ -106,7 +106,7 @@ class Fournisseur extends Societe public function load_state_board() { // phpcs:enable - global $conf, $user; + global $conf, $user, $hookmanager; $this->nb = array(); $clause = "WHERE"; @@ -120,6 +120,12 @@ class Fournisseur extends Societe } $sql .= " ".$clause." s.fournisseur = 1"; $sql .= " AND s.entity IN (".getEntity('societe').")"; + // Add where from hooks + if (is_object($hookmanager)) { + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $this); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; + } $resql = $this->db->query($sql); if ($resql) { diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 8a0e0de299e..128c2ab3356 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -10,8 +10,9 @@ * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018-2022 Frédéric France - * Copyright (C) 2018-2021 Ferran Marcet + * Copyright (C) 2018-2022 Ferran Marcet * Copyright (C) 2021 Josep Lluís Amador + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +34,7 @@ * \brief File of class to manage suppliers orders */ -include_once DOL_DOCUMENT_ROOT.'/core/class/commonorder.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/commonorder.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (!empty($conf->productbatch->enabled)) { require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; @@ -185,56 +186,79 @@ class CommandeFournisseur extends CommonOrder public $multicurrency_total_ttc; - + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM' or '!empty($conf->multicurrency->enabled)' ...) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage) + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' + * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar' + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * 'validate' is 1 if need to validate with $this->validateField() + * 'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value) + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ public $fields = array( - 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15), - 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), - 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'showoncombobox'=>1, 'position'=>25), - 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>30, 'index'=>1), + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>10), + 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'showoncombobox'=>1, 'position'=>25, 'searchall'=>1), 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35), - 'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefSupplier', 'enabled'=>1, 'visible'=>-1, 'position'=>40), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>45), - 'date_creation' =>array('type'=>'datetime', 'label'=>'Date creation', 'enabled'=>1, 'visible'=>-1, 'position'=>50), - 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), - 'date_approve' =>array('type'=>'datetime', 'label'=>'Date approve', 'enabled'=>1, 'visible'=>-1, 'position'=>60), - 'date_approve2' =>array('type'=>'datetime', 'label'=>'Date approve2', 'enabled'=>1, 'visible'=>-1, 'position'=>65), - 'date_commande' =>array('type'=>'date', 'label'=>'Date commande', 'enabled'=>1, 'visible'=>-1, 'position'=>70), - 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>75), - 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>80), - 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>85), - 'fk_user_approve' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval', 'enabled'=>1, 'visible'=>-1, 'position'=>90), - 'fk_user_approve2' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserSecondApproval', 'enabled'=>1, 'visible'=>-1, 'position'=>95), - 'source' =>array('type'=>'smallint(6)', 'label'=>'Source', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>100), - 'billed' =>array('type'=>'smallint(6)', 'label'=>'Billed', 'enabled'=>1, 'visible'=>-1, 'position'=>110), - 'amount_ht' =>array('type'=>'double(24,8)', 'label'=>'Amount ht', 'enabled'=>1, 'visible'=>-1, 'position'=>115), - 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>120), - 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>125), - 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1), - 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1), - 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1), - 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>145, 'isameasure'=>1), + 'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefOrderSupplierShort', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'searchall'=>1), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'date_approve' =>array('type'=>'datetime', 'label'=>'DateApprove', 'enabled'=>1, 'visible'=>-1, 'position'=>62), + 'date_approve2' =>array('type'=>'datetime', 'label'=>'DateApprove2', 'enabled'=>1, 'visible'=>3, 'position'=>64), + 'date_commande' =>array('type'=>'date', 'label'=>'OrderDateShort', 'enabled'=>1, 'visible'=>1, 'position'=>70), + 'date_livraison' =>array('type'=>'datetime', 'label'=>'DeliveryDate', 'enabled'=>'empty($conf->global->ORDER_DISABLE_DELIVERY_DATE)', 'visible'=>1, 'position'=>74), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>3, 'position'=>75), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>3, 'notnull'=>-1, 'position'=>80), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>3, 'position'=>85), + 'fk_user_approve' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval', 'enabled'=>1, 'visible'=>3, 'position'=>90), + 'fk_user_approve2' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval2', 'enabled'=>1, 'visible'=>3, 'position'=>95), + 'source' =>array('type'=>'smallint(6)', 'label'=>'Source', 'enabled'=>1, 'visible'=>3, 'notnull'=>1, 'position'=>100), + 'billed' =>array('type'=>'smallint(6)', 'label'=>'Billed', 'enabled'=>1, 'visible'=>1, 'position'=>110), + 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>1, 'position'=>130, 'isameasure'=>1), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>3, 'position'=>135, 'isameasure'=>1), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>3, 'position'=>140, 'isameasure'=>1), + 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>1, 'position'=>145, 'isameasure'=>1), 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>150, 'isameasure'=>1), 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>155), - 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>160), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>160, 'searchall'=>1), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPDF', 'enabled'=>1, 'visible'=>0, 'position'=>165), - 'fk_input_method' =>array('type'=>'integer', 'label'=>'InputMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>170), - 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>175), - 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>180), - 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>190), - 'date_livraison' =>array('type'=>'datetime', 'label'=>'DeliveryDate', 'enabled'=>1, 'visible'=>-1, 'position'=>195), - 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>200), - 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>1, 'visible'=>-1, 'position'=>205), - 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLocation', 'enabled'=>1, 'visible'=>-1, 'position'=>210), - 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>215), - 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>220), - 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>1, 'visible'=>-1, 'position'=>225), - 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>230), - 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>235), - 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>240), - 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>245), - 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'position'=>500), - 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), + 'fk_input_method' =>array('type'=>'integer', 'label'=>'OrderMode', 'enabled'=>1, 'visible'=>3, 'position'=>170), + 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>3, 'position'=>175), + 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>3, 'position'=>180), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>0, 'position'=>190), + 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>1, 'visible'=>3, 'position'=>200), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>1, 'visible'=>3, 'position'=>205), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLocation', 'enabled'=>1, 'visible'=>3, 'position'=>210), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>0, 'position'=>215), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Currency', 'enabled'=>'!empty($conf->multicurrency->enabled)', 'visible'=>-1, 'position'=>220), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'CurrencyRate', 'enabled'=>'!empty($conf->multicurrency->enabled)', 'visible'=>-1, 'position'=>225), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountHT', 'enabled'=>'!empty($conf->multicurrency->enabled)', 'visible'=>-1, 'position'=>230), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'!empty($conf->multicurrency->enabled)', 'visible'=>-1, 'position'=>235), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'!empty($conf->multicurrency->enabled)', 'visible'=>-1, 'position'=>240), + 'date_creation' =>array('type'=>'datetime', 'label'=>'Date creation', 'enabled'=>1, 'visible'=>-1, 'position'=>500), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>46), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>1000, 'index'=>1), + 'tms'=>array('type'=>'datetime', 'label'=>"DateModificationShort", 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>501), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>0, 'position'=>700), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'position'=>701), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>0, 'position'=>900), ); @@ -438,6 +462,7 @@ class CommandeFournisseur extends CommonOrder * Lines */ $result = $this->fetch_lines(); + if ($result < 0) { return -1; } else { @@ -460,7 +485,7 @@ class CommandeFournisseur extends CommonOrder { global $conf; // phpcs:enable - //$result=$this->fetch_lines(); + $this->lines = array(); $sql = "SELECT l.rowid, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description, l.qty,"; @@ -471,26 +496,17 @@ class CommandeFournisseur extends CommonOrder $sql .= " l.fk_unit,"; $sql .= " l.date_start, l.date_end,"; $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc'; - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= ", pfp.rowid as fk_pfp, pfp.packaging, MAX(pfp.quantity) as max_qty"; - } $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND l.fk_product = pfp.fk_product and l.ref = pfp.ref_fourn AND pfp.fk_soc = ".((int) $this->socid); - } $sql .= " WHERE l.fk_commande = ".((int) $this->id); if ($only_product) { $sql .= ' AND p.fk_product_type = 0'; } - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql.= " AND l.qty >= pfp.quantity "; - $sql.= " GROUP BY l.rowid HAVING max_qty = MAX(pfp.quantity) "; - } $sql .= " ORDER BY l.rang, l.rowid"; //print $sql; - dol_syslog(get_class($this)."::fetch get lines", LOG_DEBUG); + dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); + $result = $this->db->query($sql); if ($result) { $num = $this->db->num_rows($result); @@ -536,11 +552,34 @@ class CommandeFournisseur extends CommonOrder $line->ref_supplier = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $line->fk_fournprice = $objp->fk_pfp; - $line->packaging = $objp->packaging; + // TODO We should not fetch this properties into the fetch_lines. This is NOT properties of a line. + // Move this into another method and call it when required. + + // Take better packaging for $objp->qty (first supplier ref quantity <= $objp->qty) + $sqlsearchpackage = 'SELECT rowid, packaging FROM '.MAIN_DB_PREFIX."product_fournisseur_price"; + $sqlsearchpackage .= ' WHERE entity IN ('.getEntity('product_fournisseur_price').")"; + $sqlsearchpackage .= " AND fk_product = ".((int) $objp->fk_product); + $sqlsearchpackage .= " AND ref_fourn = '".$this->db->escape($objp->ref_supplier)."'"; + $sqlsearchpackage .= " AND quantity <= ".((float) $objp->qty); // required to be qualified + $sqlsearchpackage .= " AND (packaging IS NULL OR packaging = 0 OR packaging <= ".((float) $objp->qty).")"; // required to be qualified + $sqlsearchpackage .= " AND fk_soc = ".((int) $this->socid); + $sqlsearchpackage .= " ORDER BY packaging ASC"; // Take the smaller package first + $sqlsearchpackage .= " LIMIT 1"; + + $resqlsearchpackage = $this->db->query($sqlsearchpackage); + if ($resqlsearchpackage) { + $objsearchpackage = $this->db->fetch_object($resqlsearchpackage); + if ($objsearchpackage) { + $line->fk_fournprice = $objsearchpackage->rowid; + $line->packaging = $objsearchpackage->packaging; + } + } else { + $this->error = $this->db->lasterror(); + return -1; + } } - $line->date_start = $this->db->jdate($objp->date_start); + $line->date_start = $this->db->jdate($objp->date_start); $line->date_end = $this->db->jdate($objp->date_end); $line->fk_unit = $objp->fk_unit; @@ -1066,6 +1105,7 @@ class CommandeFournisseur extends CommonOrder $this->line = $this->lines[$i]; $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; + $mouvP->setOrigin($this->element, $this->id); // We decrement stock of product (and sub-products) $up_ht_disc = $this->lines[$i]->subprice; if (!empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) { @@ -1680,7 +1720,7 @@ class CommandeFournisseur extends CommonOrder * Add order line * * @param string $desc Description - * @param float $pu_ht Unit price + * @param float $pu_ht Unit price (used if $price_base_type is 'HT') * @param float $qty Quantity * @param float $txtva Taux tva * @param float $txlocaltax1 Localtax1 tax @@ -1690,7 +1730,7 @@ class CommandeFournisseur extends CommonOrder * @param string $ref_supplier Supplier reference price * @param float $remise_percent Remise * @param string $price_base_type HT or TTC - * @param float $pu_ttc Unit price TTC + * @param float $pu_ttc Unit price TTC (used if $price_base_type is 'TTC') * @param int $type Type of line (0=product, 1=service) * @param int $info_bits More information * @param bool $notrigger Disable triggers @@ -1701,9 +1741,10 @@ class CommandeFournisseur extends CommonOrder * @param string $pu_ht_devise Amount in currency * @param string $origin 'order', ... * @param int $origin_id Id of origin object + * @param int $rang Rank * @return int <=0 if KO, >0 if OK */ - public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $fk_prod_fourn_price = 0, $ref_supplier = '', $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $type = 0, $info_bits = 0, $notrigger = false, $date_start = null, $date_end = null, $array_options = 0, $fk_unit = null, $pu_ht_devise = 0, $origin = '', $origin_id = 0) + public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $fk_prod_fourn_price = 0, $ref_supplier = '', $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $type = 0, $info_bits = 0, $notrigger = false, $date_start = null, $date_end = null, $array_options = 0, $fk_unit = null, $pu_ht_devise = 0, $origin = '', $origin_id = 0, $rang = -1) { global $langs, $mysoc, $conf; @@ -1723,6 +1764,9 @@ class CommandeFournisseur extends CommonOrder if (empty($txtva)) { $txtva = 0; } + if (empty($rang)) { + $rang = 0; + } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } @@ -1826,6 +1870,7 @@ class CommandeFournisseur extends CommonOrder if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { $prod = new Product($this->db, $fk_product); $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc ? $this->fk_soc : $this->socid)); + if ($qty < $prod->packaging) { $qty = $prod->packaging; } else { @@ -1874,8 +1919,10 @@ class CommandeFournisseur extends CommonOrder $localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; $localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; - $rangmax = $this->line_max(); - $rang = $rangmax + 1; + if ($rang < 0) { + $rangmax = $this->line_max(); + $rang = $rangmax + 1; + } // Insert line $this->line = new CommandeFournisseurLigne($this->db); @@ -1937,6 +1984,11 @@ class CommandeFournisseur extends CommonOrder // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); + } elseif ($rang > 0 && $rang <= count($this->lines)) { // Update all rank of all other lines + $linecount = count($this->lines); + for ($ii = $rang; $ii <= $linecount; $ii++) { + $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii + 1); + } } // Mise a jour informations denormalisees au niveau de la commande meme @@ -2031,8 +2083,7 @@ class CommandeFournisseur extends CommonOrder if ($product > 0) { // $price should take into account discount (except if option STOCK_EXCLUDE_DISCOUNT_FOR_PMP is on) $mouv->origin = &$this; - $mouv->origin_type = $this->element; - $mouv->origin_id = $this->id; + $mouv->setOrigin($this->element, $this->id); $result = $mouv->reception($user, $product, $entrepot, $qty, $price, $comment, $eatby, $sellby, $batch); if ($result < 0) { $this->error = $mouv->error; @@ -3210,6 +3261,23 @@ class CommandeFournisseur extends CommonOrder return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'commande_fournisseurdet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Is the supplier order delayed? * We suppose a purchase ordered as late if a the purchase order has been sent and the delivery date is set and before the delay. @@ -3539,25 +3607,18 @@ class CommandeFournisseurLigne extends CommonOrderLine global $conf; $sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_product, cd.product_type, cd.description, cd.qty, cd.tva_tx, cd.special_code,'; - $sql .= ' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref,'; + $sql .= ' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref as ref_supplier,'; $sql .= ' cd.remise, cd.remise_percent, cd.subprice,'; $sql .= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_ttc,'; $sql .= ' cd.total_localtax1, cd.total_localtax2,'; $sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; $sql .= ' cd.date_start, cd.date_end, cd.fk_unit,'; - $sql .= ' cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc'; - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= ", pfp.rowid as fk_pfp, pfp.packaging, MAX(pfp.quantity) as max_qty"; - } - $sql .= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; + $sql .= ' cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc,'; + $sql .= ' c.fk_soc as socid'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseur as c, '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND cd.fk_product = pfp.fk_product and cd.ref = pfp.ref_fourn"; - } - $sql .= ' WHERE cd.rowid = '.((int) $rowid); - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " AND cd.qty >= pfp.quantity GROUP BY cd.rowid HAVING max_qty = MAX(pfp.quantity)"; - } + $sql .= ' WHERE cd.fk_commande = c.rowid AND cd.rowid = '.((int) $rowid); + $result = $this->db->query($sql); if ($result) { $objp = $this->db->fetch_object($result); @@ -3568,8 +3629,8 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->fk_commande = $objp->fk_commande; $this->desc = $objp->description; $this->qty = $objp->qty; - $this->ref_fourn = $objp->ref; - $this->ref_supplier = $objp->ref; + $this->ref_fourn = $objp->ref_supplier; + $this->ref_supplier = $objp->ref_supplier; $this->subprice = $objp->subprice; $this->tva_tx = $objp->tva_tx; $this->localtax1_tx = $objp->localtax1_tx; @@ -3593,9 +3654,33 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->product_ref = $objp->product_ref; $this->product_label = $objp->product_label; $this->product_desc = $objp->product_desc; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $this->packaging = $objp->packaging; - $this->fk_fournprice = $objp->fk_pfp; + // TODO We should not fetch this properties into the fetch_lines. This is NOT properties of a line. + // Move this into another method and call it when required. + + // Take better packaging for $objp->qty (first supplier ref quantity <= $objp->qty) + $sqlsearchpackage = 'SELECT rowid, packaging FROM '.MAIN_DB_PREFIX."product_fournisseur_price"; + $sqlsearchpackage .= ' WHERE entity IN ('.getEntity('product_fournisseur_price').")"; + $sqlsearchpackage .= " AND fk_product = ".((int) $objp->fk_product); + $sqlsearchpackage .= " AND ref_fourn = '".$this->db->escape($objp->ref_supplier)."'"; + $sqlsearchpackage .= " AND quantity <= ".((float) $objp->qty); // required to be qualified + $sqlsearchpackage .= " AND (packaging IS NULL OR packaging = 0 OR packaging <= ".((float) $objp->qty).")"; // required to be qualified + $sqlsearchpackage .= " AND fk_soc = ".((int) $objp->socid); + $sqlsearchpackage .= " ORDER BY packaging ASC"; // Take the smaller package first + $sqlsearchpackage .= " LIMIT 1"; + + $resqlsearchpackage = $this->db->query($sqlsearchpackage); + if ($resqlsearchpackage) { + $objsearchpackage = $this->db->fetch_object($resqlsearchpackage); + if ($objsearchpackage) { + $this->fk_fournprice = $objsearchpackage->rowid; + $this->packaging = $objsearchpackage->packaging; + } + } else { + $this->error = $this->db->lasterror(); + return -1; + } } $this->date_start = $this->db->jdate($objp->date_start); @@ -3839,7 +3924,7 @@ class CommandeFournisseurLigne extends CommonOrderLine if (!$error && !$notrigger) { global $user; // Call trigger - $result = $this->call_trigger('LINEORDER_SUPPLIER_UPDATE', $user); + $result = $this->call_trigger('LINEORDER_SUPPLIER_MODIFY', $user); if ($result < 0) { $this->db->rollback(); return -1; diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index 7037cd94262..2ed936ee1f6 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -410,7 +410,7 @@ class CommandeFournisseurDispatch extends CommonObjectLine if (!$notrigger) { // Call triggers - $result = $this->call_trigger('LINERECEPTION_UPDATE', $user); + $result = $this->call_trigger('LINERECEPTION_MODIFY', $user); if ($result < 0) { $error++; } diff --git a/htdocs/fourn/class/fournisseur.facture-rec.class.php b/htdocs/fourn/class/fournisseur.facture-rec.class.php index c8f0ad75536..ab68cd3ecc6 100644 --- a/htdocs/fourn/class/fournisseur.facture-rec.class.php +++ b/htdocs/fourn/class/fournisseur.facture-rec.class.php @@ -39,6 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; */ class FactureFournisseurRec extends CommonInvoice { + const TRIGGER_PREFIX = 'SUPPLIERBILLREC'; /** * @var string ID to identify managed object */ @@ -78,8 +79,19 @@ class FactureFournisseurRec extends CommonInvoice public $suspended; public $libelle; + public $label; + + /** + * @var double $amount + * @deprecated + */ public $amount; + /** + * @var double $remise + * @deprecated + */ public $remise; + public $vat_src_code; public $localtax1; public $localtax2; @@ -167,8 +179,6 @@ class FactureFournisseurRec extends CommonInvoice 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>40), 'suspended' =>array('type'=>'integer', 'label'=>'Suspended', 'enabled'=>1, 'visible'=>-1, 'position'=>225), 'libelle' =>array('type'=>'varchar(100)', 'label'=>'Libelle', 'enabled'=>1, 'showoncombobox' => 0, 'visible'=>-1, 'position'=>15), - 'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), - 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>40), 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'isameasure'=>1), 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>65, 'isameasure'=>1), @@ -242,6 +252,8 @@ class FactureFournisseurRec extends CommonInvoice // Clean parameters $this->titre = empty($this->titre) ? '' : $this->titre; + $keyforref = $this->table_ref_field; + $this->ref = $this->$keyforref; $this->ref_supplier = empty($this->ref_supplier) ? '' : $this->ref_supplier; $this->usenewprice = empty($this->usenewprice) ? 0 : $this->usenewprice; $this->suspended = empty($this->suspended) ? 0 : $this->suspended; @@ -270,8 +282,7 @@ class FactureFournisseurRec extends CommonInvoice $sql .= ', datec'; $sql .= ', suspended'; $sql .= ', libelle'; - $sql .= ', amount'; - $sql .= ', remise'; + $sql .= ', total_ttc'; $sql .= ', fk_user_author'; $sql .= ', fk_projet'; $sql .= ', fk_account'; @@ -296,40 +307,33 @@ class FactureFournisseurRec extends CommonInvoice $sql .= ') VALUES ('; $sql .= "'".$this->db->escape($this->titre)."'"; $sql .= ", '".$this->db->escape($this->ref_supplier)."'"; - $sql .= ', ' . (int) $conf->entity; - $sql .= ', ' . (int) $facfourn_src->socid; + $sql .= ", ".((int) $conf->entity); + $sql .= ", ".((int) $facfourn_src->socid); $sql .= ", '".$this->db->idate($now)."'"; - $sql .= ', ' . (int) $this->suspended; - if (!empty(GETPOST('libelle'))) { - $sql .= ", '" . $this->db->escape(GETPOST('libelle')) . "'"; - } elseif (! empty($this->libelle)) { - $sql .= ", '" . $this->db->escape($this->libelle) . "'"; - } else { - $sql .= ", ''"; - } - $sql .= ', ' .(!empty($facfourn_src->total_ttc) ? (float) $facfourn_src->total_ttc : '0'); // amount - $sql .= ', ' .(!empty($facfourn_src->remise) ? (float) $facfourn_src->remise : '0'); - $sql .= ', ' . (int) $user->id; - $sql .= ', ' .(!empty($this->fk_project) ? $this->fk_project : 'NULL'); // Fields declarded on creation - $sql .= ', ' .(!empty($facfourn_src->fk_account) ? $facfourn_src->fk_account : 'NULL'); - $sql .= ', ' .($this->cond_reglement_id > 0 ? (int) $this->cond_reglement_id : 'NULL'); - $sql .= ', ' .($this->mode_reglement_id > 0 ? (int) $this->mode_reglement_id : 'NULL'); - $sql .= ", '".($facfourn_src->date_echeance > 0 ? $this->db->idate($facfourn_src->date_echeance) : 'NULL')."'"; // date_lim_reglement - $sql .= ', ' .(!empty($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : 'NULL'); // Fields declarded on creation - $sql .= ', ' .(!empty($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : 'NULL'); // Fields declarded on creation - $sql .= ', ' .(!empty($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : 'NULL'); // Fields declarded on creation - $sql .= ', ' . (int) $facfourn_src->fk_multicurrency; + $sql .= ", ".((int) $this->suspended); + $sql .= ", '".$this->db->escape($this->libelle)."'"; + $sql .= ", " .(!empty($facfourn_src->total_ttc) ? (float) $facfourn_src->total_ttc : '0'); // amount + $sql .= ", " .((int) $user->id); + $sql .= ", " .(!empty($this->fk_project) ? ((int) $this->fk_project) : 'NULL'); + $sql .= ", " .(!empty($facfourn_src->fk_account) ? ((int) $facfourn_src->fk_account) : 'NULL'); + $sql .= ", " .($this->cond_reglement_id > 0 ? (int) $this->cond_reglement_id : 'NULL'); + $sql .= ", " .($this->mode_reglement_id > 0 ? (int) $this->mode_reglement_id : 'NULL'); + $sql .= ", ".($facfourn_src->date_echeance > 0 ? "'".$this->db->idate($facfourn_src->date_echeance)."'" : 'NULL'); // date_lim_reglement + $sql .= ", " .(!empty($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : 'NULL'); + $sql .= ", " .(!empty($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : 'NULL'); + $sql .= ", " .(!empty($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : 'NULL'); + $sql .= ", " . (int) $facfourn_src->fk_multicurrency; $sql .= ", '".$this->db->escape($facfourn_src->multicurrency_code)."'"; - $sql .= ', ' . (float) $facfourn_src->multicurrency_tx; - $sql .= ', ' . (int) $this->usenewprice; // Fields declarded on creation - $sql .= ', ' . (int) $this->frequency; // Fields declarded on creation - $sql .= ", '".$this->db->escape($this->unit_frequency)."'"; // Fields declarded on creation - $sql .= ', ' .(!empty($this->date_when) ? "'".$this->db->idate($this->date_when)."'" : 'NULL'); // Fields declarded on creation - $sql .= ', ' .(!empty($this->date_last_gen) ? "'".$this->db->idate($this->date_last_gen)."'" : 'NULL'); // Fields declarded on creation - $sql .= ', ' . (int) $this->nb_gen_done; // Fields declarded on creation - $sql .= ', ' . (int) $this->nb_gen_max; // Fields declarded on creation - $sql .= ', ' . (int) $this->auto_validate; // Fields declarded on creation - $sql .= ', ' . (int) $this->generate_pdf; // Fields declarded on creation + $sql .= ", " . (float) $facfourn_src->multicurrency_tx; + $sql .= ", " . (int) $this->usenewprice; + $sql .= ", " . (int) $this->frequency; + $sql .= ", '".$this->db->escape($this->unit_frequency)."'"; + $sql .= ", " .(!empty($this->date_when) ? "'".$this->db->idate($this->date_when)."'" : 'NULL'); + $sql .= ", " .(!empty($this->date_last_gen) ? "'".$this->db->idate($this->date_last_gen)."'" : 'NULL'); + $sql .= ", " . (int) $this->nb_gen_done; + $sql .= ", " . (int) $this->nb_gen_max; + $sql .= ", " . (int) $this->auto_validate; + $sql .= ", " . (int) $this->generate_pdf; $sql .= ')'; if ($this->db->query($sql)) { @@ -472,44 +476,41 @@ class FactureFournisseurRec extends CommonInvoice $error = 0; $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_rec SET"; - $sql .= ' titre = "' . (!empty($this->titre) ? $this->titre .'",' : '"",') ; - $sql .= ' ref_supplier = "'. (!empty($this->ref_supplier) ? $this->ref_supplier .'",' : '" ",'); - $sql .= " entity = ". (!empty($this->entity) ? $this->entity : 1) . ','; + $sql .= " titre = '" . (!empty($this->titre) ? $this->db->escape($this->titre) : "")."'," ; + $sql .= " ref_supplier = '". (!empty($this->ref_supplier) ? $this->db->escape($this->ref_supplier) : "")."',"; + $sql .= " entity = ". (!empty($this->entity) ? ((int) $this->entity) : 1) . ','; if ($this->fk_soc > 0) $sql .= " fk_soc = ". (int) $this->fk_soc. ','; - $sql .= ' tms = "'. date('Y-m-d H:i:s', dol_now()) . '",'; - $sql .= " suspended = ". (!empty($this->suspended) ? $this->suspended : 0) . ','; - $sql .= ' libelle = "'. (!empty($this->libelle) ? $this->libelle : 'NULL') . '",'; - $sql .= " amount = ". (!empty($this->amount) ? $this->amount : 0.00) . ','; - $sql .= " remise = ". (!empty($this->remise) ? $this->remise : 'NULL') . ','; - $sql .= " vat_src_code = ". (!empty($this->vat_src_code) ? $this->vat_src_code : 'NULL') . ','; - $sql .= " localtax1 = ". (!empty($this->localtax1) ? $this->localtax1 : 0.00) . ','; - $sql .= " localtax2 = ". (!empty($this->localtax2) ? $this->localtax2 : 0.00) . ','; - $sql .= " total_ht = ". (!empty($this->total_ht) ? $this->total_ht : 0.00) . ','; - $sql .= " total_tva = ". (!empty($this->total_tva) ? $this->total_tva : 0.00) . ','; - $sql .= " total_ttc = ". (!empty($this->total_ttc) ? $this->total_ttc : 0.00) . ','; - $sql .= " fk_user_modif = ". $user->id . ','; - $sql .= " fk_projet = ". (!empty($this->fk_project) ? $this->fk_project : 'NULL') . ','; - $sql .= " fk_account = ". (!empty($this->fk_account) ? $this->fk_account : 'NULL') . ','; - $sql .= " fk_mode_reglement = ". (!empty($this->mode_reglement_id) ? $this->mode_reglement_id : 'NULL') . ','; - $sql .= " fk_cond_reglement = ". (!empty($this->cond_reglement_id) ? $this->cond_reglement_id : 'NULL') . ','; - $sql .= " date_lim_reglement = ". (!empty($this->date_lim_reglement) ? '"'.date("Y-m-d H:i:s", $this->date_lim_reglement).'"' : 'NULL') . ','; - $sql .= ' note_private = "'. (!empty($this->note_private) ? $this->note_private : '') . '",'; - $sql .= ' note_public = "'. (!empty($this->note_public) ? $this->note_public : '') . '",'; - $sql .= ' modelpdf = "'. (!empty($this->model_pdf) ? $this->model_pdf : 'NULL') . '",'; - $sql .= " fk_multicurrency = ". (!empty($this->fk_multicurrency) ? $this->fk_multicurrency : 'NULL') . ','; - $sql .= ' multicurrency_code = "'. (!empty($this->multicurrency_code) ? $this->multicurrency_code : 'NULL') . '",'; - $sql .= " multicurrency_tx = ". (!empty($this->multicurrency_tx) ? $this->multicurrency_tx : 1) . ','; - $sql .= " multicurrency_total_ht = ". (!empty($this->multicurrency_total_ht) ? $this->multicurrency_total_ht : 0.00) . ','; - $sql .= " multicurrency_total_tva = ". (!empty($this->multicurrency_total_tva) ? $this->multicurrency_total_tva : 0.00) . ','; - $sql .= " multicurrency_total_ttc = ". (!empty($this->multicurrency_total_ttc) ? $this->multicurrency_total_ttc : 0.00) . ','; - $sql .= " usenewprice = ". (!empty($this->usenewprice) ? $this->usenewprice : 0) . ','; - $sql .= " frequency = ". (!empty($this->frequency) ? $this->frequency : 0). ','; - $sql .= ' unit_frequency = "'. (!empty($this->unit_frequency) ? $this->unit_frequency : 0). '",'; - $sql .= " date_when = ". (!empty($this->date_when) ? '"'.date("Y-m-d H:i:s", $this->date_when).'"' : 0) . ','; - $sql .= " date_last_gen = ". (!empty($this->date_last_gen) ? '"'.date("Y-m-d H:i:s", $this->date_last_gen).'"' : 0) . ','; - $sql .= " nb_gen_done = ". (!empty($this->nb_gen_done) ? $this->nb_gen_done : 0) . ','; - $sql .= " nb_gen_max = ". (!empty($this->nb_gen_max) ? $this->nb_gen_max : 0) . ','; - $sql .= " auto_validate = ". (!empty($this->auto_validate) ? $this->auto_validate : 0); + $sql .= " suspended = ". (!empty($this->suspended) ? ((int) $this->suspended) : 0) . ','; + $sql .= " libelle = ". (!empty($this->libelle) ? "'".$this->db->escape($this->libelle)."'" : 'NULL') . ","; + $sql .= " vat_src_code = ". (!empty($this->vat_src_code) ? "'".$this->db->escape($this->vat_src_code)."'" : 'NULL') . ','; + $sql .= " localtax1 = ". (!empty($this->localtax1) ? ((float) $this->localtax1) : 0.00) . ','; + $sql .= " localtax2 = ". (!empty($this->localtax2) ? ((float) $this->localtax2) : 0.00) . ','; + $sql .= " total_ht = ". (!empty($this->total_ht) ? ((float) $this->total_ht) : 0.00) . ','; + $sql .= " total_tva = ". (!empty($this->total_tva) ? ((float) $this->total_tva) : 0.00) . ','; + $sql .= " total_ttc = ". (!empty($this->total_ttc) ? ((float) $this->total_ttc) : 0.00) . ','; + $sql .= " fk_user_modif = ". ((int) $user->id) . ','; + $sql .= " fk_projet = ". (!empty($this->fk_project) ? ((int) $this->fk_project) : 'NULL') . ','; + $sql .= " fk_account = ". (!empty($this->fk_account) ? ((int) $this->fk_account) : 'NULL') . ','; + $sql .= " fk_mode_reglement = ". (!empty($this->mode_reglement_id) ? ((int) $this->mode_reglement_id) : 'NULL') . ','; + $sql .= " fk_cond_reglement = ". (!empty($this->cond_reglement_id) ? ((int) $this->cond_reglement_id) : 'NULL') . ','; + $sql .= " date_lim_reglement = ". (!empty($this->date_lim_reglement) ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'NULL') . ','; + $sql .= " note_private = '". (!empty($this->note_private) ? $this->db->escape($this->note_private) : '') . "',"; + $sql .= " note_public = '". (!empty($this->note_public) ? $this->db->escape($this->note_public) : '') . "',"; + $sql .= " modelpdf = ". (!empty($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : 'NULL') . ","; + $sql .= " fk_multicurrency = ". (!empty($this->fk_multicurrency) ? ((int) $this->fk_multicurrency) : 'NULL') . ','; + $sql .= " multicurrency_code = ". (!empty($this->multicurrency_code) ? "'".$this->db->escape($this->multicurrency_code)."'" : 'NULL') . ","; + $sql .= " multicurrency_tx = ". (!empty($this->multicurrency_tx) ? ((float) $this->multicurrency_tx) : 1) . ','; + $sql .= " multicurrency_total_ht = ". (!empty($this->multicurrency_total_ht) ? ((float) $this->multicurrency_total_ht) : 0.00) . ','; + $sql .= " multicurrency_total_tva = ". (!empty($this->multicurrency_total_tva) ? ((float) $this->multicurrency_total_tva) : 0.00) . ','; + $sql .= " multicurrency_total_ttc = ". (!empty($this->multicurrency_total_ttc) ? ((float) $this->multicurrency_total_ttc) : 0.00) . ','; + $sql .= " usenewprice = ". (!empty($this->usenewprice) ? ((int) $this->usenewprice) : 0) . ','; + $sql .= " frequency = ". (!empty($this->frequency) ? ((int) $this->frequency) : 0). ','; + $sql .= " unit_frequency = '". (!empty($this->unit_frequency) ? $this->db->escape($this->unit_frequency) : ''). "',"; + $sql .= " date_when = ". (!empty($this->date_when) ? "'".$this->db->idate($this->date_when)."'" : 'NULL') . ','; + $sql .= " date_last_gen = ". (!empty($this->date_last_gen) ? "'".$this->db->idate($this->date_last_gen)."'" : 'NULL') . ','; + $sql .= " nb_gen_done = ". (!empty($this->nb_gen_done) ? ((int) $this->nb_gen_done) : 0) . ','; + $sql .= " nb_gen_max = ". (!empty($this->nb_gen_max) ? ((int) $this->nb_gen_max) : 0) . ','; + $sql .= " auto_validate = ". (!empty($this->auto_validate) ? ((int) $this->auto_validate) : 0); $sql .= " WHERE rowid = ". (int) $this->id; dol_syslog(get_class($this)."::update", LOG_DEBUG); @@ -524,7 +525,7 @@ class FactureFournisseurRec extends CommonInvoice if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('BILLREC_UPDATE', $user); + $result = $this->call_trigger('SUPPLIERBILLREC_MODIFY', $user); if ($result < 0) { $this->db->rollback(); return -2; @@ -552,7 +553,7 @@ class FactureFournisseurRec extends CommonInvoice { $sql = 'SELECT f.rowid, f.titre, f.ref_supplier, f.entity, f.fk_soc'; $sql .= ', f.datec, f.tms, f.suspended'; - $sql .= ', f.libelle, f.amount, f.remise'; + $sql .= ', f.libelle as label'; $sql .= ', f.vat_src_code, f.localtax1, f.localtax2'; $sql .= ', f.total_tva, f.total_ht, f.total_ttc'; $sql .= ', f.fk_user_author, f.fk_user_modif'; @@ -581,17 +582,19 @@ class FactureFournisseurRec extends CommonInvoice if ($this->db->num_rows($result)) { $obj = $this->db->fetch_object($result); + $keyforref = $this->table_ref_field; + $this->id = $obj->rowid; $this->titre = $obj->titre; + $this->ref = $obj->$keyforref; $this->ref_supplier = $obj->ref_supplier; $this->entity = $obj->entity; $this->socid = $obj->fk_soc; $this->date_creation = $obj->datec; $this->date_modification = $obj->tms; $this->suspended = $obj->suspended; - $this->libelle = $obj->libelle; - $this->amount = $obj->amount; - $this->remise = $obj->remise; + $this->libelle = $obj->label; + $this->label = $obj->label; $this->vat_src_code = $obj->vat_src_code; $this->total_localtax1 = $obj->localtax1; $this->total_localtax2 = $obj->localtax2; @@ -615,19 +618,19 @@ class FactureFournisseurRec extends CommonInvoice $this->model_pdf = $obj->modelpdf; // Multicurrency - $this->fk_multicurrency = $obj->fk_multicurrency; + $this->fk_multicurrency = $obj->fk_multicurrency; $this->multicurrency_code = $obj->multicurrency_code; - $this->multicurrency_tx = $obj->multicurrency_tx; + $this->multicurrency_tx = $obj->multicurrency_tx; $this->multicurrency_total_ht = $obj->multicurrency_total_ht; - $this->multicurrency_total_tva = $obj->multicurrency_total_tva; - $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc; + $this->multicurrency_total_tva = $obj->multicurrency_total_tva; + $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc; - $this->usenewprice = $obj->usenewprice; - $this->frequency = $obj->frequency; + $this->usenewprice = $obj->usenewprice; + $this->frequency = $obj->frequency; $this->unit_frequency = $obj->unit_frequency; - $this->date_when = $this->db->jdate($obj->date_when); + $this->date_when = $this->db->jdate($obj->date_when); $this->date_last_gen = $this->db->jdate($obj->date_last_gen); - $this->nb_gen_done = $obj->nb_gen_done; + $this->nb_gen_done = $obj->nb_gen_done; $this->nb_gen_max = $obj->nb_gen_max; $this->auto_validate = $obj->auto_validate; $this->generate_pdf = $obj->generate_pdf; @@ -672,8 +675,7 @@ class FactureFournisseurRec extends CommonInvoice return $this->fetch_lines(); } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Get lines of template invoices into this->lines * @@ -681,18 +683,17 @@ class FactureFournisseurRec extends CommonInvoice */ public function fetch_lines() { - global $extrafields; - - // phpcs:enable + // phpcs:enable $this->lines = array(); // Retrieve all extrafield for line // fetch optionals attributes and labels - if (!is_object($extrafields)) { + /*if (!is_object($extrafields)) { require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); } $extrafields->fetch_name_optionals_label($this->table_element_line, true); + */ $sql = 'SELECT l.rowid,'; $sql .= ' l.fk_facture_fourn, l.fk_parent_line, l.fk_product, l.ref, l.label, l.description,'; @@ -710,12 +711,14 @@ class FactureFournisseurRec extends CommonInvoice $sql .= ' ORDER BY l.rang'; dol_syslog('FactureFournisseurRec::fetch_lines', LOG_DEBUG); + $result = $this->db->query($sql); if ($result) { $num = $this->db->num_rows($result); $i = 0; while ($i < $num) { $objp = $this->db->fetch_object($result); + $line = new FactureFournisseurLigneRec($this->db); $line->id = $objp->rowid; @@ -744,7 +747,7 @@ class FactureFournisseurRec extends CommonInvoice $line->product_type = $objp->product_type; $line->date_start = $objp->date_start; $line->date_end = $objp->date_end; - $line->info_bits = $objp->info_bits ; + $line->info_bits = $objp->info_bits ; $line->special_code = $objp->special_code; $line->rang = $objp->rang; $line->fk_unit = $objp->fk_unit; @@ -819,8 +822,15 @@ class FactureFournisseurRec extends CommonInvoice $this->error = $this->db->lasterror(); $error = -2; } - - if (!$error) { + if (!$error && !$notrigger) { + // Call trigger + $result = $this->call_trigger('SUPPLIERBILLREC_DELETE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + if (! $error) { $this->db->commit(); return 1; } else { @@ -1018,29 +1028,29 @@ class FactureFournisseurRec extends CommonInvoice } /** - * Update a line to supplier invoice template + * Update a line to supplier invoice template * - * @param $rowid ID - * @param int $fk_product Product/Service ID predefined - * @param $ref Ref - * @param string $label Label of the line - * @param string $desc Description de la ligne - * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) - * @param double $qty Quantity - * @param int $remise_percent Percentage discount of the line - * @param double $txtva Taux de tva force, sinon -1 - * @param int $txlocaltax1 Local tax 1 rate (deprecated) - * @param int $txlocaltax2 Local tax 2 rate (deprecated) - * @param string $price_base_type HT or TTC - * @param int $type Type of line (0=product, 1=service) - * @param int $date_start Date start - * @param int $date_end Date end - * @param int $info_bits Bits of type of lines - * @param int $special_code Special code - * @param int $rang Position of line - * @param string $fk_unit Unit - * @param int $pu_ht_devise Unit price in currency - * @return int <0 if KO, Id of line if OK + * @param int $rowid ID + * @param int $fk_product Product/Service ID predefined + * @param string $ref Ref + * @param string $label Label of the line + * @param string $desc Description de la ligne + * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) + * @param double $qty Quantity + * @param int $remise_percent Percentage discount of the line + * @param double $txtva Taux de tva force, sinon -1 + * @param int $txlocaltax1 Local tax 1 rate (deprecated) + * @param int $txlocaltax2 Local tax 2 rate (deprecated) + * @param string $price_base_type HT or TTC + * @param int $type Type of line (0=product, 1=service) + * @param int $date_start Date start + * @param int $date_end Date end + * @param int $info_bits Bits of type of lines + * @param int $special_code Special code + * @param int $rang Position of line + * @param string $fk_unit Unit + * @param int $pu_ht_devise Unit price in currency + * @return int <0 if KO, Id of line if OK * @throws Exception */ public function updateline($rowid, $fk_product, $ref, $label, $desc, $pu_ht, $qty, $remise_percent, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $type = 0, $date_start = 0, $date_end = 0, $info_bits = 0, $special_code = 0, $rang = -1, $fk_unit = null, $pu_ht_devise = 0) @@ -1126,28 +1136,28 @@ class FactureFournisseurRec extends CommonInvoice $sql .= ", ref = '" . $this->db->escape($ref) . "'"; $sql .= ", label = '" . $this->db->escape($label) . "'"; $sql .= ", description = '" . $this->db->escape($desc) . "'"; - $sql .= ', pu_ht=' . price2num($pu_ht); - $sql .= ', qty=' . price2num($qty); - $sql .= ", remise_percent='" . price2num($remise_percent) . "'"; - $sql .= ", vat_src_code='" . $this->db->escape($vat_src_code) . "'"; - $sql .= ', tva_tx=' . price2num($txtva); - $sql .= ', localtax1_tx=' . (float) $txlocaltax1; - $sql .= ", localtax1_type='" . $this->db->escape($localtaxes_type[0]) . "'"; - $sql .= ', localtax2_tx=' . (float) $txlocaltax2; - $sql .= ", localtax2_type='" . $this->db->escape($localtaxes_type[2]) . "'"; - $sql .= ", total_ht='" . price2num($total_ht) . "'"; - $sql .= ", total_tva='" . price2num($total_tva) . "'"; - $sql .= ", total_localtax1='" . price2num($total_localtax1) . "'"; - $sql .= ", total_localtax2='" . price2num($total_localtax2) . "'"; - $sql .= ", total_ttc='" . price2num($total_ttc) . "'"; - $sql .= ', product_type=' . (int) $product_type; - $sql .= ', date_start=' . (empty($date_start) ? 'NULL' : (int) $date_start); - $sql .= ', date_end=' . (empty($date_end) ? 'NULL' : (int) $date_end); - $sql .= ', info_bits=' . (int) $info_bits; - $sql .= ', special_code=' . (int) $special_code; - $sql .= ', rang=' . (int) $rang; - $sql .= ', fk_unit=' . ($fk_unit ? "'" . $this->db->escape($fk_unit) . "'" : 'null'); - $sql .= ', fk_user_modif=' . (int) $user; + $sql .= ', pu_ht = ' . price2num($pu_ht); + $sql .= ', qty = ' . price2num($qty); + $sql .= ", remise_percent = '" . price2num($remise_percent) . "'"; + $sql .= ", vat_src_code = '" . $this->db->escape($vat_src_code) . "'"; + $sql .= ', tva_tx = ' . price2num($txtva); + $sql .= ', localtax1_tx = ' . (float) $txlocaltax1; + $sql .= ", localtax1_type = '" . $this->db->escape($localtaxes_type[0]) . "'"; + $sql .= ', localtax2_tx = ' . (float) $txlocaltax2; + $sql .= ", localtax2_type = '" . $this->db->escape($localtaxes_type[2]) . "'"; + $sql .= ", total_ht = '" . price2num($total_ht) . "'"; + $sql .= ", total_tva = '" . price2num($total_tva) . "'"; + $sql .= ", total_localtax1 = '" . price2num($total_localtax1) . "'"; + $sql .= ", total_localtax2 = '" . price2num($total_localtax2) . "'"; + $sql .= ", total_ttc = '" . price2num($total_ttc) . "'"; + $sql .= ', product_type = ' . (int) $product_type; + $sql .= ', date_start = ' . (empty($date_start) ? 'NULL' : (int) $date_start); + $sql .= ', date_end = ' . (empty($date_end) ? 'NULL' : (int) $date_end); + $sql .= ', info_bits = ' . (int) $info_bits; + $sql .= ', special_code = ' . (int) $special_code; + $sql .= ', rang = ' . (int) $rang; + $sql .= ', fk_unit = ' . ($fk_unit ? "'" . $this->db->escape($fk_unit) . "'" : 'null'); + $sql .= ', fk_user_modif = ' . (int) $user; $sql .= ', multicurrency_subprice = '.price2num($pu_ht_devise); $sql .= ', multicurrency_total_ht = '.price2num($multicurrency_total_ht); $sql .= ', multicurrency_total_tva = '.price2num($multicurrency_total_tva); @@ -1453,7 +1463,7 @@ class FactureFournisseurRec extends CommonInvoice return $this->LibStatut($this->frequency ? 1 : 0, $this->suspended, $mode, $alreadypaid, empty($this->type) ? 0 : $this->type); } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Return label of a status * @@ -1466,7 +1476,7 @@ class FactureFournisseurRec extends CommonInvoice */ public function LibStatut($recur, $status, $mode = 0, $alreadypaid = -1, $type = 0) { - // phpcs:enable + // phpcs:enable global $langs; $langs->load('bills'); @@ -1753,14 +1763,15 @@ class FactureFournisseurRec extends CommonInvoice return -2; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET frequency = '.($frequency ? $this->db->escape($frequency) : 'null'); + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET frequency = ".($frequency ? ((int) $this->db->escape($frequency)) : "NULL"); if (!empty($unit)) { - $sql .= ', unit_frequency = '.$this->db->escape($unit); + $sql .= ", unit_frequency = '".$this->db->escape($unit)."'"; } - $sql .= ' WHERE rowid = ' . (int) $this->id; + $sql .= " WHERE rowid = ".((int) $this->id); + + dol_syslog(get_class($this).'::setFrequencyAndUnit', LOG_DEBUG); - dol_syslog(get_class($this). '::setFrequencyAndUnit', LOG_DEBUG); if ($this->db->query($sql)) { $this->frequency = $frequency; if (!empty($unit)) { @@ -1768,7 +1779,7 @@ class FactureFournisseurRec extends CommonInvoice } return 1; } else { - dol_print_error($this->db); + $this->error = $this->db->lasterror(); return -1; } } @@ -1783,17 +1794,18 @@ class FactureFournisseurRec extends CommonInvoice public function setNextDate($date, $increment_nb_gen_done = 0) { if (!$this->table_element) { - dol_syslog(get_class($this). '::setNextDate was called on objet with property table_element not defined', LOG_ERR); + dol_syslog(get_class($this).'::setNextDate was called on objet with property table_element not defined', LOG_ERR); return -1; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET date_when = ' .($date ? "'".$this->db->idate($date)."'" : 'null'); + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET date_when = " .($date ? "'".$this->db->idate($date)."'" : "NULL"); if ($increment_nb_gen_done > 0) { - $sql .= ', nb_gen_done = nb_gen_done + 1'; + $sql .= ", nb_gen_done = nb_gen_done + 1"; } - $sql .= ' WHERE rowid = ' . (int) $this->id; + $sql .= " WHERE rowid = " . (int) $this->id; + + dol_syslog(get_class($this).'::setNextDate', LOG_DEBUG); - dol_syslog(get_class($this). '::setNextDate', LOG_DEBUG); if ($this->db->query($sql)) { $this->date_when = $date; if ($increment_nb_gen_done > 0) { @@ -1801,7 +1813,7 @@ class FactureFournisseurRec extends CommonInvoice } return 1; } else { - dol_print_error($this->db); + $this->error = $this->db->lasterror(); return -1; } } @@ -1815,7 +1827,7 @@ class FactureFournisseurRec extends CommonInvoice public function setMaxPeriod($nb) { if (!$this->table_element) { - dol_syslog(get_class($this). '::setMaxPeriod was called on objet with property table_element not defined', LOG_ERR); + dol_syslog(get_class($this).'::setMaxPeriod was called on objet with property table_element not defined', LOG_ERR); return -1; } @@ -1823,11 +1835,12 @@ class FactureFournisseurRec extends CommonInvoice $nb = 0; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET nb_gen_max = '. (int) $nb; - $sql .= ' WHERE rowid = ' . (int) $this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET nb_gen_max = ". (int) $nb; + $sql .= " WHERE rowid = " . (int) $this->id; + + dol_syslog(get_class($this).'::setMaxPeriod', LOG_DEBUG); - dol_syslog(get_class($this). '::setMaxPeriod', LOG_DEBUG); if ($this->db->query($sql)) { $this->nb_gen_max = $nb; return 1; @@ -1846,15 +1859,16 @@ class FactureFournisseurRec extends CommonInvoice public function setAutoValidate($validate) { if (!$this->table_element) { - dol_syslog(get_class($this). '::setAutoValidate was called on objet with property table_element not defined', LOG_ERR); + dol_syslog(get_class($this).'::setAutoValidate was called on objet with property table_element not defined', LOG_ERR); return -1; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET auto_validate = '.((int) $validate); - $sql .= ' WHERE rowid = ' . (int) $this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET auto_validate = ".((int) $validate); + $sql .= " WHERE rowid = " . (int) $this->id; + + dol_syslog(get_class($this).'::setAutoValidate', LOG_DEBUG); - dol_syslog(get_class($this). '::setAutoValidate', LOG_DEBUG); if ($this->db->query($sql)) { $this->auto_validate = $validate; return 1; @@ -1873,15 +1887,16 @@ class FactureFournisseurRec extends CommonInvoice public function setGeneratePdf($validate) { if (!$this->table_element) { - dol_syslog(get_class($this). '::setGeneratePdf was called on objet with property table_element not defined', LOG_ERR); + dol_syslog(get_class($this).'::setGeneratePdf was called on objet with property table_element not defined', LOG_ERR); return -1; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' SET generate_pdf = '. (int) $validate; - $sql .= ' WHERE rowid = ' . (int) $this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET generate_pdf = ". (int) $validate; + $sql .= " WHERE rowid = " . (int) $this->id; + + dol_syslog(get_class($this).'::setGeneratePdf', LOG_DEBUG); - dol_syslog(get_class($this). '::setGeneratePdf', LOG_DEBUG); if ($this->db->query($sql)) { $this->generate_pdf = $validate; return 1; @@ -1900,15 +1915,16 @@ class FactureFournisseurRec extends CommonInvoice public function setModelPdf($model) { if (!$this->table_element) { - dol_syslog(get_class($this). '::setModelPdf was called on objet with property table_element not defined', LOG_ERR); + dol_syslog(get_class($this).'::setModelPdf was called on objet with property table_element not defined', LOG_ERR); return -1; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; $sql .= " SET modelpdf = '".$this->db->escape($model)."'"; - $sql .= ' WHERE rowid = ' . (int) $this->id; + $sql .= " WHERE rowid = " . (int) $this->id; + + dol_syslog(get_class($this).'::setModelPdf', LOG_DEBUG); - dol_syslog(get_class($this). '::setModelPdf', LOG_DEBUG); if ($this->db->query($sql)) { $this->model_pdf = $model; return 1; @@ -1999,7 +2015,7 @@ class FactureFournisseurLigneRec extends CommonObjectLine if (! $error) { if (! $notrigger) { // Call triggers - $result = $this->call_trigger('LINEBILLREC_DELETE', $user); + $result = $this->call_trigger('LINESUPPLIERBILLREC_DELETE', $user); if ($result < 0) { $error++; } // Do also here what you must do to rollback action if trigger fail @@ -2089,7 +2105,7 @@ class FactureFournisseurLigneRec extends CommonObjectLine $this->product_type = $objp->product_type; $this->date_start = $objp->date_start; $this->date_end = $objp->date_end; - $this->info_bits = $objp->info_bits ; + $this->info_bits = $objp->info_bits; $this->special_code = $objp->special_code; $this->rang = $objp->rang; $this->fk_unit = $objp->fk_unit; @@ -2131,8 +2147,8 @@ class FactureFournisseurLigneRec extends CommonObjectLine $sql .= ' fk_facture_fourn = ' . (int) $this->fk_facture_fourn; $sql .= ', fk_parent_line = ' . (int) $this->fk_parent; $sql .= ', fk_product = ' . (int) $this->fk_product; - $sql .= ', ref = ' . (! empty($this->ref) ? "'" . $this->db->escape($this->ref) . "'" : 'null'); - $sql .= ", label = " . (! empty($this->label) ? "'" . $this->db->escape($this->label) . "'" : 'null'); + $sql .= ', ref = ' . (! empty($this->ref) ? "'" . $this->db->escape($this->ref) . "'" : 'NULL'); + $sql .= ", label = " . (! empty($this->label) ? "'" . $this->db->escape($this->label) . "'" : 'NULL'); $sql .= ", description = '" . $this->db->escape($this->description) . "'"; $sql .= ', pu_ht = ' . price2num($this->pu_ht); $sql .= ', pu_ttc = ' . price2num($this->pu_ttc); @@ -2140,27 +2156,26 @@ class FactureFournisseurLigneRec extends CommonObjectLine $sql .= ", remise_percent = '" . price2num($this->remise_percent) . "'"; $sql .= ', fk_remise_except = ' . (int) $this->fk_remise_except; $sql .= ", vat_src_code = '" . $this->db->escape($this->vat_src_code) . "'"; - $sql .= ', tva_tx =' . price2num($this->tva_tx); + $sql .= ', tva_tx = ' . price2num($this->tva_tx); $sql .= ', localtax1_tx = ' . price2num($this->localtax1_tx); $sql .= ", localtax1_type = '" . $this->db->escape($this->localtax1_type) . "'"; $sql .= ', localtax2_tx = ' . price2num($this->localtax2_tx); $sql .= ", localtax2_type = '" . $this->db->escape($this->localtax2_type) . "'"; if (empty($this->skip_update_total)) { - $sql .= ', total_ht =' . price2num($this->total_ht); - $sql .= ', total_tva =' . price2num($this->total_tva); - $sql .= ', total_localtax1 =' . price2num($this->total_localtax1); - $sql .= ', total_localtax2 =' . price2num($this->total_localtax2); - $sql .= ', total_ttc =' . price2num($this->total_ttc); + $sql .= ', total_ht = ' . price2num($this->total_ht); + $sql .= ', total_tva = ' . price2num($this->total_tva); + $sql .= ', total_localtax1 = ' . price2num($this->total_localtax1); + $sql .= ', total_localtax2 = ' . price2num($this->total_localtax2); + $sql .= ', total_ttc = ' . price2num($this->total_ttc); } - $sql .= ', product_type =' . (int) $this->product_type; - $sql .= ', date_start =' . (int) $this->date_start; - $sql .= ', date_end =' . (int) $this->date_end; - $sql .= ", info_bits ='" . price2num($this->info_bits) . "'"; + $sql .= ', product_type = ' . (int) $this->product_type; + $sql .= ', date_start = ' . (int) $this->date_start; + $sql .= ', date_end = ' . (int) $this->date_end; + $sql .= ", info_bits = " . ((int) $this->info_bits); $sql .= ', special_code =' . (int) $this->special_code; - $sql .= ', rang =' . (int) $this->rang; - $sql .= ', fk_unit =' .($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : 'null'); - $sql .= ', fk_user_modif =' . (int) $user; - + $sql .= ', rang = ' . (int) $this->rang; + $sql .= ', fk_unit = ' .($this->fk_unit ? "'".$this->db->escape($this->fk_unit)."'" : 'null'); + $sql .= ', fk_user_modif = ' . (int) $user; $sql .= ' WHERE rowid = ' . (int) $this->id; $this->db->begin(); @@ -2177,7 +2192,7 @@ class FactureFournisseurLigneRec extends CommonObjectLine if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('LINESUPPLIERBILLREC_UPDATE', $user); + $result = $this->call_trigger('LINESUPPLIERBILLREC_MODIFY', $user); if ($result < 0) { $error++; } diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 922d9f25e29..94f66f0d0b3 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -9,10 +9,11 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2016 Marcos García * Copyright (C) 2015 Bahfir Abbes - * Copyright (C) 2015-2019 Ferran Marcet + * Copyright (C) 2015-2022 Ferran Marcet * Copyright (C) 2016-2021 Alexandre Spangaro * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2018-2022 Frédéric France + * Copyright (C) 2022 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -125,6 +126,13 @@ class FactureFournisseur extends CommonInvoice */ public $statut; + /** + * Supplier invoice status + * @var int + * @see FactureFournisseur::STATUS_DRAFT, FactureFournisseur::STATUS_VALIDATED, FactureFournisseur::STATUS_PAID, FactureFournisseur::STATUS_ABANDONED + */ + public $status; + /** * ! Closing after partial payment: discount_vat, badsupplier, abandon * ! Closing when no payment: replaced, abandoned @@ -174,7 +182,15 @@ class FactureFournisseur extends CommonInvoice */ public $date_echeance; + /** + * @var double $amount + * @deprecated + */ public $amount = 0; + /** + * @var double $remise + * @deprecated + */ public $remise = 0; /** @@ -245,7 +261,7 @@ class FactureFournisseur extends CommonInvoice public $multicurrency_total_ht; public $multicurrency_total_tva; public $multicurrency_total_ttc; - //! id of source var_dump($$this);invoice if replacement invoice or credit note + //! id of source invoice if replacement invoice or credit note /** * @var int ID */ @@ -393,11 +409,6 @@ class FactureFournisseur extends CommonInvoice $this->date = $now; } - $socid = $this->socid; - $ref_supplier = $this->ref_supplier; - $amount = $this->amount; - $remise = $this->remise; - // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate) if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) { list($this->fk_multicurrency, $this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $this->date); @@ -445,7 +456,6 @@ class FactureFournisseur extends CommonInvoice $this->total_ttc = $_facrec->total_ttc; // Fields always coming from template - $this->remise = $_facrec->remise; $this->fk_incoterms = $_facrec->fk_incoterms; $this->location_incoterms = $_facrec->location_incoterms; @@ -464,7 +474,6 @@ class FactureFournisseur extends CommonInvoice $this->array_options = $_facrec->array_options; - //if (! $this->remise) $this->remise = 0; if (! $this->mode_reglement_id) { $this->mode_reglement_id = 0; } @@ -534,10 +543,6 @@ class FactureFournisseur extends CommonInvoice $this->date_echeance = $forceduedate; } - if (!$remise) { - $remise = 0; - } - $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture_fourn ("; $sql .= "ref"; $sql .= ", ref_supplier"; @@ -871,8 +876,6 @@ class FactureFournisseur extends CommonInvoice $sql .= " t.tms,"; $sql .= " t.libelle as label,"; $sql .= " t.paye,"; - $sql .= " t.amount,"; - $sql .= " t.remise,"; $sql .= " t.close_code,"; $sql .= " t.close_note,"; $sql .= " t.tva,"; @@ -881,7 +884,7 @@ class FactureFournisseur extends CommonInvoice $sql .= " t.total_ht,"; $sql .= " t.total_tva,"; $sql .= " t.total_ttc,"; - $sql .= " t.fk_statut,"; + $sql .= " t.fk_statut as status,"; $sql .= " t.fk_user_author,"; $sql .= " t.fk_user_valid,"; $sql .= " t.fk_facture_source,"; @@ -937,18 +940,16 @@ class FactureFournisseur extends CommonInvoice $this->label = $obj->label; $this->paye = $obj->paye; $this->paid = $obj->paye; - $this->amount = $obj->amount; - $this->remise = $obj->remise; $this->close_code = $obj->close_code; $this->close_note = $obj->close_note; - //$this->tva = $obj->tva; $this->total_localtax1 = $obj->localtax1; $this->total_localtax2 = $obj->localtax2; $this->total_ht = $obj->total_ht; $this->total_tva = $obj->total_tva; $this->total_ttc = $obj->total_ttc; - $this->fk_statut = $obj->fk_statut; - $this->statut = $obj->fk_statut; + $this->status = $obj->status; + $this->statut = $obj->status; // For backward compatibility + $this->fk_statut = $obj->status; // For backward compatibility $this->fk_user_author = $obj->fk_user_author; $this->author = $obj->fk_user_author; $this->fk_user_valid = $obj->fk_user_valid; @@ -1041,6 +1042,7 @@ class FactureFournisseur extends CommonInvoice $sql .= ' ORDER BY f.rang, f.rowid'; dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); + $resql_rows = $this->db->query($sql); if ($resql_rows) { $num_rows = $this->db->num_rows($resql_rows); @@ -1164,21 +1166,12 @@ class FactureFournisseur extends CommonInvoice if (isset($this->paye)) { $this->paye = trim($this->paye); } - if (isset($this->amount)) { - $this->amount = trim($this->amount); - } - if (isset($this->remise)) { - $this->remise = trim($this->remise); - } if (isset($this->close_code)) { $this->close_code = trim($this->close_code); } if (isset($this->close_note)) { $this->close_note = trim($this->close_note); } - /*if (isset($this->tva)) { - $this->tva = trim($this->tva); - }*/ if (isset($this->localtax1)) { $this->localtax1 = trim($this->localtax1); } @@ -1199,6 +1192,9 @@ class FactureFournisseur extends CommonInvoice if (isset($this->statut)) { $this->statut = (int) $this->statut; } + if (isset($this->status)) { + $this->status = (int) $this->status; + } if (isset($this->author)) { $this->author = trim($this->author); } @@ -1209,7 +1205,8 @@ class FactureFournisseur extends CommonInvoice $this->fk_facture_source = trim($this->fk_facture_source); } if (isset($this->fk_project)) { - $this->fk_project = trim($this->fk_project); + if (empty($this->fk_project)) $this->fk_project = null; + else $this->fk_project = intval($this->fk_project); } if (isset($this->cond_reglement_id)) { $this->cond_reglement_id = trim($this->cond_reglement_id); @@ -1246,8 +1243,6 @@ class FactureFournisseur extends CommonInvoice } $sql .= " libelle=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; $sql .= " paye=".(isset($this->paye) ? $this->paye : "null").","; - $sql .= " amount=".(isset($this->amount) ? $this->amount : "null").","; - $sql .= " remise=".(isset($this->remise) ? $this->remise : "null").","; $sql .= " close_code=".(isset($this->close_code) ? "'".$this->db->escape($this->close_code)."'" : "null").","; $sql .= " close_note=".(isset($this->close_note) ? "'".$this->db->escape($this->close_note)."'" : "null").","; //$sql .= " tva=".(isset($this->tva) ? $this->tva : "null").","; @@ -1256,7 +1251,7 @@ class FactureFournisseur extends CommonInvoice $sql .= " total_ht=".(isset($this->total_ht) ? $this->total_ht : "null").","; $sql .= " total_tva=".(isset($this->total_tva) ? $this->total_tva : "null").","; $sql .= " total_ttc=".(isset($this->total_ttc) ? $this->total_ttc : "null").","; - $sql .= " fk_statut=".(isset($this->statut) ? $this->statut : "null").","; + $sql .= " fk_statut=".(isset($this->status) ? $this->status : (isset($this->statut) ? $this->statut : "null")).","; $sql .= " fk_user_author=".(isset($this->author) ? $this->author : "null").","; $sql .= " fk_user_valid=".(isset($this->fk_user_valid) ? $this->fk_user_valid : "null").","; $sql .= " fk_facture_source=".(isset($this->fk_facture_source) ? $this->fk_facture_source : "null").","; @@ -1294,7 +1289,7 @@ class FactureFournisseur extends CommonInvoice if (!$error) { if (!$notrigger) { // Call trigger - $result = $this->call_trigger('BILL_SUPPLIER_UPDATE', $user); + $result = $this->call_trigger('BILL_SUPPLIER_MODIFY', $user); if ($result < 0) { $error++; } @@ -1326,7 +1321,7 @@ class FactureFournisseur extends CommonInvoice public function insert_discount($idremise) { // phpcs:enable - global $langs; + global $conf, $langs; include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; @@ -1357,6 +1352,14 @@ class FactureFournisseur extends CommonInvoice $facligne->rang = -1; $facligne->info_bits = 2; + if (!empty($conf->global->MAIN_ADD_LINE_AT_POSITION)) { + $facligne->rang = 1; + $linecount = count($this->lines); + for ($ii = 1; $ii <= $linecount; $ii++) { + $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii+1); + } + } + // Get buy/cost price of invoice that is source of discount if ($remise->fk_invoice_supplier_source > 0) { $srcinvoice = new FactureFournisseur($this->db); @@ -1818,6 +1821,7 @@ class FactureFournisseur extends CommonInvoice $this->line = $this->lines[$i]; $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; + $mouvP->setOrigin($this->element, $this->id); // We increase stock for product $up_ht_disc = $this->lines[$i]->pu_ht; if (!empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) { @@ -1947,6 +1951,7 @@ class FactureFournisseur extends CommonInvoice if ($this->lines[$i]->fk_product > 0) { $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; + $mouvP->setOrigin($this->element, $this->id); // We increase stock for product if ($this->type == FactureFournisseur::TYPE_CREDIT_NOTE) { $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref)); @@ -2222,6 +2227,11 @@ class FactureFournisseur extends CommonInvoice // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); + } elseif ($rang > 0 && $rang <= count($this->lines)) { // Update all rank of all other lines + $linecount = count($this->lines); + for ($ii = $rang; $ii <= $linecount; $ii++) { + $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii + 1); + } } // Mise a jour informations denormalisees au niveau de la facture meme @@ -2432,7 +2442,7 @@ class FactureFournisseur extends CommonInvoice $this->db->begin(); - // Libere remise liee a ligne de facture + // Free the discount linked to a line of invoice $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; $sql .= ' SET fk_invoice_supplier_line = NULL'; $sql .= ' WHERE fk_invoice_supplier_line = '.((int) $rowid); @@ -2631,7 +2641,7 @@ class FactureFournisseur extends CommonInvoice // phpcs:enable global $conf, $langs; - $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut'; + $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut as status, ff.total_ht, ff.total_ttc'; $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as ff'; if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ff.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); @@ -2653,14 +2663,15 @@ class FactureFournisseur extends CommonInvoice $response->label = $langs->trans("SupplierBillsToPay"); $response->labelShort = $langs->trans("StatusToPay"); - $response->url = DOL_URL_ROOT.'/fourn/facture/list.php?search_status=1&mainmenu=billing&leftmenu=suppliers_bills'; + $response->url = DOL_URL_ROOT.'/fourn/facture/list.php?search_status=1&mainmenu=billing&leftmenu=suppliers_bills'; $response->img = img_object($langs->trans("Bills"), "bill"); $facturestatic = new FactureFournisseur($this->db); while ($obj = $this->db->fetch_object($resql)) { $facturestatic->date_echeance = $this->db->jdate($obj->datefin); - $facturestatic->statut = $obj->fk_statut; + $facturestatic->statut = $obj->status; // For backward compatibility + $facturestatic->status = $obj->status; $response->nbtodo++; $response->total += $obj->total_ht; @@ -3037,7 +3048,8 @@ class FactureFournisseur extends CommonInvoice // Load source object $object->fetch($fromid); $object->id = 0; - $object->statut = self::STATUS_DRAFT; + $object->statut = self::STATUS_DRAFT; // For backward compatibility + $object->status = self::STATUS_DRAFT; $object->fetch_thirdparty(); // We need it to recalculate VAT localtaxes according to main sale taxes and vendor @@ -3155,6 +3167,23 @@ class FactureFournisseur extends CommonInvoice return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'facture_fourn_det' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Is the payment of the supplier invoice having a delay? * @@ -3170,7 +3199,9 @@ class FactureFournisseur extends CommonInvoice return false; } - return ($this->statut == self::STATUS_VALIDATED) && ($this->date_echeance < ($now - $conf->facture->fournisseur->warning_delay)); + $status = isset($this->status) ? $this->status : $this->statut; + + return ($status == self::STATUS_VALIDATED) && ($this->date_echeance < ($now - $conf->facture->fournisseur->warning_delay)); } /** @@ -3686,7 +3717,7 @@ class SupplierInvoiceLine extends CommonObjectLine global $langs, $user; // Call trigger - if ($this->call_trigger('LINEBILL_SUPPLIER_UPDATE', $user) < 0) { + if ($this->call_trigger('LINEBILL_SUPPLIER_MODIFY', $user) < 0) { $this->db->rollback(); return -1; } diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index cb9416e3da2..55aabde8141 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -317,7 +317,9 @@ class ProductFournisseur extends Product $qty = price2num($qty, 'MS'); $unitBuyPrice = price2num($buyprice / $qty, 'MU'); - $packaging = price2num(((empty($this->packaging) || $this->packaging < $qty) ? $qty : $this->packaging), 'MS'); + // We can have a puchase ref that need to buy 100 min for a given price and with a packaging of 50. + //$packaging = price2num(((empty($this->packaging) || $this->packaging < $qty) ? $qty : $this->packaging), 'MS'); + $packaging = price2num((empty($this->packaging) ? $qty : $this->packaging), 'MS'); $error = 0; $now = dol_now(); @@ -405,13 +407,14 @@ class ProductFournisseur extends Product $sql .= ", packaging = ".(empty($packaging) ? 1 : $packaging); } $sql .= " WHERE rowid = ".((int) $this->product_fourn_price_id); + //print $sql;exit; // TODO Add price_base_type and price_ttc dol_syslog(get_class($this).'::update_buyprice update knowing id of line = product_fourn_price_id = '.$this->product_fourn_price_id, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { // Call trigger - $result = $this->call_trigger('SUPPLIER_PRODUCT_BUYPRICE_UPDATE', $user); + $result = $this->call_trigger('SUPPLIER_PRODUCT_BUYPRICE_MODIFY', $user); if ($result < 0) { $error++; } @@ -593,13 +596,7 @@ class ProductFournisseur extends Product $this->supplier_barcode = $obj->barcode; $this->supplier_fk_barcode_type = $obj->fk_barcode_type; } - - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $this->packaging = $obj->packaging; - if ($this->packaging < $this->fourn_qty) { - $this->packaging = $this->fourn_qty; - } - } + $this->packaging = $obj->packaging; if (empty($ignore_expression) && !empty($this->fk_supplier_price_expression)) { $priceparser = new PriceParser($this->db); @@ -647,10 +644,7 @@ class ProductFournisseur extends Product $sql .= " pfp.rowid as product_fourn_pri_id, pfp.entity, pfp.ref_fourn, pfp.desc_fourn, pfp.fk_product as product_fourn_id, pfp.fk_supplier_price_expression,"; $sql .= " pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability, pfp.charges, pfp.info_bits, pfp.delivery_time_days, pfp.supplier_reputation,"; $sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code, pfp.datec, pfp.tms,"; - $sql .= " pfp.barcode, pfp.fk_barcode_type"; - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= ", pfp.packaging"; - } + $sql .= " pfp.barcode, pfp.fk_barcode_type, pfp.packaging"; $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."societe as s"; $sql .= " WHERE pfp.entity IN (".getEntity('productsupplierprice').")"; $sql .= " AND pfp.fk_soc = s.rowid AND pfp.fk_product = p.rowid"; @@ -704,12 +698,7 @@ class ProductFournisseur extends Product $prodfourn->fourn_multicurrency_id = $record["fk_multicurrency"]; $prodfourn->fourn_multicurrency_code = $record["multicurrency_code"]; - if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $prodfourn->packaging = $record["packaging"]; - if ($prodfourn->packaging < $prodfourn->fourn_qty) { - $prodfourn->packaging = $prodfourn->fourn_qty; - } - } + $prodfourn->packaging = $record["packaging"]; if (!empty($conf->barcode->enabled)) { $prodfourn->supplier_barcode = $record["barcode"]; @@ -983,6 +972,23 @@ class ProductFournisseur extends Product return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'product_fournisseur_price' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * List supplier prices log of a supplier price * diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index 75984c94f99..b85b373f81f 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -596,6 +596,10 @@ class PaiementFourn extends Paiement { global $langs, $conf, $hookmanager; + if (!empty($conf->dol_no_mouse_hover)) { + $notooltip = 1; // Force disable tooltips + } + $result = ''; $text = $this->ref; // Sometimes ref contains label @@ -610,8 +614,12 @@ class PaiementFourn extends Paiement $label = img_picto('', $this->picto).' '.$langs->trans("Payment").'
    '; $label .= ''.$langs->trans("Ref").': '.$text; - if ($this->datepaye ? $this->datepaye : $this->date) { - $label .= '
    '.$langs->trans("Date").': '.dol_print_date($this->datepaye ? $this->datepaye : $this->date, 'dayhour', 'tzuser'); + $dateofpayment = ($this->datepaye ? $this->datepaye : $this->date); + if ($dateofpayment) { + $label .= '
    '.$langs->trans("Date").': '.dol_print_date($dateofpayment, 'dayhour', 'tzuser'); + } + if ($this->amount) { + $label .= '
    '.$langs->trans("Amount").': '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency); } $linkclose = ''; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index c7a937518d7..a945a03b85d 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -9,6 +9,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2014 Ion Agorria * Copyright (C) 2018-2019 Frédéric France + * Copyright (C) 2022 Gauthier VERDOL * Copyright (C) 2022 Charlene Benke * * This program is free software; you can redistribute it and/or modify @@ -78,6 +79,7 @@ $cancel = GETPOST('cancel', 'alpha'); $lineid = GETPOST('lineid', 'int'); $origin = GETPOST('origin', 'alpha'); $originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility +$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1; //PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -412,10 +414,9 @@ if (empty($reshook)) { // Set if we used free entry or predefined product $predef = ''; $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); - $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); - $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); $date_start = dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); $date_end = dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); + $prod_entry_mode = GETPOST('prod_entry_mode'); if ($prod_entry_mode == 'free') { $idprod = 0; @@ -425,6 +426,8 @@ if (empty($reshook)) { $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)' + $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); + $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS'); @@ -461,7 +464,7 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors'); $error++; } - if (GETPOST('qty', 'int') == '') { + if (GETPOST('qty', 'alpha') == '') { // 0 is allowed for order setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); $error++; } @@ -506,13 +509,14 @@ if (empty($reshook)) { } } elseif (GETPOST('idprodfournprice', 'alpha') > 0) { $qtytosearch = $qty; // Just to see if a price exists for the quantity. Not used to found vat. - //$qtytosearch=-1; // We force qty to -1 to be sure to find if a supplier price exist + //$qtytosearch = -1; // We force qty to -1 to be sure to find if a supplier price exist $idprod = $productsupplier->get_buyprice(GETPOST('idprodfournprice', 'alpha'), $qtytosearch); $res = $productsupplier->fetch($idprod); } if ($idprod > 0) { $label = $productsupplier->label; + // Define output language if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { $outputlangs = $langs; @@ -550,41 +554,44 @@ if (empty($reshook)) { $ref_supplier = $productsupplier->ref_supplier; - $type = $productsupplier->type; - if (GETPOST('price_ht') != '' || GETPOST('price_ht_devise') != '') { - $price_base_type = 'HT'; - $pu = price2num($price_ht, 'MU'); - $pu_ht_devise = price2num($price_ht_devise, 'CU'); - } elseif (GETPOST('price_ttc') != '' || GETPOST('price_ttc_devise') != '') { - $price_base_type = 'TTC'; - $pu = price2num($price_ttc, 'MU'); - $pu_ht_devise = price2num($price_ttc_devise, 'CU'); - } else { - $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT'); - if (empty($object->multicurrency_code) || ($productsupplier->fourn_multicurrency_code != $object->multicurrency_code)) { // If object is in a different currency and price not in this currency - $pu = $productsupplier->fourn_pu; - $pu_ht_devise = 0; - } else { - $pu = $productsupplier->fourn_pu; - $pu_ht_devise = $productsupplier->fourn_multicurrency_unitprice; - } + // Get vat rate + if (!GETPOSTISSET('tva_tx')) { // If vat rate not provided from the form (the form has the priority) + $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha')); + $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha')); } - - $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha')); - $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha')); if (empty($tva_tx)) { $tva_npr = 0; } $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr); $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr); + $type = $productsupplier->type; + if (GETPOST('price_ht') != '' || GETPOST('price_ht_devise') != '') { + $price_base_type = 'HT'; + $pu = price2num($price_ht, 'MU'); + $pu_devise = price2num($price_ht_devise, 'CU'); + } elseif (GETPOST('price_ttc') != '' || GETPOST('price_ttc_devise') != '') { + $price_base_type = 'TTC'; + $pu = price2num($price_ttc, 'MU'); + $pu_devise = price2num($price_ttc_devise, 'CU'); + } else { + $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT'); + if (empty($object->multicurrency_code) || ($productsupplier->fourn_multicurrency_code != $object->multicurrency_code)) { // If object is in a different currency and price not in this currency + $pu = $productsupplier->fourn_pu; + $pu_devise = 0; + } else { + $pu = $productsupplier->fourn_pu; + $pu_devise = $productsupplier->fourn_multicurrency_unitprice; + } + } + if (empty($pu)) { $pu = 0; // If pu is '' or null, we force to have a numeric value } $result = $object->addline( $desc, - $pu, + ($price_base_type == 'HT' ? $pu : 0), $qty, $tva_tx, $localtax1_tx, @@ -594,7 +601,7 @@ if (empty($reshook)) { $ref_supplier, $remise_percent, $price_base_type, - $pu_ttc, + ($price_base_type == 'TTC' ? $pu : 0), $type, $tva_npr, '', @@ -602,9 +609,10 @@ if (empty($reshook)) { $date_end, $array_options, $productsupplier->fk_unit, - $pu_ht_devise, + $pu_devise, '', - 0 + 0, + min($rank, count($object->lines) + 1) ); } if ($idprod == -99 || $idprod == 0) { @@ -645,7 +653,7 @@ if (empty($reshook)) { } $price_base_type = 'HT'; $pu_ht_devise = price2num($price_ht_devise, 'CU'); - // var_dump($pu_ht.' '.$tva_tx.' '.$pu_ttc.' '.$price_base_type.' '.$pu_ht_devise); exit; + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, $ref_supplier, $remise_percent, $price_base_type, $pu_ttc, $type, '', '', $date_start, $date_end, $array_options, $fk_unit, $pu_ht_devise); } @@ -759,6 +767,7 @@ if (empty($reshook)) { $price_base_type = 'HT'; $ht = price2num(GETPOST('price_ht'), '', 2); } else { + $reg = array(); $vatratecleaned = $vat_rate; if (preg_match('/^(.*)\s*\((.*)\)$/', $vat_rate, $reg)) { // If vat is "xx (yy)" $vatratecleaned = trim($reg[1]); @@ -770,7 +779,7 @@ if (empty($reshook)) { $price_base_type = 'HT'; } - $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2); + $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), 'CU', 2); // Extrafields Lines $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line); @@ -1834,11 +1843,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
    '; print ''; $objectsrc->printOriginLinesList('', $selectedLines); print '
    '; + print '
    '; } print "\n"; } elseif (!empty($object->id)) { diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index ca9bd1b3065..166da07ab03 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -6,7 +6,7 @@ * Copyright (C) 2010-2021 Juanjo Menent * Copyright (C) 2014 Cedric Gross * Copyright (C) 2016 Florian Henry - * Copyright (C) 2017-2020 Ferran Marcet + * Copyright (C) 2017-2022 Ferran Marcet * Copyright (C) 2018 Frédéric France * Copyright (C) 2019-2020 Christophe Battarel * @@ -337,7 +337,7 @@ if ($action == 'dispatch' && $permissiontoreceive) { } if (!$error) { - $result = $object->dispatchProduct($user, GETPOST($prod, 'int'), GETPOST($qty), GETPOST($ent, 'int'), GETPOST($pu), GETPOST('comment'), $dDLC, $dDLUO, GETPOST($lot, 'alpha'), GETPOST($fk_commandefourndet, 'int'), $notrigger); + $result = $object->dispatchProduct($user, GETPOST($prod, 'int'), GETPOST($qty), GETPOST($ent, 'int'), GETPOST($pu), GETPOST('comment'), $dDLUO, $dDLC, GETPOST($lot, 'alpha'), GETPOST($fk_commandefourndet, 'int'), $notrigger); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; @@ -373,7 +373,7 @@ if ($action == 'dispatch' && $permissiontoreceive) { } } - if (!$notrigger && !$error) { + if (!$error) { global $conf, $langs, $user; // Call trigger @@ -423,6 +423,7 @@ if ($action == 'confirm_deleteline' && $confirm == 'yes' && $permissiontoreceive $mouv = new MouvementStock($db); if ($product > 0) { $mouv->origin = &$object; + $mouv->setOrigin($object->element, $object->id); $result = $mouv->livraison($user, $product, $entrepot, $qty, $price, $comment, '', $eatby, $sellby, $batch); if ($result < 0) { $errors = $mouv->errors; @@ -469,6 +470,7 @@ if ($action == 'updateline' && $permissiontoreceive) { $mouv = new MouvementStock($db); if ($product > 0) { $mouv->origin = &$object; + $mouv->setOrigin($object->element, $object->id); $result = $mouv->livraison($user, $product, $entrepot, $qty, $price, $comment, '', $eatby, $sellby, $batch); if ($result < 0) { $errors = $mouv->errors; @@ -682,7 +684,8 @@ if ($id > 0 || !empty($ref)) { $db->free($resql); } - $sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,"; + //$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,"; + $sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, l.qty as qty,"; $sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse"; // Enable hooks to alter the SQL query (SELECT) @@ -718,8 +721,8 @@ if ($id > 0 || !empty($ref)) { } $sql .= $hookmanager->resPrint; - $sql .= " GROUP BY p.ref, p.label, p.tobatch, p.fk_default_warehouse, l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref"; // Calculation of amount dispatched is done per fk_product so we must group by fk_product - $sql .= " ORDER BY p.ref, p.label"; + //$sql .= " GROUP BY p.ref, p.label, p.tobatch, p.fk_default_warehouse, l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref"; // Calculation of amount dispatched is done per fk_product so we must group by fk_product + $sql .= " ORDER BY l.rang, p.ref, p.label"; $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index e5cc12fe1c4..3ddb1350a8b 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -162,49 +162,45 @@ $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); // List of fields to search into when doing a "search in all" -$fieldstosearchall = array( - 'cf.ref'=>'Ref', - 'cf.ref_supplier'=>'RefOrderSupplier', - 'pd.description'=>'Description', - 's.nom'=>"ThirdParty", - 's.name_alias'=>"AliasNameShort", - 's.zip'=>"Zip", - 's.town'=>"Town", - 'cf.note_public'=>'NotePublic', -); +$fieldstosearchall = array(); +foreach ($object->fields as $key => $val) { + if (!empty($val['searchall'])) { + $fieldstosearchall['cf.'.$key] = $val['label']; + } +} +$fieldstosearchall['pd.description'] = 'Description'; +$fieldstosearchall['s.nom'] = "ThirdParty"; +$fieldstosearchall['s.name_alias'] = "AliasNameShort"; +$fieldstosearchall['s.zip'] = "Zip"; +$fieldstosearchall['s.town'] = "Town"; if (empty($user->socid)) { $fieldstosearchall["cf.note_private"] = "NotePrivate"; } $checkedtypetiers = 0; + +// Definition of array of fields for columns $arrayfields = array( - 'cf.ref'=>array('label'=>"Ref", 'checked'=>1), - 'cf.ref_supplier'=>array('label'=>"RefOrderSupplierShort", 'checked'=>1, 'enabled'=>1), - 'p.project_ref'=>array('label'=>"ProjectRef", 'checked'=>0, 'enabled'=>1), - 'u.login'=>array('label'=>"AuthorRequest", 'checked'=>1), - 's.nom'=>array('label'=>"ThirdParty", 'checked'=>1), - 's.town'=>array('label'=>"Town", 'checked'=>1), - 's.zip'=>array('label'=>"Zip", 'checked'=>1), - 'state.nom'=>array('label'=>"StateShort", 'checked'=>0), - 'country.code_iso'=>array('label'=>"Country", 'checked'=>0), - 'typent.code'=>array('label'=>"ThirdPartyType", 'checked'=>$checkedtypetiers), - 'cf.date_commande'=>array('label'=>"OrderDateShort", 'checked'=>1), - 'cf.date_livraison'=>array('label'=>"DateDeliveryPlanned", 'checked'=>1, 'enabled'=>empty($conf->global->ORDER_DISABLE_DELIVERY_DATE)), - 'cf.total_ht'=>array('label'=>"AmountHT", 'checked'=>1), - 'cf.total_tva'=>array('label'=>"AmountVAT", 'checked'=>0), - 'cf.total_ttc'=>array('label'=>"AmountTTC", 'checked'=>0), - 'cf.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), - 'cf.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), - 'cf.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), - 'cf.multicurrency_total_tva'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), - 'cf.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), - 'cf.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), - 'cf.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), - 'cf.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), - 'cf.billed'=>array('label'=>"Billed", 'checked'=>1, 'position'=>1000, 'enabled'=>1), - 'cf.date_valid' =>array('label' => 'DateValidation', 'checked' => 0), - 'cf.date_approve' =>array('label' => 'DateApprove', 'checked' => 0) + 's.town'=>array('label'=>"Town", 'enabled'=>1, 'position'=>47, 'checked'=>1), + 's.zip'=>array('label'=>"Zip", 'enabled'=>1, 'position'=>47, 'checked'=>1), + 'state.nom'=>array('label'=>"StateShort", 'enabled'=>1, 'position'=>48), + 'country.code_iso'=>array('label'=>"Country", 'enabled'=>1, 'position'=>49), + 'typent.code'=>array('label'=>"ThirdPartyType", 'enabled'=>$checkedtypetiers, 'position'=>50), + 'u.login'=>array('label'=>"AuthorRequest", 'enabled'=>1, 'position'=>51) ); +foreach ($object->fields as $key => $val) { + // If $val['visible']==0, then we never show the field + if (!empty($val['visible'])) { + $visible = (int) dol_eval($val['visible'], 1); + $arrayfields['cf.'.$key] = array( + 'label'=>$val['label'], + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>(abs($visible) != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' + ); + } +} // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; @@ -359,6 +355,8 @@ if (empty($reshook)) { $db->begin(); + $default_ref_supplier=dol_print_date(dol_now(), '%Y%m%d%H%M%S'); + foreach ($orders as $id_order) { $cmd = new CommandeFournisseur($db); if ($cmd->fetch($id_order) <= 0) { @@ -375,9 +373,8 @@ if (empty($reshook)) { $objecttmp->mode_reglement_id = $cmd->mode_reglement_id; $objecttmp->fk_project = $cmd->fk_project; $objecttmp->multicurrency_code = $cmd->multicurrency_code; - if (empty($createbills_onebythird)) { - $objecttmp->ref_client = $cmd->ref_client; - } + $objecttmp->ref_supplier = !empty($cmd->ref_supplier) ? $cmd->ref_supplier : $default_ref_supplier; + $default_ref_supplier+=1; $datefacture = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); if (empty($datefacture)) { @@ -1262,7 +1259,7 @@ if ($resql) { print '
    '; print ''; $thirdpartytmp->id = $obj->socid; $thirdpartytmp->name = $obj->name; @@ -1783,7 +1780,7 @@ if ($resql) { $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation - if (!empty($arrayfields['cf.datec']['checked'])) { + if (!empty($arrayfields['cf.date_creation']['checked'])) { print ''; print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser'); print '
    '.$langs->trans('Supplier').''; - if ($societe->id > 0 && (!GETPOST('fac_rec', 'int') || !empty($invoice_predefined->frequency))) { + if ($societe->id > 0 && ($fac_recid <= 0 || !empty($invoice_predefined->frequency))) { $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1); print $societe->getNomUrl(1, 'supplier'); print ''; @@ -2035,15 +2048,15 @@ if ($action == 'create') { }); '; } - if (!GETPOST('fac_rec', 'int')) { + if ($fac_recid <= 0) { print ' '; } } print '
    '.$langs->trans('CreateFromRepeatableInvoice').''; - //print ''; + //print ''; print '
    '.$langs->trans('Project').''; print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); - print ' id.($fac_rec ? '&fac_rec='.$fac_rec : '')).'">'; + print ' id.($fac_recid > 0 ? '&fac_rec='.$fac_recid : '')).'">'; print '
    '; $objectsrc->printOriginLinesList('', $selectedLines); print '
    '; + print '
    '; } print "\n"; @@ -3164,7 +3179,7 @@ if ($action == 'create') { // Amount print ''.$langs->trans('AmountHT').''.price($object->total_ht, 1, $langs, 0, -1, -1, $conf->currency).''; - print ''.$langs->trans('AmountVAT').''.price($object->total_tva, 1, $langs, 0, -1, -1, $conf->currency).'
            '; + print ''.$langs->trans('AmountVAT').''.price($object->total_tva, 1, $langs, 0, -1, -1, $conf->currency); if (GETPOST('calculationrule')) { $calculationrule = GETPOST('calculationrule', 'alpha'); } else { @@ -3177,13 +3192,16 @@ if ($action == 'create') { } // Show link for "recalculate" if ($object->getVentilExportCompta() == 0) { - $s = $langs->trans("ReCalculate").' '; + $s = ''.$langs->trans("ReCalculate").' '; $s .= ''.$langs->trans("Mode1").''; $s .= ' / '; $s .= ''.$langs->trans("Mode2").''; - print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc", $calculationrulenum).'
    '.$langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('', 'help')); + print '
    '; + print '         '; + print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc", $calculationrulenum).'
    '.$langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('', 'help'), '', 3, '', 0, 'recalculate'); + print '
    '; } - print '
    '; + print ''; // Amount Local Taxes //TODO: Place into a function to control showing by country or study better option @@ -3552,7 +3570,7 @@ if ($action == 'create') { } print '
    '; - print ''; + print '
    '; global $forceall, $senderissupplier, $dateSelector, $inputalsopricewithtax; $forceall = 1; $dateSelector = 0; $inputalsopricewithtax = 1; diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index 4b6e5bf151c..2662e38951d 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -499,7 +499,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie if (!empty($conf->banque->enabled)) { print ''; } else { print ''; diff --git a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php index 3f728d99567..e9ec8accf30 100644 --- a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php @@ -25,7 +25,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 1f421230bbb..3c2c864346a 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -344,7 +344,7 @@ if ($result > 0) { // Send by mail if ($user->socid == 0 && $action == '') { - $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS)); + $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->supplier_invoice_advance->send))); if ($usercansend) { print ''.$langs->trans('SendMail').''; } else { diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 6ea0ec3b83c..a9bfe8ab4f2 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -112,7 +112,7 @@ if ($object->statut == Holiday::STATUS_DRAFT && $user->rights->holiday->write && if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'holiday', $object->id, 'holiday'); +$result = restrictedArea($user, 'holiday', $object->id, 'holiday', '', '', 'rowid', $object->statut); /* @@ -1083,7 +1083,9 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { if (empty($include_users)) { print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateHolidays"); } else { - $defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator); // Will work only if supervisor has permission to approve so is inside include_users + // Defined default approver (the forced approved of user or the supervisor if no forced value defined) + // Note: This use will be set only if the deinfed approvr has permission to approve so is inside include_users + $defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator); if (!empty($conf->global->HOLIDAY_DEFAULT_VALIDATOR)) { $defaultselectuser = $conf->global->HOLIDAY_DEFAULT_VALIDATOR; // Can force default approver } @@ -1414,7 +1416,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { // Confirmation messages if ($action == 'delete') { - if ($user->rights->holiday->delete) { + if ($candelete) { print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("TitleDeleteCP"), $langs->trans("ConfirmDeleteCP"), "confirm_delete", '', 0, 1); } } diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index b4985100e44..bcae536f720 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -721,7 +721,7 @@ if ($resql) { if (!empty($arrayfields['cp.statut']['checked'])) { print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "cp.statut", "", $param, '', $sortfield, $sortorder, 'right '); } - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch '); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch center '); print "\n"; $listhalfday = array('morning'=>$langs->trans("Morning"), "afternoon"=>$langs->trans("Afternoon")); @@ -789,21 +789,23 @@ if ($resql) { } } if (!empty($arrayfields['cp.fk_user']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } } if (!empty($arrayfields['cp.fk_validator']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } } if (!empty($arrayfields['cp.fk_type']['checked'])) { - print ''; if (!$i) { $totalarray['nbfield']++; @@ -813,7 +815,8 @@ if ($resql) { print ''; if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/holiday/month_report.php b/htdocs/holiday/month_report.php index 9080072220e..e76d316bf6c 100644 --- a/htdocs/holiday/month_report.php +++ b/htdocs/holiday/month_report.php @@ -32,7 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; // Load translation files required by the page -$langs->loadLangs(array("holiday")); +$langs->loadLangs(array('holiday', 'hrm')); // Security check $socid = 0; @@ -112,7 +112,7 @@ if (empty($reshook)) { $arrayfields = array( 'cp.ref'=>array('label'=>$langs->trans('Ref'), 'checked'=>1), 'cp.fk_user'=>array('label'=>$langs->trans('Employee'), 'checked'=>1), - 'ct.label'=>array('label'=>$langs->trans('Type'), 'checked'=>1), + 'cp.fk_type'=>array('label'=>$langs->trans('Type'), 'checked'=>1), 'cp.date_debut'=>array('label'=>$langs->trans('DateDebCP'), 'checked'=>1), 'cp.date_fin'=>array('label'=>$langs->trans('DateFinCP'), 'checked'=>1), 'used_days'=>array('label'=>$langs->trans('NbUseDaysCPShort'), 'checked'=>1), @@ -141,10 +141,9 @@ $search_month = GETPOST("remonth", 'int') ?GETPOST("remonth", 'int') : date("m", $search_year = GETPOST("reyear", 'int') ?GETPOST("reyear", 'int') : date("Y", time()); $year_month = sprintf("%04d", $search_year).'-'.sprintf("%02d", $search_month); -$sql = "SELECT cp.rowid, cp.ref, cp.fk_user, cp.date_debut, cp.date_fin, ct.label, cp.description, cp.halfday"; +$sql = "SELECT cp.rowid, cp.ref, cp.fk_user, cp.date_debut, cp.date_fin, cp.fk_type, cp.description, cp.halfday"; $sql .= " FROM ".MAIN_DB_PREFIX."holiday cp"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user u ON cp.fk_user = u.rowid"; -$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_holiday_types ct ON cp.fk_type = ct.rowid"; $sql .= " WHERE cp.rowid > 0"; $sql .= " AND cp.statut = ".Holiday::STATUS_APPROVED; $sql .= " AND ("; @@ -244,7 +243,7 @@ if (!empty($arrayfields['cp.fk_user']['checked'])) { } // Filter: Type -if (!empty($arrayfields['ct.label']['checked'])) { +if (!empty($arrayfields['cp.fk_type']['checked'])) { $typeleaves = $holidaystatic->getTypes(1, -1); $arraytypeleaves = array(); foreach ($typeleaves as $key => $val) { @@ -297,6 +296,9 @@ if (!empty($arrayfields['cp.ref']['checked'])) { if (!empty($arrayfields['cp.fk_user']['checked'])) { print_liste_field_titre($arrayfields['cp.fk_user']['label'], $_SERVER["PHP_SELF"], 'cp.fk_user', '', '', '', $sortfield, $sortorder); } +if (!empty($arrayfields['cp.fk_type']['checked'])) { + print_liste_field_titre($arrayfields['cp.fk_type']['label'], $_SERVER["PHP_SELF"], 'cp.fk_type', '', '', '', $sortfield, $sortorder); +} if (!empty($arrayfields['ct.label']['checked'])) { print_liste_field_titre($arrayfields['ct.label']['label'], $_SERVER["PHP_SELF"], 'ct.label', '', '', '', $sortfield, $sortorder); } @@ -382,8 +384,8 @@ if ($num == 0) { if (!empty($arrayfields['cp.fk_user']['checked'])) { print ''; } - if (!empty($arrayfields['ct.label']['checked'])) { - print ''; + if (!empty($arrayfields['cp.fk_type']['checked'])) { + print ''; } if (!empty($arrayfields['cp.date_debut']['checked'])) { @@ -418,7 +420,7 @@ if ($num == 0) { print ''; } if (!empty($arrayfields['cp.description']['checked'])) { - print ''; + print ''; } print ''; diff --git a/htdocs/hrm/admin/evaluation_extrafields.php b/htdocs/hrm/admin/evaluation_extrafields.php new file mode 100644 index 00000000000..a9614ccd03f --- /dev/null +++ b/htdocs/hrm/admin/evaluation_extrafields.php @@ -0,0 +1,143 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2015 Jean-François Ferry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file admin/evaluation_extrafields.php + * \ingroup hrm + * \brief Page to setup extra fields of hrm + */ + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) { + $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +} +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { + $i--; $j--; +} +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) { + $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +} +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) { + $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +} +// Try main.inc.php using relative path +if (!$res && file_exists("../../main.inc.php")) { + $res = @include "../../main.inc.php"; +} +if (!$res && file_exists("../../../main.inc.php")) { + $res = @include "../../../main.inc.php"; +} +if (!$res) { + die("Include of main fails"); +} + +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once '../lib/hrm.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array('hrm', 'admin')); + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label = ExtraFields::$type2label; +$type2label = array(''); +foreach ($tmptype2label as $key => $val) { + $type2label[$key] = $langs->transnoentitiesnoconv($val); +} + +$action = GETPOST('action', 'aZ09'); +$attrname = GETPOST('attrname', 'alpha'); +$elementtype = 'hrm_evaluation'; //Must be the $table_element of the class that manage extrafield + +if (!$user->admin) { + accessforbidden(); +} + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; + + + +/* + * View + */ + +$help_url = ''; +$page_name = "HrmSetup"; + +llxHeader('', $langs->trans("HrmSetup"), $help_url); + + +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); + + +$head = hrmAdminPrepareHead(); + +print dol_get_fiche_head($head, 'evaluationsAttributes', $langs->trans($page_name), -1, 'hrm@hrm'); + +require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; + +print dol_get_fiche_end(); + + +// Buttons +if ($action != 'create' && $action != 'edit') { + print '
    '; + print "".$langs->trans("NewAttribute").""; + print "
    "; +} + + +/* + * Creation of an optional field + */ +if ($action == 'create') { + print '
    '; + print load_fiche_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* + * Edition of an optional field + */ +if ($action == 'edit' && !empty($attrname)) { + print "
    "; + print load_fiche_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/admin/job_extrafields.php b/htdocs/hrm/admin/job_extrafields.php new file mode 100644 index 00000000000..4b0d76e5187 --- /dev/null +++ b/htdocs/hrm/admin/job_extrafields.php @@ -0,0 +1,143 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2015 Jean-François Ferry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file admin/job_extrafields.php + * \ingroup hrm + * \brief Page to setup extra fields of hrm + */ + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) { + $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +} +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { + $i--; $j--; +} +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) { + $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +} +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) { + $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +} +// Try main.inc.php using relative path +if (!$res && file_exists("../../main.inc.php")) { + $res = @include "../../main.inc.php"; +} +if (!$res && file_exists("../../../main.inc.php")) { + $res = @include "../../../main.inc.php"; +} +if (!$res) { + die("Include of main fails"); +} + +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once '../lib/hrm.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array('hrm', 'admin')); + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label = ExtraFields::$type2label; +$type2label = array(''); +foreach ($tmptype2label as $key => $val) { + $type2label[$key] = $langs->transnoentitiesnoconv($val); +} + +$action = GETPOST('action', 'aZ09'); +$attrname = GETPOST('attrname', 'alpha'); +$elementtype = 'hrm_job'; //Must be the $table_element of the class that manage extrafield + +if (!$user->admin) { + accessforbidden(); +} + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; + + + +/* + * View + */ + +$help_url = ''; +$page_name = "HrmSetup"; + +llxHeader('', $langs->trans("Setup"), $help_url); + + +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); + + +$head = hrmAdminPrepareHead(); + +print dol_get_fiche_head($head, 'jobsAttributes', $langs->trans($page_name), -1, 'hrm@job'); + +require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; + +print dol_get_fiche_end(); + + +// Buttons +if ($action != 'create' && $action != 'edit') { + print '
    '; + print "".$langs->trans("NewAttribute").""; + print "
    "; +} + + +/* + * Creation of an optional field + */ +if ($action == 'create') { + print '
    '; + print load_fiche_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* + * Edition of an optional field + */ +if ($action == 'edit' && !empty($attrname)) { + print "
    "; + print load_fiche_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/admin/skill_extrafields.php b/htdocs/hrm/admin/skill_extrafields.php new file mode 100644 index 00000000000..f8d123cce74 --- /dev/null +++ b/htdocs/hrm/admin/skill_extrafields.php @@ -0,0 +1,143 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2015 Jean-François Ferry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file admin/skill_extrafields.php + * \ingroup hrm + * \brief Page to setup extra fields of hrm + */ + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) { + $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +} +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { + $i--; $j--; +} +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) { + $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +} +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) { + $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +} +// Try main.inc.php using relative path +if (!$res && file_exists("../../main.inc.php")) { + $res = @include "../../main.inc.php"; +} +if (!$res && file_exists("../../../main.inc.php")) { + $res = @include "../../../main.inc.php"; +} +if (!$res) { + die("Include of main fails"); +} + +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once '../lib/hrm.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array('hrm', 'admin')); + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label = ExtraFields::$type2label; +$type2label = array(''); +foreach ($tmptype2label as $key => $val) { + $type2label[$key] = $langs->transnoentitiesnoconv($val); +} + +$action = GETPOST('action', 'aZ09'); +$attrname = GETPOST('attrname', 'alpha'); +$elementtype = 'hrm_skill'; //Must be the $table_element of the class that manage extrafield + +if (!$user->admin) { + accessforbidden(); +} + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; + + + +/* + * View + */ + +$help_url = ''; +$page_name = "HrmSetup"; + +llxHeader('', $langs->trans("HrmSetup"), $help_url); + + +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); + + +$head = hrmAdminPrepareHead(); + +print dol_get_fiche_head($head, 'skillsAttributes', $langs->trans($page_name), -1, 'hrm@skill'); + +require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; + +print dol_get_fiche_end(); + + +// Buttons +if ($action != 'create' && $action != 'edit') { + print '
    '; + print "".$langs->trans("NewAttribute").""; + print "
    "; +} + + +/* + * Creation of an optional field + */ +if ($action == 'create') { + print '
    '; + print load_fiche_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* + * Edition of an optional field + */ +if ($action == 'edit' && !empty($attrname)) { + print "
    "; + print load_fiche_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/class/evaluation.class.php b/htdocs/hrm/class/evaluation.class.php index 5e8124fe09a..8050eb08ec9 100644 --- a/htdocs/hrm/class/evaluation.class.php +++ b/htdocs/hrm/class/evaluation.class.php @@ -1067,79 +1067,4 @@ class Evaluation extends CommonObject return $error; } - - /** - * @param string $action - * @param int $selected - */ - // public function printObjectLines($action, $selected = 0) - // { - // global $conf, $hookmanager, $langs, $user, $extrafields, $object; - // // TODO We should not use global var for this - // global $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $disableremove, $outputalsopricetotalwithtax; - // - // // Define usemargins - //// $usemargins = 0; - //// if (!empty($conf->margin->enabled) && !empty($this->element) && in_array($this->element, array('facture', 'facturerec', 'propal', 'commande'))) { - //// $usemargins = 1; - //// } - // - // $num = count($this->lines); - // - // // Line extrafield - // if (!is_object($extrafields)) { - // require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - // $extrafields = new ExtraFields($this->db); - // } - // $extrafields->fetch_name_optionals_label($this->table_element_line); - // - // $parameters = array('num'=>$num, 'selected'=>$selected, 'table_element_line'=>$this->table_element_line); - // $reshook = $hookmanager->executeHooks('printObjectLineTitle', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - // if (empty($reshook)) { - // // Output template part (modules that overwrite templates must declare this into descriptor) - // // Note: This is deprecated. If you need to overwrite the tpl file, use instead the hook. - // include dol_buildpath('hrm/core/tpl/objectline_title.tpl.php'); - // } - // - // $i = 0; - // - // print "
    \n"; - // foreach ($this->lines as $line) { - // //Line extrafield - // $line->fetch_optionals(); - // - // //if (is_object($hookmanager) && (($line->product_type == 9 && ! empty($line->special_code)) || ! empty($line->fk_parent_line))) - // if (is_object($hookmanager)) { // Old code is commented on preceding line. - // if (empty($line->fk_parent_line)) { - // $parameters = array('line'=>$line, 'num'=>$num, 'i'=>$i, 'selected'=>$selected, 'table_element_line'=>$line->table_element); - // $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - // } else { - // $parameters = array('line'=>$line, 'num'=>$num, 'i'=>$i, 'selected'=>$selected, 'table_element_line'=>$line->table_element, 'fk_parent_line'=>$line->fk_parent_line); - // $reshook = $hookmanager->executeHooks('printObjectSubLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - // } - // } - // if (empty($reshook)) { - // $this->printObjectLine($action, $line); - // } - // - // $i++; - // } - // print "\n"; - // } - - // public function printObjectLine($action, $line) - // { - // global $conf, $langs, $user, $object, $hookmanager; - // global $form; - // global $object_rights, $disableedit, $disablemove, $disableremove; // TODO We should not use global var for this ! - // - // $object_rights = $this->getRights(); - // - // $element = $this->element; - // - // $text = ''; - // $description = ''; - // - // include dol_buildpath('hrm/tpl/objectline_view.tpl.php'); - // } } diff --git a/htdocs/hrm/class/skill.class.php b/htdocs/hrm/class/skill.class.php index 724c14b93c0..ececc70b4f1 100644 --- a/htdocs/hrm/class/skill.class.php +++ b/htdocs/hrm/class/skill.class.php @@ -977,7 +977,7 @@ class Skill extends CommonObject { $this->lines = array(); - $objectline = new SkillLine($this->db); + $objectline = new Skilldet($this->db); $result = $objectline->fetchAll('ASC', 'rankorder', 0, 0, array('customsql'=>'fk_skill = '.$this->id)); if (is_numeric($result)) { diff --git a/htdocs/hrm/class/skilldet.class.php b/htdocs/hrm/class/skilldet.class.php index 5e2da1ba7aa..ac91e2ef21a 100644 --- a/htdocs/hrm/class/skilldet.class.php +++ b/htdocs/hrm/class/skilldet.class.php @@ -882,27 +882,6 @@ class Skilldet extends CommonObject $this->initAsSpecimenCommon(); } - /** - * Create an array of lines - * - * @return array|int array of lines if OK, <0 if KO - */ - public function getLinesArray() - { - $this->lines = array(); - - $objectline = new SkilldetLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_skilldet = '.$this->id)); - - if (is_numeric($result)) { - $this->error = $this->error; - $this->errors = $this->errors; - return $result; - } else { - $this->lines = $result; - return $this->lines; - } - } /** * Returns the reference to the following non used object depending on the active numbering module. diff --git a/htdocs/hrm/class/skillrank.class.php b/htdocs/hrm/class/skillrank.class.php index eb93208040b..aa1d70b430f 100644 --- a/htdocs/hrm/class/skillrank.class.php +++ b/htdocs/hrm/class/skillrank.class.php @@ -930,6 +930,7 @@ class SkillRank extends CommonObject { $this->lines = array(); + /* $objectline = new SkillRankLine($this->db); $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_skillrank = '.((int) $this->id))); @@ -941,6 +942,7 @@ class SkillRank extends CommonObject $this->lines = $result; return $this->lines; } + */ } /** diff --git a/htdocs/hrm/evaluation_card.php b/htdocs/hrm/evaluation_card.php index 7b0b7bcfd7d..71d3101e1c7 100644 --- a/htdocs/hrm/evaluation_card.php +++ b/htdocs/hrm/evaluation_card.php @@ -159,6 +159,7 @@ if (empty($reshook)) { $line->rankorder = $TNote[$line->fk_skill]; $line->update($user); } + setEventMessage($langs->trans("SaveLevelSkill")); } } @@ -569,7 +570,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; print ''; - print ''; + print ''; print ''; $sk = new Skill($db); diff --git a/htdocs/hrm/evaluation_list.php b/htdocs/hrm/evaluation_list.php index 35189f11b87..466741153c4 100644 --- a/htdocs/hrm/evaluation_list.php +++ b/htdocs/hrm/evaluation_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); @@ -412,7 +412,7 @@ print ''; print ''; print ''; -$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/evaluation_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/evaluation_card.php', 1).'?action=create', '', $permissiontoadd); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index 2603d73ab81..c573b78ed51 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -34,17 +34,17 @@ require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; -if ($conf->deplacement->enabled) { +if (!empty($conf->deplacement->enabled)) { require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php'; } -if ($conf->expensereport->enabled) { +if (!empty($conf->expensereport->enabled)) { require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; } -if ($conf->recruitment->enabled) { +if (!empty($conf->recruitment->enabled)) { require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentcandidature.class.php'; require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; } -if ($conf->holiday->enabled) { +if (!empty($conf->holiday->enabled)) { require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; } @@ -235,8 +235,10 @@ if (!empty($conf->holiday->enabled) && $user->rights->holiday->read) { print ''; print ''; - print ''; - print ''; + print ''; + + $leavecode = empty($typeleaves[$obj->fk_type]) ? 'Undefined' : $typeleaves[$obj->fk_type]['code']; + print ''; $starthalfday = ($obj->halfday == -1 || $obj->halfday == 2) ? 'afternoon' : 'morning'; $endhalfday = ($obj->halfday == 1 || $obj->halfday == 2) ? 'morning' : 'afternoon'; diff --git a/htdocs/hrm/job_list.php b/htdocs/hrm/job_list.php index 55363d729b5..33f4ea46305 100644 --- a/htdocs/hrm/job_list.php +++ b/htdocs/hrm/job_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); @@ -412,7 +412,7 @@ print ''; print ''; print ''; -$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/job_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/job_card.php', 1).'?action=create', '', $permissiontoadd); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/hrm/lib/hrm.lib.php b/htdocs/hrm/lib/hrm.lib.php index e875f61b9e4..508cbef22fd 100644 --- a/htdocs/hrm/lib/hrm.lib.php +++ b/htdocs/hrm/lib/hrm.lib.php @@ -48,6 +48,21 @@ function hrmAdminPrepareHead() $head[$h][2] = 'establishments'; $h++; + $head[$h][0] = DOL_URL_ROOT . '/hrm/admin/evaluation_extrafields.php'; + $head[$h][1] = $langs->trans("EvaluationsExtraFields"); + $head[$h][2] = 'evaluationsAttributes'; + $h++; + + $head[$h][0] = DOL_URL_ROOT . '/hrm/admin/job_extrafields.php'; + $head[$h][1] = $langs->trans("JobsExtraFields"); + $head[$h][2] = 'jobsAttributes'; + $h++; + + $head[$h][0] = DOL_URL_ROOT . '/hrm/admin/skill_extrafields.php'; + $head[$h][1] = $langs->trans("SkillsExtraFields"); + $head[$h][2] = 'skillsAttributes'; + $h++; + /* $head[$h][0] = dol_buildpath("/workstation/admin/myobject_extrafields.php", 1); $head[$h][1] = $langs->trans("ExtraFields"); diff --git a/htdocs/hrm/lib/hrm_evaluation.lib.php b/htdocs/hrm/lib/hrm_evaluation.lib.php index 87e6b80adaa..57a24878c52 100644 --- a/htdocs/hrm/lib/hrm_evaluation.lib.php +++ b/htdocs/hrm/lib/hrm_evaluation.lib.php @@ -93,3 +93,37 @@ function evaluationPrepareHead($object) return $head; } + +/** + * @return string + */ +function GetLegendSkills() +{ + global $langs; + $legendSkills = '
    + ' . $langs->trans('legend') . ' +
    '.$langs->trans('Account').''; print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(empty($accountid) ? $obj->fk_account : $accountid, 'accountid', 0, '', 2); + print $form->select_comptes(empty($accountid) ? $obj->fk_account : $accountid, 'accountid', 0, '', 2, '', 0, 'widthcentpercentminusx maxwidth500', 1); print '
     
    '.$userstatic->getNomUrl(-1, 'leave').''.$userstatic->getNomUrl(-1, 'leave').''.$approbatorstatic->getNomUrl(-1).''.$approbatorstatic->getNomUrl(-1).''; $labeltypeleavetoshow = ($langs->trans($typeleaves[$obj->fk_type]['code']) != $typeleaves[$obj->fk_type]['code'] ? $langs->trans($typeleaves[$obj->fk_type]['code']) : $typeleaves[$obj->fk_type]['label']); - print empty($typeleaves[$obj->fk_type]['label']) ? $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type) : $labeltypeleavetoshow; + $labeltypeleavetoshow = empty($typeleaves[$obj->fk_type]['label']) ? $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type) : $labeltypeleavetoshow; + + print ''; + print $labeltypeleavetoshow; print ''; $nbopenedday = num_open_day($db->jdate($obj->date_debut, 1), $db->jdate($obj->date_fin, 1), 0, 1, $obj->halfday); // user jdate(..., 1) because num_open_day need UTC dates $totalduration += $nbopenedday; - print $nbopenedday.' '.$langs->trans('DurationDays'); + print $nbopenedday; + //print ' '.$langs->trans('DurationDays'); print ''.$user->getFullName($langs).''.$obj->label.''.$arraytypeleaves[$obj->fk_type].''.num_open_day($date_start_inmonth, $date_end_inmonth, 0, 1, $halfdayinmonth).''.dol_escape_htmltag(dolGetFirstLineOfText($obj->description)).''.dolGetFirstLineOfText(dol_string_nohtmltag($obj->description, 1)).'
    ' . $langs->trans("Description") . '' . $langs->trans("EmployeeRank") . '' . $langs->trans("RequiredRank") . '' . $langs->trans("Result") . '' . $langs->trans("Result") . ' ' .$form->textwithpicto('', GetLegendSkills(), 1) .'
    '.$holidaystatic->getNomUrl(1).''.$userstatic->getNomUrl(-1, 'leave').''.dol_escape_htmltag($langs->trans($typeleaves[$obj->fk_type]['code'])).''.$userstatic->getNomUrl(-1, 'leave').''.dol_escape_htmltag($langs->trans($leavecode)).'
    + + + + + + + + + + + + + + + +
    + ' . $langs->trans('CompetenceAcquiredByOneOrMore') . '
    + ' . $langs->trans('MaxlevelGreaterThan') . '
    + ' . $langs->trans('MaxLevelEqualTo') . '
    + ' . $langs->trans('MaxLevelLowerThan') . '
    + ' . $langs->trans('SkillNotAcquired') . '
    +
    '; + return $legendSkills; +} diff --git a/htdocs/hrm/position.php b/htdocs/hrm/position.php index 19749d94c19..78838136a1e 100644 --- a/htdocs/hrm/position.php +++ b/htdocs/hrm/position.php @@ -160,9 +160,9 @@ if (empty($reshook)) { $backurlforlist = dol_buildpath('/hrm/position_list.php', 1); //$backtopage = dol_buildpath('/hrm/position.php', 1) . '?fk_job=' . ($fk_job > 0 ? $fk_job : '__ID__'); - if (empty($backtopage) || ($cancel && empty($fk_job))) { + if (empty($backtopage) || ($cancel && $fk_job <= 0)) { if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { - if (empty($fk_job) && (($action != 'add' && $action != 'create') || $cancel)) { + if ($fk_job == -1 && (($action != 'add' && $action != 'create') || $cancel)) { $backtopage = $backurlforlist; } else { if ($fk_job > 0) { @@ -357,11 +357,11 @@ function DisplayPositionList() foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.' . $key] = array( 'label' => $val['label'], 'checked' => (($visible < 0) ? 0 : 1), - 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position' => $val['position'], 'help' => isset($val['help']) ? $val['help'] : '' ); @@ -631,7 +631,7 @@ function DisplayPositionList() print ''; print ''; - $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/position.php', 1) . '?action=create&backtopage=' . urlencode($_SERVER['PHP_SELF'].'?fk_job=' . $fk_job).'&fk_job=' . $fk_job, '', $permissiontoadd); + $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/position.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']).'&fk_job='.((int) $fk_job), '', $permissiontoadd); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_' . $object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/hrm/position_list.php b/htdocs/hrm/position_list.php index 1585ed1e03f..f193783cb42 100644 --- a/htdocs/hrm/position_list.php +++ b/htdocs/hrm/position_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); @@ -417,7 +417,7 @@ print ''; print ''; print ''; -$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/position.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/position.php', 1).'?action=create', '', $permissiontoadd); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/hrm/skill_card.php b/htdocs/hrm/skill_card.php index 45e2bfea16a..6cac7b4d448 100644 --- a/htdocs/hrm/skill_card.php +++ b/htdocs/hrm/skill_card.php @@ -51,9 +51,16 @@ $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // Initialize technical objects $object = new Skill($db); +$extrafields = new ExtraFields($db); //$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('skillcard', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + + // Initialize array of search criterias $search_all = GETPOST("search_all", 'alpha'); $search = array(); @@ -201,6 +208,9 @@ if ($action == 'create') { // Common attributes include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_add.tpl.php'; + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; + // SKILLDET ADD //@todo je stop ici ... à continuer (affichage des 5 skilled input pour create action @@ -247,6 +257,8 @@ if (($id || $ref) && $action == 'edit') { print ''; + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; // SKILLDET @@ -416,6 +428,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $object->fields['label']['visible']=0; // Already in banner include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php'; + // Other attributes. Fields from hook formObjectOptions and Extrafields. + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + print ''; print '
    '; @@ -535,11 +550,11 @@ if ($action != "create" && $action != "edit") { foreach ($objectline->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.' . $key] = array( 'label' => $val['label'], 'checked' => (($visible < 0) ? 0 : 1), - 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position' => $val['position'], 'help' => isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/hrm/skill_list.php b/htdocs/hrm/skill_list.php index 1fc5440e589..9c5a4740c15 100644 --- a/htdocs/hrm/skill_list.php +++ b/htdocs/hrm/skill_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); @@ -412,7 +412,7 @@ print ''; print ''; print ''; -$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/skill_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/hrm/skill_card.php?action=create', '', $permissiontoadd); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/hrm/skill_tab.php b/htdocs/hrm/skill_tab.php index 1ed9e370839..0bbc039152c 100644 --- a/htdocs/hrm/skill_tab.php +++ b/htdocs/hrm/skill_tab.php @@ -123,6 +123,7 @@ if (empty($reshook)) { if ($ret < 0) setEventMessage($skillAdded->error, 'errors'); //else unset($TSkillsToAdd); } + if ($ret > 0) setEventMessage($langs->trans("SaveAddSkill")); } } elseif ($action == 'saveSkill') { if (!empty($TNote)) { @@ -135,10 +136,14 @@ if (empty($reshook)) { } } } + setEventMessage($langs->trans("SaveLevelSkill")); + header("Location: " . dol_buildpath('/hrm/skill_tab.php', 1) . '?id=' . $id. '&objecttype=job'); + exit; } } elseif ($action == 'confirm_deleteskill' && $confirm == 'yes') { $skillToDelete = new SkillRank($db); $ret = $skillToDelete->fetch($lineid); + setEventMessage($langs->trans("DeleteSkill")); if ($ret > 0) { $skillToDelete->delete($user); } diff --git a/htdocs/includes/ace/.npmignore b/htdocs/includes/ace/.npmignore new file mode 100644 index 00000000000..b7e6c1b552d --- /dev/null +++ b/htdocs/includes/ace/.npmignore @@ -0,0 +1,3 @@ +demo/ +kitchen-sink.html +* * \ No newline at end of file diff --git a/htdocs/includes/ace/ChangeLog.txt b/htdocs/includes/ace/ChangeLog.txt index 824f8750e12..2819a6014d0 100644 --- a/htdocs/includes/ace/ChangeLog.txt +++ b/htdocs/includes/ace/ChangeLog.txt @@ -1,3 +1,26 @@ +2022.01.26 Version 1.4.14 +* update vim mode +* remove slow regex in beautify extension + +2021.09.30 Version 1.4.13 +* added useStrictCSP global option to use in environments where dynamic style creation is disabled + see demo/csp.html for an example of a page which loads external css files instead of generating styles with javascript +* updated vim mode, added support for gqq command + +2020.07.06 Version 1.4.12 +* removed unused es5-shim +* imporved ruby and vbscript highlighting and folding +* workaround for double space being converted to dot on mobile keyboards + +2020.04.15 Version 1.4.10 +* added workaround for chrome bug causing memory leak after calling editor.destroy +* added code folding support for vbscript mode + +2020.04.01 Version 1.4.9 +* added option to disable autoindent +* added new language modes +* fixed backspace not working with some mobile keyboards + 2020.01.14 Version 1.4.8 * highlight both matched braces, and highlight unmatched brace in red * improve snippet manager diff --git a/htdocs/includes/ace/ace-modules.d.ts b/htdocs/includes/ace/ace-modules.d.ts index a25e20c9c84..0f0bac5fbfd 100644 --- a/htdocs/includes/ace/ace-modules.d.ts +++ b/htdocs/includes/ace/ace-modules.d.ts @@ -1,7 +1,11 @@ +declare module 'ace-builds/webpack-resolver'; +declare module 'ace-builds/src-noconflict/ace'; declare module 'ace-builds/src-noconflict/ext-beautify'; +declare module 'ace-builds/src-noconflict/ext-code_lens'; declare module 'ace-builds/src-noconflict/ext-elastic_tabstops_lite'; declare module 'ace-builds/src-noconflict/ext-emmet'; declare module 'ace-builds/src-noconflict/ext-error_marker'; +declare module 'ace-builds/src-noconflict/ext-hardwrap'; declare module 'ace-builds/src-noconflict/ext-keybinding_menu'; declare module 'ace-builds/src-noconflict/ext-language_tools'; declare module 'ace-builds/src-noconflict/ext-linking'; @@ -21,10 +25,12 @@ declare module 'ace-builds/src-noconflict/ext-whitespace'; declare module 'ace-builds/src-noconflict/keybinding-emacs'; declare module 'ace-builds/src-noconflict/keybinding-sublime'; declare module 'ace-builds/src-noconflict/keybinding-vim'; +declare module 'ace-builds/src-noconflict/keybinding-vscode'; declare module 'ace-builds/src-noconflict/mode-abap'; declare module 'ace-builds/src-noconflict/mode-abc'; declare module 'ace-builds/src-noconflict/mode-actionscript'; declare module 'ace-builds/src-noconflict/mode-ada'; +declare module 'ace-builds/src-noconflict/mode-alda'; declare module 'ace-builds/src-noconflict/mode-apache_conf'; declare module 'ace-builds/src-noconflict/mode-apex'; declare module 'ace-builds/src-noconflict/mode-applescript'; @@ -34,7 +40,6 @@ declare module 'ace-builds/src-noconflict/mode-asl'; declare module 'ace-builds/src-noconflict/mode-assembly_x86'; declare module 'ace-builds/src-noconflict/mode-autohotkey'; declare module 'ace-builds/src-noconflict/mode-batchfile'; -declare module 'ace-builds/src-noconflict/mode-bro'; declare module 'ace-builds/src-noconflict/mode-c9search'; declare module 'ace-builds/src-noconflict/mode-cirru'; declare module 'ace-builds/src-noconflict/mode-clojure'; @@ -92,6 +97,7 @@ declare module 'ace-builds/src-noconflict/mode-jade'; declare module 'ace-builds/src-noconflict/mode-java'; declare module 'ace-builds/src-noconflict/mode-javascript'; declare module 'ace-builds/src-noconflict/mode-json'; +declare module 'ace-builds/src-noconflict/mode-json5'; declare module 'ace-builds/src-noconflict/mode-jsoniq'; declare module 'ace-builds/src-noconflict/mode-jsp'; declare module 'ace-builds/src-noconflict/mode-jssm'; @@ -99,6 +105,7 @@ declare module 'ace-builds/src-noconflict/mode-jsx'; declare module 'ace-builds/src-noconflict/mode-julia'; declare module 'ace-builds/src-noconflict/mode-kotlin'; declare module 'ace-builds/src-noconflict/mode-latex'; +declare module 'ace-builds/src-noconflict/mode-latte'; declare module 'ace-builds/src-noconflict/mode-less'; declare module 'ace-builds/src-noconflict/mode-liquid'; declare module 'ace-builds/src-noconflict/mode-lisp'; @@ -114,7 +121,9 @@ declare module 'ace-builds/src-noconflict/mode-markdown'; declare module 'ace-builds/src-noconflict/mode-mask'; declare module 'ace-builds/src-noconflict/mode-matlab'; declare module 'ace-builds/src-noconflict/mode-maze'; +declare module 'ace-builds/src-noconflict/mode-mediawiki'; declare module 'ace-builds/src-noconflict/mode-mel'; +declare module 'ace-builds/src-noconflict/mode-mips'; declare module 'ace-builds/src-noconflict/mode-mixal'; declare module 'ace-builds/src-noconflict/mode-mushcode'; declare module 'ace-builds/src-noconflict/mode-mysql'; @@ -122,11 +131,11 @@ declare module 'ace-builds/src-noconflict/mode-nginx'; declare module 'ace-builds/src-noconflict/mode-nim'; declare module 'ace-builds/src-noconflict/mode-nix'; declare module 'ace-builds/src-noconflict/mode-nsis'; +declare module 'ace-builds/src-noconflict/mode-nunjucks'; declare module 'ace-builds/src-noconflict/mode-objectivec'; declare module 'ace-builds/src-noconflict/mode-ocaml'; declare module 'ace-builds/src-noconflict/mode-pascal'; declare module 'ace-builds/src-noconflict/mode-perl'; -declare module 'ace-builds/src-noconflict/mode-perl6'; declare module 'ace-builds/src-noconflict/mode-pgsql'; declare module 'ace-builds/src-noconflict/mode-php'; declare module 'ace-builds/src-noconflict/mode-php_laravel_blade'; @@ -134,12 +143,15 @@ declare module 'ace-builds/src-noconflict/mode-pig'; declare module 'ace-builds/src-noconflict/mode-plain_text'; declare module 'ace-builds/src-noconflict/mode-powershell'; declare module 'ace-builds/src-noconflict/mode-praat'; +declare module 'ace-builds/src-noconflict/mode-prisma'; declare module 'ace-builds/src-noconflict/mode-prolog'; declare module 'ace-builds/src-noconflict/mode-properties'; declare module 'ace-builds/src-noconflict/mode-protobuf'; declare module 'ace-builds/src-noconflict/mode-puppet'; declare module 'ace-builds/src-noconflict/mode-python'; +declare module 'ace-builds/src-noconflict/mode-qml'; declare module 'ace-builds/src-noconflict/mode-r'; +declare module 'ace-builds/src-noconflict/mode-raku'; declare module 'ace-builds/src-noconflict/mode-razor'; declare module 'ace-builds/src-noconflict/mode-rdoc'; declare module 'ace-builds/src-noconflict/mode-red'; @@ -152,11 +164,13 @@ declare module 'ace-builds/src-noconflict/mode-sass'; declare module 'ace-builds/src-noconflict/mode-scad'; declare module 'ace-builds/src-noconflict/mode-scala'; declare module 'ace-builds/src-noconflict/mode-scheme'; +declare module 'ace-builds/src-noconflict/mode-scrypt'; declare module 'ace-builds/src-noconflict/mode-scss'; declare module 'ace-builds/src-noconflict/mode-sh'; declare module 'ace-builds/src-noconflict/mode-sjs'; declare module 'ace-builds/src-noconflict/mode-slim'; declare module 'ace-builds/src-noconflict/mode-smarty'; +declare module 'ace-builds/src-noconflict/mode-smithy'; declare module 'ace-builds/src-noconflict/mode-snippets'; declare module 'ace-builds/src-noconflict/mode-soy_template'; declare module 'ace-builds/src-noconflict/mode-space'; @@ -210,6 +224,8 @@ declare module 'ace-builds/src-noconflict/theme-merbivore'; declare module 'ace-builds/src-noconflict/theme-merbivore_soft'; declare module 'ace-builds/src-noconflict/theme-monokai'; declare module 'ace-builds/src-noconflict/theme-mono_industrial'; +declare module 'ace-builds/src-noconflict/theme-nord_dark'; +declare module 'ace-builds/src-noconflict/theme-one_dark'; declare module 'ace-builds/src-noconflict/theme-pastel_on_dark'; declare module 'ace-builds/src-noconflict/theme-solarized_dark'; declare module 'ace-builds/src-noconflict/theme-solarized_light'; @@ -228,6 +244,7 @@ declare module 'ace-builds/src-noconflict/snippets/abap'; declare module 'ace-builds/src-noconflict/snippets/abc'; declare module 'ace-builds/src-noconflict/snippets/actionscript'; declare module 'ace-builds/src-noconflict/snippets/ada'; +declare module 'ace-builds/src-noconflict/snippets/alda'; declare module 'ace-builds/src-noconflict/snippets/apache_conf'; declare module 'ace-builds/src-noconflict/snippets/apex'; declare module 'ace-builds/src-noconflict/snippets/applescript'; @@ -237,7 +254,6 @@ declare module 'ace-builds/src-noconflict/snippets/asl'; declare module 'ace-builds/src-noconflict/snippets/assembly_x86'; declare module 'ace-builds/src-noconflict/snippets/autohotkey'; declare module 'ace-builds/src-noconflict/snippets/batchfile'; -declare module 'ace-builds/src-noconflict/snippets/bro'; declare module 'ace-builds/src-noconflict/snippets/c9search'; declare module 'ace-builds/src-noconflict/snippets/cirru'; declare module 'ace-builds/src-noconflict/snippets/clojure'; @@ -295,6 +311,7 @@ declare module 'ace-builds/src-noconflict/snippets/jade'; declare module 'ace-builds/src-noconflict/snippets/java'; declare module 'ace-builds/src-noconflict/snippets/javascript'; declare module 'ace-builds/src-noconflict/snippets/json'; +declare module 'ace-builds/src-noconflict/snippets/json5'; declare module 'ace-builds/src-noconflict/snippets/jsoniq'; declare module 'ace-builds/src-noconflict/snippets/jsp'; declare module 'ace-builds/src-noconflict/snippets/jssm'; @@ -302,6 +319,7 @@ declare module 'ace-builds/src-noconflict/snippets/jsx'; declare module 'ace-builds/src-noconflict/snippets/julia'; declare module 'ace-builds/src-noconflict/snippets/kotlin'; declare module 'ace-builds/src-noconflict/snippets/latex'; +declare module 'ace-builds/src-noconflict/snippets/latte'; declare module 'ace-builds/src-noconflict/snippets/less'; declare module 'ace-builds/src-noconflict/snippets/liquid'; declare module 'ace-builds/src-noconflict/snippets/lisp'; @@ -317,7 +335,9 @@ declare module 'ace-builds/src-noconflict/snippets/markdown'; declare module 'ace-builds/src-noconflict/snippets/mask'; declare module 'ace-builds/src-noconflict/snippets/matlab'; declare module 'ace-builds/src-noconflict/snippets/maze'; +declare module 'ace-builds/src-noconflict/snippets/mediawiki'; declare module 'ace-builds/src-noconflict/snippets/mel'; +declare module 'ace-builds/src-noconflict/snippets/mips'; declare module 'ace-builds/src-noconflict/snippets/mixal'; declare module 'ace-builds/src-noconflict/snippets/mushcode'; declare module 'ace-builds/src-noconflict/snippets/mysql'; @@ -325,11 +345,11 @@ declare module 'ace-builds/src-noconflict/snippets/nginx'; declare module 'ace-builds/src-noconflict/snippets/nim'; declare module 'ace-builds/src-noconflict/snippets/nix'; declare module 'ace-builds/src-noconflict/snippets/nsis'; +declare module 'ace-builds/src-noconflict/snippets/nunjucks'; declare module 'ace-builds/src-noconflict/snippets/objectivec'; declare module 'ace-builds/src-noconflict/snippets/ocaml'; declare module 'ace-builds/src-noconflict/snippets/pascal'; declare module 'ace-builds/src-noconflict/snippets/perl'; -declare module 'ace-builds/src-noconflict/snippets/perl6'; declare module 'ace-builds/src-noconflict/snippets/pgsql'; declare module 'ace-builds/src-noconflict/snippets/php'; declare module 'ace-builds/src-noconflict/snippets/php_laravel_blade'; @@ -337,12 +357,15 @@ declare module 'ace-builds/src-noconflict/snippets/pig'; declare module 'ace-builds/src-noconflict/snippets/plain_text'; declare module 'ace-builds/src-noconflict/snippets/powershell'; declare module 'ace-builds/src-noconflict/snippets/praat'; +declare module 'ace-builds/src-noconflict/snippets/prisma'; declare module 'ace-builds/src-noconflict/snippets/prolog'; declare module 'ace-builds/src-noconflict/snippets/properties'; declare module 'ace-builds/src-noconflict/snippets/protobuf'; declare module 'ace-builds/src-noconflict/snippets/puppet'; declare module 'ace-builds/src-noconflict/snippets/python'; +declare module 'ace-builds/src-noconflict/snippets/qml'; declare module 'ace-builds/src-noconflict/snippets/r'; +declare module 'ace-builds/src-noconflict/snippets/raku'; declare module 'ace-builds/src-noconflict/snippets/razor'; declare module 'ace-builds/src-noconflict/snippets/rdoc'; declare module 'ace-builds/src-noconflict/snippets/red'; @@ -355,11 +378,13 @@ declare module 'ace-builds/src-noconflict/snippets/sass'; declare module 'ace-builds/src-noconflict/snippets/scad'; declare module 'ace-builds/src-noconflict/snippets/scala'; declare module 'ace-builds/src-noconflict/snippets/scheme'; +declare module 'ace-builds/src-noconflict/snippets/scrypt'; declare module 'ace-builds/src-noconflict/snippets/scss'; declare module 'ace-builds/src-noconflict/snippets/sh'; declare module 'ace-builds/src-noconflict/snippets/sjs'; declare module 'ace-builds/src-noconflict/snippets/slim'; declare module 'ace-builds/src-noconflict/snippets/smarty'; +declare module 'ace-builds/src-noconflict/snippets/smithy'; declare module 'ace-builds/src-noconflict/snippets/snippets'; declare module 'ace-builds/src-noconflict/snippets/soy_template'; declare module 'ace-builds/src-noconflict/snippets/space'; @@ -390,4 +415,3 @@ declare module 'ace-builds/src-noconflict/snippets/xml'; declare module 'ace-builds/src-noconflict/snippets/xquery'; declare module 'ace-builds/src-noconflict/snippets/yaml'; declare module 'ace-builds/src-noconflict/snippets/zeek'; -declare module 'ace-builds/webpack-resolver'; diff --git a/htdocs/includes/ace/ace.d.ts b/htdocs/includes/ace/ace.d.ts index dd1a2952a06..bdf62ffd3a4 100644 --- a/htdocs/includes/ace/ace.d.ts +++ b/htdocs/includes/ace/ace.d.ts @@ -21,10 +21,12 @@ export namespace Ace { getLine(row: number): string; getLines(firstRow: number, lastRow: number): string[]; getAllLines(): string[]; + getLength(): number; getTextRange(range: Range): string; getLinesForRange(range: Range): string[]; insert(position: Point, text: string): Point; insertInLine(position: Point, text: string): Point; + insertNewLine(position: Point): Point; clippedPos(row: number, column: number): Point; clonePos(pos: Point): Point; pos(row: number, column: number): Point; @@ -153,7 +155,7 @@ export namespace Ace { } export interface EditSessionOptions { - wrap: string | number; + wrap: "off" | "free" | "printmargin" | boolean | number; wrapMethod: 'code' | 'text' | 'auto'; indentedSoftWrap: boolean; firstLineNumber: number; @@ -212,6 +214,7 @@ export namespace Ace { mergeUndoDeltas: true | false | 'always'; behavioursEnabled: boolean; wrapBehavioursEnabled: boolean; + enableAutoIndent: boolean; autoScrollEditorIntoView: boolean; keyboardHandler: string; placeholder: string; @@ -228,7 +231,7 @@ export namespace Ace { range: Range; preserveCase: boolean; regExp: RegExp; - wholeWord: string; + wholeWord: boolean; caseSensitive: boolean; wrap: boolean; } @@ -362,7 +365,7 @@ export namespace Ace { moduleUrl(name: string, component?: string): string; setModuleUrl(name: string, subst: string): string; loadModule(moduleName: string | [string, string], - onLoad: (module: any) => void): void; + onLoad?: (module: any) => void): void; init(packaged: any): any; defineOptions(obj: any, path: string, options: { [key: string]: any }): Config; resetOptions(obj: any): void; @@ -398,6 +401,8 @@ export namespace Ace { export interface EditSession extends EventEmitter, OptionsProvider, Folding { selection: Selection; + // TODO: define BackgroundTokenizer + on(name: 'changeFold', callback: (obj: { data: Fold, action: string }) => void): Function; on(name: 'changeScrollLeft', callback: (scrollLeft: number) => void): Function; @@ -519,6 +524,8 @@ export namespace Ace { removeKeyboardHandler(handler: KeyboardHandler): boolean; getKeyboardHandler(): KeyboardHandler; getStatusText(): string; + onCommandKey(e: any, hashId: number, keyCode: number): boolean; + onTextInput(text: string): boolean; } interface CommandMap { @@ -549,10 +556,17 @@ export namespace Ace { toggleRecording(editor: Editor): void; replay(editor: Editor): void; addCommand(command: Command): void; - removeCommand(command: Command, keepCommand?: boolean): void; + addCommands(command: Command[]): void; + removeCommand(command: Command | string, keepCommand?: boolean): void; + removeCommands(command: Command[]): void; bindKey(key: string | { mac?: string, win?: string }, command: CommandLike, position?: number): void; + bindKeys(keys: {[s: string]: Function}): void; + parseKeys(keyPart: string): {key: string, hashId: number}; + findKeyCommand(hashId: number, keyString: string): string | undefined; + handleKeyboard(data: {}, hashId: number, keyString: string, keyCode: string | number): void | {command: string}; + getStatusText(editor: Editor, data: {}): string; } export interface VirtualRenderer extends OptionsProvider, EventEmitter { @@ -746,7 +760,7 @@ export namespace Ace { setFontSize(size: string): void; focus(): void; isFocused(): boolean; - flur(): void; + blur(): void; getSelectedText(): string; getCopyText(): string; execCommand(command: string | string[], args?: any): boolean; @@ -844,9 +858,10 @@ export namespace Ace { replace(replacement: string, options?: Partial): number; replaceAll(replacement: string, options?: Partial): number; getLastSearchOptions(): Partial; - find(needle: string, options?: Partial, animate?: boolean): void; + find(needle: string | RegExp, options?: Partial, animate?: boolean): Ace.Range | undefined; findNext(options?: Partial, animate?: boolean): void; findPrevious(options?: Partial, animate?: boolean): void; + findAll(needle: string | RegExp, options?: Partial, additive?: boolean): number; undo(): void; redo(): void; destroy(): void; @@ -857,6 +872,7 @@ export namespace Ace { type CompleterCallback = (error: any, completions: Completion[]) => void; interface Completer { + identifierRegexps?: Array, getCompletions(editor: Editor, session: EditSession, position: Point, diff --git a/htdocs/includes/ace/kitchen-sink.html b/htdocs/includes/ace/kitchen-sink.html index 27014fa6004..026b357ca4a 100644 --- a/htdocs/includes/ace/kitchen-sink.html +++ b/htdocs/includes/ace/kitchen-sink.html @@ -8,7 +8,7 @@ @@ -21,18 +21,18 @@
    -
    +
    - - + +
    diff --git a/htdocs/includes/ace/package.json b/htdocs/includes/ace/package.json index a00dddeb40a..5deb5e6d478 100644 --- a/htdocs/includes/ace/package.json +++ b/htdocs/includes/ace/package.json @@ -2,7 +2,7 @@ "name": "ace-builds", "main": "./src-noconflict/ace.js", "typings": "ace.d.ts", - "version": "1.4.8", + "version": "1.4.14", "description": "Ace (Ajax.org Cloud9 Editor)", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/htdocs/includes/ace/src/ace.js b/htdocs/includes/ace/src/ace.js index 43d9931a3c4..74913993af1 100644 --- a/htdocs/includes/ace/src/ace.js +++ b/htdocs/includes/ace/src/ace.js @@ -173,781 +173,8 @@ exportAce(ACE_NAMESPACE); })(); -define("ace/lib/regexp",["require","exports","module"], function(require, exports, module) { +define("ace/lib/fixoldbrowsers",["require","exports","module"], function(require, exports, module) { "use strict"; - - var real = { - exec: RegExp.prototype.exec, - test: RegExp.prototype.test, - match: String.prototype.match, - replace: String.prototype.replace, - split: String.prototype.split - }, - compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups - compliantLastIndexIncrement = function () { - var x = /^/g; - real.test.call(x, ""); - return !x.lastIndex; - }(); - - if (compliantLastIndexIncrement && compliantExecNpcg) - return; - RegExp.prototype.exec = function (str) { - var match = real.exec.apply(this, arguments), - name, r2; - if ( typeof(str) == 'string' && match) { - if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) { - r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", "")); - real.replace.call(str.slice(match.index), r2, function () { - for (var i = 1; i < arguments.length - 2; i++) { - if (arguments[i] === undefined) - match[i] = undefined; - } - }); - } - if (this._xregexp && this._xregexp.captureNames) { - for (var i = 1; i < match.length; i++) { - name = this._xregexp.captureNames[i - 1]; - if (name) - match[name] = match[i]; - } - } - if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index)) - this.lastIndex--; - } - return match; - }; - if (!compliantLastIndexIncrement) { - RegExp.prototype.test = function (str) { - var match = real.exec.call(this, str); - if (match && this.global && !match[0].length && (this.lastIndex > match.index)) - this.lastIndex--; - return !!match; - }; - } - - function getNativeFlags (regex) { - return (regex.global ? "g" : "") + - (regex.ignoreCase ? "i" : "") + - (regex.multiline ? "m" : "") + - (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3 - (regex.sticky ? "y" : ""); - } - - function indexOf (array, item, from) { - if (Array.prototype.indexOf) // Use the native array method if available - return array.indexOf(item, from); - for (var i = from || 0; i < array.length; i++) { - if (array[i] === item) - return i; - } - return -1; - } - -}); - -define("ace/lib/es5-shim",["require","exports","module"], function(require, exports, module) { - -function Empty() {} - -if (!Function.prototype.bind) { - Function.prototype.bind = function bind(that) { // .length is 1 - var target = this; - if (typeof target != "function") { - throw new TypeError("Function.prototype.bind called on incompatible " + target); - } - var args = slice.call(arguments, 1); // for normal call - var bound = function () { - - if (this instanceof bound) { - - var result = target.apply( - this, - args.concat(slice.call(arguments)) - ); - if (Object(result) === result) { - return result; - } - return this; - - } else { - return target.apply( - that, - args.concat(slice.call(arguments)) - ); - - } - - }; - if(target.prototype) { - Empty.prototype = target.prototype; - bound.prototype = new Empty(); - Empty.prototype = null; - } - return bound; - }; -} -var call = Function.prototype.call; -var prototypeOfArray = Array.prototype; -var prototypeOfObject = Object.prototype; -var slice = prototypeOfArray.slice; -var _toString = call.bind(prototypeOfObject.toString); -var owns = call.bind(prototypeOfObject.hasOwnProperty); -var defineGetter; -var defineSetter; -var lookupGetter; -var lookupSetter; -var supportsAccessors; -if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { - defineGetter = call.bind(prototypeOfObject.__defineGetter__); - defineSetter = call.bind(prototypeOfObject.__defineSetter__); - lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); - lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); -} -if ([1,2].splice(0).length != 2) { - if(function() { // test IE < 9 to splice bug - see issue #138 - function makeArray(l) { - var a = new Array(l+2); - a[0] = a[1] = 0; - return a; - } - var array = [], lengthBefore; - - array.splice.apply(array, makeArray(20)); - array.splice.apply(array, makeArray(26)); - - lengthBefore = array.length; //46 - array.splice(5, 0, "XXX"); // add one element - - lengthBefore + 1 == array.length - - if (lengthBefore + 1 == array.length) { - return true;// has right splice implementation without bugs - } - }()) {//IE 6/7 - var array_splice = Array.prototype.splice; - Array.prototype.splice = function(start, deleteCount) { - if (!arguments.length) { - return []; - } else { - return array_splice.apply(this, [ - start === void 0 ? 0 : start, - deleteCount === void 0 ? (this.length - start) : deleteCount - ].concat(slice.call(arguments, 2))) - } - }; - } else {//IE8 - Array.prototype.splice = function(pos, removeCount){ - var length = this.length; - if (pos > 0) { - if (pos > length) - pos = length; - } else if (pos == void 0) { - pos = 0; - } else if (pos < 0) { - pos = Math.max(length + pos, 0); - } - - if (!(pos+removeCount < length)) - removeCount = length - pos; - - var removed = this.slice(pos, pos+removeCount); - var insert = slice.call(arguments, 2); - var add = insert.length; - if (pos === length) { - if (add) { - this.push.apply(this, insert); - } - } else { - var remove = Math.min(removeCount, length - pos); - var tailOldPos = pos + remove; - var tailNewPos = tailOldPos + add - remove; - var tailCount = length - tailOldPos; - var lengthAfterRemove = length - remove; - - if (tailNewPos < tailOldPos) { // case A - for (var i = 0; i < tailCount; ++i) { - this[tailNewPos+i] = this[tailOldPos+i]; - } - } else if (tailNewPos > tailOldPos) { // case B - for (i = tailCount; i--; ) { - this[tailNewPos+i] = this[tailOldPos+i]; - } - } // else, add == remove (nothing to do) - - if (add && pos === lengthAfterRemove) { - this.length = lengthAfterRemove; // truncate array - this.push.apply(this, insert); - } else { - this.length = lengthAfterRemove + add; // reserves space - for (i = 0; i < add; ++i) { - this[pos+i] = insert[i]; - } - } - } - return removed; - }; - } -} -if (!Array.isArray) { - Array.isArray = function isArray(obj) { - return _toString(obj) == "[object Array]"; - }; -} -var boxedString = Object("a"), - splitString = boxedString[0] != "a" || !(0 in boxedString); - -if (!Array.prototype.forEach) { - Array.prototype.forEach = function forEach(fun /*, thisp*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - thisp = arguments[1], - i = -1, - length = self.length >>> 0; - if (_toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message - } - - while (++i < length) { - if (i in self) { - fun.call(thisp, self[i], i, object); - } - } - }; -} -if (!Array.prototype.map) { - Array.prototype.map = function map(fun /*, thisp*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - result = Array(length), - thisp = arguments[1]; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self) - result[i] = fun.call(thisp, self[i], i, object); - } - return result; - }; -} -if (!Array.prototype.filter) { - Array.prototype.filter = function filter(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - result = [], - value, - thisp = arguments[1]; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self) { - value = self[i]; - if (fun.call(thisp, value, i, object)) { - result.push(value); - } - } - } - return result; - }; -} -if (!Array.prototype.every) { - Array.prototype.every = function every(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - thisp = arguments[1]; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self && !fun.call(thisp, self[i], i, object)) { - return false; - } - } - return true; - }; -} -if (!Array.prototype.some) { - Array.prototype.some = function some(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - thisp = arguments[1]; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self && fun.call(thisp, self[i], i, object)) { - return true; - } - } - return false; - }; -} -if (!Array.prototype.reduce) { - Array.prototype.reduce = function reduce(fun /*, initial*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - if (!length && arguments.length == 1) { - throw new TypeError("reduce of empty array with no initial value"); - } - - var i = 0; - var result; - if (arguments.length >= 2) { - result = arguments[1]; - } else { - do { - if (i in self) { - result = self[i++]; - break; - } - if (++i >= length) { - throw new TypeError("reduce of empty array with no initial value"); - } - } while (true); - } - - for (; i < length; i++) { - if (i in self) { - result = fun.call(void 0, result, self[i], i, object); - } - } - - return result; - }; -} -if (!Array.prototype.reduceRight) { - Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - if (!length && arguments.length == 1) { - throw new TypeError("reduceRight of empty array with no initial value"); - } - - var result, i = length - 1; - if (arguments.length >= 2) { - result = arguments[1]; - } else { - do { - if (i in self) { - result = self[i--]; - break; - } - if (--i < 0) { - throw new TypeError("reduceRight of empty array with no initial value"); - } - } while (true); - } - - do { - if (i in this) { - result = fun.call(void 0, result, self[i], i, object); - } - } while (i--); - - return result; - }; -} -if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { - Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { - var self = splitString && _toString(this) == "[object String]" ? - this.split("") : - toObject(this), - length = self.length >>> 0; - - if (!length) { - return -1; - } - - var i = 0; - if (arguments.length > 1) { - i = toInteger(arguments[1]); - } - i = i >= 0 ? i : Math.max(0, length + i); - for (; i < length; i++) { - if (i in self && self[i] === sought) { - return i; - } - } - return -1; - }; -} -if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { - Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { - var self = splitString && _toString(this) == "[object String]" ? - this.split("") : - toObject(this), - length = self.length >>> 0; - - if (!length) { - return -1; - } - var i = length - 1; - if (arguments.length > 1) { - i = Math.min(i, toInteger(arguments[1])); - } - i = i >= 0 ? i : length - Math.abs(i); - for (; i >= 0; i--) { - if (i in self && sought === self[i]) { - return i; - } - } - return -1; - }; -} -if (!Object.getPrototypeOf) { - Object.getPrototypeOf = function getPrototypeOf(object) { - return object.__proto__ || ( - object.constructor ? - object.constructor.prototype : - prototypeOfObject - ); - }; -} -if (!Object.getOwnPropertyDescriptor) { - var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " + - "non-object: "; - Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { - if ((typeof object != "object" && typeof object != "function") || object === null) - throw new TypeError(ERR_NON_OBJECT + object); - if (!owns(object, property)) - return; - - var descriptor, getter, setter; - descriptor = { enumerable: true, configurable: true }; - if (supportsAccessors) { - var prototype = object.__proto__; - object.__proto__ = prototypeOfObject; - - var getter = lookupGetter(object, property); - var setter = lookupSetter(object, property); - object.__proto__ = prototype; - - if (getter || setter) { - if (getter) descriptor.get = getter; - if (setter) descriptor.set = setter; - return descriptor; - } - } - descriptor.value = object[property]; - return descriptor; - }; -} -if (!Object.getOwnPropertyNames) { - Object.getOwnPropertyNames = function getOwnPropertyNames(object) { - return Object.keys(object); - }; -} -if (!Object.create) { - var createEmpty; - if (Object.prototype.__proto__ === null) { - createEmpty = function () { - return { "__proto__": null }; - }; - } else { - createEmpty = function () { - var empty = {}; - for (var i in empty) - empty[i] = null; - empty.constructor = - empty.hasOwnProperty = - empty.propertyIsEnumerable = - empty.isPrototypeOf = - empty.toLocaleString = - empty.toString = - empty.valueOf = - empty.__proto__ = null; - return empty; - } - } - - Object.create = function create(prototype, properties) { - var object; - if (prototype === null) { - object = createEmpty(); - } else { - if (typeof prototype != "object") - throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); - var Type = function () {}; - Type.prototype = prototype; - object = new Type(); - object.__proto__ = prototype; - } - if (properties !== void 0) - Object.defineProperties(object, properties); - return object; - }; -} - -function doesDefinePropertyWork(object) { - try { - Object.defineProperty(object, "sentinel", {}); - return "sentinel" in object; - } catch (exception) { - } -} -if (Object.defineProperty) { - var definePropertyWorksOnObject = doesDefinePropertyWork({}); - var definePropertyWorksOnDom = typeof document == "undefined" || - doesDefinePropertyWork(document.createElement("div")); - if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { - var definePropertyFallback = Object.defineProperty; - } -} - -if (!Object.defineProperty || definePropertyFallback) { - var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; - var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " - var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + - "on this javascript engine"; - - Object.defineProperty = function defineProperty(object, property, descriptor) { - if ((typeof object != "object" && typeof object != "function") || object === null) - throw new TypeError(ERR_NON_OBJECT_TARGET + object); - if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) - throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); - if (definePropertyFallback) { - try { - return definePropertyFallback.call(Object, object, property, descriptor); - } catch (exception) { - } - } - if (owns(descriptor, "value")) { - - if (supportsAccessors && (lookupGetter(object, property) || - lookupSetter(object, property))) - { - var prototype = object.__proto__; - object.__proto__ = prototypeOfObject; - delete object[property]; - object[property] = descriptor.value; - object.__proto__ = prototype; - } else { - object[property] = descriptor.value; - } - } else { - if (!supportsAccessors) - throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); - if (owns(descriptor, "get")) - defineGetter(object, property, descriptor.get); - if (owns(descriptor, "set")) - defineSetter(object, property, descriptor.set); - } - - return object; - }; -} -if (!Object.defineProperties) { - Object.defineProperties = function defineProperties(object, properties) { - for (var property in properties) { - if (owns(properties, property)) - Object.defineProperty(object, property, properties[property]); - } - return object; - }; -} -if (!Object.seal) { - Object.seal = function seal(object) { - return object; - }; -} -if (!Object.freeze) { - Object.freeze = function freeze(object) { - return object; - }; -} -try { - Object.freeze(function () {}); -} catch (exception) { - Object.freeze = (function freeze(freezeObject) { - return function freeze(object) { - if (typeof object == "function") { - return object; - } else { - return freezeObject(object); - } - }; - })(Object.freeze); -} -if (!Object.preventExtensions) { - Object.preventExtensions = function preventExtensions(object) { - return object; - }; -} -if (!Object.isSealed) { - Object.isSealed = function isSealed(object) { - return false; - }; -} -if (!Object.isFrozen) { - Object.isFrozen = function isFrozen(object) { - return false; - }; -} -if (!Object.isExtensible) { - Object.isExtensible = function isExtensible(object) { - if (Object(object) === object) { - throw new TypeError(); // TODO message - } - var name = ''; - while (owns(object, name)) { - name += '?'; - } - object[name] = true; - var returnValue = owns(object, name); - delete object[name]; - return returnValue; - }; -} -if (!Object.keys) { - var hasDontEnumBug = true, - dontEnums = [ - "toString", - "toLocaleString", - "valueOf", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "constructor" - ], - dontEnumsLength = dontEnums.length; - - for (var key in {"toString": null}) { - hasDontEnumBug = false; - } - - Object.keys = function keys(object) { - - if ( - (typeof object != "object" && typeof object != "function") || - object === null - ) { - throw new TypeError("Object.keys called on a non-object"); - } - - var keys = []; - for (var name in object) { - if (owns(object, name)) { - keys.push(name); - } - } - - if (hasDontEnumBug) { - for (var i = 0, ii = dontEnumsLength; i < ii; i++) { - var dontEnum = dontEnums[i]; - if (owns(object, dontEnum)) { - keys.push(dontEnum); - } - } - } - return keys; - }; - -} -if (!Date.now) { - Date.now = function now() { - return new Date().getTime(); - }; -} -var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" + - "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + - "\u2029\uFEFF"; -if (!String.prototype.trim) { - ws = "[" + ws + "]"; - var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), - trimEndRegexp = new RegExp(ws + ws + "*$"); - String.prototype.trim = function trim() { - return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); - }; -} - -function toInteger(n) { - n = +n; - if (n !== n) { // isNaN - n = 0; - } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - return n; -} - -function isPrimitive(input) { - var type = typeof input; - return ( - input === null || - type === "undefined" || - type === "boolean" || - type === "number" || - type === "string" - ); -} - -function toPrimitive(input) { - var val, valueOf, toString; - if (isPrimitive(input)) { - return input; - } - valueOf = input.valueOf; - if (typeof valueOf === "function") { - val = valueOf.call(input); - if (isPrimitive(val)) { - return val; - } - } - toString = input.toString; - if (typeof toString === "function") { - val = toString.call(input); - if (isPrimitive(val)) { - return val; - } - } - throw new TypeError(); -} -var toObject = function (o) { - if (o == null) { // this matches both null and undefined - throw new TypeError("can't convert "+o+" to object"); - } - return Object(o); -}; - -}); - -define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"], function(require, exports, module) { -"use strict"; - -require("./regexp"); -require("./es5-shim"); if (typeof Element != "undefined" && !Element.prototype.remove) { Object.defineProperty(Element.prototype, "remove", { enumerable: false, @@ -1026,8 +253,11 @@ exports.buildDom = function buildDom(arr, parent, refs) { return txt; } - if (!Array.isArray(arr)) + if (!Array.isArray(arr)) { + if (arr && arr.appendChild && parent) + parent.appendChild(arr); return arr; + } if (typeof arr[0] != "string" || !arr[0]) { var els = []; for (var i = 0; i < arr.length; i++) { @@ -1049,10 +279,12 @@ exports.buildDom = function buildDom(arr, parent, refs) { var val = options[n]; if (n === "class") { el.className = Array.isArray(val) ? val.join(" ") : val; - } else if (typeof val == "function" || n == "value") { + } else if (typeof val == "function" || n == "value" || n[0] == "$") { el[n] = val; } else if (n === "ref") { if (refs) refs[val] = el; + } else if (n === "style") { + if (typeof val == "string") el.style.cssText = val; } else if (val != null) { el.setAttribute(n, val); } @@ -1144,7 +376,34 @@ exports.hasCssString = function(id, doc) { } }; -exports.importCssString = function importCssString(cssText, id, target) { +var strictCSP; +var cssCache = []; +exports.useStrictCSP = function(value) { + strictCSP = value; + if (value == false) insertPendingStyles(); + else if (!cssCache) cssCache = []; +}; + +function insertPendingStyles() { + var cache = cssCache; + cssCache = null; + cache && cache.forEach(function(item) { + importCssString(item[0], item[1]); + }); +} + +function importCssString(cssText, id, target) { + if (typeof document == "undefined") + return; + if (cssCache) { + if (target) { + insertPendingStyles(); + } else if (target === false) { + return cssCache.push([cssText, id]); + } + } + if (strictCSP) return; + var container = target; if (!target || !target.getRootNode) { container = document; @@ -1169,7 +428,8 @@ exports.importCssString = function importCssString(cssText, id, target) { if (container == doc) container = exports.getDocumentHead(doc); container.insertBefore(style, container.firstChild); -}; +} +exports.importCssString = importCssString; exports.importCssStylsheet = function(uri, doc) { exports.buildDom(["link", {rel: "stylesheet", href: uri}], exports.getDocumentHead(doc)); @@ -1211,10 +471,6 @@ exports.scrollbarWidth = function(document) { return noScrollbar-withScrollbar; }; -if (typeof document == "undefined") { - exports.importCssString = function() {}; -} - exports.computedStyle = function(element, style) { return window.getComputedStyle(element, "") || {}; }; @@ -1231,6 +487,8 @@ exports.HI_DPI = useragent.isWin ? typeof window !== "undefined" && window.devicePixelRatio >= 1.5 : true; +if (useragent.isChromeOS) exports.HI_DPI = false; + if (typeof document !== "undefined") { var div = document.createElement("div"); if (exports.HI_DPI && div.style.transform !== undefined) @@ -1294,7 +552,8 @@ var Keys = (function() { KEY_MODS: { "ctrl": 1, "alt": 2, "option" : 2, "shift": 4, - "super": 8, "meta": 8, "command": 8, "cmd": 8 + "super": 8, "meta": 8, "command": 8, "cmd": 8, + "control": 1 }, FUNCTION_KEYS : { @@ -1422,12 +681,24 @@ function getListenerOptions() { return activeListenerOptions; } -exports.addListener = function(elem, type, callback) { - return elem.addEventListener(type, callback, getListenerOptions()); +function EventListener(elem, type, callback) { + this.elem = elem; + this.type = type; + this.callback = callback; +} +EventListener.prototype.destroy = function() { + removeListener(this.elem, this.type, this.callback); + this.elem = this.type = this.callback = undefined; }; -exports.removeListener = function(elem, type, callback) { - return elem.removeEventListener(type, callback, getListenerOptions()); +var addListener = exports.addListener = function(elem, type, callback, destroyer) { + elem.addEventListener(type, callback, getListenerOptions()); + if (destroyer) + destroyer.$toDestroy.push(new EventListener(elem, type, callback)); +}; + +var removeListener = exports.removeListener = function(elem, type, callback) { + elem.removeEventListener(type, callback, getListenerOptions()); }; exports.stopEvent = function(e) { exports.stopPropagation(e); @@ -1453,25 +724,26 @@ exports.getButton = function(e) { }; exports.capture = function(el, eventHandler, releaseCaptureHandler) { + var ownerDocument = el && el.ownerDocument || document; function onMouseUp(e) { eventHandler && eventHandler(e); releaseCaptureHandler && releaseCaptureHandler(e); - exports.removeListener(document, "mousemove", eventHandler, true); - exports.removeListener(document, "mouseup", onMouseUp, true); - exports.removeListener(document, "dragstart", onMouseUp, true); + removeListener(ownerDocument, "mousemove", eventHandler); + removeListener(ownerDocument, "mouseup", onMouseUp); + removeListener(ownerDocument, "dragstart", onMouseUp); } - exports.addListener(document, "mousemove", eventHandler, true); - exports.addListener(document, "mouseup", onMouseUp, true); - exports.addListener(document, "dragstart", onMouseUp, true); + addListener(ownerDocument, "mousemove", eventHandler); + addListener(ownerDocument, "mouseup", onMouseUp); + addListener(ownerDocument, "dragstart", onMouseUp); return onMouseUp; }; -exports.addMouseWheelListener = function(el, callback) { +exports.addMouseWheelListener = function(el, callback, destroyer) { if ("onmousewheel" in el) { - exports.addListener(el, "mousewheel", function(e) { + addListener(el, "mousewheel", function(e) { var factor = 8; if (e.wheelDeltaX !== undefined) { e.wheelX = -e.wheelDeltaX / factor; @@ -1481,9 +753,9 @@ exports.addMouseWheelListener = function(el, callback) { e.wheelY = -e.wheelDelta / factor; } callback(e); - }); + }, destroyer); } else if ("onwheel" in el) { - exports.addListener(el, "wheel", function(e) { + addListener(el, "wheel", function(e) { var factor = 0.35; switch (e.deltaMode) { case e.DOM_DELTA_PIXEL: @@ -1498,9 +770,9 @@ exports.addMouseWheelListener = function(el, callback) { } callback(e); - }); + }, destroyer); } else { - exports.addListener(el, "DOMMouseScroll", function(e) { + addListener(el, "DOMMouseScroll", function(e) { if (e.axis && e.axis == e.HORIZONTAL_AXIS) { e.wheelX = (e.detail || 0) * 5; e.wheelY = 0; @@ -1509,11 +781,11 @@ exports.addMouseWheelListener = function(el, callback) { e.wheelY = (e.detail || 0) * 5; } callback(e); - }); + }, destroyer); } }; -exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName) { +exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName, destroyer) { var clicks = 0; var startX, startY, timer; var eventNames = { @@ -1558,7 +830,7 @@ exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, c if (!Array.isArray(elements)) elements = [elements]; elements.forEach(function(el) { - exports.addListener(el, "mousedown", onMousedown); + addListener(el, "mousedown", onMousedown, destroyer); }); }; @@ -1623,16 +895,15 @@ function normalizeCommandKeys(callback, e, keyCode) { } -exports.addCommandKeyListener = function(el, callback) { - var addListener = exports.addListener; +exports.addCommandKeyListener = function(el, callback, destroyer) { if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) { var lastKeyDownKeyCode = null; addListener(el, "keydown", function(e) { lastKeyDownKeyCode = e.keyCode; - }); + }, destroyer); addListener(el, "keypress", function(e) { return normalizeCommandKeys(callback, e, lastKeyDownKeyCode); - }); + }, destroyer); } else { var lastDefaultPrevented = null; @@ -1641,18 +912,18 @@ exports.addCommandKeyListener = function(el, callback) { var result = normalizeCommandKeys(callback, e, e.keyCode); lastDefaultPrevented = e.defaultPrevented; return result; - }); + }, destroyer); addListener(el, "keypress", function(e) { if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) { exports.stopEvent(e); lastDefaultPrevented = null; } - }); + }, destroyer); addListener(el, "keyup", function(e) { pressedKeys[e.keyCode] = null; - }); + }, destroyer); if (!pressedKeys) { resetPressedKeys(); @@ -1673,12 +944,12 @@ if (typeof window == "object" && window.postMessage && !useragent.isOldIE) { var listener = function(e) { if (e.data == messageName) { exports.stopPropagation(e); - exports.removeListener(win, "message", listener); + removeListener(win, "message", listener); callback(); } }; - exports.addListener(win, "message", listener); + addListener(win, "message", listener); win.postMessage(messageName, "*"); }; } @@ -2181,6 +1452,7 @@ var KEYS = require("../lib/keys"); var MODS = KEYS.KEY_MODS; var isIOS = useragent.isIOS; var valueResetRegex = isIOS ? /\s/ : /\n/; +var isMobile = useragent.isMobile; var TextInput = function(parentNode, host) { var text = dom.createElement("textarea"); @@ -2200,7 +1472,7 @@ var TextInput = function(parentNode, host) { var sendingText = false; var tempStyle = ''; - if (!useragent.isMobile) + if (!isMobile) text.style.fontSize = "1px"; var commandMode = false; @@ -2216,7 +1488,7 @@ var TextInput = function(parentNode, host) { if (ignoreFocusEvents) return; host.onBlur(e); isFocused = false; - }); + }, host); event.addListener(text, "focus", function(e) { if (ignoreFocusEvents) return; isFocused = true; @@ -2231,7 +1503,7 @@ var TextInput = function(parentNode, host) { setTimeout(resetSelection); else resetSelection(); - }); + }, host); this.$focusScroll = false; this.focus = function() { if (tempStyle || HAS_FOCUS_ARGS || this.$focusScroll == "browser") @@ -2277,9 +1549,12 @@ var TextInput = function(parentNode, host) { }; host.on("beforeEndOperation", function() { - if (host.curOp && host.curOp.command.name == "insertstring") + var curOp = host.curOp; + var commandName = curOp && curOp.command && curOp.command.name; + if (commandName == "insertstring") return; - if (inComposition) { + var isUserAction = commandName && (curOp.docChanged || curOp.selectionChanged); + if (inComposition && isUserAction) { lastValue = text.value = ""; onCompositionEnd(); } @@ -2311,33 +1586,49 @@ var TextInput = function(parentNode, host) { return; inComposition = true; - var selection = host.selection; - var range = selection.getRange(); - var row = selection.cursor.row; - var selectionStart = range.start.column; - var selectionEnd = range.end.column; - var line = host.session.getLine(row); + var selectionStart = 0; + var selectionEnd = 0; + var line = ""; - if (range.start.row != row) { - var prevLine = host.session.getLine(row - 1); - selectionStart = range.start.row < row - 1 ? 0 : selectionStart; - selectionEnd += prevLine.length + 1; - line = prevLine + "\n" + line; - } - else if (range.end.row != row) { - var nextLine = host.session.getLine(row + 1); - selectionEnd = range.end.row > row + 1 ? nextLine.length : selectionEnd; - selectionEnd += line.length + 1; - line = line + "\n" + nextLine; - } + if (host.session) { + var selection = host.selection; + var range = selection.getRange(); + var row = selection.cursor.row; + selectionStart = range.start.column; + selectionEnd = range.end.column; + line = host.session.getLine(row); - if (line.length > MAX_LINE_LENGTH) { - if (selectionStart < MAX_LINE_LENGTH && selectionEnd < MAX_LINE_LENGTH) { - line = line.slice(0, MAX_LINE_LENGTH); - } else { - line = "\n"; - selectionStart = 0; - selectionEnd = 1; + if (range.start.row != row) { + var prevLine = host.session.getLine(row - 1); + selectionStart = range.start.row < row - 1 ? 0 : selectionStart; + selectionEnd += prevLine.length + 1; + line = prevLine + "\n" + line; + } + else if (range.end.row != row) { + var nextLine = host.session.getLine(row + 1); + selectionEnd = range.end.row > row + 1 ? nextLine.length : selectionEnd; + selectionEnd += line.length + 1; + line = line + "\n" + nextLine; + } + else if (isMobile && row > 0) { + line = "\n" + line; + selectionEnd += 1; + selectionStart += 1; + } + + if (line.length > MAX_LINE_LENGTH) { + if (selectionStart < MAX_LINE_LENGTH && selectionEnd < MAX_LINE_LENGTH) { + line = line.slice(0, MAX_LINE_LENGTH); + } else { + line = "\n"; + if (selectionStart == selectionEnd) { + selectionStart = selectionEnd = 0; + } + else { + selectionStart = 0; + selectionEnd = 1; + } + } } } @@ -2363,6 +1654,7 @@ var TextInput = function(parentNode, host) { } inComposition = false; }; + this.resetSelection = resetSelection; if (isFocused) host.onFocus(); @@ -2382,6 +1674,8 @@ var TextInput = function(parentNode, host) { } else if (isAllSelected(text)) { host.selectAll(); resetSelection(); + } else if (isMobile && text.selectionStart != lastSelectionStart) { + resetSelection(); } }; @@ -2432,6 +1726,12 @@ var TextInput = function(parentNode, host) { if (!fromInput && !inserted && !restoreStart && !extendLeft && !extendRight && !restoreEnd) return ""; sendingText = true; + var shouldReset = false; + if (useragent.isAndroid && inserted == ". ") { + inserted = " "; + shouldReset = true; + } + if (inserted && !extendLeft && !extendRight && !restoreStart && !restoreEnd || commandMode) { host.onTextInput(inserted); } else { @@ -2448,7 +1748,7 @@ var TextInput = function(parentNode, host) { lastSelectionStart = selectionStart; lastSelectionEnd = selectionEnd; lastRestoreEnd = restoreEnd; - return inserted; + return shouldReset ? "\n" : inserted; } }; var onInput = function(e) { @@ -2460,8 +1760,13 @@ var TextInput = function(parentNode, host) { } var data = text.value; var inserted = sendText(data, true); - if (data.length > MAX_LINE_LENGTH + 100 || valueResetRegex.test(inserted)) + if ( + data.length > MAX_LINE_LENGTH + 100 + || valueResetRegex.test(inserted) + || isMobile && lastSelectionStart < 1 && lastSelectionStart == lastSelectionEnd + ) { resetSelection(); + } }; var handleClipboardData = function(e, data, forceIEMime) { @@ -2533,14 +1838,14 @@ var TextInput = function(parentNode, host) { } }; - event.addCommandKeyListener(text, host.onCommandKey.bind(host)); + event.addCommandKeyListener(text, host.onCommandKey.bind(host), host); - event.addListener(text, "select", onSelect); - event.addListener(text, "input", onInput); + event.addListener(text, "select", onSelect, host); + event.addListener(text, "input", onInput, host); - event.addListener(text, "cut", onCut); - event.addListener(text, "copy", onCopy); - event.addListener(text, "paste", onPaste); + event.addListener(text, "cut", onCut, host); + event.addListener(text, "copy", onCopy, host); + event.addListener(text, "paste", onPaste, host); if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)) { event.addListener(parentNode, "keydown", function(e) { if ((useragent.isMac && !e.metaKey) || !e.ctrlKey) @@ -2557,7 +1862,7 @@ var TextInput = function(parentNode, host) { onCut(e); break; } - }); + }, host); } var onCompositionStart = function(e) { if (inComposition || !host.onCompositionStart || host.$readOnly) @@ -2568,7 +1873,11 @@ var TextInput = function(parentNode, host) { if (commandMode) return; + if (e.data) + inComposition.useTextareaForIME = false; + setTimeout(onCompositionUpdate, 0); + host._signal("compositionStart"); host.on("mousedown", cancelComposition); var range = host.getSelectionRange(); @@ -2579,8 +1888,7 @@ var TextInput = function(parentNode, host) { host.onCompositionStart(inComposition); if (inComposition.useTextareaForIME) { - text.value = ""; - lastValue = ""; + lastValue = text.value = ""; lastSelectionStart = 0; lastSelectionEnd = 0; } @@ -2643,11 +1951,11 @@ var TextInput = function(parentNode, host) { syncComposition(); } - event.addListener(text, "compositionstart", onCompositionStart); - event.addListener(text, "compositionupdate", onCompositionUpdate); - event.addListener(text, "keyup", onKeyup); - event.addListener(text, "keydown", syncComposition); - event.addListener(text, "compositionend", onCompositionEnd); + event.addListener(text, "compositionstart", onCompositionStart, host); + event.addListener(text, "compositionupdate", onCompositionUpdate, host); + event.addListener(text, "keyup", onKeyup, host); + event.addListener(text, "keydown", syncComposition, host); + event.addListener(text, "compositionend", onCompositionEnd, host); this.getElement = function() { return text; @@ -2718,13 +2026,13 @@ var TextInput = function(parentNode, host) { host.textInput.onContextMenu(e); onContextMenuClose(); }; - event.addListener(text, "mouseup", onContextMenu); + event.addListener(text, "mouseup", onContextMenu, host); event.addListener(text, "mousedown", function(e) { e.preventDefault(); onContextMenuClose(); - }); - event.addListener(host.renderer.scroller, "contextmenu", onContextMenu); - event.addListener(text, "contextmenu", onContextMenu); + }, host); + event.addListener(host.renderer.scroller, "contextmenu", onContextMenu, host); + event.addListener(text, "contextmenu", onContextMenu, host); if (isIOS) addIosSelectionHandler(parentNode, host, text); @@ -2810,10 +2118,13 @@ var TextInput = function(parentNode, host) { document.removeEventListener("selectionchange", detectArrowKeys); }); } - }; exports.TextInput = TextInput; +exports.$setUserAgentForTests = function(_isMobile, _isIOS) { + isMobile = _isMobile; + isIOS = _isIOS; +}; }); define("ace/mouse/default_handlers",["require","exports","module","ace/lib/useragent"], function(require, exports, module) { @@ -3243,7 +2554,7 @@ function GutterHandler(mouseHandler) { tooltip.hide(); tooltipAnnotation = null; editor._signal("hideGutterTooltip", tooltip); - editor.removeEventListener("mousewheel", hideTooltip); + editor.off("mousewheel", hideTooltip); } } @@ -3280,7 +2591,7 @@ function GutterHandler(mouseHandler) { tooltipTimeout = null; hideTooltip(); }, 50); - }); + }, editor); editor.on("changeSession", hideTooltip); } @@ -3405,18 +2716,16 @@ function DragdropHandler(mouseHandler) { var editor = mouseHandler.editor; - var blankImage = dom.createElement("img"); - blankImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; - if (useragent.isOpera) - blankImage.style.cssText = "width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;"; + var dragImage = dom.createElement("div"); + dragImage.style.cssText = "top:-100px;position:absolute;z-index:2147483647;opacity:0.5"; + dragImage.textContent = "\xa0"; var exports = ["dragWait", "dragWaitEnd", "startDrag", "dragReadyEnd", "onMouseDrag"]; - exports.forEach(function(x) { - mouseHandler[x] = this[x]; + exports.forEach(function(x) { + mouseHandler[x] = this[x]; }, this); - editor.addEventListener("mousedown", this.onMouseDown.bind(mouseHandler)); - + editor.on("mousedown", this.onMouseDown.bind(mouseHandler)); var mouseTarget = editor.container; var dragSelectionMarker, x, y; @@ -3441,14 +2750,12 @@ function DragdropHandler(mouseHandler) { var dataTransfer = e.dataTransfer; dataTransfer.effectAllowed = editor.getReadOnly() ? "copy" : "copyMove"; - if (useragent.isOpera) { - editor.container.appendChild(blankImage); - blankImage.scrollTop = 0; - } - dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0); - if (useragent.isOpera) { - editor.container.removeChild(blankImage); - } + editor.container.appendChild(dragImage); + + dataTransfer.setDragImage && dataTransfer.setDragImage(dragImage, 0, 0); + setTimeout(function() { + editor.container.removeChild(dragImage); + }); dataTransfer.clearData(); dataTransfer.setData("Text", editor.session.getTextRange()); @@ -3540,12 +2847,12 @@ function DragdropHandler(mouseHandler) { return event.preventDefault(e); }; - event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler)); - event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler)); - event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler)); - event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler)); - event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler)); - event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler)); + event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler), editor); + event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler), editor); + event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler), editor); + event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler), editor); + event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler), editor); + event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler), editor); function scrollCursorIntoView(cursor, prevCursor) { var now = Date.now(); @@ -3860,9 +3167,17 @@ exports.addTouchListeners = function(el, editor) { if (!contextMenu) createContextMenu(); var cursor = editor.selection.cursor; var pagePos = editor.renderer.textToScreenCoordinates(cursor.row, cursor.column); + var leftOffset = editor.renderer.textToScreenCoordinates(0, 0).pageX; + var scrollLeft = editor.renderer.scrollLeft; var rect = editor.container.getBoundingClientRect(); contextMenu.style.top = pagePos.pageY - rect.top - 3 + "px"; - contextMenu.style.right = "10px"; + if (pagePos.pageX - rect.left < rect.width - 70) { + contextMenu.style.left = ""; + contextMenu.style.right = "10px"; + } else { + contextMenu.style.right = ""; + contextMenu.style.left = leftOffset + scrollLeft - rect.left + "px"; + } contextMenu.style.display = ""; contextMenu.firstChild.style.display = "none"; editor.on("input", hideContextMenu); @@ -3903,7 +3218,7 @@ exports.addTouchListeners = function(el, editor) { if (!pressed) return; var textarea = editor.textInput.getElement(); textarea.focus(); - }); + }, editor); event.addListener(el, "touchstart", function (e) { var touches = e.touches; if (longTouchTimer || touches.length > 1) { @@ -3945,6 +3260,8 @@ exports.addTouchListeners = function(el, editor) { var cursorPos = editor.renderer.$cursorLayer.getPixelPosition(cursor, true); var anchorPos = editor.renderer.$cursorLayer.getPixelPosition(anchor, true); var rect = editor.renderer.scroller.getBoundingClientRect(); + var offsetTop = editor.renderer.layerConfig.offset; + var offsetLeft = editor.renderer.scrollLeft; var weightedDistance = function(x, y) { x = x / w; y = y / h - 0.75; @@ -3957,12 +3274,12 @@ exports.addTouchListeners = function(el, editor) { } var diff1 = weightedDistance( - e.clientX - rect.left - cursorPos.left, - e.clientY - rect.top - cursorPos.top + e.clientX - rect.left - cursorPos.left + offsetLeft, + e.clientY - rect.top - cursorPos.top + offsetTop ); var diff2 = weightedDistance( - e.clientX - rect.left - anchorPos.left, - e.clientY - rect.top - anchorPos.top + e.clientX - rect.left - anchorPos.left + offsetLeft, + e.clientY - rect.top - anchorPos.top + offsetTop ); if (diff1 < 3.5 && diff2 < 3.5) mode = diff1 > diff2 ? "cursor" : "anchor"; @@ -3976,7 +3293,7 @@ exports.addTouchListeners = function(el, editor) { longTouchTimer = setTimeout(handleLongTap, 450); } touchStartT = t; - }); + }, editor); event.addListener(el, "touchend", function (e) { pressed = editor.$mouseHandler.isMousePressed = false; @@ -3990,14 +3307,13 @@ exports.addTouchListeners = function(el, editor) { showContextMenu(); } else if (mode == "scroll") { animate(); - e.preventDefault(); hideContextMenu(); } else { showContextMenu(); } clearTimeout(longTouchTimer); longTouchTimer = null; - }); + }, editor); event.addListener(el, "touchmove", function (e) { if (longTouchTimer) { clearTimeout(longTouchTimer); @@ -4053,7 +3369,7 @@ exports.addTouchListeners = function(el, editor) { editor.renderer.scrollCursorIntoView(pos); e.preventDefault(); } - }); + }, editor); function animate() { animationSteps += 60; @@ -4164,8 +3480,8 @@ EventEmitter._signal = function(eventName, e) { EventEmitter.once = function(eventName, callback) { var _self = this; - this.addEventListener(eventName, function newCallback() { - _self.removeEventListener(eventName, newCallback); + this.on(eventName, function newCallback() { + _self.off(eventName, newCallback); callback.apply(null, arguments); }); if (!callback) { @@ -4237,7 +3553,9 @@ EventEmitter.removeEventListener = function(eventName, callback) { }; EventEmitter.removeAllListeners = function(eventName) { - if (this._eventRegistry) this._eventRegistry[eventName] = []; + if (!eventName) this._eventRegistry = this._defaultHandlers = undefined; + if (this._eventRegistry) this._eventRegistry[eventName] = undefined; + if (this._defaultHandlers) this._defaultHandlers[eventName] = undefined; }; exports.EventEmitter = EventEmitter; @@ -4376,12 +3694,13 @@ exports.AppConfig = AppConfig; }); -define("ace/config",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/lib/net","ace/lib/app_config"], function(require, exports, module) { +define("ace/config",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/lib/net","ace/lib/dom","ace/lib/app_config"], function(require, exports, module) { "no use strict"; var lang = require("./lib/lang"); var oop = require("./lib/oop"); var net = require("./lib/net"); +var dom = require("./lib/dom"); var AppConfig = require("./lib/app_config").AppConfig; module.exports = exports = new AppConfig(); @@ -4399,13 +3718,13 @@ var options = { suffix: ".js", $moduleUrls: {}, loadWorkerFromBlob: true, - sharedPopups: false + sharedPopups: false, + useStrictCSP: null }; exports.get = function(key) { if (!options.hasOwnProperty(key)) throw new Error("Unknown config key: " + key); - return options[key]; }; @@ -4414,6 +3733,8 @@ exports.set = function(key, value) { options[key] = value; else if (this.setDefaultValue("", key, value) == false) throw new Error("Unknown config key: " + key); + if (key == "useStrictCSP") + dom.useStrictCSP(value); }; exports.all = function() { @@ -4560,7 +3881,7 @@ function deHyphenate(str) { return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); }); } -exports.version = "1.4.8"; +exports.version = "1.4.14"; }); @@ -4593,28 +3914,28 @@ var MouseHandler = function(editor) { }; var mouseTarget = editor.renderer.getMouseEventTarget(); - event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click")); - event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove")); + event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"), editor); + event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove"), editor); event.addMultiMouseDownListener([ mouseTarget, editor.renderer.scrollBarV && editor.renderer.scrollBarV.inner, editor.renderer.scrollBarH && editor.renderer.scrollBarH.inner, editor.textInput && editor.textInput.getElement() - ].filter(Boolean), [400, 300, 250], this, "onMouseEvent"); - event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel")); + ].filter(Boolean), [400, 300, 250], this, "onMouseEvent", editor); + event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel"), editor); addTouchListeners(editor.container, editor); var gutterEl = editor.renderer.$gutter; - event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown")); - event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick")); - event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick")); - event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove")); + event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown"), editor); + event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"), editor); + event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick"), editor); + event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove"), editor); - event.addListener(mouseTarget, "mousedown", focusEditor); - event.addListener(gutterEl, "mousedown", focusEditor); + event.addListener(mouseTarget, "mousedown", focusEditor, editor); + event.addListener(gutterEl, "mousedown", focusEditor, editor); if (useragent.isIE && editor.renderer.scrollBarV) { - event.addListener(editor.renderer.scrollBarV.element, "mousedown", focusEditor); - event.addListener(editor.renderer.scrollBarH.element, "mousedown", focusEditor); + event.addListener(editor.renderer.scrollBarV.element, "mousedown", focusEditor, editor); + event.addListener(editor.renderer.scrollBarH.element, "mousedown", focusEditor, editor); } editor.on("mousemove", function(e){ @@ -4630,11 +3951,12 @@ var MouseHandler = function(editor) { } else { renderer.setCursorStyle(""); } - }); + }, editor); }; (function() { this.onMouseEvent = function(name, e) { + if (!this.editor.session) return; this.editor._emit(name, new MouseEvent(e, this.editor)); }; @@ -4684,7 +4006,7 @@ var MouseHandler = function(editor) { var onCaptureEnd = function(e) { editor.off("beforeEndOperation", onOperationEnd); clearInterval(timerId); - onCaptureInterval(); + if (editor.session) onCaptureInterval(); self[self.state + "End"] && self[self.state + "End"](e); self.state = ""; self.isMousePressed = renderer.$isMousePressed = false; @@ -4732,6 +4054,9 @@ var MouseHandler = function(editor) { setTimeout(stop, 10); this.editor.on("nativecontextmenu", stop); }; + this.destroy = function() { + if (this.releaseMouse) this.releaseMouse(); + }; }).call(MouseHandler.prototype); config.defineOptions(MouseHandler.prototype, "mouseHandler", { @@ -6102,7 +5427,6 @@ var Selection = function(session) { this.detach = function() { this.lead.detach(); this.anchor.detach(); - this.session = this.doc = null; }; this.fromOrientedRange = function(range) { @@ -6318,7 +5642,7 @@ var Tokenizer = function(rules) { this.removeCapturingGroups = function(src) { var r = src.replace( - /\\.|\[(?:\\.|[^\\\]])*|\(\?[:=!]|(\()/g, + /\\.|\[(?:\\.|[^\\\]])*|\(\?[:=!<]|(\()/g, function(x, y) {return y ? "(?:" : x;} ); return r; @@ -6677,18 +6001,18 @@ var TextHighlightRules = function() { this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) { var keywords = Object.create(null); + this.$keywordList = []; Object.keys(map).forEach(function(className) { var a = map[className]; - if (ignoreCase) - a = a.toLowerCase(); var list = a.split(splitChar || "|"); - for (var i = list.length; i--; ) - keywords[list[i]] = className; - }); - if (Object.getPrototypeOf(keywords)) { - keywords.__proto__ = null; - } - this.$keywordList = Object.keys(keywords); + for (var i = list.length; i--; ) { + var word = list[i]; + this.$keywordList.push(word); + if (ignoreCase) + word = word.toLowerCase(); + keywords[word] = className; + } + }, this); map = null; return ignoreCase ? function(value) {return keywords[value.toLowerCase()] || defaultToken; } @@ -7751,7 +7075,7 @@ var Anchor = exports.Anchor = function(doc, row, column) { }); }; this.detach = function() { - this.document.removeEventListener("change", this.$onChange); + this.document.off("change", this.$onChange); }; this.attach = function(doc) { this.document = doc || this.document; @@ -8083,6 +7407,16 @@ var Document = function(textOrLines) { } }; + this.$safeApplyDelta = function(delta) { + var docLength = this.$lines.length; + if ( + delta.action == "remove" && delta.start.row < docLength && delta.end.row < docLength + || delta.action == "insert" && delta.start.row <= docLength + ) { + this.applyDelta(delta); + } + }; + this.$splitAndapplyLargeDelta = function(delta, MAX) { var lines = delta.lines; var l = lines.length - MAX + 1; @@ -8105,7 +7439,7 @@ var Document = function(textOrLines) { this.applyDelta(delta, true); }; this.revertDelta = function(delta) { - this.applyDelta({ + this.$safeApplyDelta({ start: this.clonePos(delta.start), end: this.clonePos(delta.end), action: (delta.action == "insert" ? "remove" : "insert"), @@ -9142,9 +8476,11 @@ function Folding() { var folds = this.getFoldsInRange(fold.range); if (folds.length > 0) { this.removeFolds(folds); - folds.forEach(function(subFold) { - fold.addSubFold(subFold); - }); + if (!fold.collapseChildren) { + folds.forEach(function(subFold) { + fold.addSubFold(subFold); + }); + } } for (var i = 0; i < foldData.length; i++) { @@ -9263,26 +8599,39 @@ function Folding() { var range, folds; if (location == null) { range = new Range(0, 0, this.getLength(), 0); - expandInner = true; - } else if (typeof location == "number") + if (expandInner == null) expandInner = true; + } else if (typeof location == "number") { range = new Range(location, 0, location, this.getLine(location).length); - else if ("row" in location) + } else if ("row" in location) { range = Range.fromPoints(location, location); - else + } else if (Array.isArray(location)) { + folds = []; + location.forEach(function(range) { + folds = folds.concat(this.unfold(range)); + }, this); + return folds; + } else { range = location; + } folds = this.getFoldsInRangeList(range); - if (expandInner) { + var outermostFolds = folds; + while ( + folds.length == 1 + && Range.comparePoints(folds[0].start, range.start) < 0 + && Range.comparePoints(folds[0].end, range.end) > 0 + ) { + this.expandFolds(folds); + folds = this.getFoldsInRangeList(range); + } + + if (expandInner != false) { this.removeFolds(folds); } else { - var subFolds = folds; - while (subFolds.length) { - this.expandFolds(subFolds); - subFolds = this.getFoldsInRangeList(range); - } + this.expandFolds(folds); } - if (folds.length) - return folds; + if (outermostFolds.length) + return outermostFolds; }; this.isRowFolded = function(docRow, startFoldRow) { return !!this.getFoldLine(docRow, startFoldRow); @@ -9416,7 +8765,7 @@ function Folding() { this.getCommentFoldRange = function(row, column, dir) { var iterator = new TokenIterator(this, row, column); var token = iterator.getCurrentToken(); - var type = token.type; + var type = token && token.type; if (token && /^comment|string/.test(type)) { type = type.match(/comment|string/)[0]; if (type == "comment") @@ -9457,7 +8806,7 @@ function Folding() { } }; - this.foldAll = function(startRow, endRow, depth) { + this.foldAll = function(startRow, endRow, depth, test) { if (depth == undefined) depth = 100000; // JSON.stringify doesn't hanle Infinity var foldWidgets = this.foldWidgets; @@ -9470,6 +8819,8 @@ function Folding() { foldWidgets[row] = this.getFoldWidget(row); if (foldWidgets[row] != "start") continue; + + if (test && !test(row)) continue; var range = this.getFoldWidgetRange(row); if (range && range.isMultiLine() @@ -9477,14 +8828,32 @@ function Folding() { && range.start.row >= startRow ) { row = range.end.row; - try { - var fold = this.addFold("...", range); - if (fold) - fold.collapseChildren = depth; - } catch(e) {} + range.collapseChildren = depth; + this.addFold("...", range); } } }; + + this.foldToLevel = function(level) { + this.foldAll(); + while (level-- > 0) + this.unfold(null, false); + }; + + this.foldAllComments = function() { + var session = this; + this.foldAll(null, null, null, function(row) { + var tokens = session.getTokens(row); + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + if (token.type == "text" && /^\s+$/.test(token.value)) + continue; + if (/comment/.test(token.type)) + return true; + return false; + } + }); + }; this.$foldStyles = { "manual": 1, "markbegin": 1, @@ -9929,7 +9298,7 @@ EditSession.$uid = 0; oop.implement(this, EventEmitter); this.setDocument = function(doc) { if (this.doc) - this.doc.removeListener("change", this.$onChange); + this.doc.off("change", this.$onChange); this.doc = doc; doc.on("change", this.$onChange); @@ -10356,7 +9725,8 @@ EditSession.$uid = 0; this.$modeId = mode.$id; if (this.$mode === mode) return; - + + var oldMode = this.$mode; this.$mode = mode; this.$stopWorker(); @@ -10366,15 +9736,15 @@ EditSession.$uid = 0; var tokenizer = mode.getTokenizer(); - if(tokenizer.addEventListener !== undefined) { + if(tokenizer.on !== undefined) { var onReloadTokenizer = this.onReloadTokenizer.bind(this); - tokenizer.addEventListener("update", onReloadTokenizer); + tokenizer.on("update", onReloadTokenizer); } if (!this.bgTokenizer) { this.bgTokenizer = new BackgroundTokenizer(tokenizer); var _self = this; - this.bgTokenizer.addEventListener("update", function(e) { + this.bgTokenizer.on("update", function(e) { _self._signal("tokenizerUpdate", e); }); } else { @@ -10393,7 +9763,7 @@ EditSession.$uid = 0; this.$options.wrapMethod.set.call(this, this.$wrapMethod); this.$setFolding(mode.foldingRules); this.bgTokenizer.start(0); - this._emit("changeMode"); + this._emit("changeMode", {oldMode: oldMode, mode: mode}); } }; @@ -10539,7 +9909,7 @@ EditSession.$uid = 0; for (var i = 0; i < deltas.length; i++) { var delta = deltas[i]; if (delta.action == "insert" || delta.action == "remove") { - this.doc.applyDelta(delta); + this.doc.$safeApplyDelta(delta); } } @@ -10561,7 +9931,6 @@ EditSession.$uid = 0; } var range, point; - var lastDeltaIsInsert; for (var i = 0; i < deltas.length; i++) { var delta = deltas[i]; @@ -10569,10 +9938,8 @@ EditSession.$uid = 0; if (!range) { if (isInsert(delta)) { range = Range.fromPoints(delta.start, delta.end); - lastDeltaIsInsert = true; } else { range = Range.fromPoints(delta.start, delta.start); - lastDeltaIsInsert = false; } continue; } @@ -10586,13 +9953,11 @@ EditSession.$uid = 0; if (range.compare(point.row, point.column) == 1) { range.setEnd(point); } - lastDeltaIsInsert = true; } else { point = delta.start; if (range.compare(point.row, point.column) == -1) { range = Range.fromPoints(delta.start, delta.start); } - lastDeltaIsInsert = false; } } return range; @@ -11458,6 +10823,11 @@ EditSession.$uid = 0; this.bgTokenizer = null; } this.$stopWorker(); + this.removeAllListeners(); + if (this.doc) { + this.doc.off("change", this.$onChange); + } + this.selection.detach(); }; this.isFullWidth = isFullWidth; @@ -11848,7 +11218,7 @@ var Search = function() { var len = re.length; var forEachInLine = function(row, offset, callback) { var startRow = backwards ? row - len + 1 : row; - if (startRow < 0) return; + if (startRow < 0 || startRow + len > session.getLength()) return; var line = session.getLine(startRow); var startIndex = line.search(re[0]); if (!backwards && startIndex < offset || startIndex === -1) return; @@ -12199,7 +11569,7 @@ oop.inherits(CommandManager, MultiHashHandler); editor && editor._emit("changeStatus"); if (this.recording) { this.macro.pop(); - this.removeEventListener("exec", this.$addCommandToMacro); + this.off("exec", this.$addCommandToMacro); if (!this.macro.length) this.macro = this.oldMacro; @@ -12266,6 +11636,7 @@ function bindKey(win, mac) { } exports.commands = [{ name: "showSettingsMenu", + description: "Show settings menu", bindKey: bindKey("Ctrl-,", "Command-,"), exec: function(editor) { config.loadModule("ace/ext/settings_menu", function(module) { @@ -12276,6 +11647,7 @@ exports.commands = [{ readOnly: true }, { name: "goToNextError", + description: "Go to next error", bindKey: bindKey("Alt-E", "F4"), exec: function(editor) { config.loadModule("./ext/error_marker", function(module) { @@ -12286,6 +11658,7 @@ exports.commands = [{ readOnly: true }, { name: "goToPreviousError", + description: "Go to previous error", bindKey: bindKey("Alt-Shift-E", "Shift-F4"), exec: function(editor) { config.loadModule("./ext/error_marker", function(module) { @@ -12332,6 +11705,7 @@ exports.commands = [{ readOnly: true }, { name: "toggleFoldWidget", + description: "Toggle fold widget", bindKey: bindKey("F2", "F2"), exec: function(editor) { editor.session.toggleFoldWidget(); }, multiSelectAction: "forEach", @@ -12339,6 +11713,7 @@ exports.commands = [{ readOnly: true }, { name: "toggleParentFoldWidget", + description: "Toggle parent fold widget", bindKey: bindKey("Alt-F2", "Alt-F2"), exec: function(editor) { editor.session.toggleFoldWidget(true); }, multiSelectAction: "forEach", @@ -12351,6 +11726,13 @@ exports.commands = [{ exec: function(editor) { editor.session.foldAll(); }, scrollIntoView: "center", readOnly: true +}, { + name: "foldAllComments", + description: "Fold all comments", + bindKey: bindKey(null, "Ctrl-Command-Option-0"), + exec: function(editor) { editor.session.foldAllComments(); }, + scrollIntoView: "center", + readOnly: true }, { name: "foldOther", description: "Fold other", @@ -12959,6 +12341,13 @@ exports.commands = [{ exec: function(editor) { editor.toLowerCase(); }, multiSelectAction: "forEach", scrollIntoView: "cursor" +}, { + name: "autoindent", + description: "Auto Indent", + bindKey: bindKey(null, null), + exec: function(editor) { editor.autoIndent(); }, + multiSelectAction: "forEachLine", + scrollIntoView: "animate" }, { name: "expandtoline", description: "Expand to line", @@ -13051,6 +12440,7 @@ exports.commands = [{ scrollIntoView: "none" }, { name: "addLineAfter", + description: "Add new line after the current line", exec: function(editor) { editor.selection.clearSelection(); editor.navigateLineEnd(); @@ -13060,6 +12450,7 @@ exports.commands = [{ scrollIntoView: "cursor" }, { name: "addLineBefore", + description: "Add new line before the current line", exec: function(editor) { editor.selection.clearSelection(); var cursor = editor.getCursorPosition(); @@ -13087,6 +12478,17 @@ exports.commands = [{ readOnly: true }]; +for (var i = 1; i < 9; i++) { + exports.commands.push({ + name: "foldToLevel" + i, + description: "Fold To Level " + i, + level: i, + exec: function(editor) { editor.session.foldToLevel(this.level); }, + scrollIntoView: "center", + readOnly: true + }); +} + }); define("ace/editor",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/keyboard/textinput","ace/mouse/mouse_handler","ace/mouse/fold_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/range","ace/lib/event_emitter","ace/commands/command_manager","ace/commands/default_commands","ace/config","ace/token_iterator","ace/clipboard"], function(require, exports, module) { @@ -13113,6 +12515,7 @@ var TokenIterator = require("./token_iterator").TokenIterator; var clipboard = require("./clipboard"); var Editor = function(renderer, session, options) { + this.$toDestroy = []; var container = renderer.getContainerElement(); this.container = container; this.renderer = renderer; @@ -13205,8 +12608,8 @@ Editor.$uid = 0; }; this.endOperation = function(e) { - if (this.curOp) { - if (e && e.returnValue === false) + if (this.curOp && this.session) { + if (e && e.returnValue === false || !this.session) return (this.curOp = null); if (e == true && this.curOp.command && this.curOp.command.name == "mouse") return; @@ -13517,25 +12920,33 @@ Editor.$uid = 0; return; } - if (token.type.indexOf("tag-open") != -1) { + if (token.type.indexOf("tag-open") !== -1) { token = iterator.stepForward(); if (!token) return; } var tag = token.value; + var currentTag = token.value; var depth = 0; var prevToken = iterator.stepBackward(); - if (prevToken.value == '<'){ + if (prevToken.value === '<'){ do { prevToken = token; token = iterator.stepForward(); - - if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) { - if (prevToken.value === '<'){ - depth++; - } else if (prevToken.value === '') { // self closing tag depth--; } } @@ -13545,12 +12956,32 @@ Editor.$uid = 0; do { token = prevToken; prevToken = iterator.stepBackward(); - - if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) { - if (prevToken.value === '<') { - depth++; - } else if (prevToken.value === '') { // self closing tag + var stepCount = 0; + var tmpToken = prevToken; + while (tmpToken) { + if (tmpToken.type.indexOf('tag-name') !== -1 && tmpToken.value === tag) { + depth--; + break; + } else if (tmpToken.value === '<') { + break; + } + tmpToken = iterator.stepBackward(); + stepCount++; + } + for (var i = 0; i < stepCount; i++) { + iterator.stepForward(); + } } } } while (prevToken && depth <= 0); @@ -13609,6 +13040,9 @@ Editor.$uid = 0; this.$cursorChange = function() { this.renderer.updateCursor(); + this.$highlightBrackets(); + this.$highlightTags(); + this.$updateHighlightActiveLine(); }; this.onDocumentChange = function(delta) { var wrap = this.session.$useWrapMode; @@ -13617,7 +13051,6 @@ Editor.$uid = 0; this._signal("change", delta); this.$cursorChange(); - this.$updateHighlightActiveLine(); }; this.onTokenizerUpdate = function(e) { @@ -13635,10 +13068,6 @@ Editor.$uid = 0; }; this.onCursorChange = function() { this.$cursorChange(); - - this.$highlightBrackets(); - this.$highlightTags(); - this.$updateHighlightActiveLine(); this._signal("changeSelection"); }; @@ -13777,7 +13206,7 @@ Editor.$uid = 0; } var e = {text: text}; this._signal("copy", e); - clipboard.lineMode = copyLine ? e.text : ""; + clipboard.lineMode = copyLine ? e.text : false; return e.text; }; this.onCopy = function() { @@ -13797,7 +13226,7 @@ Editor.$uid = 0; this._signal("paste", e); var text = e.text; - var lineMode = text == clipboard.lineMode; + var lineMode = text === clipboard.lineMode; var session = this.session; if (!this.inMultiSelectMode || this.inVirtualSelectionMode) { if (lineMode) @@ -13889,16 +13318,62 @@ Editor.$uid = 0; transform.selection[3])); } } + if (this.$enableAutoIndent) { + if (session.getDocument().isNewLine(text)) { + var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString()); - if (session.getDocument().isNewLine(text)) { - var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString()); - - session.insert({row: cursor.row+1, column: 0}, lineIndent); + session.insert({row: cursor.row+1, column: 0}, lineIndent); + } + if (shouldOutdent) + mode.autoOutdent(lineState, session, cursor.row); } - if (shouldOutdent) - mode.autoOutdent(lineState, session, cursor.row); }; + this.autoIndent = function () { + var session = this.session; + var mode = session.getMode(); + + var startRow, endRow; + if (this.selection.isEmpty()) { + startRow = 0; + endRow = session.doc.getLength() - 1; + } else { + var selectedRange = this.getSelectionRange(); + + startRow = selectedRange.start.row; + endRow = selectedRange.end.row; + } + + var prevLineState = ""; + var prevLine = ""; + var lineIndent = ""; + var line, currIndent, range; + var tab = session.getTabString(); + + for (var row = startRow; row <= endRow; row++) { + if (row > 0) { + prevLineState = session.getState(row - 1); + prevLine = session.getLine(row - 1); + lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab); + } + + line = session.getLine(row); + currIndent = mode.$getIndent(line); + if (lineIndent !== currIndent) { + if (currIndent.length > 0) { + range = new Range(row, 0, row, currIndent.length); + session.remove(range); + } + if (lineIndent.length > 0) { + session.insert({row: row, column: 0}, lineIndent); + } + } + + mode.autoOutdent(prevLineState, session, row); + } + }; + + this.onTextInput = function(text, composition) { if (!composition) return this.keyBinding.onTextInput(text); @@ -13917,6 +13392,10 @@ Editor.$uid = 0; var r = this.selection.getRange(); r.start.column -= composition.extendLeft; r.end.column += composition.extendRight; + if (r.start.column < 0) { + r.start.row--; + r.start.column += this.session.getLine(r.start.row).length + 1; + } this.selection.setRange(r); if (!text && !r.isEmpty()) this.remove(); @@ -14922,13 +14401,21 @@ Editor.$uid = 0; this.renderer.scrollCursorIntoView(null, 0.5); }; this.destroy = function() { + if (this.$toDestroy) { + this.$toDestroy.forEach(function(el) { + el.destroy(); + }); + this.$toDestroy = null; + } + if (this.$mouseHandler) + this.$mouseHandler.destroy(); this.renderer.destroy(); this._signal("destroy", this); if (this.session) this.session.destroy(); if (this._$emitInputEvent) this._$emitInputEvent.cancel(); - this.session = null; + this.removeAllListeners(); }; this.setAutoScrollEditorIntoView = function(enable) { if (!enable) @@ -15044,6 +14531,7 @@ config.defineOptions(Editor.prototype, "editor", { }, behavioursEnabled: {initialValue: true}, wrapBehavioursEnabled: {initialValue: true}, + enableAutoIndent: {initialValue: true}, autoScrollEditorIntoView: { set: function(val) {this.setAutoScrollEditorIntoView(val);} }, @@ -15088,7 +14576,7 @@ config.defineOptions(Editor.prototype, "editor", { set: function(message) { if (!this.$updatePlaceholder) { this.$updatePlaceholder = function() { - var value = this.renderer.$composition || this.getValue(); + var value = this.session && (this.renderer.$composition || this.getValue()); if (value && this.renderer.placeholderNode) { this.renderer.off("afterRender", this.$updatePlaceholder); dom.removeCssClass(this.container, "ace_hasPlaceholder"); @@ -15102,6 +14590,8 @@ config.defineOptions(Editor.prototype, "editor", { el.textContent = this.$placeholder || ""; this.renderer.placeholderNode = el; this.renderer.content.appendChild(this.renderer.placeholderNode); + } else if (!value && this.renderer.placeholderNode) { + this.renderer.placeholderNode.textContent = this.$placeholder || ""; } }.bind(this); this.on("input", this.$updatePlaceholder); @@ -15276,25 +14766,6 @@ var UndoManager = function() { if (to == null) to = this.$rev + 1; }; - - this.validateDeltaBoundaries = function(deltaSet, docLength, invertAction) { - if (!deltaSet) { - return false; - } - return deltaSet.every(function(delta) { - var action = delta.action; - if (invertAction && delta.action === "insert") action = "remove"; - if (invertAction && delta.action === "remove") action = "insert"; - switch(action) { - case "insert": - return delta.start.row <= docLength; - case "remove": - return delta.start.row < docLength && delta.end.row < docLength; - default: - return true; - } - }); - }; this.undo = function(session, dontSelect) { this.lastDeltas = null; var stack = this.$undoStack; @@ -15312,7 +14783,7 @@ var UndoManager = function() { var deltaSet = stack.pop(); var undoSelectionRange = null; - if (this.validateDeltaBoundaries(deltaSet, session.getLength(), true)) { + if (deltaSet) { undoSelectionRange = session.undoChanges(deltaSet, dontSelect); this.$redoStack.push(deltaSet); this.$syncRev(); @@ -15340,7 +14811,7 @@ var UndoManager = function() { var deltaSet = this.$redoStack.pop(); var redoSelectionRange = null; - if (this.validateDeltaBoundaries(deltaSet, session.getLength(), false)) { + if (deltaSet) { redoSelectionRange = session.redoChanges(deltaSet, dontSelect); this.$undoStack.push(deltaSet); this.$syncRev(); @@ -15840,7 +15311,7 @@ var Gutter = function(parentEl) { this.setSession = function(session) { if (this.session) - this.session.removeEventListener("change", this.$updateAnnotations); + this.session.off("change", this.$updateAnnotations); this.session = session; if (session) session.on("change", this.$updateAnnotations); @@ -16529,11 +16000,21 @@ var Text = function(parentEl) { }; this.showInvisibles = false; + this.showSpaces = false; + this.showTabs = false; + this.showEOL = false; this.setShowInvisibles = function(showInvisibles) { if (this.showInvisibles == showInvisibles) return false; this.showInvisibles = showInvisibles; + if (typeof showInvisibles == "string") { + this.showSpaces = /tab/i.test(showInvisibles); + this.showTabs = /space/i.test(showInvisibles); + this.showEOL = /eol/i.test(showInvisibles); + } else { + this.showSpaces = this.showTabs = this.showEOL = showInvisibles; + } this.$computeTabString(); return true; }; @@ -16555,7 +16036,7 @@ var Text = function(parentEl) { this.tabSize = tabSize; var tabStr = this.$tabStrings = [0]; for (var i = 1; i < tabSize + 1; i++) { - if (this.showInvisibles) { + if (this.showTabs) { var span = this.dom.createElement("span"); span.className = "ace_invisible ace_invisible_tab"; span.textContent = lang.stringRepeat(this.TAB_CHAR, i); @@ -16567,18 +16048,15 @@ var Text = function(parentEl) { if (this.displayIndentGuides) { this.$indentGuideRe = /\s\S| \t|\t |\s$/; var className = "ace_indent-guide"; - var spaceClass = ""; - var tabClass = ""; - if (this.showInvisibles) { - className += " ace_invisible"; - spaceClass = " ace_invisible_space"; - tabClass = " ace_invisible_tab"; - var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize); - var tabContent = lang.stringRepeat(this.TAB_CHAR, this.tabSize); - } else { - var spaceContent = lang.stringRepeat(" ", this.tabSize); - var tabContent = spaceContent; - } + var spaceClass = this.showSpaces ? " ace_invisible ace_invisible_space" : ""; + var spaceContent = this.showSpaces + ? lang.stringRepeat(this.SPACE_CHAR, this.tabSize) + : lang.stringRepeat(" ", this.tabSize); + + var tabClass = this.showTabs ? " ace_invisible ace_invisible_tab" : ""; + var tabContent = this.showTabs + ? lang.stringRepeat(this.TAB_CHAR, this.tabSize) + : spaceContent; var span = this.dom.createElement("span"); span.className = className + spaceClass; @@ -16771,7 +16249,7 @@ var Text = function(parentEl) { var cjkSpace = m[4]; var cjk = m[5]; - if (!self.showInvisibles && simpleSpace) + if (!self.showSpaces && simpleSpace) continue; var before = i != m.index ? value.slice(i, m.index) : ""; @@ -16787,7 +16265,7 @@ var Text = function(parentEl) { valueFragment.appendChild(self.$tabStrings[tabSize].cloneNode(true)); screenColumn += tabSize - 1; } else if (simpleSpace) { - if (self.showInvisibles) { + if (self.showSpaces) { var span = this.dom.createElement("span"); span.className = "ace_invisible ace_invisible_space"; span.textContent = lang.stringRepeat(self.SPACE_CHAR, simpleSpace.length); @@ -16805,8 +16283,8 @@ var Text = function(parentEl) { var span = this.dom.createElement("span"); span.style.width = (self.config.characterWidth * 2) + "px"; - span.className = self.showInvisibles ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk"; - span.textContent = self.showInvisibles ? self.SPACE_CHAR : cjkSpace; + span.className = self.showSpaces ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk"; + span.textContent = self.showSpaces ? self.SPACE_CHAR : cjkSpace; valueFragment.appendChild(span); } else if (cjk) { screenColumn += 1; @@ -16975,7 +16453,7 @@ var Text = function(parentEl) { parent.appendChild(lastLineEl); } - if (this.showInvisibles && lastLineEl) { + if (this.showEOL && lastLineEl) { if (foldLine) row = foldLine.end.row; @@ -17092,12 +16570,16 @@ var Cursor = function(parentEl) { for (var i = cursors.length; i--; ) cursors[i].style.animationDuration = this.blinkInterval + "ms"; + this.$isAnimating = true; setTimeout(function() { - dom.addCssClass(this.element, "ace_animate-blinking"); + if (this.$isAnimating) { + dom.addCssClass(this.element, "ace_animate-blinking"); + } }.bind(this)); }; this.$stopCssAnimation = function() { + this.$isAnimating = false; dom.removeCssClass(this.element, "ace_animate-blinking"); }; @@ -17168,6 +16650,7 @@ var Cursor = function(parentEl) { this.$stopCssAnimation(); if (this.smoothBlinking) { + this.$isSmoothBlinking = false; dom.removeCssClass(this.element, "ace_smooth-blinking"); } @@ -17179,8 +16662,11 @@ var Cursor = function(parentEl) { } if (this.smoothBlinking) { - setTimeout(function(){ - dom.addCssClass(this.element, "ace_smooth-blinking"); + this.$isSmoothBlinking = true; + setTimeout(function() { + if (this.$isSmoothBlinking) { + dom.addCssClass(this.element, "ace_smooth-blinking"); + } }.bind(this)); } @@ -17506,7 +16992,7 @@ var FontMetrics = exports.FontMetrics = function(parentEl) { this.el.appendChild(this.$measureNode); parentEl.appendChild(this.el); - this.$measureNode.innerHTML = lang.stringRepeat("X", CHAR_COUNT); + this.$measureNode.textContent = lang.stringRepeat("X", CHAR_COUNT); this.$characterSize = {width: 0, height: 0}; @@ -17555,11 +17041,7 @@ var FontMetrics = exports.FontMetrics = function(parentEl) { this.$addObserver = function() { var self = this; this.$observer = new window.ResizeObserver(function(e) { - var rect = e[0].contentRect; - self.checkForSizeChanges({ - height: rect.height, - width: rect.width / CHAR_COUNT - }); + self.checkForSizeChanges(); }); this.$observer.observe(this.$measureNode); }; @@ -17595,7 +17077,7 @@ var FontMetrics = exports.FontMetrics = function(parentEl) { }; this.$measureCharWidth = function(ch) { - this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT); + this.$main.textContent = lang.stringRepeat(ch, CHAR_COUNT); var rect = this.$main.getBoundingClientRect(); return rect.width / CHAR_COUNT; }; @@ -17618,7 +17100,7 @@ var FontMetrics = exports.FontMetrics = function(parentEl) { this.$getZoom = function getZoom(element) { - if (!element) return 1; + if (!element || !element.parentElement) return 1; return (window.getComputedStyle(element).zoom || 1) * getZoom(element.parentElement); }; this.$initTransformMeasureNodes = function() { @@ -17712,6 +17194,7 @@ var editorCss = "\ .ace_editor {\ position: relative;\ overflow: hidden;\ +padding: 0;\ font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\ direction: ltr;\ text-align: left;\ @@ -18184,7 +17667,7 @@ margin: 0 10px;\ var useragent = require("./lib/useragent"); var HIDE_TEXTAREA = useragent.isIE; -dom.importCssString(editorCss, "ace_editor.css"); +dom.importCssString(editorCss, "ace_editor.css", false); var VirtualRenderer = function(container, theme) { var _self = this; @@ -18195,6 +17678,8 @@ var VirtualRenderer = function(container, theme) { if (dom.HI_DPI) dom.addCssClass(this.container, "ace_hidpi"); this.setTheme(theme); + if (config.get("useStrictCSP") == null) + config.set("useStrictCSP", false); this.$gutter = dom.createElement("div"); this.$gutter.className = "ace_gutter"; @@ -18227,11 +17712,11 @@ var VirtualRenderer = function(container, theme) { this.scrollBar = this.scrollBarV = new VScrollBar(this.container, this); this.scrollBarH = new HScrollBar(this.container, this); - this.scrollBarV.addEventListener("scroll", function(e) { + this.scrollBarV.on("scroll", function(e) { if (!_self.$scrollAnimation) _self.session.setScrollTop(e.data - _self.scrollMargin.top); }); - this.scrollBarH.addEventListener("scroll", function(e) { + this.scrollBarH.on("scroll", function(e) { if (!_self.$scrollAnimation) _self.session.setScrollLeft(e.data - _self.scrollMargin.left); }); @@ -18246,7 +17731,7 @@ var VirtualRenderer = function(container, theme) { this.$fontMetrics = new FontMetrics(this.container); this.$textLayer.$setFontMetrics(this.$fontMetrics); - this.$textLayer.addEventListener("changeCharacterSize", function(e) { + this.$textLayer.on("changeCharacterSize", function(e) { _self.updateCharacterSize(); _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height); _self._signal("changeCharacterSize", e); @@ -18446,7 +17931,7 @@ var VirtualRenderer = function(container, theme) { if (this.resizing) this.resizing = 0; - this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null; + this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null; }; this.$updateCachedSize = function(force, gutterWidth, width, height) { @@ -19183,6 +18668,8 @@ var VirtualRenderer = function(container, theme) { _self.session.setScrollTop(steps.shift()); _self.session.$scrollTop = toValue; this.$timer = setInterval(function() { + if (!_self.session) + return clearInterval(_self.$timer); if (steps.length) { _self.session.setScrollTop(steps.shift()); _self.session.$scrollTop = toValue; @@ -19210,7 +18697,7 @@ var VirtualRenderer = function(container, theme) { }; this.scrollTo = function(x, y) { this.session.setScrollTop(y); - this.session.setScrollLeft(y); + this.session.setScrollLeft(x); }; this.scrollBy = function(deltaX, deltaY) { deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY); @@ -19293,7 +18780,8 @@ var VirtualRenderer = function(container, theme) { if (!composition.cssText) { composition.cssText = this.textarea.style.cssText; } - composition.useTextareaForIME = this.$useTextareaForIME; + if (composition.useTextareaForIME == undefined) + composition.useTextareaForIME = this.$useTextareaForIME; if (this.$useTextareaForIME) { dom.addCssClass(this.textarea, "ace_composition"); @@ -19319,6 +18807,8 @@ var VirtualRenderer = function(container, theme) { dom.removeCssClass(this.textarea, "ace_composition"); this.textarea.style.cssText = this.$composition.cssText; + var cursor = this.session.selection.cursor; + this.removeExtraToken(cursor.row, cursor.column); this.$composition = null; this.$cursorLayer.element.style.display = ""; }; @@ -19347,6 +18837,10 @@ var VirtualRenderer = function(container, theme) { } this.updateLines(row, row); }; + + this.removeExtraToken = function(row, column) { + this.updateLines(row, row); + }; this.setTheme = function(theme, cb) { var _self = this; this.$themeId = theme; @@ -19417,6 +18911,8 @@ var VirtualRenderer = function(container, theme) { this.freeze(); this.$fontMetrics.destroy(); this.$cursorLayer.destroy(); + this.removeAllListeners(); + this.container.textContent = ""; }; }).call(VirtualRenderer.prototype); @@ -19943,8 +19439,8 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.detach = function() { this.session.removeMarker(this.pos && this.pos.markerId); this.hideOtherMarkers(); - this.doc.removeEventListener("change", this.$onUpdate); - this.session.selection.removeEventListener("changeCursor", this.$onCursorChange); + this.doc.off("change", this.$onUpdate); + this.session.selection.off("changeCursor", this.$onCursorChange); this.session.setUndoSelect(true); this.session = null; }; @@ -20998,10 +20494,10 @@ function addAltCursorListeners(editor){ } else if (altCursor) { reset(); } - }); + }, editor); - event.addListener(el, "keyup", reset); - event.addListener(el, "blur", reset); + event.addListener(el, "keyup", reset, editor); + event.addListener(el, "blur", reset, editor); function reset(e) { if (altCursor) { editor.renderer.setMouseCursor(""); @@ -21259,7 +20755,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ exports.$id = "ace/theme/textmate"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); define("ace/line_widgets",["require","exports","module","ace/lib/dom"], function(require, exports, module) { @@ -21806,7 +21302,7 @@ dom.importCssString("\ border-left-color: transparent!important;\ top: -5px;\ }\ -", ""); +", "error_marker.css", false); }); diff --git a/htdocs/includes/ace/src/ext-beautify.js b/htdocs/includes/ace/src/ext-beautify.js index a39074326a2..674cf671131 100644 --- a/htdocs/includes/ace/src/ext-beautify.js +++ b/htdocs/includes/ace/src/ext-beautify.js @@ -40,16 +40,28 @@ exports.beautify = function(session) { var inBlock = false; var levels = {0: 0}; var parents = []; + var caseBody = false; var trimNext = function() { if (nextToken && nextToken.value && nextToken.type !== 'string.regexp') - nextToken.value = nextToken.value.trim(); + nextToken.value = nextToken.value.replace(/^\s*/, ""); }; - + var trimLine = function() { - code = code.replace(/ +$/, ""); - }; + var end = code.length - 1; + while (true) { + if (end == 0) + break; + if (code[end] !== " ") + break; + + end = end - 1; + } + + code = code.slice(0, end + 1); + }; + var trimCode = function() { code = code.trimRight(); breakBefore = false; @@ -201,8 +213,11 @@ exports.beautify = function(session) { trimLine(); if(value === "/>") spaceBefore = true; + } else if (token.type === "keyword" && value.match(/^(case|default)$/)) { + if (caseBody) + unindent = 1; } - if (breakBefore && !(token.type.match(/^(comment)$/) && !value.substr(0, 1).match(/^[/#]$/)) && !(token.type.match(/^(string)$/) && !value.substr(0, 1).match(/^['"]$/))) { + if (breakBefore && !(token.type.match(/^(comment)$/) && !value.substr(0, 1).match(/^[/#]$/)) && !(token.type.match(/^(string)$/) && !value.substr(0, 1).match(/^['"@]$/))) { indent = lastIndent; @@ -229,16 +244,16 @@ exports.beautify = function(session) { code += tabString; } - if (token.type === "keyword" && value.match(/^(case|default)$/)) { - parents[depth] = value; - depth++; - } - - - if (token.type === "keyword" && value.match(/^(break)$/)) { + if (caseBody === false) { + parents[depth] = value; + depth++; + caseBody = true; + } + } else if (token.type === "keyword" && value.match(/^(break)$/)) { if(parents[depth-1] && parents[depth-1].match(/^(case|default)$/)) { depth--; + caseBody = false; } } if (token.type === "paren.lparen") { @@ -264,6 +279,9 @@ exports.beautify = function(session) { } } } + + if (token.type == "text") + value = value.replace(/\s+$/, " "); if (spaceBefore && !breakBefore) { trimLine(); if (code.substr(-1) !== "\n") diff --git a/htdocs/includes/ace/src/ext-code_lens.js b/htdocs/includes/ace/src/ext-code_lens.js index 4b7e4340f22..ee4653d8595 100644 --- a/htdocs/includes/ace/src/ext-code_lens.js +++ b/htdocs/includes/ace/src/ext-code_lens.js @@ -1,6 +1,7 @@ -define("ace/ext/code_lens",["require","exports","module","ace/line_widgets","ace/lib/lang","ace/lib/dom","ace/editor","ace/config"], function(require, exports, module) { +define("ace/ext/code_lens",["require","exports","module","ace/line_widgets","ace/lib/event","ace/lib/lang","ace/lib/dom","ace/editor","ace/config"], function(require, exports, module) { "use strict"; var LineWidgets = require("../line_widgets").LineWidgets; +var event = require("../lib/event"); var lang = require("../lib/lang"); var dom = require("../lib/dom"); @@ -120,12 +121,14 @@ exports.setLenses = function(session, lenses) { function attachToEditor(editor) { editor.codeLensProviders = []; editor.renderer.on("afterRender", renderWidgets); - editor.$codeLensClickHandler = function(e) { - var command = e.target.lensCommand; - if (command) - editor.execCommand(command.id, command.arguments); - }; - editor.container.addEventListener("click", editor.$codeLensClickHandler); + if (!editor.$codeLensClickHandler) { + editor.$codeLensClickHandler = function(e) { + var command = e.target.lensCommand; + if (command) + editor.execCommand(command.id, command.arguments); + }; + event.addListener(editor.container, "click", editor.$codeLensClickHandler, editor); + } editor.$updateLenses = function() { var session = editor.session; if (!session) return; @@ -138,8 +141,9 @@ function attachToEditor(editor) { var providersToWaitNum = editor.codeLensProviders.length; var lenses = []; editor.codeLensProviders.forEach(function(provider) { - provider.provideCodeLenses(session, function(currentLenses) { - currentLenses.forEach(function(lens) { + provider.provideCodeLenses(session, function(err, payload) { + if (err) return; + payload.forEach(function(lens) { lenses.push(lens); }); providersToWaitNum--; @@ -222,7 +226,7 @@ dom.importCssString("\ .ace_dark > .ace_codeLens > a:hover {\ color: #4e94ce;\ }\ -", ""); +", "codelense.css", false); }); (function() { window.require(["ace/ext/code_lens"], function(m) { diff --git a/htdocs/includes/ace/src/ext-emmet.js b/htdocs/includes/ace/src/ext-emmet.js index 3cb3818d1b5..68fc0ff1367 100644 --- a/htdocs/includes/ace/src/ext-emmet.js +++ b/htdocs/includes/ace/src/ext-emmet.js @@ -1,5 +1,6 @@ -define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/lib/dom","ace/editor"], function(require, exports, module) { +define("ace/snippets",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/editor"], function(require, exports, module) { "use strict"; +var dom = require("./lib/dom"); var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var lang = require("./lib/lang"); @@ -144,7 +145,9 @@ var SnippetManager = function() { {regex: "\\|" + escape("\\|") + "*\\|", onMatch: function(val, state, stack) { var choices = val.slice(1, -1).replace(/\\[,|\\]|,/g, function(operator) { return operator.length == 2 ? operator[1] : "\x00"; - }).split("\x00"); + }).split("\x00").map(function(value){ + return {value: value}; + }); stack[0].choices = choices; return [choices[0]]; }, next: "start"}, @@ -615,6 +618,12 @@ var SnippetManager = function() { } snippetMap[scope].push(s); + if (s.prefix) + s.tabTrigger = s.prefix; + + if (!s.content && s.body) + s.content = Array.isArray(s.body) ? s.body.join("\n") : s.body; + if (s.tabTrigger && !s.trigger) { if (!s.guard && /^\w/.test(s.tabTrigger)) s.guard = "\\b"; @@ -631,10 +640,13 @@ var SnippetManager = function() { s.endTriggerRe = new RegExp(s.endTrigger); } - if (snippets && snippets.content) - addSnippet(snippets); - else if (Array.isArray(snippets)) + if (Array.isArray(snippets)) { snippets.forEach(addSnippet); + } else { + Object.keys(snippets).forEach(function(key) { + addSnippet(snippets[key]); + }); + } this._signal("registerSnippets", {scope: scope}); }; @@ -684,7 +696,7 @@ var SnippetManager = function() { snippet.tabTrigger = val.match(/^\S*/)[0]; if (!snippet.name) snippet.name = val; - } else { + } else if (key) { snippet[key] = val; } } @@ -833,18 +845,17 @@ var TabstopManager = function(editor) { this.selectedTabstop = ts; var range = ts.firstNonLinked || ts; + if (ts.choices) range.cursor = range.start; if (!this.editor.inVirtualSelectionMode) { var sel = this.editor.multiSelect; - sel.toSingleRange(range.clone()); + sel.toSingleRange(range); for (var i = 0; i < ts.length; i++) { if (ts.hasLinkedRanges && ts[i].linked) continue; sel.addRange(ts[i].clone(), true); } - if (sel.ranges[0]) - sel.addRange(sel.ranges[0].clone()); } else { - this.editor.selection.setRange(range); + this.editor.selection.fromOrientedRange(range); } this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler); @@ -971,14 +982,14 @@ var moveRelative = function(point, start) { }; -require("./lib/dom").importCssString("\ +dom.importCssString("\ .ace_snippet-marker {\ -moz-box-sizing: border-box;\ box-sizing: border-box;\ background: rgba(194, 193, 208, 0.09);\ border: 1px dotted rgba(211, 208, 235, 0.62);\ position: absolute;\ -}"); +}", "snippets.css", false); exports.snippetManager = new SnippetManager(); diff --git a/htdocs/includes/ace/src/ext-hardwrap.js b/htdocs/includes/ace/src/ext-hardwrap.js new file mode 100644 index 00000000000..a2037b9113e --- /dev/null +++ b/htdocs/includes/ace/src/ext-hardwrap.js @@ -0,0 +1,125 @@ +define("ace/ext/hardwrap",["require","exports","module","ace/range","ace/editor","ace/config"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +function hardWrap(editor, options) { + var max = options.column || editor.getOption("printMarginColumn"); + var allowMerge = options.allowMerge != false; + + var row = Math.min(options.startRow, options.endRow); + var endRow = Math.max(options.startRow, options.endRow); + + var session = editor.session; + + while (row <= endRow) { + var line = session.getLine(row); + if (line.length > max) { + var space = findSpace(line, max, 5); + if (space) { + var indentation = /^\s*/.exec(line)[0]; + session.replace(new Range(row,space.start,row,space.end), "\n" + indentation); + } + endRow++; + } else if (allowMerge && /\S/.test(line) && row != endRow) { + var nextLine = session.getLine(row + 1); + if (nextLine && /\S/.test(nextLine)) { + var trimmedLine = line.replace(/\s+$/, ""); + var trimmedNextLine = nextLine.replace(/^\s+/, ""); + var mergedLine = trimmedLine + " " + trimmedNextLine; + + var space = findSpace(mergedLine, max, 5); + if (space && space.start > trimmedLine.length || mergedLine.length < max) { + var replaceRange = new Range(row,trimmedLine.length,row + 1,nextLine.length - trimmedNextLine.length); + session.replace(replaceRange, " "); + row--; + endRow--; + } else if (trimmedLine.length < line.length) { + session.remove(new Range(row, trimmedLine.length, row, line.length)); + } + } + } + row++; + } + + function findSpace(line, max, min) { + if (line.length < max) + return; + var before = line.slice(0, max); + var after = line.slice(max); + var spaceAfter = /^(?:(\s+)|(\S+)(\s+))/.exec(after); + var spaceBefore = /(?:(\s+)|(\s+)(\S+))$/.exec(before); + var start = 0; + var end = 0; + if (spaceBefore && !spaceBefore[2]) { + start = max - spaceBefore[1].length; + end = max; + } + if (spaceAfter && !spaceAfter[2]) { + if (!start) + start = max; + end = max + spaceAfter[1].length; + } + if (start) { + return { + start: start, + end: end + }; + } + if (spaceBefore && spaceBefore[2] && spaceBefore.index > min) { + return { + start: spaceBefore.index, + end: spaceBefore.index + spaceBefore[2].length + }; + } + if (spaceAfter && spaceAfter[2]) { + start = max + spaceAfter[2].length; + return { + start: start, + end: start + spaceAfter[3].length + }; + } + } + +} + +function wrapAfterInput(e) { + if (e.command.name == "insertstring" && /\S/.test(e.args)) { + var editor = e.editor; + var cursor = editor.selection.cursor; + if (cursor.column <= editor.renderer.$printMarginColumn) return; + var lastDelta = editor.session.$undoManager.$lastDelta; + + hardWrap(editor, { + startRow: cursor.row, endRow: cursor.row, + allowMerge: false + }); + if (lastDelta != editor.session.$undoManager.$lastDelta) + editor.session.markUndoGroup(); + } +} + +var Editor = require("../editor").Editor; +require("../config").defineOptions(Editor.prototype, "editor", { + hardWrap: { + set: function(val) { + if (val) { + this.commands.on("afterExec", wrapAfterInput); + } else { + this.commands.off("afterExec", wrapAfterInput); + } + }, + value: false + } +}); + +exports.hardWrap = hardWrap; + +}); (function() { + window.require(["ace/ext/hardwrap"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/ext-keybinding_menu.js b/htdocs/includes/ace/src/ext-keybinding_menu.js index 4f980686e68..b9ad46ee724 100644 --- a/htdocs/includes/ace/src/ext-keybinding_menu.js +++ b/htdocs/includes/ace/src/ext-keybinding_menu.js @@ -61,7 +61,7 @@ margin: 0px;\ .ace_optionsMenuEntry button:hover{\ background: #f0f0f0;\ }"; -dom.importCssString(cssText); +dom.importCssString(cssText, "settings_menu.css", false); module.exports.overlayPage = function overlayPage(editor, contentElement, callback) { var closer = document.createElement('div'); diff --git a/htdocs/includes/ace/src/ext-language_tools.js b/htdocs/includes/ace/src/ext-language_tools.js index 7e6967e0d7a..b561c3bc87d 100644 --- a/htdocs/includes/ace/src/ext-language_tools.js +++ b/htdocs/includes/ace/src/ext-language_tools.js @@ -1,5 +1,6 @@ -define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/lib/dom","ace/editor"], function(require, exports, module) { +define("ace/snippets",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/editor"], function(require, exports, module) { "use strict"; +var dom = require("./lib/dom"); var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var lang = require("./lib/lang"); @@ -144,7 +145,9 @@ var SnippetManager = function() { {regex: "\\|" + escape("\\|") + "*\\|", onMatch: function(val, state, stack) { var choices = val.slice(1, -1).replace(/\\[,|\\]|,/g, function(operator) { return operator.length == 2 ? operator[1] : "\x00"; - }).split("\x00"); + }).split("\x00").map(function(value){ + return {value: value}; + }); stack[0].choices = choices; return [choices[0]]; }, next: "start"}, @@ -615,6 +618,12 @@ var SnippetManager = function() { } snippetMap[scope].push(s); + if (s.prefix) + s.tabTrigger = s.prefix; + + if (!s.content && s.body) + s.content = Array.isArray(s.body) ? s.body.join("\n") : s.body; + if (s.tabTrigger && !s.trigger) { if (!s.guard && /^\w/.test(s.tabTrigger)) s.guard = "\\b"; @@ -631,10 +640,13 @@ var SnippetManager = function() { s.endTriggerRe = new RegExp(s.endTrigger); } - if (snippets && snippets.content) - addSnippet(snippets); - else if (Array.isArray(snippets)) + if (Array.isArray(snippets)) { snippets.forEach(addSnippet); + } else { + Object.keys(snippets).forEach(function(key) { + addSnippet(snippets[key]); + }); + } this._signal("registerSnippets", {scope: scope}); }; @@ -684,7 +696,7 @@ var SnippetManager = function() { snippet.tabTrigger = val.match(/^\S*/)[0]; if (!snippet.name) snippet.name = val; - } else { + } else if (key) { snippet[key] = val; } } @@ -833,18 +845,17 @@ var TabstopManager = function(editor) { this.selectedTabstop = ts; var range = ts.firstNonLinked || ts; + if (ts.choices) range.cursor = range.start; if (!this.editor.inVirtualSelectionMode) { var sel = this.editor.multiSelect; - sel.toSingleRange(range.clone()); + sel.toSingleRange(range); for (var i = 0; i < ts.length; i++) { if (ts.hasLinkedRanges && ts[i].linked) continue; sel.addRange(ts[i].clone(), true); } - if (sel.ranges[0]) - sel.addRange(sel.ranges[0].clone()); } else { - this.editor.selection.setRange(range); + this.editor.selection.fromOrientedRange(range); } this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler); @@ -971,14 +982,14 @@ var moveRelative = function(point, start) { }; -require("./lib/dom").importCssString("\ +dom.importCssString("\ .ace_snippet-marker {\ -moz-box-sizing: border-box;\ box-sizing: border-box;\ background: rgba(194, 193, 208, 0.09);\ border: 1px dotted rgba(211, 208, 235, 0.62);\ position: absolute;\ -}"); +}", "snippets.css", false); exports.snippetManager = new SnippetManager(); @@ -1330,7 +1341,7 @@ dom.importCssString("\ line-height: 1.4;\ background: #25282c;\ color: #c1c1c1;\ -}", "autocompletion.css"); +}", "autocompletion.css", false); exports.AcePopup = AcePopup; exports.$singleLineEditor = $singleLineEditor; @@ -1476,6 +1487,7 @@ var Autocomplete = function() { } else if (keepPopupPosition && !prefix) { this.detach(); } + this.changeTimer.cancel(); }; this.detach = function() { @@ -1538,13 +1550,15 @@ var Autocomplete = function() { if (!data) return false; + var completions = this.completions; + this.editor.startOperation({command: {name: "insertMatch"}}); if (data.completer && data.completer.insertMatch) { data.completer.insertMatch(this.editor, data); } else { - if (this.completions.filterText) { + if (completions.filterText) { var ranges = this.editor.selection.getAllRanges(); for (var i = 0, range; range = ranges[i]; i++) { - range.start.column -= this.completions.filterText.length; + range.start.column -= completions.filterText.length; this.editor.session.remove(range); } } @@ -1553,7 +1567,9 @@ var Autocomplete = function() { else this.editor.execCommand("insertstring", data.value || data); } - this.detach(); + if (this.completions == completions) + this.detach(); + this.editor.endOperation(); }; @@ -1649,19 +1665,14 @@ var Autocomplete = function() { return this.openPopup(this.editor, "", keepPopupPosition); } var _id = this.gatherCompletionsId; - this.gatherCompletions(this.editor, function(err, results) { - var detachIfFinished = function() { - if (!results.finished) return; - return this.detach(); - }.bind(this); + var detachIfFinished = function(results) { + if (!results.finished) return; + return this.detach(); + }.bind(this); + var processResults = function(results) { var prefix = results.prefix; - var matches = results && results.matches; - - if (!matches || !matches.length) - return detachIfFinished(); - if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId) - return; + var matches = results.matches; this.completions = new FilteredList(matches); @@ -1671,14 +1682,39 @@ var Autocomplete = function() { this.completions.setFilter(prefix); var filtered = this.completions.filtered; if (!filtered.length) - return detachIfFinished(); + return detachIfFinished(results); if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet) - return detachIfFinished(); + return detachIfFinished(results); if (this.autoInsert && filtered.length == 1 && results.finished) return this.insertMatch(filtered[0]); this.openPopup(this.editor, prefix, keepPopupPosition); + }.bind(this); + + var isImmediate = true; + var immediateResults = null; + this.gatherCompletions(this.editor, function(err, results) { + var prefix = results.prefix; + var matches = results && results.matches; + + if (!matches || !matches.length) + return detachIfFinished(results); + if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId) + return; + if (isImmediate) { + immediateResults = results; + return; + } + + processResults(results); }.bind(this)); + + isImmediate = false; + if (immediateResults) { + var results = immediateResults; + immediateResults = null; + processResults(results); + } }; this.cancelContextMenu = function() { @@ -2032,31 +2068,33 @@ var onChangeMode = function(e, editor) { }; var loadSnippetsForMode = function(mode) { - var id = mode.$id; + if (typeof mode == "string") + mode = config.$modes[mode]; + if (!mode) + return; if (!snippetManager.files) snippetManager.files = {}; - loadSnippetFile(id); + + loadSnippetFile(mode.$id, mode.snippetFileId); if (mode.modes) mode.modes.forEach(loadSnippetsForMode); }; -var loadSnippetFile = function(id) { - if (!id || snippetManager.files[id]) +var loadSnippetFile = function(id, snippetFilePath) { + if (!snippetFilePath || !id || snippetManager.files[id]) return; - var snippetFilePath = id.replace("mode", "snippets"); snippetManager.files[id] = {}; config.loadModule(snippetFilePath, function(m) { - if (m) { - snippetManager.files[id] = m; - if (!m.snippets && m.snippetText) - m.snippets = snippetManager.parseSnippetFile(m.snippetText); - snippetManager.register(m.snippets || [], m.scope); - if (m.includeScopes) { - snippetManager.snippetMap[m.scope].includeScopes = m.includeScopes; - m.includeScopes.forEach(function(x) { - loadSnippetFile("ace/mode/" + x); - }); - } + if (!m) return; + snippetManager.files[id] = m; + if (!m.snippets && m.snippetText) + m.snippets = snippetManager.parseSnippetFile(m.snippetText); + snippetManager.register(m.snippets || [], m.scope); + if (m.includeScopes) { + snippetManager.snippetMap[m.scope].includeScopes = m.includeScopes; + m.includeScopes.forEach(function(x) { + loadSnippetsForMode("ace/mode/" + x); + }); } }); }; diff --git a/htdocs/includes/ace/src/ext-modelist.js b/htdocs/includes/ace/src/ext-modelist.js index 8b771ffeb99..064e398db75 100644 --- a/htdocs/includes/ace/src/ext-modelist.js +++ b/htdocs/includes/ace/src/ext-modelist.js @@ -39,22 +39,23 @@ var supportedModes = { ABC: ["abc"], ActionScript:["as"], ADA: ["ada|adb"], + Alda: ["alda"], Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"], - AsciiDoc: ["asciidoc|adoc"], - ASL: ["dsl|asl"], - Assembly_x86:["asm|a"], - AutoHotKey: ["ahk"], Apex: ["apex|cls|trigger|tgr"], AQL: ["aql"], + AsciiDoc: ["asciidoc|adoc"], + ASL: ["dsl|asl|asl.json"], + Assembly_x86:["asm|a"], + AutoHotKey: ["ahk"], BatchFile: ["bat|cmd"], C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp|ino"], C9Search: ["c9search_results"], - Crystal: ["cr"], Cirru: ["cirru|cr"], Clojure: ["clj|cljs"], Cobol: ["CBL|COB"], coffee: ["coffee|cf|cson|^Cakefile"], ColdFusion: ["cfm"], + Crystal: ["cr"], CSharp: ["cs"], Csound_Document: ["csd"], Csound_Orchestra: ["orc"], @@ -101,8 +102,8 @@ var supportedModes = { Jade: ["jade|pug"], Java: ["java"], JavaScript: ["js|jsm|jsx"], - JSON5: ["json5"], JSON: ["json"], + JSON5: ["json5"], JSONiq: ["jq"], JSP: ["jsp"], JSSM: ["jssm|jssm_state"], @@ -110,6 +111,7 @@ var supportedModes = { Julia: ["jl"], Kotlin: ["kt|kts"], LaTeX: ["tex|latex|ltx|bib"], + Latte: ["latte"], LESS: ["less"], Liquid: ["liquid"], Lisp: ["lisp"], @@ -124,32 +126,36 @@ var supportedModes = { Mask: ["mask"], MATLAB: ["matlab"], Maze: ["mz"], + MediaWiki: ["wiki|mediawiki"], MEL: ["mel"], + MIPS: ["s|asm"], MIXAL: ["mixal"], MUSHCode: ["mc|mush"], MySQL: ["mysql"], Nginx: ["nginx|conf"], - Nix: ["nix"], Nim: ["nim"], + Nix: ["nix"], NSIS: ["nsi|nsh"], Nunjucks: ["nunjucks|nunjs|nj|njk"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], Perl: ["pl|pm"], - Perl6: ["p6|pl6|pm6"], pgSQL: ["pgsql"], - PHP_Laravel_blade: ["blade.php"], PHP: ["php|inc|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module"], - Puppet: ["epp|pp"], + PHP_Laravel_blade: ["blade.php"], Pig: ["pig"], Powershell: ["ps1"], Praat: ["praat|praatscript|psc|proc"], + Prisma: ["prisma"], Prolog: ["plg|prolog"], Properties: ["properties"], Protobuf: ["proto"], + Puppet: ["epp|pp"], Python: ["py"], + QML: ["qml"], R: ["r"], + Raku: ["raku|rakumod|rakutest|p6|pl6|pm6"], Razor: ["cshtml|asp"], RDoc: ["Rd"], Red: ["red|reds"], @@ -161,11 +167,13 @@ var supportedModes = { SCAD: ["scad"], Scala: ["scala|sbt"], Scheme: ["scm|sm|rkt|oak|scheme"], + Scrypt: ["scrypt"], SCSS: ["scss"], SH: ["sh|bash|^.bashrc"], SJS: ["sjs"], Slim: ["slim|skim"], Smarty: ["smarty|tpl"], + Smithy: ["smithy"], snippets: ["snippets"], Soy_Template:["soy"], Space: ["space"], @@ -181,7 +189,7 @@ var supportedModes = { Textile: ["textile"], Toml: ["toml"], TSX: ["tsx"], - Twig: ["latte|twig|swig"], + Twig: ["twig|swig"], Typescript: ["ts|typescript|str"], Vala: ["vala"], VBScript: ["vbs|vb"], @@ -213,6 +221,7 @@ var nameOverrides = { Perl6: "Perl 6", AutoHotKey: "AutoHotkey / AutoIt" }; + var modesByName = {}; for (var name in supportedModes) { var data = supportedModes[name]; diff --git a/htdocs/includes/ace/src/ext-options.js b/htdocs/includes/ace/src/ext-options.js index d1d01cefa05..d200e821a3e 100644 --- a/htdocs/includes/ace/src/ext-options.js +++ b/htdocs/includes/ace/src/ext-options.js @@ -61,7 +61,7 @@ margin: 0px;\ .ace_optionsMenuEntry button:hover{\ background: #f0f0f0;\ }"; -dom.importCssString(cssText); +dom.importCssString(cssText, "settings_menu.css", false); module.exports.overlayPage = function overlayPage(editor, contentElement, callback) { var closer = document.createElement('div'); @@ -160,22 +160,23 @@ var supportedModes = { ABC: ["abc"], ActionScript:["as"], ADA: ["ada|adb"], + Alda: ["alda"], Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"], - AsciiDoc: ["asciidoc|adoc"], - ASL: ["dsl|asl"], - Assembly_x86:["asm|a"], - AutoHotKey: ["ahk"], Apex: ["apex|cls|trigger|tgr"], AQL: ["aql"], + AsciiDoc: ["asciidoc|adoc"], + ASL: ["dsl|asl|asl.json"], + Assembly_x86:["asm|a"], + AutoHotKey: ["ahk"], BatchFile: ["bat|cmd"], C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp|ino"], C9Search: ["c9search_results"], - Crystal: ["cr"], Cirru: ["cirru|cr"], Clojure: ["clj|cljs"], Cobol: ["CBL|COB"], coffee: ["coffee|cf|cson|^Cakefile"], ColdFusion: ["cfm"], + Crystal: ["cr"], CSharp: ["cs"], Csound_Document: ["csd"], Csound_Orchestra: ["orc"], @@ -222,8 +223,8 @@ var supportedModes = { Jade: ["jade|pug"], Java: ["java"], JavaScript: ["js|jsm|jsx"], - JSON5: ["json5"], JSON: ["json"], + JSON5: ["json5"], JSONiq: ["jq"], JSP: ["jsp"], JSSM: ["jssm|jssm_state"], @@ -231,6 +232,7 @@ var supportedModes = { Julia: ["jl"], Kotlin: ["kt|kts"], LaTeX: ["tex|latex|ltx|bib"], + Latte: ["latte"], LESS: ["less"], Liquid: ["liquid"], Lisp: ["lisp"], @@ -245,32 +247,36 @@ var supportedModes = { Mask: ["mask"], MATLAB: ["matlab"], Maze: ["mz"], + MediaWiki: ["wiki|mediawiki"], MEL: ["mel"], + MIPS: ["s|asm"], MIXAL: ["mixal"], MUSHCode: ["mc|mush"], MySQL: ["mysql"], Nginx: ["nginx|conf"], - Nix: ["nix"], Nim: ["nim"], + Nix: ["nix"], NSIS: ["nsi|nsh"], Nunjucks: ["nunjucks|nunjs|nj|njk"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], Perl: ["pl|pm"], - Perl6: ["p6|pl6|pm6"], pgSQL: ["pgsql"], - PHP_Laravel_blade: ["blade.php"], PHP: ["php|inc|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module"], - Puppet: ["epp|pp"], + PHP_Laravel_blade: ["blade.php"], Pig: ["pig"], Powershell: ["ps1"], Praat: ["praat|praatscript|psc|proc"], + Prisma: ["prisma"], Prolog: ["plg|prolog"], Properties: ["properties"], Protobuf: ["proto"], + Puppet: ["epp|pp"], Python: ["py"], + QML: ["qml"], R: ["r"], + Raku: ["raku|rakumod|rakutest|p6|pl6|pm6"], Razor: ["cshtml|asp"], RDoc: ["Rd"], Red: ["red|reds"], @@ -282,11 +288,13 @@ var supportedModes = { SCAD: ["scad"], Scala: ["scala|sbt"], Scheme: ["scm|sm|rkt|oak|scheme"], + Scrypt: ["scrypt"], SCSS: ["scss"], SH: ["sh|bash|^.bashrc"], SJS: ["sjs"], Slim: ["slim|skim"], Smarty: ["smarty|tpl"], + Smithy: ["smithy"], snippets: ["snippets"], Soy_Template:["soy"], Space: ["space"], @@ -302,7 +310,7 @@ var supportedModes = { Textile: ["textile"], Toml: ["toml"], TSX: ["tsx"], - Twig: ["latte|twig|swig"], + Twig: ["twig|swig"], Typescript: ["ts|typescript|str"], Vala: ["vala"], VBScript: ["vbs|vb"], @@ -334,6 +342,7 @@ var nameOverrides = { Perl6: "Perl 6", AutoHotKey: "AutoHotkey / AutoIt" }; + var modesByName = {}; for (var name in supportedModes) { var data = supportedModes[name]; @@ -367,7 +376,7 @@ var themeData = [ ["Solarized Light"], ["TextMate" ], ["Tomorrow" ], - ["XCode" ], + ["Xcode" ], ["Kuroir"], ["KatzenMilch"], ["SQL Server" ,"sqlserver" , "light"], @@ -384,6 +393,8 @@ var themeData = [ ["Merbivore Soft" ,"merbivore_soft" , "dark"], ["Mono Industrial" ,"mono_industrial" , "dark"], ["Monokai" ,"monokai" , "dark"], + ["Nord Dark" ,"nord_dark" , "dark"], + ["One Dark" ,"one_dark" , "dark"], ["Pastel on dark" ,"pastel_on_dark" , "dark"], ["Solarized Dark" ,"solarized_dark" , "dark"], ["Terminal" ,"terminal" , "dark"], @@ -498,6 +509,7 @@ var optionGroups = { "Soft Tabs": [{ path: "useSoftTabs" }, { + ariaLabel: "Tab Size", path: "tabSize", type: "number", values: [2, 3, 4, 8, 16] @@ -519,6 +531,12 @@ var optionGroups = { "Enable Behaviours": { path: "behavioursEnabled" }, + "Wrap with quotes": { + path: "wrapBehavioursEnabled" + }, + "Enable Auto Indent": { + path: "enableAutoIndent" + }, "Full Line Selection": { type: "checkbox", values: "text|line", @@ -533,11 +551,12 @@ var optionGroups = { "Show Indent Guides": { path: "displayIndentGuides" }, - "Persistent Scrollbar": [{ + "Persistent HScrollbar": { path: "hScrollBarAlwaysVisible" - }, { + }, + "Persistent VScrollbar": { path: "vScrollBarAlwaysVisible" - }], + }, "Animate scrolling": { path: "animatedScroll" }, @@ -556,6 +575,7 @@ var optionGroups = { "Show Print Margin": [{ path: "showPrintMargin" }, { + ariaLabel: "Print Margin", type: "number", path: "printMarginColumn" }], @@ -618,10 +638,10 @@ var OptionPanel = function(editor, element) { this.render = function() { this.container.innerHTML = ""; - buildDom(["table", {id: "controls"}, + buildDom(["table", {role: "presentation", id: "controls"}, this.renderOptionGroup(optionGroups.Main), ["tr", null, ["td", {colspan: 2}, - ["table", {id: "more-controls"}, + ["table", {role: "presentation", id: "more-controls"}, this.renderOptionGroup(optionGroups.More) ] ]], @@ -664,17 +684,20 @@ var OptionPanel = function(editor, element) { } if (option.type == "buttonBar") { - control = ["div", option.items.map(function(item) { + control = ["div", {role: "group", "aria-labelledby": option.path + "-label"}, option.items.map(function(item) { return ["button", { value: item.value, ace_selected_button: value == item.value, + 'aria-pressed': value == item.value, onclick: function() { self.setOption(option, item.value); var nodes = this.parentNode.querySelectorAll("[ace_selected_button]"); for (var i = 0; i < nodes.length; i++) { nodes[i].removeAttribute("ace_selected_button"); + nodes[i].setAttribute("aria-pressed", false); } this.setAttribute("ace_selected_button", true); + this.setAttribute("aria-pressed", true); } }, item.desc || item.caption || item.name]; })]; @@ -682,6 +705,11 @@ var OptionPanel = function(editor, element) { control = ["input", {type: "number", value: value || option.defaultValue, style:"width:3em", oninput: function() { self.setOption(option, parseInt(this.value)); }}]; + if (option.ariaLabel) { + control[1]["aria-label"] = option.ariaLabel; + } else { + control[1].id = key; + } if (option.defaults) { control = [control, option.defaults.map(function(item) { return ["button", {onclick: function() { @@ -725,11 +753,13 @@ var OptionPanel = function(editor, element) { this.renderOption = function(key, option) { if (option.path && !option.onchange && !this.editor.$options[option.path]) return; - this.options[option.path] = option; - var safeKey = "-" + option.path; + var path = Array.isArray(option) ? option[0].path : option.path; + this.options[path] = option; + var safeKey = "-" + path; + var safeId = path + "-label"; var control = this.renderOptionControl(safeKey, option); return ["tr", {class: "ace_optionsMenuEntry"}, ["td", - ["label", {for: safeKey}, key] + ["label", {for: safeKey, id: safeId}, key] ], ["td", control]]; }; diff --git a/htdocs/includes/ace/src/ext-prompt.js b/htdocs/includes/ace/src/ext-prompt.js index bcc99f70806..34d7e36d513 100644 --- a/htdocs/includes/ace/src/ext-prompt.js +++ b/htdocs/includes/ace/src/ext-prompt.js @@ -364,7 +364,7 @@ dom.importCssString("\ line-height: 1.4;\ background: #25282c;\ color: #c1c1c1;\ -}", "autocompletion.css"); +}", "autocompletion.css", false); exports.AcePopup = AcePopup; exports.$singleLineEditor = $singleLineEditor; @@ -430,8 +430,9 @@ exports.getCompletionPrefix = function (editor) { }); -define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/lib/dom","ace/editor"], function(require, exports, module) { +define("ace/snippets",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/editor"], function(require, exports, module) { "use strict"; +var dom = require("./lib/dom"); var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var lang = require("./lib/lang"); @@ -576,7 +577,9 @@ var SnippetManager = function() { {regex: "\\|" + escape("\\|") + "*\\|", onMatch: function(val, state, stack) { var choices = val.slice(1, -1).replace(/\\[,|\\]|,/g, function(operator) { return operator.length == 2 ? operator[1] : "\x00"; - }).split("\x00"); + }).split("\x00").map(function(value){ + return {value: value}; + }); stack[0].choices = choices; return [choices[0]]; }, next: "start"}, @@ -1047,6 +1050,12 @@ var SnippetManager = function() { } snippetMap[scope].push(s); + if (s.prefix) + s.tabTrigger = s.prefix; + + if (!s.content && s.body) + s.content = Array.isArray(s.body) ? s.body.join("\n") : s.body; + if (s.tabTrigger && !s.trigger) { if (!s.guard && /^\w/.test(s.tabTrigger)) s.guard = "\\b"; @@ -1063,10 +1072,13 @@ var SnippetManager = function() { s.endTriggerRe = new RegExp(s.endTrigger); } - if (snippets && snippets.content) - addSnippet(snippets); - else if (Array.isArray(snippets)) + if (Array.isArray(snippets)) { snippets.forEach(addSnippet); + } else { + Object.keys(snippets).forEach(function(key) { + addSnippet(snippets[key]); + }); + } this._signal("registerSnippets", {scope: scope}); }; @@ -1116,7 +1128,7 @@ var SnippetManager = function() { snippet.tabTrigger = val.match(/^\S*/)[0]; if (!snippet.name) snippet.name = val; - } else { + } else if (key) { snippet[key] = val; } } @@ -1265,18 +1277,17 @@ var TabstopManager = function(editor) { this.selectedTabstop = ts; var range = ts.firstNonLinked || ts; + if (ts.choices) range.cursor = range.start; if (!this.editor.inVirtualSelectionMode) { var sel = this.editor.multiSelect; - sel.toSingleRange(range.clone()); + sel.toSingleRange(range); for (var i = 0; i < ts.length; i++) { if (ts.hasLinkedRanges && ts[i].linked) continue; sel.addRange(ts[i].clone(), true); } - if (sel.ranges[0]) - sel.addRange(sel.ranges[0].clone()); } else { - this.editor.selection.setRange(range); + this.editor.selection.fromOrientedRange(range); } this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler); @@ -1403,14 +1414,14 @@ var moveRelative = function(point, start) { }; -require("./lib/dom").importCssString("\ +dom.importCssString("\ .ace_snippet-marker {\ -moz-box-sizing: border-box;\ box-sizing: border-box;\ background: rgba(194, 193, 208, 0.09);\ border: 1px dotted rgba(211, 208, 235, 0.62);\ position: absolute;\ -}"); +}", "snippets.css", false); exports.snippetManager = new SnippetManager(); @@ -1507,6 +1518,7 @@ var Autocomplete = function() { } else if (keepPopupPosition && !prefix) { this.detach(); } + this.changeTimer.cancel(); }; this.detach = function() { @@ -1569,13 +1581,15 @@ var Autocomplete = function() { if (!data) return false; + var completions = this.completions; + this.editor.startOperation({command: {name: "insertMatch"}}); if (data.completer && data.completer.insertMatch) { data.completer.insertMatch(this.editor, data); } else { - if (this.completions.filterText) { + if (completions.filterText) { var ranges = this.editor.selection.getAllRanges(); for (var i = 0, range; range = ranges[i]; i++) { - range.start.column -= this.completions.filterText.length; + range.start.column -= completions.filterText.length; this.editor.session.remove(range); } } @@ -1584,7 +1598,9 @@ var Autocomplete = function() { else this.editor.execCommand("insertstring", data.value || data); } - this.detach(); + if (this.completions == completions) + this.detach(); + this.editor.endOperation(); }; @@ -1680,19 +1696,14 @@ var Autocomplete = function() { return this.openPopup(this.editor, "", keepPopupPosition); } var _id = this.gatherCompletionsId; - this.gatherCompletions(this.editor, function(err, results) { - var detachIfFinished = function() { - if (!results.finished) return; - return this.detach(); - }.bind(this); + var detachIfFinished = function(results) { + if (!results.finished) return; + return this.detach(); + }.bind(this); + var processResults = function(results) { var prefix = results.prefix; - var matches = results && results.matches; - - if (!matches || !matches.length) - return detachIfFinished(); - if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId) - return; + var matches = results.matches; this.completions = new FilteredList(matches); @@ -1702,14 +1713,39 @@ var Autocomplete = function() { this.completions.setFilter(prefix); var filtered = this.completions.filtered; if (!filtered.length) - return detachIfFinished(); + return detachIfFinished(results); if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet) - return detachIfFinished(); + return detachIfFinished(results); if (this.autoInsert && filtered.length == 1 && results.finished) return this.insertMatch(filtered[0]); this.openPopup(this.editor, prefix, keepPopupPosition); + }.bind(this); + + var isImmediate = true; + var immediateResults = null; + this.gatherCompletions(this.editor, function(err, results) { + var prefix = results.prefix; + var matches = results && results.matches; + + if (!matches || !matches.length) + return detachIfFinished(results); + if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId) + return; + if (isImmediate) { + immediateResults = results; + return; + } + + processResults(results); }.bind(this)); + + isImmediate = false; + if (immediateResults) { + var results = immediateResults; + immediateResults = null; + processResults(results); + } }; this.cancelContextMenu = function() { @@ -1998,7 +2034,7 @@ margin: 0px;\ .ace_optionsMenuEntry button:hover{\ background: #f0f0f0;\ }"; -dom.importCssString(cssText); +dom.importCssString(cssText, "settings_menu.css", false); module.exports.overlayPage = function overlayPage(editor, contentElement, callback) { var closer = document.createElement('div'); @@ -2097,22 +2133,23 @@ var supportedModes = { ABC: ["abc"], ActionScript:["as"], ADA: ["ada|adb"], + Alda: ["alda"], Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"], - AsciiDoc: ["asciidoc|adoc"], - ASL: ["dsl|asl"], - Assembly_x86:["asm|a"], - AutoHotKey: ["ahk"], Apex: ["apex|cls|trigger|tgr"], AQL: ["aql"], + AsciiDoc: ["asciidoc|adoc"], + ASL: ["dsl|asl|asl.json"], + Assembly_x86:["asm|a"], + AutoHotKey: ["ahk"], BatchFile: ["bat|cmd"], C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp|ino"], C9Search: ["c9search_results"], - Crystal: ["cr"], Cirru: ["cirru|cr"], Clojure: ["clj|cljs"], Cobol: ["CBL|COB"], coffee: ["coffee|cf|cson|^Cakefile"], ColdFusion: ["cfm"], + Crystal: ["cr"], CSharp: ["cs"], Csound_Document: ["csd"], Csound_Orchestra: ["orc"], @@ -2159,8 +2196,8 @@ var supportedModes = { Jade: ["jade|pug"], Java: ["java"], JavaScript: ["js|jsm|jsx"], - JSON5: ["json5"], JSON: ["json"], + JSON5: ["json5"], JSONiq: ["jq"], JSP: ["jsp"], JSSM: ["jssm|jssm_state"], @@ -2168,6 +2205,7 @@ var supportedModes = { Julia: ["jl"], Kotlin: ["kt|kts"], LaTeX: ["tex|latex|ltx|bib"], + Latte: ["latte"], LESS: ["less"], Liquid: ["liquid"], Lisp: ["lisp"], @@ -2182,32 +2220,36 @@ var supportedModes = { Mask: ["mask"], MATLAB: ["matlab"], Maze: ["mz"], + MediaWiki: ["wiki|mediawiki"], MEL: ["mel"], + MIPS: ["s|asm"], MIXAL: ["mixal"], MUSHCode: ["mc|mush"], MySQL: ["mysql"], Nginx: ["nginx|conf"], - Nix: ["nix"], Nim: ["nim"], + Nix: ["nix"], NSIS: ["nsi|nsh"], Nunjucks: ["nunjucks|nunjs|nj|njk"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], Perl: ["pl|pm"], - Perl6: ["p6|pl6|pm6"], pgSQL: ["pgsql"], - PHP_Laravel_blade: ["blade.php"], PHP: ["php|inc|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module"], - Puppet: ["epp|pp"], + PHP_Laravel_blade: ["blade.php"], Pig: ["pig"], Powershell: ["ps1"], Praat: ["praat|praatscript|psc|proc"], + Prisma: ["prisma"], Prolog: ["plg|prolog"], Properties: ["properties"], Protobuf: ["proto"], + Puppet: ["epp|pp"], Python: ["py"], + QML: ["qml"], R: ["r"], + Raku: ["raku|rakumod|rakutest|p6|pl6|pm6"], Razor: ["cshtml|asp"], RDoc: ["Rd"], Red: ["red|reds"], @@ -2219,11 +2261,13 @@ var supportedModes = { SCAD: ["scad"], Scala: ["scala|sbt"], Scheme: ["scm|sm|rkt|oak|scheme"], + Scrypt: ["scrypt"], SCSS: ["scss"], SH: ["sh|bash|^.bashrc"], SJS: ["sjs"], Slim: ["slim|skim"], Smarty: ["smarty|tpl"], + Smithy: ["smithy"], snippets: ["snippets"], Soy_Template:["soy"], Space: ["space"], @@ -2239,7 +2283,7 @@ var supportedModes = { Textile: ["textile"], Toml: ["toml"], TSX: ["tsx"], - Twig: ["latte|twig|swig"], + Twig: ["twig|swig"], Typescript: ["ts|typescript|str"], Vala: ["vala"], VBScript: ["vbs|vb"], @@ -2271,6 +2315,7 @@ var nameOverrides = { Perl6: "Perl 6", AutoHotKey: "AutoHotkey / AutoIt" }; + var modesByName = {}; for (var name in supportedModes) { var data = supportedModes[name]; @@ -2586,13 +2631,10 @@ prompt.commands = function(editor, callback) { var platform = handler.platform; var cbn = handler.byName; for (var i in cbn) { - var key; - if (cbn[i].bindKey && cbn[i].bindKey[platform] !== null) { - key = cbn[i].bindKey["win"]; - } else { - key = ""; + var key = cbn[i].bindKey; + if (typeof key !== "string") { + key = key && key[platform] || ""; } - var commands = cbn[i]; var description = commands.description || normalizeName(commands.name); if (!Array.isArray(commands)) @@ -2749,7 +2791,7 @@ dom.importCssString(".ace_prompt_container {\ background: white;\ border-radius: 2px;\ box-shadow: 0px 2px 3px 0px #555;\ -}"); +}", "promtp.css", false); exports.prompt = prompt; diff --git a/htdocs/includes/ace/src/ext-searchbox.js b/htdocs/includes/ace/src/ext-searchbox.js index 4fbe7933506..8be7e8c12e7 100644 --- a/htdocs/includes/ace/src/ext-searchbox.js +++ b/htdocs/includes/ace/src/ext-searchbox.js @@ -160,7 +160,7 @@ var keyUtil = require("../lib/keys"); var MAX_COUNT = 999; -dom.importCssString(searchboxCss, "ace_searchbox"); +dom.importCssString(searchboxCss, "ace_searchbox", false); var SearchBox = function(editor, range, showReplaceForm) { var div = dom.createElement("div"); diff --git a/htdocs/includes/ace/src/ext-settings_menu.js b/htdocs/includes/ace/src/ext-settings_menu.js index ebfa4108519..1d88965b63b 100644 --- a/htdocs/includes/ace/src/ext-settings_menu.js +++ b/htdocs/includes/ace/src/ext-settings_menu.js @@ -61,7 +61,7 @@ margin: 0px;\ .ace_optionsMenuEntry button:hover{\ background: #f0f0f0;\ }"; -dom.importCssString(cssText); +dom.importCssString(cssText, "settings_menu.css", false); module.exports.overlayPage = function overlayPage(editor, contentElement, callback) { var closer = document.createElement('div'); @@ -160,22 +160,23 @@ var supportedModes = { ABC: ["abc"], ActionScript:["as"], ADA: ["ada|adb"], + Alda: ["alda"], Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"], - AsciiDoc: ["asciidoc|adoc"], - ASL: ["dsl|asl"], - Assembly_x86:["asm|a"], - AutoHotKey: ["ahk"], Apex: ["apex|cls|trigger|tgr"], AQL: ["aql"], + AsciiDoc: ["asciidoc|adoc"], + ASL: ["dsl|asl|asl.json"], + Assembly_x86:["asm|a"], + AutoHotKey: ["ahk"], BatchFile: ["bat|cmd"], C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp|ino"], C9Search: ["c9search_results"], - Crystal: ["cr"], Cirru: ["cirru|cr"], Clojure: ["clj|cljs"], Cobol: ["CBL|COB"], coffee: ["coffee|cf|cson|^Cakefile"], ColdFusion: ["cfm"], + Crystal: ["cr"], CSharp: ["cs"], Csound_Document: ["csd"], Csound_Orchestra: ["orc"], @@ -222,8 +223,8 @@ var supportedModes = { Jade: ["jade|pug"], Java: ["java"], JavaScript: ["js|jsm|jsx"], - JSON5: ["json5"], JSON: ["json"], + JSON5: ["json5"], JSONiq: ["jq"], JSP: ["jsp"], JSSM: ["jssm|jssm_state"], @@ -231,6 +232,7 @@ var supportedModes = { Julia: ["jl"], Kotlin: ["kt|kts"], LaTeX: ["tex|latex|ltx|bib"], + Latte: ["latte"], LESS: ["less"], Liquid: ["liquid"], Lisp: ["lisp"], @@ -245,32 +247,36 @@ var supportedModes = { Mask: ["mask"], MATLAB: ["matlab"], Maze: ["mz"], + MediaWiki: ["wiki|mediawiki"], MEL: ["mel"], + MIPS: ["s|asm"], MIXAL: ["mixal"], MUSHCode: ["mc|mush"], MySQL: ["mysql"], Nginx: ["nginx|conf"], - Nix: ["nix"], Nim: ["nim"], + Nix: ["nix"], NSIS: ["nsi|nsh"], Nunjucks: ["nunjucks|nunjs|nj|njk"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], Perl: ["pl|pm"], - Perl6: ["p6|pl6|pm6"], pgSQL: ["pgsql"], - PHP_Laravel_blade: ["blade.php"], PHP: ["php|inc|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module"], - Puppet: ["epp|pp"], + PHP_Laravel_blade: ["blade.php"], Pig: ["pig"], Powershell: ["ps1"], Praat: ["praat|praatscript|psc|proc"], + Prisma: ["prisma"], Prolog: ["plg|prolog"], Properties: ["properties"], Protobuf: ["proto"], + Puppet: ["epp|pp"], Python: ["py"], + QML: ["qml"], R: ["r"], + Raku: ["raku|rakumod|rakutest|p6|pl6|pm6"], Razor: ["cshtml|asp"], RDoc: ["Rd"], Red: ["red|reds"], @@ -282,11 +288,13 @@ var supportedModes = { SCAD: ["scad"], Scala: ["scala|sbt"], Scheme: ["scm|sm|rkt|oak|scheme"], + Scrypt: ["scrypt"], SCSS: ["scss"], SH: ["sh|bash|^.bashrc"], SJS: ["sjs"], Slim: ["slim|skim"], Smarty: ["smarty|tpl"], + Smithy: ["smithy"], snippets: ["snippets"], Soy_Template:["soy"], Space: ["space"], @@ -302,7 +310,7 @@ var supportedModes = { Textile: ["textile"], Toml: ["toml"], TSX: ["tsx"], - Twig: ["latte|twig|swig"], + Twig: ["twig|swig"], Typescript: ["ts|typescript|str"], Vala: ["vala"], VBScript: ["vbs|vb"], @@ -334,6 +342,7 @@ var nameOverrides = { Perl6: "Perl 6", AutoHotKey: "AutoHotkey / AutoIt" }; + var modesByName = {}; for (var name in supportedModes) { var data = supportedModes[name]; @@ -367,7 +376,7 @@ var themeData = [ ["Solarized Light"], ["TextMate" ], ["Tomorrow" ], - ["XCode" ], + ["Xcode" ], ["Kuroir"], ["KatzenMilch"], ["SQL Server" ,"sqlserver" , "light"], @@ -384,6 +393,8 @@ var themeData = [ ["Merbivore Soft" ,"merbivore_soft" , "dark"], ["Mono Industrial" ,"mono_industrial" , "dark"], ["Monokai" ,"monokai" , "dark"], + ["Nord Dark" ,"nord_dark" , "dark"], + ["One Dark" ,"one_dark" , "dark"], ["Pastel on dark" ,"pastel_on_dark" , "dark"], ["Solarized Dark" ,"solarized_dark" , "dark"], ["Terminal" ,"terminal" , "dark"], @@ -498,6 +509,7 @@ var optionGroups = { "Soft Tabs": [{ path: "useSoftTabs" }, { + ariaLabel: "Tab Size", path: "tabSize", type: "number", values: [2, 3, 4, 8, 16] @@ -519,6 +531,12 @@ var optionGroups = { "Enable Behaviours": { path: "behavioursEnabled" }, + "Wrap with quotes": { + path: "wrapBehavioursEnabled" + }, + "Enable Auto Indent": { + path: "enableAutoIndent" + }, "Full Line Selection": { type: "checkbox", values: "text|line", @@ -533,11 +551,12 @@ var optionGroups = { "Show Indent Guides": { path: "displayIndentGuides" }, - "Persistent Scrollbar": [{ + "Persistent HScrollbar": { path: "hScrollBarAlwaysVisible" - }, { + }, + "Persistent VScrollbar": { path: "vScrollBarAlwaysVisible" - }], + }, "Animate scrolling": { path: "animatedScroll" }, @@ -556,6 +575,7 @@ var optionGroups = { "Show Print Margin": [{ path: "showPrintMargin" }, { + ariaLabel: "Print Margin", type: "number", path: "printMarginColumn" }], @@ -618,10 +638,10 @@ var OptionPanel = function(editor, element) { this.render = function() { this.container.innerHTML = ""; - buildDom(["table", {id: "controls"}, + buildDom(["table", {role: "presentation", id: "controls"}, this.renderOptionGroup(optionGroups.Main), ["tr", null, ["td", {colspan: 2}, - ["table", {id: "more-controls"}, + ["table", {role: "presentation", id: "more-controls"}, this.renderOptionGroup(optionGroups.More) ] ]], @@ -664,17 +684,20 @@ var OptionPanel = function(editor, element) { } if (option.type == "buttonBar") { - control = ["div", option.items.map(function(item) { + control = ["div", {role: "group", "aria-labelledby": option.path + "-label"}, option.items.map(function(item) { return ["button", { value: item.value, ace_selected_button: value == item.value, + 'aria-pressed': value == item.value, onclick: function() { self.setOption(option, item.value); var nodes = this.parentNode.querySelectorAll("[ace_selected_button]"); for (var i = 0; i < nodes.length; i++) { nodes[i].removeAttribute("ace_selected_button"); + nodes[i].setAttribute("aria-pressed", false); } this.setAttribute("ace_selected_button", true); + this.setAttribute("aria-pressed", true); } }, item.desc || item.caption || item.name]; })]; @@ -682,6 +705,11 @@ var OptionPanel = function(editor, element) { control = ["input", {type: "number", value: value || option.defaultValue, style:"width:3em", oninput: function() { self.setOption(option, parseInt(this.value)); }}]; + if (option.ariaLabel) { + control[1]["aria-label"] = option.ariaLabel; + } else { + control[1].id = key; + } if (option.defaults) { control = [control, option.defaults.map(function(item) { return ["button", {onclick: function() { @@ -725,11 +753,13 @@ var OptionPanel = function(editor, element) { this.renderOption = function(key, option) { if (option.path && !option.onchange && !this.editor.$options[option.path]) return; - this.options[option.path] = option; - var safeKey = "-" + option.path; + var path = Array.isArray(option) ? option[0].path : option.path; + this.options[path] = option; + var safeKey = "-" + path; + var safeId = path + "-label"; var control = this.renderOptionControl(safeKey, option); return ["tr", {class: "ace_optionsMenuEntry"}, ["td", - ["label", {for: safeKey}, key] + ["label", {for: safeKey, id: safeId}, key] ], ["td", control]]; }; diff --git a/htdocs/includes/ace/src/ext-textarea.js b/htdocs/includes/ace/src/ext-textarea.js index b876bd3854e..c4bc96bdd1a 100644 --- a/htdocs/includes/ace/src/ext-textarea.js +++ b/htdocs/includes/ace/src/ext-textarea.js @@ -1,135 +1,4 @@ -define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(require, exports, module) { -"use strict"; - -exports.isDark = false; -exports.cssClass = "ace-tm"; -exports.cssText = ".ace-tm .ace_gutter {\ -background: #f0f0f0;\ -color: #333;\ -}\ -.ace-tm .ace_print-margin {\ -width: 1px;\ -background: #e8e8e8;\ -}\ -.ace-tm .ace_fold {\ -background-color: #6B72E6;\ -}\ -.ace-tm {\ -background-color: #FFFFFF;\ -color: black;\ -}\ -.ace-tm .ace_cursor {\ -color: black;\ -}\ -.ace-tm .ace_invisible {\ -color: rgb(191, 191, 191);\ -}\ -.ace-tm .ace_storage,\ -.ace-tm .ace_keyword {\ -color: blue;\ -}\ -.ace-tm .ace_constant {\ -color: rgb(197, 6, 11);\ -}\ -.ace-tm .ace_constant.ace_buildin {\ -color: rgb(88, 72, 246);\ -}\ -.ace-tm .ace_constant.ace_language {\ -color: rgb(88, 92, 246);\ -}\ -.ace-tm .ace_constant.ace_library {\ -color: rgb(6, 150, 14);\ -}\ -.ace-tm .ace_invalid {\ -background-color: rgba(255, 0, 0, 0.1);\ -color: red;\ -}\ -.ace-tm .ace_support.ace_function {\ -color: rgb(60, 76, 114);\ -}\ -.ace-tm .ace_support.ace_constant {\ -color: rgb(6, 150, 14);\ -}\ -.ace-tm .ace_support.ace_type,\ -.ace-tm .ace_support.ace_class {\ -color: rgb(109, 121, 222);\ -}\ -.ace-tm .ace_keyword.ace_operator {\ -color: rgb(104, 118, 135);\ -}\ -.ace-tm .ace_string {\ -color: rgb(3, 106, 7);\ -}\ -.ace-tm .ace_comment {\ -color: rgb(76, 136, 107);\ -}\ -.ace-tm .ace_comment.ace_doc {\ -color: rgb(0, 102, 255);\ -}\ -.ace-tm .ace_comment.ace_doc.ace_tag {\ -color: rgb(128, 159, 191);\ -}\ -.ace-tm .ace_constant.ace_numeric {\ -color: rgb(0, 0, 205);\ -}\ -.ace-tm .ace_variable {\ -color: rgb(49, 132, 149);\ -}\ -.ace-tm .ace_xml-pe {\ -color: rgb(104, 104, 91);\ -}\ -.ace-tm .ace_entity.ace_name.ace_function {\ -color: #0000A2;\ -}\ -.ace-tm .ace_heading {\ -color: rgb(12, 7, 255);\ -}\ -.ace-tm .ace_list {\ -color:rgb(185, 6, 144);\ -}\ -.ace-tm .ace_meta.ace_tag {\ -color:rgb(0, 22, 142);\ -}\ -.ace-tm .ace_string.ace_regex {\ -color: rgb(255, 0, 0)\ -}\ -.ace-tm .ace_marker-layer .ace_selection {\ -background: rgb(181, 213, 255);\ -}\ -.ace-tm.ace_multiselect .ace_selection.ace_start {\ -box-shadow: 0 0 3px 0px white;\ -}\ -.ace-tm .ace_marker-layer .ace_step {\ -background: rgb(252, 255, 0);\ -}\ -.ace-tm .ace_marker-layer .ace_stack {\ -background: rgb(164, 229, 101);\ -}\ -.ace-tm .ace_marker-layer .ace_bracket {\ -margin: -1px 0 0 -1px;\ -border: 1px solid rgb(192, 192, 192);\ -}\ -.ace-tm .ace_marker-layer .ace_active-line {\ -background: rgba(0, 0, 0, 0.07);\ -}\ -.ace-tm .ace_gutter-active-line {\ -background-color : #dcdcdc;\ -}\ -.ace-tm .ace_marker-layer .ace_selected-word {\ -background: rgb(250, 250, 255);\ -border: 1px solid rgb(200, 200, 250);\ -}\ -.ace-tm .ace_indent-guide {\ -background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\ -}\ -"; -exports.$id = "ace/theme/textmate"; - -var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); -}); - -define("ace/ext/textarea",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/net","ace/ace","ace/theme/textmate"], function(require, exports, module) { +define("ace/ext/textarea",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/net","ace/ace"], function(require, exports, module) { "use strict"; var event = require("../lib/event"); @@ -137,8 +6,6 @@ var UA = require("../lib/useragent"); var net = require("../lib/net"); var ace = require("../ace"); -require("../theme/textmate"); - module.exports = exports = ace; var getCSSProperty = function(element, container, property) { var ret = element.style[property]; diff --git a/htdocs/includes/ace/src/ext-themelist.js b/htdocs/includes/ace/src/ext-themelist.js index 712700a64bd..e8a8ea8974a 100644 --- a/htdocs/includes/ace/src/ext-themelist.js +++ b/htdocs/includes/ace/src/ext-themelist.js @@ -13,7 +13,7 @@ var themeData = [ ["Solarized Light"], ["TextMate" ], ["Tomorrow" ], - ["XCode" ], + ["Xcode" ], ["Kuroir"], ["KatzenMilch"], ["SQL Server" ,"sqlserver" , "light"], @@ -30,6 +30,8 @@ var themeData = [ ["Merbivore Soft" ,"merbivore_soft" , "dark"], ["Mono Industrial" ,"mono_industrial" , "dark"], ["Monokai" ,"monokai" , "dark"], + ["Nord Dark" ,"nord_dark" , "dark"], + ["One Dark" ,"one_dark" , "dark"], ["Pastel on dark" ,"pastel_on_dark" , "dark"], ["Solarized Dark" ,"solarized_dark" , "dark"], ["Terminal" ,"terminal" , "dark"], diff --git a/htdocs/includes/ace/src/keybinding-emacs.js b/htdocs/includes/ace/src/keybinding-emacs.js index 58e79cd44fc..07ffa85cd9d 100644 --- a/htdocs/includes/ace/src/keybinding-emacs.js +++ b/htdocs/includes/ace/src/keybinding-emacs.js @@ -98,7 +98,7 @@ dom.importCssString(".ace_occur-highlight {\n\ .ace_dark .ace_occur-highlight {\n\ background-color: rgb(80, 140, 85);\n\ box-shadow: 0 0 4px rgb(60, 120, 70);\n\ -}\n", "incremental-occur-highlighting"); +}\n", "incremental-occur-highlighting", false); exports.Occur = Occur; @@ -325,7 +325,7 @@ oop.inherits(IncrementalSearchKeyboardHandler, HashHandler); this.attach = function(editor) { var iSearch = this.$iSearch; HashHandler.call(this, exports.iSearchCommands, editor.commands.platform); - this.$commandExecHandler = editor.commands.addEventListener('exec', function(e) { + this.$commandExecHandler = editor.commands.on('exec', function(e) { if (!e.command.isIncrementalSearchCommand) return iSearch.deactivate(); e.stopPropagation(); @@ -340,7 +340,7 @@ oop.inherits(IncrementalSearchKeyboardHandler, HashHandler); this.detach = function(editor) { if (!this.$commandExecHandler) return; - editor.commands.removeEventListener('exec', this.$commandExecHandler); + editor.commands.off('exec', this.$commandExecHandler); delete this.$commandExecHandler; }; @@ -349,7 +349,7 @@ oop.inherits(IncrementalSearchKeyboardHandler, HashHandler); if (((hashId === 1/*ctrl*/ || hashId === 8/*command*/) && key === 'v') || (hashId === 1/*ctrl*/ && key === 'y')) return null; var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode); - if (cmd.command) { return cmd; } + if (cmd && cmd.command) { return cmd; } if (hashId == -1) { var extendCmd = this.commands.extendSearchTerm; if (extendCmd) { return {command: extendCmd, args: key}; } @@ -406,27 +406,28 @@ function objectToRegExp(obj) { (function() { - this.activate = function(ed, backwards) { - this.$editor = ed; - this.$startPos = this.$currentPos = ed.getCursorPosition(); + this.activate = function(editor, backwards) { + this.$editor = editor; + this.$startPos = this.$currentPos = editor.getCursorPosition(); this.$options.needle = ''; this.$options.backwards = backwards; - ed.keyBinding.addKeyboardHandler(this.$keyboardHandler); - this.$originalEditorOnPaste = ed.onPaste; ed.onPaste = this.onPaste.bind(this); - this.$mousedownHandler = ed.addEventListener('mousedown', this.onMouseDown.bind(this)); - this.selectionFix(ed); + editor.keyBinding.addKeyboardHandler(this.$keyboardHandler); + this.$originalEditorOnPaste = editor.onPaste; + editor.onPaste = this.onPaste.bind(this); + this.$mousedownHandler = editor.on('mousedown', this.onMouseDown.bind(this)); + this.selectionFix(editor); this.statusMessage(true); }; this.deactivate = function(reset) { this.cancelSearch(reset); - var ed = this.$editor; - ed.keyBinding.removeKeyboardHandler(this.$keyboardHandler); + var editor = this.$editor; + editor.keyBinding.removeKeyboardHandler(this.$keyboardHandler); if (this.$mousedownHandler) { - ed.removeEventListener('mousedown', this.$mousedownHandler); + editor.off('mousedown', this.$mousedownHandler); delete this.$mousedownHandler; } - ed.onPaste = this.$originalEditorOnPaste; + editor.onPaste = this.$originalEditorOnPaste; this.message(''); }; @@ -557,7 +558,7 @@ function objectToRegExp(obj) { exports.IncrementalSearch = IncrementalSearch; var dom = require('./lib/dom'); -dom.importCssString && dom.importCssString("\ +dom.importCssString("\ .ace_marker-layer .ace_isearch-result {\ position: absolute;\ z-index: 6;\ @@ -571,7 +572,7 @@ div.ace_isearch-result {\ .ace_dark div.ace_isearch-result {\ background-color: rgb(100, 110, 160);\ box-shadow: 0 0 4px rgb(80, 90, 140);\ -}", "incremental-search-highlighting"); +}", "incremental-search-highlighting", false); var commands = require("./commands/command_manager"); (function() { this.setupIncrementalSearch = function(editor, val) { @@ -700,20 +701,20 @@ exports.handler.attach = function(editor) { editor.commands.addCommands(commands); exports.handler.platform = editor.commands.platform; editor.$emacsModeHandler = this; - editor.addEventListener('copy', this.onCopy); - editor.addEventListener('paste', this.onPaste); + editor.on('copy', this.onCopy); + editor.on('paste', this.onPaste); }; exports.handler.detach = function(editor) { editor.renderer.$blockCursor = false; editor.session.$selectLongWords = $formerLongWords; editor.session.$useEmacsStyleLineStart = $formerLineStart; - editor.removeEventListener("click", $resetMarkMode); - editor.removeEventListener("changeSession", $kbSessionChange); + editor.off("click", $resetMarkMode); + editor.off("changeSession", $kbSessionChange); editor.unsetStyle("emacs-mode"); editor.commands.removeCommands(commands); - editor.removeEventListener('copy', this.onCopy); - editor.removeEventListener('paste', this.onPaste); + editor.off('copy', this.onCopy); + editor.off('paste', this.onPaste); editor.$emacsModeHandler = null; }; diff --git a/htdocs/includes/ace/src/keybinding-vim.js b/htdocs/includes/ace/src/keybinding-vim.js index 79761280e93..bfb7e0bafe5 100644 --- a/htdocs/includes/ace/src/keybinding-vim.js +++ b/htdocs/includes/ace/src/keybinding-vim.js @@ -1,4 +1,123 @@ -define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/dom","ace/lib/oop","ace/lib/keys","ace/lib/event","ace/search","ace/lib/useragent","ace/search_highlight","ace/commands/multi_select_commands","ace/mode/text","ace/multi_select"], function(require, exports, module) { +define("ace/ext/hardwrap",["require","exports","module","ace/range","ace/editor","ace/config"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +function hardWrap(editor, options) { + var max = options.column || editor.getOption("printMarginColumn"); + var allowMerge = options.allowMerge != false; + + var row = Math.min(options.startRow, options.endRow); + var endRow = Math.max(options.startRow, options.endRow); + + var session = editor.session; + + while (row <= endRow) { + var line = session.getLine(row); + if (line.length > max) { + var space = findSpace(line, max, 5); + if (space) { + var indentation = /^\s*/.exec(line)[0]; + session.replace(new Range(row,space.start,row,space.end), "\n" + indentation); + } + endRow++; + } else if (allowMerge && /\S/.test(line) && row != endRow) { + var nextLine = session.getLine(row + 1); + if (nextLine && /\S/.test(nextLine)) { + var trimmedLine = line.replace(/\s+$/, ""); + var trimmedNextLine = nextLine.replace(/^\s+/, ""); + var mergedLine = trimmedLine + " " + trimmedNextLine; + + var space = findSpace(mergedLine, max, 5); + if (space && space.start > trimmedLine.length || mergedLine.length < max) { + var replaceRange = new Range(row,trimmedLine.length,row + 1,nextLine.length - trimmedNextLine.length); + session.replace(replaceRange, " "); + row--; + endRow--; + } else if (trimmedLine.length < line.length) { + session.remove(new Range(row, trimmedLine.length, row, line.length)); + } + } + } + row++; + } + + function findSpace(line, max, min) { + if (line.length < max) + return; + var before = line.slice(0, max); + var after = line.slice(max); + var spaceAfter = /^(?:(\s+)|(\S+)(\s+))/.exec(after); + var spaceBefore = /(?:(\s+)|(\s+)(\S+))$/.exec(before); + var start = 0; + var end = 0; + if (spaceBefore && !spaceBefore[2]) { + start = max - spaceBefore[1].length; + end = max; + } + if (spaceAfter && !spaceAfter[2]) { + if (!start) + start = max; + end = max + spaceAfter[1].length; + } + if (start) { + return { + start: start, + end: end + }; + } + if (spaceBefore && spaceBefore[2] && spaceBefore.index > min) { + return { + start: spaceBefore.index, + end: spaceBefore.index + spaceBefore[2].length + }; + } + if (spaceAfter && spaceAfter[2]) { + start = max + spaceAfter[2].length; + return { + start: start, + end: start + spaceAfter[3].length + }; + } + } + +} + +function wrapAfterInput(e) { + if (e.command.name == "insertstring" && /\S/.test(e.args)) { + var editor = e.editor; + var cursor = editor.selection.cursor; + if (cursor.column <= editor.renderer.$printMarginColumn) return; + var lastDelta = editor.session.$undoManager.$lastDelta; + + hardWrap(editor, { + startRow: cursor.row, endRow: cursor.row, + allowMerge: false + }); + if (lastDelta != editor.session.$undoManager.$lastDelta) + editor.session.markUndoGroup(); + } +} + +var Editor = require("../editor").Editor; +require("../config").defineOptions(Editor.prototype, "editor", { + hardWrap: { + set: function(val) { + if (val) { + this.commands.on("afterExec", wrapAfterInput); + } else { + this.commands.off("afterExec", wrapAfterInput); + } + }, + value: false + } +}); + +exports.hardWrap = hardWrap; + +}); + +define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/dom","ace/lib/oop","ace/lib/keys","ace/lib/event","ace/search","ace/lib/useragent","ace/search_highlight","ace/commands/multi_select_commands","ace/mode/text","ace/ext/hardwrap","ace/multi_select"], function(require, exports, module) { 'use strict'; function log() { @@ -36,12 +155,14 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve var SearchHighlight = require("../search_highlight").SearchHighlight; var multiSelectCommands = require("../commands/multi_select_commands"); var TextModeTokenRe = require("../mode/text").Mode.prototype.tokenRe; + var hardWrap = require("../ext/hardwrap").hardWrap; require("../multi_select"); var CodeMirror = function(ace) { this.ace = ace; this.state = {}; this.marks = {}; + this.options = {}; this.$uid = 0; this.onChange = this.onChange.bind(this); this.onSelectionChange = this.onSelectionChange.bind(this); @@ -58,7 +179,9 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve CodeMirror.commands = { redo: function(cm) { cm.ace.redo(); }, undo: function(cm) { cm.ace.undo(); }, - newlineAndIndent: function(cm) { cm.ace.insert("\n"); } + newlineAndIndent: function(cm) { cm.ace.insert("\n"); }, + goLineLeft: function(cm) { cm.ace.selection.moveCursorLineStart(); }, + goLineRight: function(cm) { cm.ace.selection.moveCursorLineEnd(); } }; CodeMirror.keyMap = {}; CodeMirror.addClass = CodeMirror.rmClass = function() {}; @@ -96,6 +219,11 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve } }; + + CodeMirror.findMatchingTag = function(cm, head) { + + }; + CodeMirror.signal = function(o, name, e) { return o._signal(name, e) }; CodeMirror.on = event.addListener; CodeMirror.off = event.removeListener; @@ -104,10 +232,10 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve TextModeTokenRe.lastIndex = 0; return TextModeTokenRe.test(ch); }; - + (function() { oop.implement(CodeMirror.prototype, EventEmitter); - + this.destroy = function() { this.ace.off('change', this.onChange); this.ace.off('changeSelection', this.onSelectionChange); @@ -194,10 +322,15 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve ch = line.ch; line = line.line; } + var shouldScroll = !this.curOp && !this.ace.inVirtualSelectionMode; if (!this.ace.inVirtualSelectionMode) this.ace.exitMultiSelectMode(); this.ace.session.unfold({row: line, column: ch}); this.ace.selection.moveTo(line, ch); + if (shouldScroll) { + this.ace.renderer.scrollCursorIntoView(); + this.ace.endOperation(); + } }; this.getCursor = function(p) { var sel = this.ace.selection; @@ -227,7 +360,7 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve r.cursor = Range.comparePoints(r.start, head) ? r.end : r.start; return r; }); - + if (this.ace.inVirtualSelectionMode) { this.ace.selection.fromOrientedRange(ranges[0]); return; @@ -259,6 +392,9 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve var pos = this.ace.session.$clipPositionToDocument(p.line, p.ch); return toCmPos(pos); }; + this.foldCode = function(pos) { + this.ace.session.$toggleFoldWidget(pos.line, {}); + }; this.markText = function(cursor) { return {clear: function() {}, find: function() {}}; }; @@ -269,7 +405,7 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve var rowShift = (end.row - start.row) * (isInsert ? 1 : -1); var colShift = (end.column - start.column) * (isInsert ? 1 : -1); if (isInsert) end = start; - + for (var i in this.marks) { var point = this.marks[i]; var cmp = Range.comparePoints(point, start); @@ -374,6 +510,7 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve query = query.source; isRegexp = true; } + if (query == "\\n") { query = "\n"; isRegexp = false; } var search = new Search(); if (pos.ch == undefined) pos.ch = Number.MAX_VALUE; var acePos = {row: pos.line, column: pos.ch}; @@ -392,14 +529,8 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve start: last || acePos }); var range = search.find(cm.ace.session); - if (range && range.isEmpty()) { - if (cm.getLine(range.start.row).length == range.start.column) { - search.$options.start = range; - range = search.find(cm.ace.session); - } - } last = range; - return last; + return last && [!last.isEmpty()]; }, from: function() { return last && toCmPos(last.start) }, to: function() { return last && toCmPos(last.end) }, @@ -433,9 +564,11 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve }; this.replaceRange = function(text, s, e) { if (!e) e = s; - return this.ace.session.replace(new Range(s.line, s.ch, e.line, e.ch), text); + var range = new Range(s.line, s.ch, e.line, e.ch); + this.ace.session.$clipRangeToDocument(range); + return this.ace.session.replace(range, text); }; - this.replaceSelection = + this.replaceSelection = this.replaceSelections = function(p) { var sel = this.ace.selection; if (this.ace.inVirtualSelectionMode) { @@ -487,7 +620,8 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve if (name) this.ace.setOption(name, val); }; - this.getOption = function(name, val) { + this.getOption = function(name) { + var val; var aceOpt = optMap[name]; if (aceOpt) val = this.ace.getOption(aceOpt); @@ -496,7 +630,7 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve name = optMap[name]; return !val; case 'keyMap': - return this.state.$keyMap; + return this.state.$keyMap || 'vim'; } return aceOpt ? val : this.state[name]; }; @@ -597,9 +731,17 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve this.getMode = function() { return { name : this.getOption("mode") }; }; - this.execCommand = function() { - + this.execCommand = function(name) { + if (CodeMirror.commands.hasOwnProperty(name)) return CodeMirror.commands[name](this); + if (name == "indentAuto") return this.ace.execCommand("autoindent"); + console.log(name + " is not implemented"); }; + this.getLineNumber = function(handle) { + return handle.row; + } + this.getLineHandle = function(row) { + return {text: this.ace.session.getLine(row), row: row}; + } }).call(CodeMirror.prototype); function toAcePos(cmPos) { return {row: cmPos.line, column: cmPos.ch}; @@ -710,7 +852,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ width: 20em;\ color: inherit;\ font-family: monospace;\ -}", "vimMode"); +}", "vimMode", false); (function() { function dialogDiv(cm, template, bottom) { var wrap = cm.ace.container; @@ -749,18 +891,26 @@ dom.importCssString(".normal-mode .ace_cursor{\ inp.value = newVal; } else { if (closed) return; - + if (newVal && newVal.type == "blur") { if (document.activeElement === inp) return; } - - me.state.dialog = null; + + if (me.state.dialog == dialog) { + me.state.dialog = null; + me.focus(); + } closed = true; - dialog.parentNode.removeChild(dialog); - me.focus(); + dialog.remove(); if (options.onClose) options.onClose(dialog); + var cm = me; + if (cm.state.vim) { + cm.state.vim.status = null; + cm.ace._signal("changeStatus"); + cm.ace.renderer.$loop.schedule(cm.ace.renderer.CHANGE_CURSOR); + } } } @@ -780,7 +930,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } if (e.keyCode == 13) callback(inp.value); if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { - inp.blur(); CodeMirror.e_stop(e); close(); } @@ -813,7 +962,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (closed) return; closed = true; clearTimeout(doneTimer); - dialog.parentNode.removeChild(dialog); + dialog.remove(); } CodeMirror.on(dialog, 'click', function(e) { @@ -828,12 +977,35 @@ dom.importCssString(".normal-mode .ace_cursor{\ }); })(); - + + var Pos = CodeMirror.Pos; + + function transformCursor(cm, range) { + var vim = cm.state.vim; + if (!vim || vim.insertMode) return range.head; + var head = vim.sel.head; + if (!head) return range.head; + + if (vim.visualBlock) { + if (range.head.line != head.line) { + return; + } + } + if (range.from() == range.anchor && !range.empty()) { + if (range.head.line == head.line && range.head.ch != head.ch) + return new Pos(range.head.line, range.head.ch - 1); + } + + return range.head; + } + var defaultKeymap = [ { keys: '', type: 'keyToKey', toKeys: 'h' }, { keys: '', type: 'keyToKey', toKeys: 'l' }, { keys: '', type: 'keyToKey', toKeys: 'k' }, { keys: '', type: 'keyToKey', toKeys: 'j' }, + { keys: 'g', type: 'keyToKey', toKeys: 'gk' }, + { keys: 'g', type: 'keyToKey', toKeys: 'gj' }, { keys: '', type: 'keyToKey', toKeys: 'l' }, { keys: '', type: 'keyToKey', toKeys: 'h', context: 'normal'}, { keys: '', type: 'keyToKey', toKeys: 'x', context: 'normal'}, @@ -858,6 +1030,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ { keys: '', type: 'keyToKey', toKeys: '' }, { keys: '', type: 'keyToKey', toKeys: '' }, { keys: '', type: 'keyToKey', toKeys: 'j^', context: 'normal' }, + { keys: '', type: 'keyToKey', toKeys: 'i', context: 'normal'}, { keys: '', type: 'action', action: 'toggleOverwrite', context: 'insert' }, { keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }}, { keys: 'M', type: 'motion', motion: 'moveToMiddleLine', motionArgs: { linewise: true, toJumplist: true }}, @@ -886,6 +1059,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ { keys: '', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }}, { keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }}, { keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }}, + {keys: "g$", type: "motion", motion: "moveToEndOfDisplayLine"}, + {keys: "g^", type: "motion", motion: "moveToStartOfDisplayLine"}, + {keys: "g0", type: "motion", motion: "moveToStartOfDisplayLine"}, { keys: '0', type: 'motion', motion: 'moveToStartOfLine' }, { keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' }, { keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }}, @@ -923,6 +1099,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ { keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true }, { keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }}, { keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }}, + { keys: 'gn', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: true }}, + { keys: 'gN', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: false }}, { keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }}, { keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }}, { keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, @@ -1002,7 +1180,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ { name: 'undo', shortName: 'u' }, { name: 'redo', shortName: 'red' }, { name: 'set', shortName: 'se' }, - { name: 'set', shortName: 'se' }, { name: 'setlocal', shortName: 'setl' }, { name: 'setglobal', shortName: 'setg' }, { name: 'sort', shortName: 'sor' }, @@ -1011,11 +1188,10 @@ dom.importCssString(".normal-mode .ace_cursor{\ { name: 'yank', shortName: 'y' }, { name: 'delmarks', shortName: 'delm' }, { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true }, + { name: 'vglobal', shortName: 'v' }, { name: 'global', shortName: 'g' } ]; - var Pos = CodeMirror.Pos; - var Vim = function() { return vimApi; } //{ function enterVimMode(cm) { cm.setOption('disableInput', true); @@ -1032,16 +1208,22 @@ dom.importCssString(".normal-mode .ace_cursor{\ CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm)); cm.state.vim = null; } + function detachVimMap(cm, next) { - if (this == CodeMirror.keyMap.vim) + if (this == CodeMirror.keyMap.vim) { + cm.options.$customCursor = null; CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor"); + } if (!next || next.attach != attachVimMap) leaveVimMode(cm); } function attachVimMap(cm, prev) { - if (this == CodeMirror.keyMap.vim) + if (this == CodeMirror.keyMap.vim) { + if (cm.curOp) cm.curOp.selectionChanged = true; + cm.options.$customCursor = transformCursor; CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor"); + } if (!prev || prev.attach != attachVimMap) enterVimMode(cm); @@ -1060,14 +1242,14 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (!vimKey) { return false; } - var cmd = CodeMirror.Vim.findKey(cm, vimKey); + var cmd = vimApi.findKey(cm, vimKey); if (typeof cmd == 'function') { CodeMirror.signal(cm, 'vim-keypress', vimKey); } return cmd; } - var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'}; + var modifiers = {Shift:'S',Ctrl:'C',Alt:'A',Cmd:'D',Mod:'A',CapsLock:''}; var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del',Insert:'Ins'}; function cmKeyToVimKey(key) { if (key.charAt(0) == '\'') { @@ -1126,7 +1308,10 @@ dom.importCssString(".normal-mode .ace_cursor{\ var lowerCaseAlphabet = makeKeyRange(97, 26); var numbers = makeKeyRange(48, 10); var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']); - var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '/']); + var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '_', '/']); + var upperCaseChars; + try { upperCaseChars = new RegExp("^[\\p{Lu}]$", "u"); } + catch (_) { upperCaseChars = /^[A-Z]$/; } function isLine(cm, line) { return line >= cm.firstLine() && line <= cm.lastLine(); @@ -1141,7 +1326,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ return numberRegex.test(k); } function isUpperCase(k) { - return (/^[A-Z]$/).test(k); + return upperCaseChars.test(k); } function isWhiteSpaceString(k) { return (/^\s*$/).test(k); @@ -1352,7 +1537,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ this.latestRegister = registerName; if (cm.openDialog) { this.onRecordingDone = cm.openDialog( - '(recording)['+registerName+']', null, {bottom:true}); + document.createTextNode('(recording)['+registerName+']'), null, {bottom:true}); } this.isRecording = true; } @@ -1369,7 +1554,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ lastHSPos: -1, lastMotion: null, marks: {}, - fakeCursor: null, insertMode: false, insertModeRepeat: undefined, visualMode: false, @@ -1422,7 +1606,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ exCommandDispatcher.map(lhs, rhs, ctx); }, unmap: function(lhs, ctx) { - exCommandDispatcher.unmap(lhs, ctx); + return exCommandDispatcher.unmap(lhs, ctx); }, noremap: function(lhs, rhs, ctx) { function toCtxArray(ctx) { @@ -1530,7 +1714,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ match = (/<\w+-.+?>|<\w+>|./).exec(keys); key = match[0]; keys = keys.substring(match.index + key.length); - CodeMirror.Vim.handleKey(cm, key, 'mapping'); + vimApi.handleKey(cm, key, 'mapping'); } } @@ -1576,9 +1760,14 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (!keysMatcher) { clearInputState(cm); return false; } var context = vim.visualMode ? 'visual' : 'normal'; - var match = commandDispatcher.matchCommand(keysMatcher[2] || keysMatcher[1], defaultKeymap, vim.inputState, context); + var mainKey = keysMatcher[2] || keysMatcher[1]; + if (vim.inputState.operatorShortcut && vim.inputState.operatorShortcut.slice(-1) == mainKey) { + mainKey = vim.inputState.operatorShortcut; + } + var match = commandDispatcher.matchCommand(mainKey, defaultKeymap, vim.inputState, context); if (match.type == 'none') { clearInputState(cm); return false; } else if (match.type == 'partial') { return true; } + else if (match.type == 'clear') { clearInputState(cm); return true; } // ace_patch vim.inputState.keyBuffer = ''; var keysMatcher = /^(\d*)(.*)$/.exec(keys); @@ -1610,7 +1799,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } catch (e) { cm.state.vim = undefined; maybeInitVimState(cm); - if (!CodeMirror.Vim.suppressErrorLogging) { + if (!vimApi.suppressErrorLogging) { console['log'](e); } throw e; @@ -1727,6 +1916,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } RegisterController.prototype = { pushText: function(registerName, operator, text, linewise, blockwise) { + if (registerName === '_') return; if (linewise && text.charAt(text.length - 1) !== '\n'){ text += '\n'; } @@ -1830,7 +2020,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } if (bestMatch.keys.slice(-11) == '') { var character = lastChar(keys); - if (//.test(character) || !character) return {type: 'none'}; //ace_patch + if (!character || character.length > 1) return {type: 'clear'}; //ace_patch inputState.selectedCharacter = character; } return {type: 'full', command: bestMatch}; @@ -1880,6 +2070,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ } inputState.operator = command.operator; inputState.operatorArgs = copyArgs(command.operatorArgs); + if (command.keys.length > 1) { + inputState.operatorShortcut = command.keys; + } if (command.exitVisualBlock) { vim.visualBlock = false; updateCmSelection(cm); @@ -1955,7 +2148,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ }); } function onPromptClose(query) { - cm.scrollTo(originalScrollPos.left, originalScrollPos.top); handleQuery(query, true /** ignoreCase */, true /** smartCase */); var macroModeState = vimGlobalState.macroModeState; if (macroModeState.isRecording) { @@ -2017,7 +2209,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ showPrompt(cm, { onClose: onPromptClose, prefix: promptPrefix, - desc: searchPromptDesc, + desc: '(JavaScript regexp)', onKeyUp: onPromptKeyUp, onKeyDown: onPromptKeyDown }); @@ -2131,7 +2323,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ motionArgs.repeat = repeat; clearInputState(cm); if (motion) { - var motionResult = motions[motion](cm, origHead, motionArgs, vim); + var motionResult = motions[motion](cm, origHead, motionArgs, vim, inputState); vim.lastMotion = motions[motion]; if (!motionResult) { return; @@ -2159,10 +2351,10 @@ dom.importCssString(".normal-mode .ace_cursor{\ } if (vim.visualMode) { if (!(vim.visualBlock && newHead.ch === Infinity)) { - newHead = clipCursorToContent(cm, newHead, vim.visualBlock); + newHead = clipCursorToContent(cm, newHead); } if (newAnchor) { - newAnchor = clipCursorToContent(cm, newAnchor, true); + newAnchor = clipCursorToContent(cm, newAnchor); } newAnchor = newAnchor || oldAnchor; sel.anchor = newAnchor; @@ -2186,13 +2378,13 @@ dom.importCssString(".normal-mode .ace_cursor{\ var lineOffset = Math.abs(lastSel.head.line - lastSel.anchor.line); var chOffset = Math.abs(lastSel.head.ch - lastSel.anchor.ch); if (lastSel.visualLine) { - newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch); + newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch); } else if (lastSel.visualBlock) { - newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset); + newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset); } else if (lastSel.head.line == lastSel.anchor.line) { - newHead = Pos(oldAnchor.line, oldAnchor.ch + chOffset); + newHead = new Pos(oldAnchor.line, oldAnchor.ch + chOffset); } else { - newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch); + newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch); } vim.visualMode = true; vim.visualLine = lastSel.visualLine; @@ -2230,7 +2422,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ ranges[i].head.ch = lineLength(cm, ranges[i].head.line); } } else if (mode == 'line') { - ranges[0].head = Pos(ranges[0].head.line + 1, 0); + ranges[0].head = new Pos(ranges[0].head.line + 1, 0); } } } else { @@ -2282,20 +2474,20 @@ dom.importCssString(".normal-mode .ace_cursor{\ var motions = { moveToTopLine: function(cm, _head, motionArgs) { var line = getUserVisibleLines(cm).top + motionArgs.repeat -1; - return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); }, moveToMiddleLine: function(cm) { var range = getUserVisibleLines(cm); var line = Math.floor((range.top + range.bottom) * 0.5); - return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); }, moveToBottomLine: function(cm, _head, motionArgs) { var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1; - return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); }, expandToLine: function(_cm, head, motionArgs) { var cur = head; - return Pos(cur.line + motionArgs.repeat - 1, Infinity); + return new Pos(cur.line + motionArgs.repeat - 1, Infinity); }, findNext: function(cm, _head, motionArgs) { var state = getSearchState(cm); @@ -2308,6 +2500,58 @@ dom.importCssString(".normal-mode .ace_cursor{\ highlightSearchMatches(cm, query); return findNext(cm, prev/** prev */, query, motionArgs.repeat); }, + findAndSelectNextInclusive: function(cm, _head, motionArgs, vim, prevInputState) { + var state = getSearchState(cm); + var query = state.getQuery(); + + if (!query) { + return; + } + + var prev = !motionArgs.forward; + prev = (state.isReversed()) ? !prev : prev; + var next = findNextFromAndToInclusive(cm, prev, query, motionArgs.repeat, vim); + if (!next) { + return; + } + if (prevInputState.operator) { + return next; + } + + var from = next[0]; + var to = new Pos(next[1].line, next[1].ch - 1); + + if (vim.visualMode) { + if (vim.visualLine || vim.visualBlock) { + vim.visualLine = false; + vim.visualBlock = false; + CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: ""}); + } + var anchor = vim.sel.anchor; + if (anchor) { + if (state.isReversed()) { + if (motionArgs.forward) { + return [anchor, from]; + } + + return [anchor, to]; + } else { + if (motionArgs.forward) { + return [anchor, to]; + } + + return [anchor, from]; + } + } + } else { + vim.visualMode = true; + vim.visualLine = false; + vim.visualBlock = false; + CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: ""}); + } + + return prev ? [to, from] : [from, to]; + }, goToMark: function(cm, _head, motionArgs, vim) { var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter); if (pos) { @@ -2319,8 +2563,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (vim.visualBlock && motionArgs.sameLine) { var sel = vim.sel; return [ - clipCursorToContent(cm, Pos(sel.anchor.line, sel.head.ch)), - clipCursorToContent(cm, Pos(sel.head.line, sel.anchor.ch)) + clipCursorToContent(cm, new Pos(sel.anchor.line, sel.head.ch)), + clipCursorToContent(cm, new Pos(sel.head.line, sel.anchor.ch)) ]; } else { return ([vim.sel.head, vim.sel.anchor]); @@ -2357,7 +2601,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } if (motionArgs.linewise) { - best = Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line))); + best = new Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line))); } return best; }, @@ -2365,7 +2609,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ var cur = head; var repeat = motionArgs.repeat; var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat; - return Pos(cur.line, ch); + return new Pos(cur.line, ch); }, moveByLines: function(cm, head, motionArgs, vim) { var cur = head; @@ -2387,8 +2631,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ var last = cm.lastLine(); if (line < first && cur.line == first){ return this.moveToStartOfLine(cm, head, motionArgs, vim); - }else if (line > last && cur.line == last){ - return this.moveToEol(cm, head, motionArgs, vim, true); + } else if (line > last && cur.line == last){ + return moveToEol(cm, head, motionArgs, vim, true); } var fold = cm.ace.session.getFoldLine(line); if (fold) { @@ -2403,8 +2647,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line)); vim.lastHPos = endCh; } - vim.lastHSPos = cm.charCoords(Pos(line, endCh),'div').left; - return Pos(line, endCh); + vim.lastHSPos = cm.charCoords(new Pos(line, endCh),'div').left; + return new Pos(line, endCh); }, moveByDisplayLines: function(cm, head, motionArgs, vim) { var cur = head; @@ -2426,7 +2670,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos }; var res = cm.coordsChar(goalCoords, 'div'); } else { - var resCoords = cm.charCoords(Pos(cm.firstLine(), 0), 'div'); + var resCoords = cm.charCoords(new Pos(cm.firstLine(), 0), 'div'); resCoords.left = vim.lastHSPos; res = cm.coordsChar(resCoords, 'div'); } @@ -2495,20 +2739,12 @@ dom.importCssString(".normal-mode .ace_cursor{\ vim.lastHSPos = cm.charCoords(head,'div').left; return moveToColumn(cm, repeat); }, - moveToEol: function(cm, head, motionArgs, vim, keepHPos) { - var cur = head; - var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity); - var end=cm.clipPos(retval); - end.ch--; - if (!keepHPos) { - vim.lastHPos = Infinity; - vim.lastHSPos = cm.charCoords(end,'div').left; - } - return retval; + moveToEol: function(cm, head, motionArgs, vim) { + return moveToEol(cm, head, motionArgs, vim, false); }, moveToFirstNonWhiteSpaceCharacter: function(cm, head) { var cursor = head; - return Pos(cursor.line, + return new Pos(cursor.line, findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line))); }, moveToMatchedSymbol: function(cm, head) { @@ -2520,7 +2756,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ for (; ch < lineText.length; ch++) { symbol = lineText.charAt(ch); if (symbol && isMatchableSymbol(symbol)) { - var style = cm.getTokenTypeAt(Pos(line, ch + 1)); + var style = cm.getTokenTypeAt(new Pos(line, ch + 1)); if (style !== "string" && style !== "comment") { break; } @@ -2528,23 +2764,33 @@ dom.importCssString(".normal-mode .ace_cursor{\ } if (ch < lineText.length) { var re = /[<>]/.test(lineText[ch]) ? /[(){}[\]<>]/ : /[(){}[\]]/; //ace_patch? - var matched = cm.findMatchingBracket(Pos(line, ch+1), {bracketRegex: re}); + var matched = cm.findMatchingBracket(new Pos(line, ch+1), {bracketRegex: re}); return matched.to; } else { return cursor; } }, moveToStartOfLine: function(_cm, head) { - return Pos(head.line, 0); + return new Pos(head.line, 0); }, moveToLineOrEdgeOfDocument: function(cm, _head, motionArgs) { var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine(); if (motionArgs.repeatIsExplicit) { lineNum = motionArgs.repeat - cm.getOption('firstLineNumber'); } - return Pos(lineNum, + return new Pos(lineNum, findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum))); }, + moveToStartOfDisplayLine: function(cm) { + cm.execCommand("goLineLeft"); + return cm.getCursor(); + }, + moveToEndOfDisplayLine: function(cm) { + cm.execCommand("goLineRight"); + var head = cm.getCursor(); + if (head.sticky == "before") head.ch--; + return head; + }, textObjectManipulation: function(cm, head, motionArgs, vim) { var mirroredPairs = {'(': ')', ')': '(', '{': '}', '}': '{', @@ -2581,6 +2827,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (operatorArgs) { operatorArgs.linewise = true; } tmp.end.line--; } + } else if (character === 't') { + tmp = expandTagUnderCursor(cm, head, inclusive); } else { return null; } @@ -2682,7 +2930,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (anchor.line == cm.firstLine()) { anchor.ch = 0; } else { - anchor = Pos(anchor.line - 1, lineLength(cm, anchor.line - 1)); + anchor = new Pos(anchor.line - 1, lineLength(cm, anchor.line - 1)); } } text = cm.getRange(anchor, head); @@ -2695,13 +2943,12 @@ dom.importCssString(".normal-mode .ace_cursor{\ text = cm.getSelection(); var replacement = fillArray('', ranges.length); cm.replaceSelections(replacement); - finalHead = ranges[0].anchor; + finalHead = cursorMin(ranges[0].head, ranges[0].anchor); } vimGlobalState.registerController.pushText( args.registerName, 'delete', text, args.linewise, vim.visualBlock); - var includeLineBreak = vim.insertMode - return clipCursorToContent(cm, finalHead, includeLineBreak); + return clipCursorToContent(cm, finalHead); }, indent: function(cm, args, ranges) { var vim = cm.state.vim; @@ -2721,6 +2968,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor); }, indentAuto: function(cm, _args, ranges) { + if (ranges.length > 1) { // ace_patch + cm.setSelection(ranges[0].anchor, ranges[ranges.length - 1].head); + } cm.execCommand("indentAuto"); return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor); }, @@ -2824,7 +3074,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ }, scrollToCursor: function(cm, actionArgs) { var lineNum = cm.getCursor().line; - var charCoords = cm.charCoords(Pos(lineNum, 0), 'local'); + var charCoords = cm.charCoords(new Pos(lineNum, 0), 'local'); var height = cm.getScrollInfo().clientHeight; var y = charCoords.top; var lineHeight = charCoords.bottom - y; @@ -2876,9 +3126,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ var head = actionArgs.head || cm.getCursor('head'); var height = cm.listSelections().length; if (insertAt == 'eol') { - head = Pos(head.line, lineLength(cm, head.line)); + head = new Pos(head.line, lineLength(cm, head.line)); } else if (insertAt == 'bol') { - head = Pos(head.line, 0); + head = new Pos(head.line, 0); } else if (insertAt == 'charAfter') { head = offsetCursor(head, 0, 1); } else if (insertAt == 'firstNonBlank') { @@ -2890,10 +3140,10 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (sel.head.line < sel.anchor.line) { head = sel.head; } else { - head = Pos(sel.anchor.line, 0); + head = new Pos(sel.anchor.line, 0); } } else { - head = Pos( + head = new Pos( Math.min(sel.head.line, sel.anchor.line), Math.min(sel.head.ch, sel.anchor.ch)); height = Math.abs(sel.head.line - sel.anchor.line) + 1; @@ -2905,12 +3155,12 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (sel.head.line >= sel.anchor.line) { head = offsetCursor(sel.head, 0, 1); } else { - head = Pos(sel.anchor.line, 0); + head = new Pos(sel.anchor.line, 0); } } else { - head = Pos( + head = new Pos( Math.min(sel.head.line, sel.anchor.line), - Math.max(sel.head.ch + 1, sel.anchor.ch)); + Math.max(sel.head.ch, sel.anchor.ch) + 1); height = Math.abs(sel.head.line - sel.anchor.line) + 1; } } else if (insertAt == 'inplace') { @@ -2948,8 +3198,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ vim.visualLine = !!actionArgs.linewise; vim.visualBlock = !!actionArgs.blockwise; head = clipCursorToContent( - cm, Pos(anchor.line, anchor.ch + repeat - 1), - true /** includeLineBreak */); + cm, new Pos(anchor.line, anchor.ch + repeat - 1)); vim.sel = { anchor: anchor, head: head @@ -3009,13 +3258,13 @@ dom.importCssString(".normal-mode .ace_cursor{\ } else { var repeat = Math.max(actionArgs.repeat, 2); curStart = cm.getCursor(); - curEnd = clipCursorToContent(cm, Pos(curStart.line + repeat - 1, + curEnd = clipCursorToContent(cm, new Pos(curStart.line + repeat - 1, Infinity)); } var finalCh = 0; for (var i = curStart.line; i < curEnd.line; i++) { finalCh = lineLength(cm, curStart.line); - var tmp = Pos(curStart.line + 1, + var tmp = new Pos(curStart.line + 1, lineLength(cm, curStart.line + 1)); var text = cm.getRange(curStart, tmp); text = actionArgs.keepSpaces @@ -3023,7 +3272,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ : text.replace(/\n\s*/g, ' '); cm.replaceRange(text, curStart, tmp); } - var curFinalPos = Pos(curStart.line, finalCh); + var curFinalPos = new Pos(curStart.line, finalCh); if (vim.visualMode) { exitVisualMode(cm, false); } @@ -3033,7 +3282,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ vim.insertMode = true; var insertAt = copyCursor(cm.getCursor()); if (insertAt.line === cm.firstLine() && !actionArgs.after) { - cm.replaceRange('\n', Pos(cm.firstLine(), 0)); + cm.replaceRange('\n', new Pos(cm.firstLine(), 0)); cm.setCursor(cm.firstLine(), 0); } else { insertAt.line = (actionArgs.after) ? insertAt.line : @@ -3125,7 +3374,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ vimGlobalState.registerController.unnamedRegister.setText(selectedText); if (blockwise) { cm.replaceSelections(emptyStrings); - selectionEnd = Pos(selectionStart.line + text.length-1, selectionStart.ch); + selectionEnd = new Pos(selectionStart.line + text.length-1, selectionStart.ch); cm.setCursor(selectionStart); selectBlock(cm, selectionEnd); cm.replaceSelections(text); @@ -3151,7 +3400,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ for (var i = 0; i < text.length; i++) { var line = cur.line+i; if (line > cm.lastLine()) { - cm.replaceRange('\n', Pos(line, 0)); + cm.replaceRange('\n', new Pos(line, 0)); } var lastCh = lineLength(cm, line); if (lastCh < cur.ch) { @@ -3159,17 +3408,17 @@ dom.importCssString(".normal-mode .ace_cursor{\ } } cm.setCursor(cur); - selectBlock(cm, Pos(cur.line + text.length-1, cur.ch)); + selectBlock(cm, new Pos(cur.line + text.length-1, cur.ch)); cm.replaceSelections(text); curPosFinal = cur; } else { cm.replaceRange(text, cur); if (linewise && actionArgs.after) { - curPosFinal = Pos( + curPosFinal = new Pos( cur.line + 1, findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1))); } else if (linewise && !actionArgs.after) { - curPosFinal = Pos( + curPosFinal = new Pos( cur.line, findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line))); } else if (!linewise && actionArgs.after) { @@ -3217,7 +3466,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (replaceTo > line.length) { replaceTo=line.length; } - curEnd = Pos(curStart.line, replaceTo); + curEnd = new Pos(curStart.line, replaceTo); } if (replaceWith=='\n') { if (!vim.visualMode) cm.replaceRange('', curStart, curEnd); @@ -3270,13 +3519,13 @@ dom.importCssString(".normal-mode .ace_cursor{\ } else { numberStr = baseStr + zeroPadding + numberStr; } - var from = Pos(cur.line, start); - var to = Pos(cur.line, end); + var from = new Pos(cur.line, start); + var to = new Pos(cur.line, end); cm.replaceRange(numberStr, from, to); } else { return; } - cm.setCursor(Pos(cur.line, start + numberStr.length - 1)); + cm.setCursor(new Pos(cur.line, start + numberStr.length - 1)); }, repeatLastEdit: function(cm, actionArgs, vim) { var lastEditInputState = vim.lastEditInputState; @@ -3298,12 +3547,13 @@ dom.importCssString(".normal-mode .ace_cursor{\ function defineAction(name, fn) { actions[name] = fn; } - function clipCursorToContent(cm, cur, includeLineBreak) { + function clipCursorToContent(cm, cur) { + var vim = cm.state.vim; + var includeLineBreak = vim.insertMode || vim.visualMode; var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() ); - var maxCh = lineLength(cm, line) - 1; - maxCh = (includeLineBreak) ? maxCh + 1 : maxCh; + var maxCh = lineLength(cm, line) - 1 + !!includeLineBreak; var ch = Math.min(Math.max(0, cur.ch), maxCh); - return Pos(line, ch); + return new Pos(line, ch); } function copyArgs(args) { var ret = {}; @@ -3319,7 +3569,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ offsetCh = offsetLine.ch; offsetLine = offsetLine.line; } - return Pos(cur.line + offsetLine, cur.ch + offsetCh); + return new Pos(cur.line + offsetLine, cur.ch + offsetCh); } function commandMatches(keys, keyMap, context, inputState) { var match, partial = [], full = []; @@ -3375,7 +3625,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ }; } function copyCursor(cur) { - return Pos(cur.line, cur.ch); + return new Pos(cur.line, cur.ch); } function cursorEqual(cur1, cur2) { return cur1.ch == cur2.ch && cur1.line == cur2.line; @@ -3421,7 +3671,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ function extendLineToColumn(cm, lineNum, column) { var endCh = lineLength(cm, lineNum); var spaces = new Array(column-endCh+1).join(' '); - cm.setCursor(Pos(lineNum, endCh)); + cm.setCursor(new Pos(lineNum, endCh)); cm.replaceRange(spaces, cm.getCursor()); } function selectBlock(cm, selectionEnd) { @@ -3495,11 +3745,11 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (block) { var width = block.width; var height = block.height; - selectionEnd = Pos(selectionStart.line + height, selectionStart.ch + width); + selectionEnd = new Pos(selectionStart.line + height, selectionStart.ch + width); var selections = []; for (var i = selectionStart.line; i < selectionEnd.line; i++) { - var anchor = Pos(i, selectionStart.ch); - var head = Pos(i, selectionEnd.ch); + var anchor = new Pos(i, selectionStart.ch); + var head = new Pos(i, selectionEnd.ch); var range = {anchor: anchor, head: head}; selections.push(range); } @@ -3511,8 +3761,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ var ch = end.ch - start.ch; selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch}; if (lastSelection.visualLine) { - selectionStart = Pos(selectionStart.line, 0); - selectionEnd = Pos(selectionEnd.line, lineLength(cm, selectionEnd.line)); + selectionStart = new Pos(selectionStart.line, 0); + selectionEnd = new Pos(selectionEnd.line, lineLength(cm, selectionEnd.line)); } cm.setSelection(selectionStart, selectionEnd); } @@ -3557,7 +3807,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ head = cursorMax(head, end); head = offsetCursor(head, 0, -1); if (head.ch == -1 && head.line != cm.firstLine()) { - head = Pos(head.line - 1, lineLength(cm, head.line - 1)); + head = new Pos(head.line - 1, lineLength(cm, head.line - 1)); } } return [anchor, head]; @@ -3569,7 +3819,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ vim.visualLine ? 'line' : vim.visualBlock ? 'block' : 'char'; var cmSel = makeCmSelection(cm, sel, mode); cm.setSelections(cmSel.ranges, cmSel.primary); - updateFakeCursor(cm); } function makeCmSelection(cm, sel, mode, exclusive) { var head = copyCursor(sel.head); @@ -3602,16 +3851,18 @@ dom.importCssString(".normal-mode .ace_cursor{\ }; } else if (mode == 'block') { var top = Math.min(anchor.line, head.line), - left = Math.min(anchor.ch, head.ch), + fromCh = anchor.ch, bottom = Math.max(anchor.line, head.line), - right = Math.max(anchor.ch, head.ch) + 1; + toCh = head.ch; + if (fromCh < toCh) { toCh += 1 } + else { fromCh += 1 }; var height = bottom - top + 1; var primary = head.line == top ? 0 : height - 1; var ranges = []; for (var i = 0; i < height; i++) { ranges.push({ - anchor: Pos(top + i, left), - head: Pos(top + i, right) + anchor: new Pos(top + i, fromCh), + head: new Pos(top + i, toCh) }); } return { @@ -3636,10 +3887,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ vim.visualMode = false; vim.visualLine = false; vim.visualBlock = false; - CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); - if (vim.fakeCursor) { - vim.fakeCursor.clear(); - } + if (!vim.insertMode) CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); } function clipToLine(cm, curStart, curEnd) { var selection = cm.getRange(curStart, curEnd); @@ -3706,7 +3954,23 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (!start) { start = wordStart; } } } - return { start: Pos(cur.line, start), end: Pos(cur.line, end) }; + return { start: new Pos(cur.line, start), end: new Pos(cur.line, end) }; + } + function expandTagUnderCursor(cm, head, inclusive) { + var cur = head; + if (!CodeMirror.findMatchingTag || !CodeMirror.findEnclosingTag) { + return { start: cur, end: cur }; + } + + var tags = CodeMirror.findMatchingTag(cm, head) || CodeMirror.findEnclosingTag(cm, head); + if (!tags || !tags.open || !tags.close) { + return { start: cur, end: cur }; + } + + if (inclusive) { + return { start: tags.open.from, end: tags.close.to }; + } + return { start: tags.open.to, end: tags.close.from }; } function recordJumpPosition(cm, oldCur, newCur) { @@ -3772,7 +4036,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ }, isComplete: function(state) { if (state.nextCh === '#') { - var token = state.lineText.match(/#(\w+)/)[1]; + var token = state.lineText.match(/^#(\w+)/)[1]; if (token === 'endif') { if (state.forward && state.depth === 0) { return true; @@ -3834,7 +4098,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } } if (state.nextCh || state.curMoveThrough) { - return Pos(line, state.index); + return new Pos(line, state.index); } return cur; } @@ -3910,7 +4174,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ break; } words.push(word); - cur = Pos(word.line, forward ? (word.to - 1) : word.from); + cur = new Pos(word.line, forward ? (word.to - 1) : word.from); } var shortCircuit = words.length != repeat; var firstWord = words[0]; @@ -3919,19 +4183,31 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (!shortCircuit && (firstWord.from != curStart.ch || firstWord.line != curStart.line)) { lastWord = words.pop(); } - return Pos(lastWord.line, lastWord.from); + return new Pos(lastWord.line, lastWord.from); } else if (forward && wordEnd) { - return Pos(lastWord.line, lastWord.to - 1); + return new Pos(lastWord.line, lastWord.to - 1); } else if (!forward && wordEnd) { if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) { lastWord = words.pop(); } - return Pos(lastWord.line, lastWord.to); + return new Pos(lastWord.line, lastWord.to); } else { - return Pos(lastWord.line, lastWord.from); + return new Pos(lastWord.line, lastWord.from); } } + function moveToEol(cm, head, motionArgs, vim, keepHPos) { + var cur = head; + var retval= new Pos(cur.line + motionArgs.repeat - 1, Infinity); + var end=cm.clipPos(retval); + end.ch--; + if (!keepHPos) { + vim.lastHPos = Infinity; + vim.lastHSPos = cm.charCoords(end,'div').left; + } + return retval; + } + function moveToCharacter(cm, repeat, forward, character) { var cur = cm.getCursor(); var start = cur.ch; @@ -3944,12 +4220,12 @@ dom.importCssString(".normal-mode .ace_cursor{\ } start = idx; } - return Pos(cm.getCursor().line, idx); + return new Pos(cm.getCursor().line, idx); } function moveToColumn(cm, repeat) { var line = cm.getCursor().line; - return clipCursorToContent(cm, Pos(line, repeat - 1)); + return clipCursorToContent(cm, new Pos(line, repeat - 1)); } function updateMark(cm, vim, markName, pos) { @@ -4167,7 +4443,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ repeat--; } - return Pos(curr_index.ln, curr_index.pos); + return new Pos(curr_index.ln, curr_index.pos); } function selectCompanionObject(cm, head, symb, inclusive) { var cur = head, start, end; @@ -4185,8 +4461,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ var curChar = cm.getLine(cur.line).charAt(cur.ch); var offset = curChar === openSym ? 1 : 0; - start = cm.scanForBracket(Pos(cur.line, cur.ch + offset), -1, undefined, {'bracketRegex': bracketRegexp}); - end = cm.scanForBracket(Pos(cur.line, cur.ch + offset), 1, undefined, {'bracketRegex': bracketRegexp}); + start = cm.scanForBracket(new Pos(cur.line, cur.ch + offset), -1, undefined, {'bracketRegex': bracketRegexp}); + end = cm.scanForBracket(new Pos(cur.line, cur.ch + offset), 1, undefined, {'bracketRegex': bracketRegexp}); if (!start || !end) { return { start: cur, end: cur }; @@ -4247,8 +4523,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ } return { - start: Pos(cur.line, start), - end: Pos(cur.line, end) + start: new Pos(cur.line, start), + end: new Pos(cur.line, end) }; } defineOption('pcre', true, 'boolean'); @@ -4283,21 +4559,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ var vim = cm.state.vim; return vim.searchState_ || (vim.searchState_ = new SearchState()); } - function dialog(cm, template, shortText, onClose, options) { - if (cm.openDialog) { - cm.openDialog(template, onClose, { bottom: true, value: options.value, - onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp, - selectValueOnOpen: false, onClose: function() { - if (cm.state.vim) { - cm.state.vim.status = ""; - cm.ace.renderer.$loop.schedule(cm.ace.renderer.CHANGE_CURSOR); - } - }}); - } - else { - onClose(prompt(shortText, '')); - } - } function splitBySlash(argString) { return splitBySeparator(argString, '/'); } @@ -4400,7 +4661,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } return out.join(''); } - var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'}; + var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t', '\\&':'&'}; function unescapeRegexReplace(str) { var stream = new CodeMirror.StringStream(str); var output = []; @@ -4446,30 +4707,58 @@ dom.importCssString(".normal-mode .ace_cursor{\ ignoreCase = (/^[^A-Z]*$/).test(regexPart); } var regexp = new RegExp(regexPart, - (ignoreCase || forceIgnoreCase) ? 'i' : undefined); + (ignoreCase || forceIgnoreCase) ? 'im' : 'm'); return regexp; } - function showConfirm(cm, text) { + function hdom(n) { + if (typeof n === 'string') n = document.createElement(n); + for (var a, i = 1; i < arguments.length; i++) { + if (!(a = arguments[i])) continue; + if (typeof a !== 'object') a = document.createTextNode(a); + if (a.nodeType) n.appendChild(a); + else for (var key in a) { + if (!Object.prototype.hasOwnProperty.call(a, key)) continue; + if (key[0] === '$') n.style[key.slice(1)] = a[key]; + else n.setAttribute(key, a[key]); + } + } + return n; + } + + function showConfirm(cm, template) { + var pre = hdom('span', {$color: 'red', $whiteSpace: 'pre', class: 'cm-vim-message'}, template); //ace_patch span instead of pre if (cm.openNotification) { - cm.openNotification('' + text + '', - {bottom: true, duration: 5000}); + cm.openNotification(pre, {bottom: true, duration: 5000}); } else { - alert(text); + alert(pre.innerText); } } + function makePrompt(prefix, desc) { - var raw = '' + - (prefix || "") + ''; - if (desc) - raw += ' ' + desc + ''; - return raw; + return hdom(document.createDocumentFragment(), + hdom('span', {$fontFamily: 'monospace', $whiteSpace: 'pre'}, + prefix, + hdom('input', {type: 'text', autocorrect: 'off', + autocapitalize: 'off', spellcheck: 'false'})), + desc && hdom('span', {$color: '#888'}, desc)); } - var searchPromptDesc = '(Javascript regexp)'; + function showPrompt(cm, options) { - var shortText = (options.prefix || '') + ' ' + (options.desc || ''); - var prompt = makePrompt(options.prefix, options.desc); - dialog(cm, prompt, shortText, options.onClose, options); + var template = makePrompt(options.prefix, options.desc); + if (cm.openDialog) { + cm.openDialog(template, options.onClose, { + onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp, + bottom: true, selectValueOnOpen: false, value: options.value + }); + } + else { + var shortText = ''; + if (typeof options.prefix != "string" && options.prefix) shortText += options.prefix.textContent; + if (options.desc) shortText += " " + options.desc; + options.onClose(prompt(shortText, '')); + } } + function regexEqual(r1, r2) { if (r1 instanceof RegExp && r2 instanceof RegExp) { var props = ['global', 'multiline', 'ignoreCase', 'source']; @@ -4558,10 +4847,17 @@ dom.importCssString(".normal-mode .ace_cursor{\ var cursor = cm.getSearchCursor(query, pos); for (var i = 0; i < repeat; i++) { var found = cursor.find(prev); - if (i == 0 && found && cursorEqual(cursor.from(), pos)) { found = cursor.find(prev); } + if (i == 0 && found && cursorEqual(cursor.from(), pos)) { + var lastEndPos = prev ? cursor.from() : cursor.to(); + found = cursor.find(prev); + if (found && !found[0] && cursorEqual(cursor.from(), lastEndPos)) { + if (cm.getLine(lastEndPos.line).length == lastEndPos.ch) + found = cursor.find(prev); + } + } if (!found) { cursor = cm.getSearchCursor(query, - (prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) ); + (prev) ? new Pos(cm.lastLine()) : new Pos(cm.firstLine(), 0) ); if (!cursor.find(prev)) { return; } @@ -4570,6 +4866,29 @@ dom.importCssString(".normal-mode .ace_cursor{\ return cursor.from(); }); } + function findNextFromAndToInclusive(cm, prev, query, repeat, vim) { + if (repeat === undefined) { repeat = 1; } + return cm.operation(function() { + var pos = cm.getCursor(); + var cursor = cm.getSearchCursor(query, pos); + var found = cursor.find(!prev); + if (!vim.visualMode && found && cursorEqual(cursor.from(), pos)) { + cursor.find(!prev); + } + + for (var i = 0; i < repeat; i++) { + found = cursor.find(prev); + if (!found) { + cursor = cm.getSearchCursor(query, + (prev) ? new Pos(cm.lastLine()) : new Pos(cm.firstLine(), 0) ); + if (!cursor.find(prev)) { + return; + } + } + } + return [cursor.from(), cursor.to()]; + }); + } function clearSearchHighlight(cm) { var state = getSearchState(cm); cm.removeOverlay(getSearchState(cm).getOverlay()); @@ -4586,7 +4905,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (start instanceof Array) { return inArray(pos, start); } else { - if (end) { + if (typeof end == 'number') { return (pos >= start && pos <= end); } else { return pos == start; @@ -4603,7 +4922,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ function getMarkPos(cm, vim, markName) { if (markName == '\'' || markName == '`') { - return vimGlobalState.jumpList.find(cm, -1) || Pos(0, 0); + return vimGlobalState.jumpList.find(cm, -1) || new Pos(0, 0); } else if (markName == '.') { return getLastEditPos(cm); } @@ -4643,7 +4962,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ try { this.parseInput_(cm, inputStream, params); } catch(e) { - showConfirm(cm, e); + showConfirm(cm, e.toString()); throw e; } var command; @@ -4662,7 +4981,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ this.parseCommandArgs_(inputStream, params, command); if (command.type == 'exToKey') { for (var i = 0; i < command.toKeys.length; i++) { - CodeMirror.Vim.handleKey(cm, command.toKeys[i], 'mapping'); + vimApi.handleKey(cm, command.toKeys[i], 'mapping'); } return; } else if (command.type == 'exToEx') { @@ -4681,7 +5000,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ params.callback(); } } catch(e) { - showConfirm(cm, e); + showConfirm(cm, e.toString()); throw e; } }, @@ -4696,7 +5015,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ result.lineEnd = this.parseLineSpec_(cm, inputStream); } } - var commandMatch = inputStream.match(/^(\w+)/); + var commandMatch = inputStream.match(/^(\w+|!!|@@|[!#&*<=>@~])/); if (commandMatch) { result.commandName = commandMatch[1]; } else { @@ -4817,7 +5136,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ var commandName = lhs.substring(1); if (this.commandMap_[commandName] && this.commandMap_[commandName].user) { delete this.commandMap_[commandName]; - return; + return true; } } else { var keys = lhs; @@ -4825,7 +5144,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (keys == defaultKeymap[i].keys && defaultKeymap[i].context === ctx) { defaultKeymap.splice(i, 1); - return; + return true; } } } @@ -4855,13 +5174,11 @@ dom.importCssString(".normal-mode .ace_cursor{\ vmap: function(cm, params) { this.map(cm, params, 'visual'); }, unmap: function(cm, params, ctx) { var mapArgs = params.args; - if (!mapArgs || mapArgs.length < 1) { + if (!mapArgs || mapArgs.length < 1 || !exCommandDispatcher.unmap(mapArgs[0], ctx)) { if (cm) { showConfirm(cm, 'No such mapping: ' + params.input); } - return; } - exCommandDispatcher.unmap(mapArgs[0], ctx); }, move: function(cm, params) { commandDispatcher.processCommand(cm, cm.state.vim, { @@ -4926,12 +5243,12 @@ dom.importCssString(".normal-mode .ace_cursor{\ registers: function(cm, params) { var regArgs = params.args; var registers = vimGlobalState.registerController.registers; - var regInfo = '----------Registers----------

    '; + var regInfo = '----------Registers----------\n\n'; if (!regArgs) { for (var registerName in registers) { var text = registers[registerName].toString(); if (text.length) { - regInfo += '"' + registerName + ' ' + text + '
    '; + regInfo += '"' + registerName + ' ' + text + '\n' } } } else { @@ -4943,7 +5260,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ continue; } var register = registers[registerName] || new Register(); - regInfo += '"' + registerName + ' ' + register.toString() + '
    '; + regInfo += '"' + registerName + ' ' + register.toString() + '\n' } } showConfirm(cm, regInfo); @@ -4980,8 +5297,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ var lineStart = params.line || cm.firstLine(); var lineEnd = params.lineEnd || params.line || cm.lastLine(); if (lineStart == lineEnd) { return; } - var curStart = Pos(lineStart, 0); - var curEnd = Pos(lineEnd, lineLength(cm, lineEnd)); + var curStart = new Pos(lineStart, 0); + var curEnd = new Pos(lineEnd, lineLength(cm, lineEnd)); var text = cm.getRange(curStart, curEnd).split('\n'); var numberRegex = pattern ? pattern : (number == 'decimal') ? /(-?)([\d]+)/ : @@ -5038,12 +5355,16 @@ dom.importCssString(".normal-mode .ace_cursor{\ } cm.replaceRange(text.join('\n'), curStart, curEnd); }, + vglobal: function(cm, params) { + this.global(cm, params); + }, global: function(cm, params) { var argString = params.argString; if (!argString) { showConfirm(cm, 'Regular Expression missing from global'); return; } + var inverted = params.commandName[0] === 'v'; var lineStart = (params.line !== undefined) ? params.line : cm.firstLine(); var lineEnd = params.lineEnd || params.line || cm.lastLine(); var tokens = splitBySlash(argString); @@ -5062,27 +5383,32 @@ dom.importCssString(".normal-mode .ace_cursor{\ } } var query = getSearchState(cm).getQuery(); - var matchedLines = [], content = ''; + var matchedLines = []; for (var i = lineStart; i <= lineEnd; i++) { - var matched = query.test(cm.getLine(i)); - if (matched) { - matchedLines.push(i+1); - content+= cm.getLine(i) + '
    '; + var line = cm.getLineHandle(i); + var matched = query.test(line.text); + if (matched !== inverted) { + matchedLines.push(cmd ? line : line.text); } } if (!cmd) { - showConfirm(cm, content); + showConfirm(cm, matchedLines.join('\n')); return; } var index = 0; var nextCommand = function() { if (index < matchedLines.length) { - var command = matchedLines[index] + cmd; + var line = matchedLines[index++]; + var lineNum = cm.getLineNumber(line); + if (lineNum == null) { + nextCommand(); + return; + } + var command = (lineNum + 1) + cmd; exCommandDispatcher.processCommand(cm, command, { callback: nextCommand }); } - index++; }; nextCommand(); }, @@ -5102,10 +5428,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ regexPart = new RegExp(regexPart).source; //normalize not escaped characters } replacePart = tokens[1]; - if (regexPart && regexPart[regexPart.length - 1] === '$') { - regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n'; - replacePart = replacePart ? replacePart + '\n' : '\n'; - } if (replacePart !== undefined) { if (getOption('pcre')) { replacePart = unescapeRegexReplace(replacePart.replace(/([^\\])&/g,"$1$$&")); @@ -5128,11 +5450,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (flagsPart) { if (flagsPart.indexOf('c') != -1) { confirm = true; - flagsPart.replace('c', ''); } if (flagsPart.indexOf('g') != -1) { global = true; - flagsPart.replace('g', ''); } if (getOption('pcre')) { regexPart = regexPart + '/' + flagsPart; @@ -5166,7 +5486,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ lineStart = lineEnd; lineEnd = lineStart + count - 1; } - var startPos = clipCursorToContent(cm, Pos(lineStart, 0)); + var startPos = clipCursorToContent(cm, new Pos(lineStart, 0)); var cursor = cm.getSearchCursor(query, startPos); doReplace(cm, confirm, global, lineStart, lineEnd, cursor, query, replacePart, params.callback); }, @@ -5243,7 +5563,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ replaceWith, callback) { cm.state.vim.exMode = true; var done = false; - var lastPos = searchCursor.from(); + var lastPos, modifiedLineNumber, joined; function replaceAll() { cm.operation(function() { while (!done) { @@ -5256,12 +5576,24 @@ dom.importCssString(".normal-mode .ace_cursor{\ function replace() { var text = cm.getRange(searchCursor.from(), searchCursor.to()); var newText = text.replace(query, replaceWith); + var unmodifiedLineNumber = searchCursor.to().line; searchCursor.replace(newText); + modifiedLineNumber = searchCursor.to().line; + lineEnd += modifiedLineNumber - unmodifiedLineNumber; + joined = modifiedLineNumber < unmodifiedLineNumber; + } + function findNextValidMatch() { + var lastMatchTo = lastPos && copyCursor(searchCursor.to()); + var match = searchCursor.findNext(); + if (match && !match[0] && lastMatchTo && cursorEqual(searchCursor.from(), lastMatchTo)) { + match = searchCursor.findNext(); + } + return match; } function next() { - while(searchCursor.findNext() && + while(findNextValidMatch() && isInRange(searchCursor.from(), lineStart, lineEnd)) { - if (!global && lastPos && searchCursor.from().line == lastPos.line) { + if (!global && searchCursor.from().line == modifiedLineNumber && !joined) { continue; } cm.scrollIntoView(searchCursor.from(), 30); @@ -5320,7 +5652,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ return; } showPrompt(cm, { - prefix: 'replace with ' + replaceWith + ' (y/n/a/q/l)', + prefix: hdom('span', 'replace with ', hdom('strong', replaceWith), ' (y/n/a/q/l)'), onKeyDown: onPromptKeyDown }); } @@ -5408,7 +5740,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ match = (/<\w+-.+?>|<\w+>|./).exec(text); key = match[0]; text = text.substring(match.index + key.length); - CodeMirror.Vim.handleKey(cm, key, 'macro'); + vimApi.handleKey(cm, key, 'macro'); if (vim.insertMode) { var changes = register.insertModeChanges[imc++].changes; vimGlobalState.macroModeState.lastInsertModeChanges.changes = @@ -5491,18 +5823,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ } else if (!cm.curOp.isVimOp) { handleExternalSelection(cm, vim); } - if (vim.visualMode) { - updateFakeCursor(cm); - } - } - function updateFakeCursor(cm) { - var vim = cm.state.vim; - var from = clipCursorToContent(cm, copyCursor(vim.sel.head)); - var to = offsetCursor(from, 0, 1); - if (vim.fakeCursor) { - vim.fakeCursor.clear(); - } - vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'}); } function handleExternalSelection(cm, vim, keepHPos) { var anchor = cm.getCursor('anchor'); @@ -5612,12 +5932,12 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (change instanceof InsertModeKey) { CodeMirror.lookupKey(change.keyName, 'vim-insert', keyHandler); } else if (typeof change == "string") { - var cur = cm.getCursor(); - cm.replaceRange(change, cur, cur); + cm.replaceSelection(change); } else { var start = cm.getCursor(); var end = offsetCursor(start, 0, change[0].length); cm.replaceRange(change[0], start, end); + cm.setCursor(end); } } } @@ -5632,7 +5952,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ Vim = CodeMirror.Vim; var specialKey = {'return':'CR',backspace:'BS','delete':'Del',esc:'Esc', - left:'Left',right:'Right',up:'Up',down:'Down',space: 'Space', + left:'Left',right:'Right',up:'Up',down:'Down',space: 'Space',insert: 'Ins', home:'Home',end:'End',pageup:'PageUp',pagedown:'PageDown', enter: 'CR' }; function lookupKey(hashId, key, e) { @@ -5684,7 +6004,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } else if (wasMultiselect && vim.visualBlock) { vim.wasInVisualBlock = true; } - + if (key == '' && !vim.insertMode && !vim.visualMode && wasMultiselect) { cm.ace.exitMultiSelectMode(); } else if (visualBlock || !wasMultiselect || cm.ace.inVirtualSelectionMode) { @@ -5703,7 +6023,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ anchor = offsetCursor(anchor, 0, anchorOffset); cm.state.vim.sel.head = head; cm.state.vim.sel.anchor = anchor; - + isHandled = handleKey(cm, key, origin); sel.$desiredColumn = cm.state.vim.lastHPos == -1 ? null : cm.state.vim.lastHPos; if (cm.virtualSelectionMode()) { @@ -5730,12 +6050,12 @@ dom.importCssString(".normal-mode .ace_cursor{\ var top = pixelPos.top; var left = pixelPos.left; if (!vim.insertMode) { - var isbackwards = !sel.cursor + var isbackwards = !sel.cursor ? session.selection.isBackwards() || session.selection.isEmpty() : Range.comparePoints(sel.cursor, sel.start) <= 0; if (!isbackwards && left > w) left -= w; - } + } if (!vim.insertMode && vim.status) { h = h / 2; top += h; @@ -5775,21 +6095,26 @@ dom.importCssString(".normal-mode .ace_cursor{\ data.inputChar = data.inputKey = null; } } + + if (cm.state.overwrite && vim.insertMode && key == "backspace" && hashId == 0) { + return {command: "gotoleft"} + } if (key == "c" && hashId == 1) { // key == "ctrl-c" if (!useragent.isMac && editor.getCopyText()) { editor.once("copy", function() { - editor.selection.clearSelection(); + if (vim.insertMode) editor.selection.clearSelection(); + else cm.operation(function() { exitVisualMode(cm); }); }); return {command: "null", passEvent: true}; } } - + if (key == "esc" && !vim.insertMode && !vim.visualMode && !cm.ace.inMultiSelectMode) { var searchState = getSearchState(cm); var overlay = searchState.getOverlay(); if (overlay) cm.removeOverlay(overlay); } - + if (hashId == -1 || hashId & 1 || hashId === 0 && key.length > 1) { var insertMode = vim.insertMode; var name = lookupKey(hashId, key, e || {}); @@ -5887,7 +6212,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ { keys: 'zA', type: 'action', action: 'fold', actionArgs: { toggle: true, all: true } }, { keys: 'zf', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, { keys: 'zd', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, - + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAbove" } }, { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelow" } }, { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAboveSkipCurrent" } }, @@ -5897,6 +6222,34 @@ dom.importCssString(".normal-mode .ace_cursor{\ { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectNextBefore" } }, { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectNextAfter" } } ); + + defaultKeymap.push({ + keys: 'gq', + type: 'operator', + operator: 'hardWrap' + }); + Vim.defineOperator("hardWrap", function(cm, operatorArgs, ranges, oldAnchor, newHead) { + var anchor = ranges[0].anchor.line; + var head = ranges[0].head.line; + if (operatorArgs.linewise) head--; + hardWrap(cm.ace, {startRow: anchor, endRow: head}); + return Pos(head, 0); + }); + defineOption('textwidth', undefined, 'number', ['tw'], function(width, cm) { + if (cm === undefined) { + return; + } + if (width === undefined) { + var value = cm.ace.getOption('printMarginColumn'); + return value; + } else { + var column = Math.round(width); + if (column > 1) { + cm.ace.setOption('printMarginColumn', column); + } + } + }); + actions.aceCommand = function(cm, actionArgs, vim) { cm.vimCmd = actionArgs; if (cm.ace.inVirtualSelectionMode) diff --git a/htdocs/includes/ace/src/keybinding-vscode.js b/htdocs/includes/ace/src/keybinding-vscode.js index 45ac5cf03ff..5ab34483c33 100644 --- a/htdocs/includes/ace/src/keybinding-vscode.js +++ b/htdocs/includes/ace/src/keybinding-vscode.js @@ -116,7 +116,7 @@ exports.handler.addCommands([{ [{ - bindKey: {mac: "Control-G", win: "Ctrl-G"}, + bindKey: {mac: "Ctrl-G", win: "Ctrl-G"}, name: "gotoline" }, { bindKey: {mac: "Command-Shift-L|Command-F2", win: "Ctrl-Shift-L|Ctrl-F2"}, @@ -158,10 +158,10 @@ exports.handler.addCommands([{ bindKey: {mac: "Command-[", win: "Ctrl-["}, name: "blockoutdent" }, { - bindKey: {mac: "Control-PageDown", win: "Alt-PageDown"}, + bindKey: {mac: "Ctrl-PageDown", win: "Alt-PageDown"}, name: "pagedown" }, { - bindKey: {mac: "Control-PageUp", win: "Alt-PageUp"}, + bindKey: {mac: "Ctrl-PageUp", win: "Alt-PageUp"}, name: "pageup" }, { bindKey: {mac: "Shift-Option-A", win: "Shift-Alt-A"}, diff --git a/htdocs/includes/ace/src/mode-abc.js b/htdocs/includes/ace/src/mode-abc.js index 94cb1605ec2..a1dd531b807 100644 --- a/htdocs/includes/ace/src/mode-abc.js +++ b/htdocs/includes/ace/src/mode-abc.js @@ -254,7 +254,10 @@ define("ace/mode/abc",["require","exports","module","ace/lib/oop","ace/mode/text oop.inherits(Mode, TextMode); (function () { + this.lineCommentStart = "%"; + this.$id = "ace/mode/abc"; + this.snippetFileId = "ace/snippets/abc"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-actionscript.js b/htdocs/includes/ace/src/mode-actionscript.js index f23c9d3ceb4..d9e6634b0d7 100644 --- a/htdocs/includes/ace/src/mode-actionscript.js +++ b/htdocs/includes/ace/src/mode-actionscript.js @@ -261,6 +261,7 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = "//"; this.blockComment = {start: "/*", end: "*/"}; this.$id = "ace/mode/actionscript"; + this.snippetFileId = "ace/snippets/actionscript"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-alda.js b/htdocs/includes/ace/src/mode-alda.js new file mode 100644 index 00000000000..72470be79d0 --- /dev/null +++ b/htdocs/includes/ace/src/mode-alda.js @@ -0,0 +1,311 @@ +define("ace/mode/alda_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { + "use strict"; + + var oop = require("../lib/oop"); + var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + + var AldaHighlightRules = function() { + + this.$rules = { + pitch: [{ + token: "variable.parameter.operator.pitch.alda", + regex: /(?:[+\-]+|\=)/ + }, { + token: "", + regex: "", + next: "timing" + }], + timing: [{ + token: "string.quoted.operator.timing.alda", + regex: /\d+(?:s|ms)?/ + }, { + token: "", + regex: "", + next: "start" + }], + start: [{ + token: [ + "constant.language.instrument.alda", + "constant.language.instrument.alda", + "meta.part.call.alda", + "storage.type.nickname.alda", + "meta.part.call.alda" + ], + regex: /^([a-zA-Z]{2}[\w\-+\'()]*)((?:\s*\/\s*[a-zA-Z]{2}[\w\-+\'()]*)*)(?:(\s*)(\"[a-zA-Z]{2}[\w\-+\'()]*\"))?(\s*:)/ + }, { + token: [ + "text", + "entity.other.inherited-class.voice.alda", + "text" + ], + regex: /^(\s*)(V\d+)(:)/ + }, { + token: "comment.line.number-sign.alda", + regex: /#.*$/ + }, { + token: "entity.name.function.pipe.measure.alda", + regex: /\|/ + }, { + token: "comment.block.inline.alda", + regex: /\(comment\b/, + push: [{ + token: "comment.block.inline.alda", + regex: /\)/, + next: "pop" + }, { + defaultToken: "comment.block.inline.alda" + }] + }, { + token: "entity.name.function.marker.alda", + regex: /%[a-zA-Z]{2}[\w\-+\'()]*/ + }, { + token: "entity.name.function.at-marker.alda", + regex: /@[a-zA-Z]{2}[\w\-+\'()]*/ + }, { + token: "keyword.operator.octave-change.alda", + regex: /\bo\d+\b/ + }, { + token: "keyword.operator.octave-shift.alda", + regex: /[><]/ + }, { + token: "keyword.operator.repeat.alda", + regex: /\*\s*\d+/ + }, { + token: "string.quoted.operator.timing.alda", + regex: /[.]|r\d*(?:s|ms)?/ + },{ + token: "text", + regex: /([cdefgab])/, + next: "pitch" + }, { + token: "string.quoted.operator.timing.alda", + regex: /~/, + next: "timing" + }, { + token: "punctuation.section.embedded.cram.alda", + regex: /\}/, + next: "timing" + }, { + token: "constant.numeric.subchord.alda", + regex: /\// + }, { + todo: { + token: "punctuation.section.embedded.cram.alda", + regex: /\{/, + push: [{ + token: "punctuation.section.embedded.cram.alda", + regex: /\}/, + next: "pop" + }, { + include: "$self" + }] + } + }, { + todo: { + token: "keyword.control.sequence.alda", + regex: /\[/, + push: [{ + token: "keyword.control.sequence.alda", + regex: /\]/, + next: "pop" + }, { + include: "$self" + }] + } + }, { + token: "meta.inline.clojure.alda", + regex: /\(/, + push: [{ + token: "meta.inline.clojure.alda", + regex: /\)/, + next: "pop" + }, { + include: "source.clojure" + }, { + defaultToken: "meta.inline.clojure.alda" + }] + }] + }; + + this.normalizeRules(); + }; + + AldaHighlightRules.metaData = { + scopeName: "source.alda", + fileTypes: ["alda"], + name: "Alda" + }; + + + oop.inherits(AldaHighlightRules, TextHighlightRules); + + exports.AldaHighlightRules = AldaHighlightRules; + }); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/alda",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/alda_highlight_rules","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var AldaHighlightRules = require("./alda_highlight_rules").AldaHighlightRules; +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = AldaHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.$id = "ace/mode/alda"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); (function() { + window.require(["ace/mode/alda"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-asl.js b/htdocs/includes/ace/src/mode-asl.js index 58c82631449..955838a94b4 100644 --- a/htdocs/includes/ace/src/mode-asl.js +++ b/htdocs/includes/ace/src/mode-asl.js @@ -58,16 +58,7 @@ define("ace/mode/asl_highlight_rules",["require","exports","module","ace/lib/oop var ASLHighlightRules = function() { var keywords = ( "Default|DefinitionBlock|Device|Method|Else|ElseIf|For|Function|If|Include|Method|Return|" + - "Scope|Switch|Case|While|Break|BreakPoint|Continue|NoOp|Wait" - ); - - var keywordOperators = ( - "Add|And|Decrement|Divide|Increment|Index|LAnd|LEqual|LGreater|LGreaterEqual|" + - "LLess|LLessEqual|LNot|LNotEqual|LOr|Mod|Multiply|NAnd|NOr|Not|Or|RefOf|Revision|" + - "ShiftLeft|ShiftRight|Subtract|XOr|DerefOf" - ); - - var buildinFunctions = ( + "Scope|Switch|Case|While|Break|BreakPoint|Continue|NoOp|Wait|True|False|" + "AccessAs|Acquire|Alias|BankField|Buffer|Concatenate|ConcatenateResTemplate|" + "CondRefOf|Connection|CopyObject|CreateBitField|CreateByteField|CreateDWordField|" + "CreateField|CreateQWordField|CreateWordField|DataTableRegion|Debug|" + @@ -83,6 +74,12 @@ define("ace/mode/asl_highlight_rules",["require","exports","module","ace/lib/oop "WordSpace" ); + var keywordOperators = ( + "Add|And|Decrement|Divide|Increment|Index|LAnd|LEqual|LGreater|LGreaterEqual|" + + "LLess|LLessEqual|LNot|LNotEqual|LOr|Mod|Multiply|NAnd|NOr|Not|Or|RefOf|Revision|" + + "ShiftLeft|ShiftRight|Subtract|XOr|DerefOf" + ); + var flags = ( "AttribQuick|AttribSendReceive|AttribByte|AttribBytes|AttribRawBytes|" + "AttribRawProcessBytes|AttribWord|AttribBlock|AttribProcessCall|AttribBlockProcessCall|" + @@ -121,21 +118,25 @@ define("ace/mode/asl_highlight_rules",["require","exports","module","ace/lib/oop "ThermalZoneObj|BuffFieldObj|DDBHandleObj" ); - var buildinConstants = ( + var builtinConstants = ( "__FILE__|__PATH__|__LINE__|__DATE__|__IASL__" ); + var strNumbers = ( + "One|Ones|Zero" + ); + var deprecated = ( "Memory24|Processor" ); var keywordMapper = this.createKeywordMapper({ "keyword": keywords, + "constant.numeric": strNumbers, "keyword.operator": keywordOperators, - "function.buildin": buildinFunctions, - "constant.language": buildinConstants, + "constant.language": builtinConstants, "storage.type": storageTypes, - "constant.character": flags, + "constant.library": flags, "invalid.deprecated": deprecated }, "identifier"); @@ -174,13 +175,13 @@ define("ace/mode/asl_highlight_rules",["require","exports","module","ace/lib/oop regex : /0[xX][0-9a-fA-F]+\b/ }, { token : "constant.numeric", - regex : /(One(s)?|Zero|True|False|[0-9]+)\b/ + regex : /[0-9]+\b/ }, { token : keywordMapper, regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { token : "keyword.operator", - regex : "/|!|\\$|%|&|\\||\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|\\^|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\|=" + regex : /[!\~\*\/%+-<>\^|=&]/ }, { token : "lparen", regex : "[[({]" diff --git a/htdocs/includes/ace/src/mode-bro.js b/htdocs/includes/ace/src/mode-bro.js deleted file mode 100644 index 86521764689..00000000000 --- a/htdocs/includes/ace/src/mode-bro.js +++ /dev/null @@ -1,334 +0,0 @@ -define("ace/mode/bro_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var BroHighlightRules = function() { - - this.$rules = { - start: [{ - token: "punctuation.definition.comment.bro", - regex: /#/, - push: [{ - token: "comment.line.number-sign.bro", - regex: /$/, - next: "pop" - }, { - defaultToken: "comment.line.number-sign.bro" - }] - }, { - token: "keyword.control.bro", - regex: /\b(?:break|case|continue|else|for|if|return|switch|next|when|timeout|schedule)\b/ - }, { - token: [ - "meta.function.bro", - "meta.function.bro", - "storage.type.bro", - "meta.function.bro", - "entity.name.function.bro", - "meta.function.bro" - ], - regex: /^(\s*)(?:function|hook|event)(\s*)(.*)(\s*\()(.*)(\).*$)/ - }, { - token: "storage.type.bro", - regex: /\b(?:bool|enum|double|int|count|port|addr|subnet|any|file|interval|time|string|table|vector|set|record|pattern|hook)\b/ - }, { - token: "storage.modifier.bro", - regex: /\b(?:global|const|redef|local|&(?:optional|rotate_interval|rotate_size|add_func|del_func|expire_func|expire_create|expire_read|expire_write|persistent|synchronized|encrypt|mergeable|priority|group|type_column|log|error_handler))\b/ - }, { - token: "keyword.operator.bro", - regex: /\s*(?:\||&&|(?:>|<|!)=?|==)\s*|\b!?in\b/ - }, { - token: "constant.language.bro", - regex: /\b(?:T|F)\b/ - }, { - token: "constant.numeric.bro", - regex: /\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:(?:e|E)(?:\+|-)?[0-9]+)?)(?:\/(?:tcp|udp|icmp)|\s*(?:u?sec|min|hr|day)s?)?\b/ - }, { - token: "punctuation.definition.string.begin.bro", - regex: /"/, - push: [{ - token: "punctuation.definition.string.end.bro", - regex: /"/, - next: "pop" - }, { - include: "#string_escaped_char" - }, { - include: "#string_placeholder" - }, { - defaultToken: "string.quoted.double.bro" - }] - }, { - token: "punctuation.definition.string.begin.bro", - regex: /\//, - push: [{ - token: "punctuation.definition.string.end.bro", - regex: /\//, - next: "pop" - }, { - include: "#string_escaped_char" - }, { - include: "#string_placeholder" - }, { - defaultToken: "string.quoted.regex.bro" - }] - }, { - token: [ - "meta.preprocessor.bro.load", - "keyword.other.special-method.bro" - ], - regex: /^(\s*)(\@load(?:-sigs)?)\b/, - push: [{ - token: [], - regex: /(?=\#)|$/, - next: "pop" - }, { - defaultToken: "meta.preprocessor.bro.load" - }] - }, { - token: [ - "meta.preprocessor.bro.if", - "keyword.other.special-method.bro", - "meta.preprocessor.bro.if" - ], - regex: /^(\s*)(\@endif|\@if(?:n?def)?)(.*$)/, - push: [{ - token: [], - regex: /$/, - next: "pop" - }, { - defaultToken: "meta.preprocessor.bro.if" - }] - }], - "#disabled": [{ - token: "text", - regex: /^\s*\@if(?:n?def)?\b.*$/, - push: [{ - token: "text", - regex: /^\s*\@endif\b.*$/, - next: "pop" - }, { - include: "#disabled" - }, { - include: "#pragma-mark" - }], - comment: "eat nested preprocessor ifdefs" - }], - "#preprocessor-rule-other": [{ - token: [ - "text", - "meta.preprocessor.bro", - "meta.preprocessor.bro", - "text" - ], - regex: /^(\s*)(@if)((?:n?def)?)\b(.*?)(?:(?=)|$)/, - push: [{ - token: ["text", "meta.preprocessor.bro", "text"], - regex: /^(\s*)(@endif)\b(.*$)/, - next: "pop" - }, { - include: "$base" - }] - }], - "#string_escaped_char": [{ - token: "constant.character.escape.bro", - regex: /\\(?:\\|[abefnprtv'"?]|[0-3]\d{,2}|[4-7]\d?|x[a-fA-F0-9]{,2})/ - }, { - token: "invalid.illegal.unknown-escape.bro", - regex: /\\./ - }], - "#string_placeholder": [{ - token: "constant.other.placeholder.bro", - regex: /%(?:\d+\$)?[#0\- +']*[,;:_]?(?:-?\d+|\*(?:-?\d+\$)?)?(?:\.(?:-?\d+|\*(?:-?\d+\$)?)?)?(?:hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)?[diouxXDOUeEfFgGaACcSspn%]/ - }, { - token: "invalid.illegal.placeholder.bro", - regex: /%/ - }] - }; - - this.normalizeRules(); -}; - -BroHighlightRules.metaData = { - fileTypes: ["bro"], - foldingStartMarker: "^(\\@if(n?def)?)", - foldingStopMarker: "^\\@endif", - keyEquivalent: "@B", - name: "Bro", - scopeName: "source.bro" -}; - - -oop.inherits(BroHighlightRules, TextHighlightRules); - -exports.BroHighlightRules = BroHighlightRules; -}); - -define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { -"use strict"; - -var oop = require("../../lib/oop"); -var Range = require("../../range").Range; -var BaseFoldMode = require("./fold_mode").FoldMode; - -var FoldMode = exports.FoldMode = function(commentRegex) { - if (commentRegex) { - this.foldingStartMarker = new RegExp( - this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) - ); - this.foldingStopMarker = new RegExp( - this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) - ); - } -}; -oop.inherits(FoldMode, BaseFoldMode); - -(function() { - - this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; - this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; - this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; - this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; - this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; - this._getFoldWidgetBase = this.getFoldWidget; - this.getFoldWidget = function(session, foldStyle, row) { - var line = session.getLine(row); - - if (this.singleLineBlockCommentRe.test(line)) { - if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) - return ""; - } - - var fw = this._getFoldWidgetBase(session, foldStyle, row); - - if (!fw && this.startRegionRe.test(line)) - return "start"; // lineCommentRegionStart - - return fw; - }; - - this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { - var line = session.getLine(row); - - if (this.startRegionRe.test(line)) - return this.getCommentRegionBlock(session, line, row); - - var match = line.match(this.foldingStartMarker); - if (match) { - var i = match.index; - - if (match[1]) - return this.openingBracketBlock(session, match[1], row, i); - - var range = session.getCommentFoldRange(row, i + match[0].length, 1); - - if (range && !range.isMultiLine()) { - if (forceMultiline) { - range = this.getSectionRange(session, row); - } else if (foldStyle != "all") - range = null; - } - - return range; - } - - if (foldStyle === "markbegin") - return; - - var match = line.match(this.foldingStopMarker); - if (match) { - var i = match.index + match[0].length; - - if (match[1]) - return this.closingBracketBlock(session, match[1], row, i); - - return session.getCommentFoldRange(row, i, -1); - } - }; - - this.getSectionRange = function(session, row) { - var line = session.getLine(row); - var startIndent = line.search(/\S/); - var startRow = row; - var startColumn = line.length; - row = row + 1; - var endRow = row; - var maxRow = session.getLength(); - while (++row < maxRow) { - line = session.getLine(row); - var indent = line.search(/\S/); - if (indent === -1) - continue; - if (startIndent > indent) - break; - var subRange = this.getFoldWidgetRange(session, "all", row); - - if (subRange) { - if (subRange.start.row <= startRow) { - break; - } else if (subRange.isMultiLine()) { - row = subRange.end.row; - } else if (startIndent == indent) { - break; - } - } - endRow = row; - } - - return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); - }; - this.getCommentRegionBlock = function(session, line, row) { - var startColumn = line.search(/\s*$/); - var maxRow = session.getLength(); - var startRow = row; - - var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; - var depth = 1; - while (++row < maxRow) { - line = session.getLine(row); - var m = re.exec(line); - if (!m) continue; - if (m[1]) depth--; - else depth++; - - if (!depth) break; - } - - var endRow = row; - if (endRow > startRow) { - return new Range(startRow, startColumn, endRow, line.length); - } - }; - -}).call(FoldMode.prototype); - -}); - -define("ace/mode/bro",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/bro_highlight_rules","ace/mode/folding/cstyle"], function(require, exports, module) { -"use strict"; - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var BroHighlightRules = require("./bro_highlight_rules").BroHighlightRules; -var FoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = BroHighlightRules; - this.foldingRules = new FoldMode(); -}; -oop.inherits(Mode, TextMode); - -(function() { - this.$id = "ace/mode/bro"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); (function() { - window.require(["ace/mode/bro"], function(m) { - if (typeof module == "object" && typeof exports == "object" && module) { - module.exports = m; - } - }); - })(); - \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-c_cpp.js b/htdocs/includes/ace/src/mode-c_cpp.js index 4e653ebe028..da730717d6c 100644 --- a/htdocs/includes/ace/src/mode-c_cpp.js +++ b/htdocs/includes/ace/src/mode-c_cpp.js @@ -65,7 +65,7 @@ var c_cppHighlightRules = function() { var storageType = ( "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + - "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|" + + "_Imaginary|int|int8_t|int16_t|int32_t|int64_t|long|short|signed|size_t|struct|typedef|uint8_t|uint16_t|uint32_t|uint64_t|union|unsigned|void|" + "class|wchar_t|template|char16_t|char32_t" ); @@ -489,6 +489,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/c_cpp"; + this.snippetFileId = "ace/snippets/c_cpp"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-clojure.js b/htdocs/includes/ace/src/mode-clojure.js index 1f7f41841a7..dd10ec76dd2 100644 --- a/htdocs/includes/ace/src/mode-clojure.js +++ b/htdocs/includes/ace/src/mode-clojure.js @@ -301,6 +301,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/clojure"; + this.snippetFileId = "ace/snippets/clojure"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-coffee.js b/htdocs/includes/ace/src/mode-coffee.js index 75d19d4d3ff..063883c9f58 100644 --- a/htdocs/includes/ace/src/mode-coffee.js +++ b/htdocs/includes/ace/src/mode-coffee.js @@ -385,6 +385,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/coffee"; + this.snippetFileId = "ace/snippets/coffee"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-coldfusion.js b/htdocs/includes/ace/src/mode-coldfusion.js index 8b85c12e940..fcb742db282 100644 --- a/htdocs/includes/ace/src/mode-coldfusion.js +++ b/htdocs/includes/ace/src/mode-coldfusion.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-csound_document.js b/htdocs/includes/ace/src/mode-csound_document.js index ae92fce17e1..de242e5c184 100644 --- a/htdocs/includes/ace/src/mode-csound_document.js +++ b/htdocs/includes/ace/src/mode-csound_document.js @@ -300,7 +300,7 @@ var CsoundScoreHighlightRules = function(embeddedRulePrefix) { start.push( { token : "keyword.control.csound-score", - regex : /[abCdefiqstvxy]/ + regex : /[aBbCdefiqstvxy]/ }, { token : "invalid.illegal.csound-score", regex : /w/ @@ -935,10 +935,10 @@ var PythonHighlightRules = function() { regex: "\\s+" }, { token: "string", - regex: "'(.)*'" + regex: "'[^']*'" }, { token: "string", - regex: '"(.)*"' + regex: '"[^"]*"' }, { token: "function.support", regex: "(!s|!r|!a)" @@ -1141,6 +1141,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "adsynt", "adsynt2", "aftouch", + "allpole", "alpass", "alwayson", "ampdb", @@ -1148,11 +1149,17 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ampmidi", "ampmidicurve", "ampmidid", + "apoleparams", + "arduinoRead", + "arduinoReadF", + "arduinoStart", + "arduinoStop", "areson", "aresonk", "atone", "atonek", "atonex", + "autocorr", "babo", "balance", "balance2", @@ -1160,8 +1167,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "barmodel", "bbcutm", "bbcuts", - "beadsynt", - "beosc", "betarand", "bexprnd", "bformdec1", @@ -1170,6 +1175,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "biquad", "biquada", "birnd", + "bob", "bpf", "bpfcos", "bqrez", @@ -1195,6 +1201,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ceps", "cepsinv", "chanctrl", + "changed", "changed2", "chani", "chano", @@ -1206,11 +1213,19 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "chnclear", "chnexport", "chnget", + "chngeta", + "chngeti", + "chngetk", "chngetks", + "chngets", "chnmix", "chnparams", "chnset", + "chnseta", + "chnseti", + "chnsetk", "chnsetks", + "chnsets", "chuap", "clear", "clfilt", @@ -1219,6 +1234,13 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "clockon", "cmp", "cmplxprod", + "cntCreate", + "cntCycles", + "cntDelete", + "cntDelete_i", + "cntRead", + "cntReset", + "cntState", "comb", "combinv", "compilecsd", @@ -1238,6 +1260,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "cosseg", "cossegb", "cossegr", + "count", + "count_i", "cps2pch", "cpsmidi", "cpsmidib", @@ -1263,6 +1287,11 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ctrl21", "ctrl7", "ctrlinit", + "ctrlpreset", + "ctrlprint", + "ctrlprintpresets", + "ctrlsave", + "ctrlselect", "cuserrnd", "dam", "date", @@ -1408,6 +1437,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ftchnls", "ftconv", "ftcps", + "ftexists", "ftfree", "ftgen", "ftgenonce", @@ -1424,7 +1454,9 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ftsamplebank", "ftsave", "ftsavek", + "ftset", "ftslice", + "ftslicei", "ftsr", "gain", "gainslider", @@ -1441,7 +1473,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "getcol", "getftargs", "getrow", - "getrowlin", "getseed", "gogobel", "grain", @@ -1689,8 +1720,12 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "la_k_upper_solve_mr", "la_k_vc_set", "la_k_vr_set", + "lag", + "lagud", + "lastcycle", "lenarray", "lfo", + "lfsr", "limit", "limit1", "lincos", @@ -1734,6 +1769,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "lowpass2", "lowres", "lowresx", + "lpcanal", + "lpcfilter", "lpf18", "lpform", "lpfreson", @@ -1749,14 +1786,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "lpshold", "lpsholdp", "lpslot", - "lua_exec", - "lua_iaopcall", - "lua_iaopcall_off", - "lua_ikopcall", - "lua_ikopcall_off", - "lua_iopcall", - "lua_iopcall_off", - "lua_opdef", + "lufs", "mac", "maca", "madsr", @@ -1779,6 +1809,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "median", "mediank", "metro", + "metro2", "mfb", "midglobal", "midiarp", @@ -1831,6 +1862,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "mp3sr", "mpulse", "mrtmsg", + "ms2st", "mtof", "mton", "multitap", @@ -1840,6 +1872,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "mvclpf2", "mvclpf3", "mvclpf4", + "mvmfilter", "mxadsr", "nchnls_hw", "nestedap", @@ -1883,6 +1916,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "oscilx", "out", "out32", + "outall", "outc", "outch", "outh", @@ -1983,12 +2017,11 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "printk2", "printks", "printks2", + "println", "prints", + "printsk", "product", "pset", - "ptable", - "ptable3", - "ptablei", "ptablew", "ptrack", "puts", @@ -2005,6 +2038,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "pvsarp", "pvsbandp", "pvsbandr", + "pvsbandwidth", "pvsbin", "pvsblur", "pvsbuffer", @@ -2013,6 +2047,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "pvscale", "pvscent", "pvsceps", + "pvscfs", "pvscross", "pvsdemix", "pvsdiskin", @@ -2032,6 +2067,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "pvsinfo", "pvsinit", "pvslock", + "pvslpc", "pvsmaska", "pvsmix", "pvsmooth", @@ -2133,6 +2169,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "qnan", "r2c", "rand", + "randc", "randh", "randi", "random", @@ -2156,6 +2193,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "repluck", "reshapearray", "reson", + "resonbnk", "resonk", "resonr", "resonx", @@ -2173,6 +2211,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "rms", "rnd", "rnd31", + "rndseed", "round", "rspline", "rtclock", @@ -2185,14 +2224,17 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "sc_phasor", "sc_trig", "scale", + "scale2", "scalearray", "scanhammer", "scans", "scantable", "scanu", + "scanu2", "schedkwhen", "schedkwhennamed", "schedule", + "schedulek", "schedwhen", "scoreline", "scoreline_i", @@ -2238,6 +2280,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "sinh", "sininv", "sinsyn", + "skf", "sleighbells", "slicearray", "slicearray_i", @@ -2273,13 +2316,16 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "spat3di", "spat3dt", "spdist", + "spf", "splitrig", "sprintf", "sprintfk", "spsend", "sqrt", "squinewave", + "st2ms", "statevar", + "sterrain", "stix", "strcat", "strcatk", @@ -2303,6 +2349,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "strrindex", "strrindexk", "strset", + "strstrip", "strsub", "strsubk", "strtod", @@ -2317,6 +2364,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "sum", "sumarray", "svfilter", + "svn", "syncgrain", "syncloop", "syncphasor", @@ -2357,7 +2405,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "tabmorphi", "tabplay", "tabrec", - "tabrowlin", "tabsum", "tabw", "tabw_i", @@ -2389,7 +2436,11 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "trcross", "trfilter", "trhighest", + "trigExpseg", + "trigLinseg", "trigger", + "trighold", + "trigphasor", "trigseq", "trim", "trim_i", @@ -2401,6 +2452,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "trsplit", "turnoff", "turnoff2", + "turnoff2_i", + "turnoff3", "turnon", "tvconv", "unirand", @@ -2424,6 +2477,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "vbapz", "vbapzmove", "vcella", + "vclpf", "vco", "vco2", "vco2ft", @@ -2472,6 +2526,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "vpow_i", "vpowv", "vpowv_i", + "vps", "vpvoc", "vrandh", "vrandi", @@ -2511,6 +2566,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "wrap", "writescratch", "wterrain", + "wterrain2", "xadsr", "xin", "xout", @@ -2543,24 +2599,47 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "zkwm" ]; var deprecatedOpcodes = [ + "OSCsendA", "array", + "beadsynt", + "beosc", "bformdec", "bformenc", - "changed", + "buchla", "copy2ftab", "copy2ttab", + "getrowlin", "hrtfer", "ktableseg", "lentab", + "lua_exec", + "lua_iaopcall", + "lua_iaopcall_off", + "lua_ikopcall", + "lua_ikopcall_off", + "lua_iopcall", + "lua_iopcall_off", + "lua_opdef", "maxtab", "mintab", + "mp3scal_check", + "mp3scal_load", + "mp3scal_load2", + "mp3scal_play", + "mp3scal_play2", "pop", "pop_f", + "ptable", + "ptable3", + "ptablei", "ptableiw", "push", "push_f", + "pvsgendy", "scalet", + "signalflowgraph", "sndload", + "socksend_k", "soundout", "soundouts", "specaddm", @@ -2573,11 +2652,14 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "specsum", "spectrum", "stack", + "sumTableFilter", "sumtab", + "systime", "tabgen", "tableiw", "tabmap", "tabmap_i", + "tabrowlin", "tabslice", "tb0", "tb0_init", @@ -2612,6 +2694,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "tb9", "tb9_init", "vbap16", + "vbap1move", "vbap4", "vbap4move", "vbap8", @@ -4006,6 +4089,11 @@ var Mode = function() { }; oop.inherits(Mode, TextMode); +(function() { + this.$id = "ace/mode/csound_document"; + this.snippetFileId = "ace/snippets/csound_document"; +}).call(Mode.prototype); + exports.Mode = Mode; }); (function() { window.require(["ace/mode/csound_document"], function(m) { diff --git a/htdocs/includes/ace/src/mode-csound_orchestra.js b/htdocs/includes/ace/src/mode-csound_orchestra.js index 7cb3917c9f4..58f932eceee 100644 --- a/htdocs/includes/ace/src/mode-csound_orchestra.js +++ b/htdocs/includes/ace/src/mode-csound_orchestra.js @@ -300,7 +300,7 @@ var CsoundScoreHighlightRules = function(embeddedRulePrefix) { start.push( { token : "keyword.control.csound-score", - regex : /[abCdefiqstvxy]/ + regex : /[aBbCdefiqstvxy]/ }, { token : "invalid.illegal.csound-score", regex : /w/ @@ -935,10 +935,10 @@ var PythonHighlightRules = function() { regex: "\\s+" }, { token: "string", - regex: "'(.)*'" + regex: "'[^']*'" }, { token: "string", - regex: '"(.)*"' + regex: '"[^"]*"' }, { token: "function.support", regex: "(!s|!r|!a)" @@ -1141,6 +1141,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "adsynt", "adsynt2", "aftouch", + "allpole", "alpass", "alwayson", "ampdb", @@ -1148,11 +1149,17 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ampmidi", "ampmidicurve", "ampmidid", + "apoleparams", + "arduinoRead", + "arduinoReadF", + "arduinoStart", + "arduinoStop", "areson", "aresonk", "atone", "atonek", "atonex", + "autocorr", "babo", "balance", "balance2", @@ -1160,8 +1167,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "barmodel", "bbcutm", "bbcuts", - "beadsynt", - "beosc", "betarand", "bexprnd", "bformdec1", @@ -1170,6 +1175,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "biquad", "biquada", "birnd", + "bob", "bpf", "bpfcos", "bqrez", @@ -1195,6 +1201,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ceps", "cepsinv", "chanctrl", + "changed", "changed2", "chani", "chano", @@ -1206,11 +1213,19 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "chnclear", "chnexport", "chnget", + "chngeta", + "chngeti", + "chngetk", "chngetks", + "chngets", "chnmix", "chnparams", "chnset", + "chnseta", + "chnseti", + "chnsetk", "chnsetks", + "chnsets", "chuap", "clear", "clfilt", @@ -1219,6 +1234,13 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "clockon", "cmp", "cmplxprod", + "cntCreate", + "cntCycles", + "cntDelete", + "cntDelete_i", + "cntRead", + "cntReset", + "cntState", "comb", "combinv", "compilecsd", @@ -1238,6 +1260,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "cosseg", "cossegb", "cossegr", + "count", + "count_i", "cps2pch", "cpsmidi", "cpsmidib", @@ -1263,6 +1287,11 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ctrl21", "ctrl7", "ctrlinit", + "ctrlpreset", + "ctrlprint", + "ctrlprintpresets", + "ctrlsave", + "ctrlselect", "cuserrnd", "dam", "date", @@ -1408,6 +1437,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ftchnls", "ftconv", "ftcps", + "ftexists", "ftfree", "ftgen", "ftgenonce", @@ -1424,7 +1454,9 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ftsamplebank", "ftsave", "ftsavek", + "ftset", "ftslice", + "ftslicei", "ftsr", "gain", "gainslider", @@ -1441,7 +1473,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "getcol", "getftargs", "getrow", - "getrowlin", "getseed", "gogobel", "grain", @@ -1689,8 +1720,12 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "la_k_upper_solve_mr", "la_k_vc_set", "la_k_vr_set", + "lag", + "lagud", + "lastcycle", "lenarray", "lfo", + "lfsr", "limit", "limit1", "lincos", @@ -1734,6 +1769,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "lowpass2", "lowres", "lowresx", + "lpcanal", + "lpcfilter", "lpf18", "lpform", "lpfreson", @@ -1749,14 +1786,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "lpshold", "lpsholdp", "lpslot", - "lua_exec", - "lua_iaopcall", - "lua_iaopcall_off", - "lua_ikopcall", - "lua_ikopcall_off", - "lua_iopcall", - "lua_iopcall_off", - "lua_opdef", + "lufs", "mac", "maca", "madsr", @@ -1779,6 +1809,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "median", "mediank", "metro", + "metro2", "mfb", "midglobal", "midiarp", @@ -1831,6 +1862,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "mp3sr", "mpulse", "mrtmsg", + "ms2st", "mtof", "mton", "multitap", @@ -1840,6 +1872,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "mvclpf2", "mvclpf3", "mvclpf4", + "mvmfilter", "mxadsr", "nchnls_hw", "nestedap", @@ -1883,6 +1916,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "oscilx", "out", "out32", + "outall", "outc", "outch", "outh", @@ -1983,12 +2017,11 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "printk2", "printks", "printks2", + "println", "prints", + "printsk", "product", "pset", - "ptable", - "ptable3", - "ptablei", "ptablew", "ptrack", "puts", @@ -2005,6 +2038,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "pvsarp", "pvsbandp", "pvsbandr", + "pvsbandwidth", "pvsbin", "pvsblur", "pvsbuffer", @@ -2013,6 +2047,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "pvscale", "pvscent", "pvsceps", + "pvscfs", "pvscross", "pvsdemix", "pvsdiskin", @@ -2032,6 +2067,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "pvsinfo", "pvsinit", "pvslock", + "pvslpc", "pvsmaska", "pvsmix", "pvsmooth", @@ -2133,6 +2169,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "qnan", "r2c", "rand", + "randc", "randh", "randi", "random", @@ -2156,6 +2193,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "repluck", "reshapearray", "reson", + "resonbnk", "resonk", "resonr", "resonx", @@ -2173,6 +2211,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "rms", "rnd", "rnd31", + "rndseed", "round", "rspline", "rtclock", @@ -2185,14 +2224,17 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "sc_phasor", "sc_trig", "scale", + "scale2", "scalearray", "scanhammer", "scans", "scantable", "scanu", + "scanu2", "schedkwhen", "schedkwhennamed", "schedule", + "schedulek", "schedwhen", "scoreline", "scoreline_i", @@ -2238,6 +2280,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "sinh", "sininv", "sinsyn", + "skf", "sleighbells", "slicearray", "slicearray_i", @@ -2273,13 +2316,16 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "spat3di", "spat3dt", "spdist", + "spf", "splitrig", "sprintf", "sprintfk", "spsend", "sqrt", "squinewave", + "st2ms", "statevar", + "sterrain", "stix", "strcat", "strcatk", @@ -2303,6 +2349,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "strrindex", "strrindexk", "strset", + "strstrip", "strsub", "strsubk", "strtod", @@ -2317,6 +2364,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "sum", "sumarray", "svfilter", + "svn", "syncgrain", "syncloop", "syncphasor", @@ -2357,7 +2405,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "tabmorphi", "tabplay", "tabrec", - "tabrowlin", "tabsum", "tabw", "tabw_i", @@ -2389,7 +2436,11 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "trcross", "trfilter", "trhighest", + "trigExpseg", + "trigLinseg", "trigger", + "trighold", + "trigphasor", "trigseq", "trim", "trim_i", @@ -2401,6 +2452,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "trsplit", "turnoff", "turnoff2", + "turnoff2_i", + "turnoff3", "turnon", "tvconv", "unirand", @@ -2424,6 +2477,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "vbapz", "vbapzmove", "vcella", + "vclpf", "vco", "vco2", "vco2ft", @@ -2472,6 +2526,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "vpow_i", "vpowv", "vpowv_i", + "vps", "vpvoc", "vrandh", "vrandi", @@ -2511,6 +2566,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "wrap", "writescratch", "wterrain", + "wterrain2", "xadsr", "xin", "xout", @@ -2543,24 +2599,47 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "zkwm" ]; var deprecatedOpcodes = [ + "OSCsendA", "array", + "beadsynt", + "beosc", "bformdec", "bformenc", - "changed", + "buchla", "copy2ftab", "copy2ttab", + "getrowlin", "hrtfer", "ktableseg", "lentab", + "lua_exec", + "lua_iaopcall", + "lua_iaopcall_off", + "lua_ikopcall", + "lua_ikopcall_off", + "lua_iopcall", + "lua_iopcall_off", + "lua_opdef", "maxtab", "mintab", + "mp3scal_check", + "mp3scal_load", + "mp3scal_load2", + "mp3scal_play", + "mp3scal_play2", "pop", "pop_f", + "ptable", + "ptable3", + "ptablei", "ptableiw", "push", "push_f", + "pvsgendy", "scalet", + "signalflowgraph", "sndload", + "socksend_k", "soundout", "soundouts", "specaddm", @@ -2573,11 +2652,14 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "specsum", "spectrum", "stack", + "sumTableFilter", "sumtab", + "systime", "tabgen", "tableiw", "tabmap", "tabmap_i", + "tabrowlin", "tabslice", "tb0", "tb0_init", @@ -2612,6 +2694,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "tb9", "tb9_init", "vbap16", + "vbap1move", "vbap4", "vbap4move", "vbap8", @@ -2937,6 +3020,8 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = ";"; this.blockComment = {start: "/*", end: "*/"}; + this.$id = "ace/mode/csound_orchestra"; + this.snippetFileId = "ace/snippets/csound_orchestra"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-csound_score.js b/htdocs/includes/ace/src/mode-csound_score.js index e7168662e1a..3155ca1ab67 100644 --- a/htdocs/includes/ace/src/mode-csound_score.js +++ b/htdocs/includes/ace/src/mode-csound_score.js @@ -300,7 +300,7 @@ var CsoundScoreHighlightRules = function(embeddedRulePrefix) { start.push( { token : "keyword.control.csound-score", - regex : /[abCdefiqstvxy]/ + regex : /[aBbCdefiqstvxy]/ }, { token : "invalid.illegal.csound-score", regex : /w/ @@ -448,6 +448,7 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = ";"; this.blockComment = {start: "/*", end: "*/"}; + this.$id = "ace/mode/csound_score"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-css.js b/htdocs/includes/ace/src/mode-css.js index 5ccc1ae304c..04560163b76 100644 --- a/htdocs/includes/ace/src/mode-css.js +++ b/htdocs/includes/ace/src/mode-css.js @@ -705,6 +705,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-curly.js b/htdocs/includes/ace/src/mode-curly.js index c408fed95ed..a3a7e712980 100644 --- a/htdocs/includes/ace/src/mode-curly.js +++ b/htdocs/includes/ace/src/mode-curly.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-d.js b/htdocs/includes/ace/src/mode-d.js index 8615c468b48..15379fb9992 100644 --- a/htdocs/includes/ace/src/mode-d.js +++ b/htdocs/includes/ace/src/mode-d.js @@ -308,7 +308,7 @@ var DHighlightRules = function() { regex: '[a-zA-Z]+' }, { token: 'string', - regex: '".*"' + regex: '"[^"]*"' }, { token: 'comment', regex: '//.*$' diff --git a/htdocs/includes/ace/src/mode-dart.js b/htdocs/includes/ace/src/mode-dart.js index 4a228361e6e..9abd9ecc054 100644 --- a/htdocs/includes/ace/src/mode-dart.js +++ b/htdocs/includes/ace/src/mode-dart.js @@ -65,7 +65,7 @@ var c_cppHighlightRules = function() { var storageType = ( "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + - "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|" + + "_Imaginary|int|int8_t|int16_t|int32_t|int64_t|long|short|signed|size_t|struct|typedef|uint8_t|uint16_t|uint32_t|uint64_t|union|unsigned|void|" + "class|wchar_t|template|char16_t|char32_t" ); @@ -489,6 +489,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/c_cpp"; + this.snippetFileId = "ace/snippets/c_cpp"; }).call(Mode.prototype); exports.Mode = Mode; @@ -700,6 +701,7 @@ oop.inherits(Mode, CMode); this.lineCommentStart = "//"; this.blockComment = {start: "/*", end: "*/"}; this.$id = "ace/mode/dart"; + this.snippetFileId = "ace/snippets/dart"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-diff.js b/htdocs/includes/ace/src/mode-diff.js index b8237149bef..8a0ec7e722a 100644 --- a/htdocs/includes/ace/src/mode-diff.js +++ b/htdocs/includes/ace/src/mode-diff.js @@ -132,6 +132,7 @@ oop.inherits(Mode, TextMode); (function() { this.$id = "ace/mode/diff"; + this.snippetFileId = "ace/snippets/diff"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-django.js b/htdocs/includes/ace/src/mode-django.js index 81ce28dc73f..3a5d519bda7 100644 --- a/htdocs/includes/ace/src/mode-django.js +++ b/htdocs/includes/ace/src/mode-django.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2578,6 +2581,7 @@ oop.inherits(Mode, HtmlMode); (function() { this.$id = "ace/mode/django"; + this.snippetFileId = "ace/snippets/django"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-dockerfile.js b/htdocs/includes/ace/src/mode-dockerfile.js index 6b4e85c871b..26d64de860b 100644 --- a/htdocs/includes/ace/src/mode-dockerfile.js +++ b/htdocs/includes/ace/src/mode-dockerfile.js @@ -435,6 +435,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/sh"; + this.snippetFileId = "ace/snippets/sh"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-drools.js b/htdocs/includes/ace/src/mode-drools.js index d208011c997..adcc08f45f7 100644 --- a/htdocs/includes/ace/src/mode-drools.js +++ b/htdocs/includes/ace/src/mode-drools.js @@ -168,7 +168,7 @@ var JavaHighlightRules = function() { regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + regex : "!|\\$|%|&|\\||\\^|\\*|\\/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?|\\:|\\*=|\\/=|%=|\\+=|\\-=|&=|\\|=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" }, { token : "lparen", regex : "[[({]" @@ -483,6 +483,7 @@ oop.inherits(Mode, TextMode); (function() { this.lineCommentStart = "//"; this.$id = "ace/mode/drools"; + this.snippetFileId = "ace/snippets/drools"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-edifact.js b/htdocs/includes/ace/src/mode-edifact.js index cffe68e2532..3fc865aee9a 100644 --- a/htdocs/includes/ace/src/mode-edifact.js +++ b/htdocs/includes/ace/src/mode-edifact.js @@ -152,6 +152,7 @@ oop.inherits(Mode, TextMode); (function() { this.$id = "ace/mode/edifact"; + this.snippetFileId = "ace/snippets/edifact"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-ejs.js b/htdocs/includes/ace/src/mode-ejs.js index 95323019651..5825e8385ca 100644 --- a/htdocs/includes/ace/src/mode-ejs.js +++ b/htdocs/includes/ace/src/mode-ejs.js @@ -1264,6 +1264,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1601,6 +1602,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2508,17 +2511,17 @@ var constantOtherSymbol = exports.constantOtherSymbol = { regex : "[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?" }; -var qString = exports.qString = { +exports.qString = { token : "string", // single line regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" }; -var qqString = exports.qqString = { +exports.qqString = { token : "string", // single line regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' }; -var tString = exports.tString = { +exports.tString = { token : "string", // backtick string regex : "[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]" }; @@ -2528,9 +2531,34 @@ var constantNumericHex = exports.constantNumericHex = { regex : "0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b" }; +var constantNumericBinary = exports.constantNumericBinary = { + token: "constant.numeric", + regex: /\b(0[bB][01](?:[01]|_(?=[01]))*)\b/ +}; + +var constantNumericDecimal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[dD](?:[1-9](?:[\d]|_(?=[\d]))*|0))\b/ +}; + +var constantNumericOctal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[oO]?(?:[1-7](?:[0-7]|_(?=[0-7]))*|0))\b/ +}; + +var constantNumericRational = exports.constantNumericRational = { + token: "constant.numeric", //rational + complex + regex: /\b([\d]+(?:[./][\d]+)?ri?)\b/ +}; + +var constantNumericComplex = exports.constantNumericComplex = { + token: "constant.numeric", //simple complex numbers + regex: /\b([\d]i)\b/ +}; + var constantNumericFloat = exports.constantNumericFloat = { - token : "constant.numeric", // float - regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b" + token : "constant.numeric", // float + complex + regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?i?\\b" }; var instanceVariable = exports.instanceVariable = { @@ -2570,18 +2598,19 @@ var RubyHighlightRules = function() { "filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|" + "translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|" + "cache|expire_fragment|expire_cache_for|observe|cache_sweeper|" + - "has_many|has_one|belongs_to|has_and_belongs_to_many" + "has_many|has_one|belongs_to|has_and_belongs_to_many|p|warn|refine|using|module_function|extend|alias_method|" + + "private_class_method|remove_method|undef_method" ); var keywords = ( "alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|" + "__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|" + - "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield" + "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|__ENCODING__|prepend" ); var buildinConstants = ( "true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|" + - "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING" + "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING|RUBY_PATCHLEVEL|RUBY_REVISION|RUBY_COPYRIGHT|RUBY_ENGINE|RUBY_ENGINE_VERSION|RUBY_DESCRIPTION" ); var builtinVariables = ( @@ -2597,126 +2626,191 @@ var RubyHighlightRules = function() { "invalid.deprecated": "debugger" // TODO is this a remnant from js mode? }, "identifier"); + var escapedChars = "\\\\(?:n(?:[1-7][0-7]{0,2}|0)|[nsrtvfbae'\"\\\\]|c(?:\\\\M-)?.|M-(?:\\\\C-|\\\\c)?.|C-(?:\\\\M-)?.|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}(?:\\s[\\da-fA-F]{1,6})*})"; + + var closeParen = { + "(": ")", + "[": "]", + "{": "}", + "<": ">", + "^": "^", + "|": "|", + "%": "%" + }; + this.$rules = { - "start" : [ + "start": [ { - token : "comment", - regex : "#.*$" + token: "comment", + regex: "#.*$" }, { - token : "comment", // multi line comment - regex : "^=begin(?:$|\\s.*$)", - next : "comment" + token: "comment.multiline", // multi line comment + regex: "^=begin(?=$|\\s.*$)", + next: "comment" }, { - token : "string.regexp", - regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" + token: "string.regexp", + regex: /[/](?=.*\/)/, + next: "regex" }, [{ - regex: "[{}]", onMatch: function(val, state, stack) { - this.next = val == "{" ? this.nextState : ""; - if (val == "{" && stack.length) { - stack.unshift("start", state); - return "paren.lparen"; - } - if (val == "}" && stack.length) { - stack.shift(); - this.next = stack.shift(); - if (this.next.indexOf("string") != -1) - return "paren.end"; - } - return val == "{" ? "paren.lparen" : "paren.rparen"; - }, - nextState: "start" - }, { - token : "string.start", - regex : /"/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(")/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /"/, - next : "pop" + token: "string.end", + regex: /"/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /`/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: "string.start", + regex: /`/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /`/, - next : "pop" + token: "string.end", + regex: /`/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /'/, - push : [{ - token : "constant.language.escape", - regex : /\\['\\]/ - }, { - token : "string.end", - regex : /'/, - next : "pop" + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(')/, + push: [{ + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "string.end", + regex: /'/, + next: "pop" }, { defaultToken: "string" }] + }, { + token: "string.start",//doesn't see any differences between strings and array of strings in highlighting + regex: /%[qwx]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithoutInterpolation"; + return this.token; + } + }, { + token: "string.start", //doesn't see any differences between strings and array of strings in highlighting + regex: /%[QWX]?([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[si]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithoutInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[SI]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithInterpolation"; + return this.token; + } + }, { + token: "string.regexp", + regex: /%[r]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "rState"; + return this.token; + } }], { - token : "text", // namespaces aren't symbols - regex : "::" + token: "punctuation", // namespaces aren't symbols + regex: "::" + }, + instanceVariable, + { + token: "variable.global", // global variable + regex: "[$][a-zA-Z_\\d]+" }, { - token : "variable.instance", // instance variable - regex : "@{1,2}[a-zA-Z_\\d]+" + token: "support.class", // class name + regex: "[A-Z][a-zA-Z_\\d]*" }, { - token : "support.class", // class name - regex : "[A-Z][a-zA-Z_\\d]+" + token: ["punctuation.operator", "support.function"], + regex: /(\.)([a-zA-Z_\d]+)(?=\()/ + }, { + token: ["punctuation.operator", "identifier"], + regex: /(\.)([a-zA-Z_][a-zA-Z_\d]*)/ + }, { + token: "string.character", + regex: "\\B\\?(?:" + escapedChars + "|\\S)" + }, { + token: "punctuation.operator", + regex: /\?(?=.+:)/ }, + constantNumericRational, + constantNumericComplex, constantOtherSymbol, constantNumericHex, constantNumericFloat, - + constantNumericBinary, + constantNumericDecimal, + constantNumericOctal, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" + token: "constant.language.boolean", + regex: "(?:true|false)\\b" }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + token: keywordMapper, + regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { - token : "punctuation.separator.key-value", - regex : "=>" + token: "punctuation.separator.key-value", + regex: "=>" }, { stateName: "heredoc", - onMatch : function(value, currentState, stack) { - var next = value[2] == '-' ? "indentedHeredoc" : "heredoc"; + onMatch: function (value, currentState, stack) { + var next = (value[2] == '-' || value[2] == '~') ? "indentedHeredoc" : "heredoc"; var tokens = value.split(this.splitRegex); stack.push(next, tokens[3]); return [ - {type:"constant", value: tokens[1]}, - {type:"string", value: tokens[2]}, - {type:"support.class", value: tokens[3]}, - {type:"string", value: tokens[4]} + {type: "constant", value: tokens[1]}, + {type: "string", value: tokens[2]}, + {type: "support.class", value: tokens[3]}, + {type: "string", value: tokens[4]} ]; }, - regex : "(<<-?)(['\"`]?)([\\w]+)(['\"`]?)", + regex: "(<<[-~]?)(['\"`]?)([\\w]+)(['\"`]?)", rules: { heredoc: [{ - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -2733,7 +2827,7 @@ var RubyHighlightRules = function() { token: "string", regex: "^ +" }, { - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -2748,38 +2842,261 @@ var RubyHighlightRules = function() { }] } }, { - regex : "$", - token : "empty", - next : function(currentState, stack) { + regex: "$", + token: "empty", + next: function(currentState, stack) { if (stack[0] === "heredoc" || stack[0] === "indentedHeredoc") return stack[0]; return currentState; } + }, { + token: "keyword.operator", + regex: "!|\\$|%|&|\\*|/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\||\\b(?:in|instanceof|new|delete|typeof|void)" }, { - token : "string.character", - regex : "\\B\\?." + token: "paren.lparen", + regex: "[[({]" }, { - token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + token: "paren.rparen", + regex: "[\\])}]", + onMatch: function(value, currentState, stack) { + this.next = ''; + if (value == "}" && stack.length > 1 && stack[1] != "start") { + stack.shift(); + this.next = stack.shift(); + } + return this.token; + } }, { - token : "paren.lparen", - regex : "[[({]" + token: "text", + regex: "\\s+" }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" + token: "punctuation.operator", + regex: /[?:,;.]/ } ], - "comment" : [ + "comment": [ { - token : "comment", // closing comment - regex : "^=end(?:$|\\s.*$)", - next : "start" + token: "comment.multiline", // closing comment + regex: "^=end(?=$|\\s.*$)", + next: "start" }, { - token : "comment", // comment spanning whole line - regex : ".+" + token: "comment", // comment spanning whole line + regex: ".+" + } + ], + "qStateWithInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "qStateWithoutInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "sStateWithoutInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "sStateWithInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "rState": [{ + token: "string.regexp",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.language.escape"; + } + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.regexp", + regex: /\// + }, { + token: "string.regexp", + regex: /[)\]>}^|%][imxouesn]*/, onMatch: function (val, state, stack) { + if (stack.length && val[0] === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.language.escape"; + } + }, + {include: "regex"}, + { + defaultToken: "string.regexp" + }], + "regex": [ + {// character classes + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "constant.language.escape", + regex: /\\[AGbBzZ]/ + }, { + token: "constant.language.escape", + regex: /\\g<[a-zA-Z0-9]*>/ + }, { + token: ["constant.language.escape", "regexp.keyword", "constant.language.escape"], + regex: /(\\p{\^?)(Alnum|Alpha|Blank|Cntrl|Digit|Graph|Lower|Print|Punct|Space|Upper|XDigit|Word|ASCII|Any|Assigned|Arabic|Armenian|Balinese|Bengali|Bopomofo|Braille|Buginese|Buhid|Canadian_Aboriginal|Carian|Cham|Cherokee|Common|Coptic|Cuneiform|Cypriot|Cyrillic|Deseret|Devanagari|Ethiopic|Georgian|Glagolitic|Gothic|Greek|Gujarati|Gurmukhi|Han|Hangul|Hanunoo|Hebrew|Hiragana|Inherited|Kannada|Katakana|Kayah_Li|Kharoshthi|Khmer|Lao|Latin|Lepcha|Limbu|Linear_B|Lycian|Lydian|Malayalam|Mongolian|Myanmar|New_Tai_Lue|Nko|Ogham|Ol_Chiki|Old_Italic|Old_Persian|Oriya|Osmanya|Phags_Pa|Phoenician|Rejang|Runic|Saurashtra|Shavian|Sinhala|Sundanese|Syloti_Nagri|Syriac|Tagalog|Tagbanwa|Tai_Le|Tamil|Telugu|Thaana|Thai|Tibetan|Tifinagh|Ugaritic|Vai|Yi|Ll|Lm|Lt|Lu|Lo|Mn|Mc|Me|Nd|Nl|Pc|Pd|Ps|Pe|Pi|Pf|Po|No|Sm|Sc|Sk|So|Zs|Zl|Zp|Cc|Cf|Cn|Co|Cs|N|L|M|P|S|Z|C)(})/ + }, { + token: ["constant.language.escape", "invalid", "constant.language.escape"], + regex: /(\\p{\^?)([^/]*)(})/ + }, {// escapes + token: "regexp.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, {// flag + token: "string.regexp", + regex: /[/][imxouesn]*/, + next: "start" + }, {// invalid operators + token: "invalid", + regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ + }, {// operators + token: "constant.language.escape", + regex: /\(\?(?:[:=!>]|<'?[a-zA-Z]*'?>|<[=!])|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ + }, { + token: "constant.language.delimiter", + regex: /\|/ + }, { + token: "regexp.keyword", + regex: /\[\[:(?:alnum|alpha|blank|cntrl|digit|graph|lower|print|punct|space|upper|xdigit|word|ascii):\]\]/ + }, { + token: "constant.language.escape", + regex: /\[\^?/, + push: "regex_character_class" + }, { + defaultToken: "string.regexp" + } + ], + "regex_character_class": [ + { + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "regexp.charclass.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "constant.language.escape", + regex: /&?&?\[\^?/, + push: "regex_character_class" + }, { + token: "constant.language.escape", + regex: "]", + next: "pop" + }, { + token: "constant.language.escape", + regex: "-" + }, { + defaultToken: "string.regexp.characterclass" } ] }; @@ -2792,94 +3109,271 @@ oop.inherits(RubyHighlightRules, TextHighlightRules); exports.RubyHighlightRules = RubyHighlightRules; }); -define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"], function(require, exports, module) { +define("ace/mode/folding/ruby",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"], function (require, exports, module) { "use strict"; var oop = require("../../lib/oop"); var BaseFoldMode = require("./fold_mode").FoldMode; var Range = require("../../range").Range; +var TokenIterator = require("../../token_iterator").TokenIterator; + + +var FoldMode = exports.FoldMode = function () { +}; -var FoldMode = exports.FoldMode = function() {}; oop.inherits(FoldMode, BaseFoldMode); -(function() { - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var range = this.indentationBlock(session, row); - if (range) - return range; - - var re = /\S/; - var line = session.getLine(row); - var startLevel = line.search(re); - if (startLevel == -1 || line[startLevel] != "#") - return; - - var startColumn = line.length; - var maxRow = session.getLength(); - var startRow = row; - var endRow = row; - - while (++row < maxRow) { - line = session.getLine(row); - var level = line.search(re); - - if (level == -1) - continue; - - if (line[level] != "#") - break; - - endRow = row; - } - - if (endRow > startRow) { - var endColumn = session.getLine(endRow).length; - return new Range(startRow, startColumn, endRow, endColumn); - } +(function () { + this.indentKeywords = { + "class": 1, + "def": 1, + "module": 1, + "do": 1, + "unless": 1, + "if": 1, + "while": 1, + "for": 1, + "until": 1, + "begin": 1, + "else": 0, + "elsif": 0, + "rescue": 0, + "ensure": 0, + "when": 0, + "end": -1, + "case": 1, + "=begin": 1, + "=end": -1 }; - this.getFoldWidget = function(session, foldStyle, row) { - var line = session.getLine(row); - var indent = line.search(/\S/); - var next = session.getLine(row + 1); - var prev = session.getLine(row - 1); - var prevIndent = prev.search(/\S/); - var nextIndent = next.search(/\S/); - if (indent == -1) { - session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : ""; - return ""; - } - if (prevIndent == -1) { - if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") { - session.foldWidgets[row - 1] = ""; - session.foldWidgets[row + 1] = ""; + this.foldingStartMarker = /(?:\s|^)(def|do|while|class|unless|module|if|for|until|begin|else|elsif|case|rescue|ensure|when)\b|({\s*$)|(=begin)/; + this.foldingStopMarker = /(=end(?=$|\s.*$))|(^\s*})|\b(end)\b/; + + this.getFoldWidget = function (session, foldStyle, row) { + var line = session.getLine(row); + var isStart = this.foldingStartMarker.test(line); + var isEnd = this.foldingStopMarker.test(line); + + if (isStart && !isEnd) { + var match = line.match(this.foldingStartMarker); + if (match[1]) { + if (match[1] == "if" || match[1] == "else" || match[1] == "while" || match[1] == "until" || match[1] == "unless") { + if (match[1] == "else" && /^\s*else\s*$/.test(line) === false) { + return; + } + if (/^\s*(?:if|else|while|until|unless)\s*/.test(line) === false) { + return; + } + } + + if (match[1] == "when") { + if (/\sthen\s/.test(line) === true) { + return; + } + } + if (session.getTokenAt(row, match.index + 2).type === "keyword") + return "start"; + } else if (match[3]) { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return "start"; + } else { return "start"; } - } else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") { - if (session.getLine(row - 2).search(/\S/) == -1) { - session.foldWidgets[row - 1] = "start"; - session.foldWidgets[row + 1] = ""; - return ""; + } + if (foldStyle != "markbeginend" || !isEnd || isStart && isEnd) + return ""; + + var match = line.match(this.foldingStopMarker); + if (match[3] === "end") { + if (session.getTokenAt(row, match.index + 1).type === "keyword") + return "end"; + } else if (match[1]) { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return "end"; + } else + return "end"; + }; + + this.getFoldWidgetRange = function (session, foldStyle, row) { + var line = session.doc.getLine(row); + var match = this.foldingStartMarker.exec(line); + if (match) { + if (match[1] || match[3]) + return this.rubyBlock(session, row, match.index + 2); + + return this.openingBracketBlock(session, "{", row, match.index); + } + + var match = this.foldingStopMarker.exec(line); + if (match) { + if (match[3] === "end") { + if (session.getTokenAt(row, match.index + 1).type === "keyword") + return this.rubyBlock(session, row, match.index + 1); + } + + if (match[1] === "=end") { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return this.rubyBlock(session, row, match.index + 1); + } + + return this.closingBracketBlock(session, "}", row, match.index + match[0].length); + } + }; + + this.rubyBlock = function (session, row, column, tokenRange) { + var stream = new TokenIterator(session, row, column); + + var token = stream.getCurrentToken(); + if (!token || (token.type != "keyword" && token.type != "comment.multiline")) + return; + + var val = token.value; + var line = session.getLine(row); + switch (token.value) { + case "if": + case "unless": + case "while": + case "until": + var checkToken = new RegExp("^\\s*" + token.value); + if (!checkToken.test(line)) { + return; + } + var dir = this.indentKeywords[val]; + break; + case "when": + if (/\sthen\s/.test(line)) { + return; + } + case "elsif": + case "rescue": + case "ensure": + var dir = 1; + break; + case "else": + var checkToken = new RegExp("^\\s*" + token.value + "\\s*$"); + if (!checkToken.test(line)) { + return; + } + var dir = 1; + break; + default: + var dir = this.indentKeywords[val]; + break; + } + + var stack = [val]; + if (!dir) + return; + + var startColumn = dir === -1 ? session.getLine(row - 1).length : session.getLine(row).length; + var startRow = row; + var ranges = []; + ranges.push(stream.getCurrentTokenRange()); + + stream.step = dir === -1 ? stream.stepBackward : stream.stepForward; + if (token.type == "comment.multiline") { + while (token = stream.step()) { + if (token.type !== "comment.multiline") + continue; + if (dir == 1) { + startColumn = 6; + if (token.value == "=end") { + break; + } + } else { + if (token.value == "=begin") { + break; + } + } + } + } else { + while (token = stream.step()) { + var ignore = false; + if (token.type !== "keyword") + continue; + var level = dir * this.indentKeywords[token.value]; + line = session.getLine(stream.getCurrentTokenRow()); + switch (token.value) { + case "do": + for (var i = stream.$tokenIndex - 1; i >= 0; i--) { + var prevToken = stream.$rowTokens[i]; + if (prevToken && (prevToken.value == "while" || prevToken.value == "until" || prevToken.value == "for")) { + level = 0; + break; + } + } + break; + case "else": + var checkToken = new RegExp("^\\s*" + token.value + "\\s*$"); + if (!checkToken.test(line) || val == "case") { + level = 0; + ignore = true; + } + break; + case "if": + case "unless": + case "while": + case "until": + var checkToken = new RegExp("^\\s*" + token.value); + if (!checkToken.test(line)) { + level = 0; + ignore = true; + } + break; + case "when": + if (/\sthen\s/.test(line) || val == "case") { + level = 0; + ignore = true; + } + break; + } + + if (level > 0) { + stack.unshift(token.value); + } else if (level <= 0 && ignore === false) { + stack.shift(); + if (!stack.length) { + if ((val == "while" || val == "until" || val == "for") && token.value != "do") { + break; + } + if (token.value == "do" && dir == -1 && level != 0) + break; + if (token.value != "do") + break; + } + + if (level === 0) { + stack.unshift(token.value); + } + } } } - if (prevIndent!= -1 && prevIndent < indent) - session.foldWidgets[row - 1] = "start"; - else - session.foldWidgets[row - 1] = ""; + if (!token) + return null; - if (indent < nextIndent) - return "start"; - else - return ""; + if (tokenRange) { + ranges.push(stream.getCurrentTokenRange()); + return ranges; + } + + var row = stream.getCurrentTokenRow(); + if (dir === -1) { + if (token.type === "comment.multiline") { + var endColumn = 6; + } else { + var endColumn = session.getLine(row).length; + } + return new Range(row, endColumn, startRow - 1, startColumn); + } else + return new Range(startRow, startColumn, row - 1, session.getLine(row - 1).length); }; }).call(FoldMode.prototype); }); -define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/coffee"], function(require, exports, module) { +define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/ruby"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); @@ -2888,13 +3382,14 @@ var RubyHighlightRules = require("./ruby_highlight_rules").RubyHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; var Range = require("../range").Range; var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var FoldMode = require("./folding/coffee").FoldMode; +var FoldMode = require("./folding/ruby").FoldMode; var Mode = function() { this.HighlightRules = RubyHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.$behaviour = new CstyleBehaviour(); this.foldingRules = new FoldMode(); + this.indentKeywords = this.foldingRules.indentKeywords; }; oop.inherits(Mode, TextMode); @@ -2909,7 +3404,7 @@ oop.inherits(Mode, TextMode); var tokenizedLine = this.getTokenizer().getLineTokens(line, state); var tokens = tokenizedLine.tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { + if (tokens.length && tokens[tokens.length - 1].type == "comment") { return indent; } @@ -2917,7 +3412,7 @@ oop.inherits(Mode, TextMode); var match = line.match(/^.*[\{\(\[]\s*$/); var startingClassOrMethod = line.match(/^\s*(class|def|module)\s.*$/); var startingDoBlock = line.match(/.*do(\s*|\s+\|.*\|\s*)$/); - var startingConditional = line.match(/^\s*(if|else|when)\s*/); + var startingConditional = line.match(/^\s*(if|else|when|elsif|unless|while|for|begin|rescue|ensure)\s*/); if (match || startingClassOrMethod || startingDoBlock || startingConditional) { indent += tab; } @@ -2927,7 +3422,7 @@ oop.inherits(Mode, TextMode); }; this.checkOutdent = function(state, line, input) { - return /^\s+(end|else)$/.test(line + input) || this.$outdent.checkOutdent(line, input); + return /^\s+(end|else|rescue|ensure)$/.test(line + input) || this.$outdent.checkOutdent(line, input); }; this.autoOutdent = function(state, session, row) { @@ -2940,11 +3435,24 @@ oop.inherits(Mode, TextMode); var tab = session.getTabString(); if (prevIndent.length <= indent.length) { if (indent.slice(-tab.length) == tab) - session.remove(new Range(row, indent.length-tab.length, row, indent.length)); + session.remove(new Range(row, indent.length - tab.length, row, indent.length)); } }; + this.getMatching = function(session, row, column) { + if (row == undefined) { + var pos = session.selection.lead; + column = pos.column; + row = pos.row; + } + + var startToken = session.getTokenAt(row, column); + if (startToken && startToken.value in this.indentKeywords) + return this.foldingRules.rubyBlock(session, row, column, true); + }; + this.$id = "ace/mode/ruby"; + this.snippetFileId = "ace/snippets/ruby"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-erlang.js b/htdocs/includes/ace/src/mode-erlang.js index 3f91c0098c8..fd1143d9e87 100644 --- a/htdocs/includes/ace/src/mode-erlang.js +++ b/htdocs/includes/ace/src/mode-erlang.js @@ -996,6 +996,7 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = "%"; this.blockComment = null; this.$id = "ace/mode/erlang"; + this.snippetFileId = "ace/snippets/erlang"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-fsl.js b/htdocs/includes/ace/src/mode-fsl.js index 9bfde7ebaba..9bd21d96c15 100644 --- a/htdocs/includes/ace/src/mode-fsl.js +++ b/htdocs/includes/ace/src/mode-fsl.js @@ -245,6 +245,7 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = "//"; this.blockComment = {start: "/*", end: "*/"}; this.$id = "ace/mode/fsl"; + this.snippetFileId = "ace/snippets/fsl"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-glsl.js b/htdocs/includes/ace/src/mode-glsl.js index b5bc6e699e1..f5d0c815c94 100644 --- a/htdocs/includes/ace/src/mode-glsl.js +++ b/htdocs/includes/ace/src/mode-glsl.js @@ -65,7 +65,7 @@ var c_cppHighlightRules = function() { var storageType = ( "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + - "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|" + + "_Imaginary|int|int8_t|int16_t|int32_t|int64_t|long|short|signed|size_t|struct|typedef|uint8_t|uint16_t|uint32_t|uint64_t|union|unsigned|void|" + "class|wchar_t|template|char16_t|char32_t" ); @@ -489,6 +489,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/c_cpp"; + this.snippetFileId = "ace/snippets/c_cpp"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-gobstones.js b/htdocs/includes/ace/src/mode-gobstones.js index 1ab66a8b898..cd2fc3aaf82 100644 --- a/htdocs/includes/ace/src/mode-gobstones.js +++ b/htdocs/includes/ace/src/mode-gobstones.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1075,6 +1076,7 @@ oop.inherits(Mode, JavaScriptMode); }; this.$id = "ace/mode/gobstones"; + this.snippetFileId = "ace/snippets/gobstones"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-graphqlschema.js b/htdocs/includes/ace/src/mode-graphqlschema.js index e252b70c78c..cf0931e3c8a 100644 --- a/htdocs/includes/ace/src/mode-graphqlschema.js +++ b/htdocs/includes/ace/src/mode-graphqlschema.js @@ -200,6 +200,7 @@ oop.inherits(Mode, TextMode); (function() { this.lineCommentStart = "#"; this.$id = "ace/mode/graphqlschema"; + this.snippetFileId = "ace/snippets/graphqlschema"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-groovy.js b/htdocs/includes/ace/src/mode-groovy.js index 4c48df1f925..8395de92087 100644 --- a/htdocs/includes/ace/src/mode-groovy.js +++ b/htdocs/includes/ace/src/mode-groovy.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-haml.js b/htdocs/includes/ace/src/mode-haml.js index e6821c8a45e..db8e69343ca 100644 --- a/htdocs/includes/ace/src/mode-haml.js +++ b/htdocs/includes/ace/src/mode-haml.js @@ -1012,17 +1012,17 @@ var constantOtherSymbol = exports.constantOtherSymbol = { regex : "[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?" }; -var qString = exports.qString = { +exports.qString = { token : "string", // single line regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" }; -var qqString = exports.qqString = { +exports.qqString = { token : "string", // single line regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' }; -var tString = exports.tString = { +exports.tString = { token : "string", // backtick string regex : "[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]" }; @@ -1032,9 +1032,34 @@ var constantNumericHex = exports.constantNumericHex = { regex : "0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b" }; +var constantNumericBinary = exports.constantNumericBinary = { + token: "constant.numeric", + regex: /\b(0[bB][01](?:[01]|_(?=[01]))*)\b/ +}; + +var constantNumericDecimal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[dD](?:[1-9](?:[\d]|_(?=[\d]))*|0))\b/ +}; + +var constantNumericOctal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[oO]?(?:[1-7](?:[0-7]|_(?=[0-7]))*|0))\b/ +}; + +var constantNumericRational = exports.constantNumericRational = { + token: "constant.numeric", //rational + complex + regex: /\b([\d]+(?:[./][\d]+)?ri?)\b/ +}; + +var constantNumericComplex = exports.constantNumericComplex = { + token: "constant.numeric", //simple complex numbers + regex: /\b([\d]i)\b/ +}; + var constantNumericFloat = exports.constantNumericFloat = { - token : "constant.numeric", // float - regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b" + token : "constant.numeric", // float + complex + regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?i?\\b" }; var instanceVariable = exports.instanceVariable = { @@ -1074,18 +1099,19 @@ var RubyHighlightRules = function() { "filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|" + "translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|" + "cache|expire_fragment|expire_cache_for|observe|cache_sweeper|" + - "has_many|has_one|belongs_to|has_and_belongs_to_many" + "has_many|has_one|belongs_to|has_and_belongs_to_many|p|warn|refine|using|module_function|extend|alias_method|" + + "private_class_method|remove_method|undef_method" ); var keywords = ( "alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|" + "__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|" + - "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield" + "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|__ENCODING__|prepend" ); var buildinConstants = ( "true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|" + - "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING" + "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING|RUBY_PATCHLEVEL|RUBY_REVISION|RUBY_COPYRIGHT|RUBY_ENGINE|RUBY_ENGINE_VERSION|RUBY_DESCRIPTION" ); var builtinVariables = ( @@ -1101,126 +1127,191 @@ var RubyHighlightRules = function() { "invalid.deprecated": "debugger" // TODO is this a remnant from js mode? }, "identifier"); + var escapedChars = "\\\\(?:n(?:[1-7][0-7]{0,2}|0)|[nsrtvfbae'\"\\\\]|c(?:\\\\M-)?.|M-(?:\\\\C-|\\\\c)?.|C-(?:\\\\M-)?.|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}(?:\\s[\\da-fA-F]{1,6})*})"; + + var closeParen = { + "(": ")", + "[": "]", + "{": "}", + "<": ">", + "^": "^", + "|": "|", + "%": "%" + }; + this.$rules = { - "start" : [ + "start": [ { - token : "comment", - regex : "#.*$" + token: "comment", + regex: "#.*$" }, { - token : "comment", // multi line comment - regex : "^=begin(?:$|\\s.*$)", - next : "comment" + token: "comment.multiline", // multi line comment + regex: "^=begin(?=$|\\s.*$)", + next: "comment" }, { - token : "string.regexp", - regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" + token: "string.regexp", + regex: /[/](?=.*\/)/, + next: "regex" }, [{ - regex: "[{}]", onMatch: function(val, state, stack) { - this.next = val == "{" ? this.nextState : ""; - if (val == "{" && stack.length) { - stack.unshift("start", state); - return "paren.lparen"; - } - if (val == "}" && stack.length) { - stack.shift(); - this.next = stack.shift(); - if (this.next.indexOf("string") != -1) - return "paren.end"; - } - return val == "{" ? "paren.lparen" : "paren.rparen"; - }, - nextState: "start" - }, { - token : "string.start", - regex : /"/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(")/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /"/, - next : "pop" + token: "string.end", + regex: /"/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /`/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: "string.start", + regex: /`/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /`/, - next : "pop" + token: "string.end", + regex: /`/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /'/, - push : [{ - token : "constant.language.escape", - regex : /\\['\\]/ - }, { - token : "string.end", - regex : /'/, - next : "pop" + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(')/, + push: [{ + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "string.end", + regex: /'/, + next: "pop" }, { defaultToken: "string" }] + }, { + token: "string.start",//doesn't see any differences between strings and array of strings in highlighting + regex: /%[qwx]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithoutInterpolation"; + return this.token; + } + }, { + token: "string.start", //doesn't see any differences between strings and array of strings in highlighting + regex: /%[QWX]?([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[si]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithoutInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[SI]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithInterpolation"; + return this.token; + } + }, { + token: "string.regexp", + regex: /%[r]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "rState"; + return this.token; + } }], { - token : "text", // namespaces aren't symbols - regex : "::" + token: "punctuation", // namespaces aren't symbols + regex: "::" + }, + instanceVariable, + { + token: "variable.global", // global variable + regex: "[$][a-zA-Z_\\d]+" }, { - token : "variable.instance", // instance variable - regex : "@{1,2}[a-zA-Z_\\d]+" + token: "support.class", // class name + regex: "[A-Z][a-zA-Z_\\d]*" }, { - token : "support.class", // class name - regex : "[A-Z][a-zA-Z_\\d]+" + token: ["punctuation.operator", "support.function"], + regex: /(\.)([a-zA-Z_\d]+)(?=\()/ + }, { + token: ["punctuation.operator", "identifier"], + regex: /(\.)([a-zA-Z_][a-zA-Z_\d]*)/ + }, { + token: "string.character", + regex: "\\B\\?(?:" + escapedChars + "|\\S)" + }, { + token: "punctuation.operator", + regex: /\?(?=.+:)/ }, + constantNumericRational, + constantNumericComplex, constantOtherSymbol, constantNumericHex, constantNumericFloat, - + constantNumericBinary, + constantNumericDecimal, + constantNumericOctal, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" + token: "constant.language.boolean", + regex: "(?:true|false)\\b" }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + token: keywordMapper, + regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { - token : "punctuation.separator.key-value", - regex : "=>" + token: "punctuation.separator.key-value", + regex: "=>" }, { stateName: "heredoc", - onMatch : function(value, currentState, stack) { - var next = value[2] == '-' ? "indentedHeredoc" : "heredoc"; + onMatch: function (value, currentState, stack) { + var next = (value[2] == '-' || value[2] == '~') ? "indentedHeredoc" : "heredoc"; var tokens = value.split(this.splitRegex); stack.push(next, tokens[3]); return [ - {type:"constant", value: tokens[1]}, - {type:"string", value: tokens[2]}, - {type:"support.class", value: tokens[3]}, - {type:"string", value: tokens[4]} + {type: "constant", value: tokens[1]}, + {type: "string", value: tokens[2]}, + {type: "support.class", value: tokens[3]}, + {type: "string", value: tokens[4]} ]; }, - regex : "(<<-?)(['\"`]?)([\\w]+)(['\"`]?)", + regex: "(<<[-~]?)(['\"`]?)([\\w]+)(['\"`]?)", rules: { heredoc: [{ - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -1237,7 +1328,7 @@ var RubyHighlightRules = function() { token: "string", regex: "^ +" }, { - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -1252,38 +1343,261 @@ var RubyHighlightRules = function() { }] } }, { - regex : "$", - token : "empty", - next : function(currentState, stack) { + regex: "$", + token: "empty", + next: function(currentState, stack) { if (stack[0] === "heredoc" || stack[0] === "indentedHeredoc") return stack[0]; return currentState; } + }, { + token: "keyword.operator", + regex: "!|\\$|%|&|\\*|/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\||\\b(?:in|instanceof|new|delete|typeof|void)" }, { - token : "string.character", - regex : "\\B\\?." + token: "paren.lparen", + regex: "[[({]" }, { - token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + token: "paren.rparen", + regex: "[\\])}]", + onMatch: function(value, currentState, stack) { + this.next = ''; + if (value == "}" && stack.length > 1 && stack[1] != "start") { + stack.shift(); + this.next = stack.shift(); + } + return this.token; + } }, { - token : "paren.lparen", - regex : "[[({]" + token: "text", + regex: "\\s+" }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" + token: "punctuation.operator", + regex: /[?:,;.]/ } ], - "comment" : [ + "comment": [ { - token : "comment", // closing comment - regex : "^=end(?:$|\\s.*$)", - next : "start" + token: "comment.multiline", // closing comment + regex: "^=end(?=$|\\s.*$)", + next: "start" }, { - token : "comment", // comment spanning whole line - regex : ".+" + token: "comment", // comment spanning whole line + regex: ".+" + } + ], + "qStateWithInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "qStateWithoutInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "sStateWithoutInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "sStateWithInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "rState": [{ + token: "string.regexp",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.language.escape"; + } + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.regexp", + regex: /\// + }, { + token: "string.regexp", + regex: /[)\]>}^|%][imxouesn]*/, onMatch: function (val, state, stack) { + if (stack.length && val[0] === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.language.escape"; + } + }, + {include: "regex"}, + { + defaultToken: "string.regexp" + }], + "regex": [ + {// character classes + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "constant.language.escape", + regex: /\\[AGbBzZ]/ + }, { + token: "constant.language.escape", + regex: /\\g<[a-zA-Z0-9]*>/ + }, { + token: ["constant.language.escape", "regexp.keyword", "constant.language.escape"], + regex: /(\\p{\^?)(Alnum|Alpha|Blank|Cntrl|Digit|Graph|Lower|Print|Punct|Space|Upper|XDigit|Word|ASCII|Any|Assigned|Arabic|Armenian|Balinese|Bengali|Bopomofo|Braille|Buginese|Buhid|Canadian_Aboriginal|Carian|Cham|Cherokee|Common|Coptic|Cuneiform|Cypriot|Cyrillic|Deseret|Devanagari|Ethiopic|Georgian|Glagolitic|Gothic|Greek|Gujarati|Gurmukhi|Han|Hangul|Hanunoo|Hebrew|Hiragana|Inherited|Kannada|Katakana|Kayah_Li|Kharoshthi|Khmer|Lao|Latin|Lepcha|Limbu|Linear_B|Lycian|Lydian|Malayalam|Mongolian|Myanmar|New_Tai_Lue|Nko|Ogham|Ol_Chiki|Old_Italic|Old_Persian|Oriya|Osmanya|Phags_Pa|Phoenician|Rejang|Runic|Saurashtra|Shavian|Sinhala|Sundanese|Syloti_Nagri|Syriac|Tagalog|Tagbanwa|Tai_Le|Tamil|Telugu|Thaana|Thai|Tibetan|Tifinagh|Ugaritic|Vai|Yi|Ll|Lm|Lt|Lu|Lo|Mn|Mc|Me|Nd|Nl|Pc|Pd|Ps|Pe|Pi|Pf|Po|No|Sm|Sc|Sk|So|Zs|Zl|Zp|Cc|Cf|Cn|Co|Cs|N|L|M|P|S|Z|C)(})/ + }, { + token: ["constant.language.escape", "invalid", "constant.language.escape"], + regex: /(\\p{\^?)([^/]*)(})/ + }, {// escapes + token: "regexp.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, {// flag + token: "string.regexp", + regex: /[/][imxouesn]*/, + next: "start" + }, {// invalid operators + token: "invalid", + regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ + }, {// operators + token: "constant.language.escape", + regex: /\(\?(?:[:=!>]|<'?[a-zA-Z]*'?>|<[=!])|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ + }, { + token: "constant.language.delimiter", + regex: /\|/ + }, { + token: "regexp.keyword", + regex: /\[\[:(?:alnum|alpha|blank|cntrl|digit|graph|lower|print|punct|space|upper|xdigit|word|ascii):\]\]/ + }, { + token: "constant.language.escape", + regex: /\[\^?/, + push: "regex_character_class" + }, { + defaultToken: "string.regexp" + } + ], + "regex_character_class": [ + { + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "regexp.charclass.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "constant.language.escape", + regex: /&?&?\[\^?/, + push: "regex_character_class" + }, { + token: "constant.language.escape", + regex: "]", + next: "pop" + }, { + token: "constant.language.escape", + regex: "-" + }, { + defaultToken: "string.regexp.characterclass" } ] }; @@ -1545,6 +1859,7 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = "//"; this.$id = "ace/mode/haml"; + this.snippetFileId = "ace/snippets/haml"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-handlebars.js b/htdocs/includes/ace/src/mode-handlebars.js index 620074baff2..ba8f7e015fc 100644 --- a/htdocs/includes/ace/src/mode-handlebars.js +++ b/htdocs/includes/ace/src/mode-handlebars.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-haskell.js b/htdocs/includes/ace/src/mode-haskell.js index af5eff5693a..bf5f1d6edb3 100644 --- a/htdocs/includes/ace/src/mode-haskell.js +++ b/htdocs/includes/ace/src/mode-haskell.js @@ -366,6 +366,7 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = "--"; this.blockComment = null; this.$id = "ace/mode/haskell"; + this.snippetFileId = "ace/snippets/haskell"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-html.js b/htdocs/includes/ace/src/mode-html.js index 2d7ddabbdaa..f8466c2ddb7 100644 --- a/htdocs/includes/ace/src/mode-html.js +++ b/htdocs/includes/ace/src/mode-html.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-html_elixir.js b/htdocs/includes/ace/src/mode-html_elixir.js index 5d80fcbbcef..53fa828bdde 100644 --- a/htdocs/includes/ace/src/mode-html_elixir.js +++ b/htdocs/includes/ace/src/mode-html_elixir.js @@ -1704,6 +1704,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2041,6 +2042,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2933,6 +2935,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-html_ruby.js b/htdocs/includes/ace/src/mode-html_ruby.js index ec77543f358..e3eb0f7761a 100644 --- a/htdocs/includes/ace/src/mode-html_ruby.js +++ b/htdocs/includes/ace/src/mode-html_ruby.js @@ -1012,17 +1012,17 @@ var constantOtherSymbol = exports.constantOtherSymbol = { regex : "[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?" }; -var qString = exports.qString = { +exports.qString = { token : "string", // single line regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" }; -var qqString = exports.qqString = { +exports.qqString = { token : "string", // single line regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' }; -var tString = exports.tString = { +exports.tString = { token : "string", // backtick string regex : "[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]" }; @@ -1032,9 +1032,34 @@ var constantNumericHex = exports.constantNumericHex = { regex : "0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b" }; +var constantNumericBinary = exports.constantNumericBinary = { + token: "constant.numeric", + regex: /\b(0[bB][01](?:[01]|_(?=[01]))*)\b/ +}; + +var constantNumericDecimal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[dD](?:[1-9](?:[\d]|_(?=[\d]))*|0))\b/ +}; + +var constantNumericOctal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[oO]?(?:[1-7](?:[0-7]|_(?=[0-7]))*|0))\b/ +}; + +var constantNumericRational = exports.constantNumericRational = { + token: "constant.numeric", //rational + complex + regex: /\b([\d]+(?:[./][\d]+)?ri?)\b/ +}; + +var constantNumericComplex = exports.constantNumericComplex = { + token: "constant.numeric", //simple complex numbers + regex: /\b([\d]i)\b/ +}; + var constantNumericFloat = exports.constantNumericFloat = { - token : "constant.numeric", // float - regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b" + token : "constant.numeric", // float + complex + regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?i?\\b" }; var instanceVariable = exports.instanceVariable = { @@ -1074,18 +1099,19 @@ var RubyHighlightRules = function() { "filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|" + "translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|" + "cache|expire_fragment|expire_cache_for|observe|cache_sweeper|" + - "has_many|has_one|belongs_to|has_and_belongs_to_many" + "has_many|has_one|belongs_to|has_and_belongs_to_many|p|warn|refine|using|module_function|extend|alias_method|" + + "private_class_method|remove_method|undef_method" ); var keywords = ( "alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|" + "__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|" + - "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield" + "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|__ENCODING__|prepend" ); var buildinConstants = ( "true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|" + - "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING" + "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING|RUBY_PATCHLEVEL|RUBY_REVISION|RUBY_COPYRIGHT|RUBY_ENGINE|RUBY_ENGINE_VERSION|RUBY_DESCRIPTION" ); var builtinVariables = ( @@ -1101,126 +1127,191 @@ var RubyHighlightRules = function() { "invalid.deprecated": "debugger" // TODO is this a remnant from js mode? }, "identifier"); + var escapedChars = "\\\\(?:n(?:[1-7][0-7]{0,2}|0)|[nsrtvfbae'\"\\\\]|c(?:\\\\M-)?.|M-(?:\\\\C-|\\\\c)?.|C-(?:\\\\M-)?.|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}(?:\\s[\\da-fA-F]{1,6})*})"; + + var closeParen = { + "(": ")", + "[": "]", + "{": "}", + "<": ">", + "^": "^", + "|": "|", + "%": "%" + }; + this.$rules = { - "start" : [ + "start": [ { - token : "comment", - regex : "#.*$" + token: "comment", + regex: "#.*$" }, { - token : "comment", // multi line comment - regex : "^=begin(?:$|\\s.*$)", - next : "comment" + token: "comment.multiline", // multi line comment + regex: "^=begin(?=$|\\s.*$)", + next: "comment" }, { - token : "string.regexp", - regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" + token: "string.regexp", + regex: /[/](?=.*\/)/, + next: "regex" }, [{ - regex: "[{}]", onMatch: function(val, state, stack) { - this.next = val == "{" ? this.nextState : ""; - if (val == "{" && stack.length) { - stack.unshift("start", state); - return "paren.lparen"; - } - if (val == "}" && stack.length) { - stack.shift(); - this.next = stack.shift(); - if (this.next.indexOf("string") != -1) - return "paren.end"; - } - return val == "{" ? "paren.lparen" : "paren.rparen"; - }, - nextState: "start" - }, { - token : "string.start", - regex : /"/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(")/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /"/, - next : "pop" + token: "string.end", + regex: /"/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /`/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: "string.start", + regex: /`/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /`/, - next : "pop" + token: "string.end", + regex: /`/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /'/, - push : [{ - token : "constant.language.escape", - regex : /\\['\\]/ - }, { - token : "string.end", - regex : /'/, - next : "pop" + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(')/, + push: [{ + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "string.end", + regex: /'/, + next: "pop" }, { defaultToken: "string" }] + }, { + token: "string.start",//doesn't see any differences between strings and array of strings in highlighting + regex: /%[qwx]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithoutInterpolation"; + return this.token; + } + }, { + token: "string.start", //doesn't see any differences between strings and array of strings in highlighting + regex: /%[QWX]?([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[si]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithoutInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[SI]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithInterpolation"; + return this.token; + } + }, { + token: "string.regexp", + regex: /%[r]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "rState"; + return this.token; + } }], { - token : "text", // namespaces aren't symbols - regex : "::" + token: "punctuation", // namespaces aren't symbols + regex: "::" + }, + instanceVariable, + { + token: "variable.global", // global variable + regex: "[$][a-zA-Z_\\d]+" }, { - token : "variable.instance", // instance variable - regex : "@{1,2}[a-zA-Z_\\d]+" + token: "support.class", // class name + regex: "[A-Z][a-zA-Z_\\d]*" }, { - token : "support.class", // class name - regex : "[A-Z][a-zA-Z_\\d]+" + token: ["punctuation.operator", "support.function"], + regex: /(\.)([a-zA-Z_\d]+)(?=\()/ + }, { + token: ["punctuation.operator", "identifier"], + regex: /(\.)([a-zA-Z_][a-zA-Z_\d]*)/ + }, { + token: "string.character", + regex: "\\B\\?(?:" + escapedChars + "|\\S)" + }, { + token: "punctuation.operator", + regex: /\?(?=.+:)/ }, + constantNumericRational, + constantNumericComplex, constantOtherSymbol, constantNumericHex, constantNumericFloat, - + constantNumericBinary, + constantNumericDecimal, + constantNumericOctal, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" + token: "constant.language.boolean", + regex: "(?:true|false)\\b" }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + token: keywordMapper, + regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { - token : "punctuation.separator.key-value", - regex : "=>" + token: "punctuation.separator.key-value", + regex: "=>" }, { stateName: "heredoc", - onMatch : function(value, currentState, stack) { - var next = value[2] == '-' ? "indentedHeredoc" : "heredoc"; + onMatch: function (value, currentState, stack) { + var next = (value[2] == '-' || value[2] == '~') ? "indentedHeredoc" : "heredoc"; var tokens = value.split(this.splitRegex); stack.push(next, tokens[3]); return [ - {type:"constant", value: tokens[1]}, - {type:"string", value: tokens[2]}, - {type:"support.class", value: tokens[3]}, - {type:"string", value: tokens[4]} + {type: "constant", value: tokens[1]}, + {type: "string", value: tokens[2]}, + {type: "support.class", value: tokens[3]}, + {type: "string", value: tokens[4]} ]; }, - regex : "(<<-?)(['\"`]?)([\\w]+)(['\"`]?)", + regex: "(<<[-~]?)(['\"`]?)([\\w]+)(['\"`]?)", rules: { heredoc: [{ - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -1237,7 +1328,7 @@ var RubyHighlightRules = function() { token: "string", regex: "^ +" }, { - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -1252,38 +1343,261 @@ var RubyHighlightRules = function() { }] } }, { - regex : "$", - token : "empty", - next : function(currentState, stack) { + regex: "$", + token: "empty", + next: function(currentState, stack) { if (stack[0] === "heredoc" || stack[0] === "indentedHeredoc") return stack[0]; return currentState; } + }, { + token: "keyword.operator", + regex: "!|\\$|%|&|\\*|/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\||\\b(?:in|instanceof|new|delete|typeof|void)" }, { - token : "string.character", - regex : "\\B\\?." + token: "paren.lparen", + regex: "[[({]" }, { - token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + token: "paren.rparen", + regex: "[\\])}]", + onMatch: function(value, currentState, stack) { + this.next = ''; + if (value == "}" && stack.length > 1 && stack[1] != "start") { + stack.shift(); + this.next = stack.shift(); + } + return this.token; + } }, { - token : "paren.lparen", - regex : "[[({]" + token: "text", + regex: "\\s+" }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" + token: "punctuation.operator", + regex: /[?:,;.]/ } ], - "comment" : [ + "comment": [ { - token : "comment", // closing comment - regex : "^=end(?:$|\\s.*$)", - next : "start" + token: "comment.multiline", // closing comment + regex: "^=end(?=$|\\s.*$)", + next: "start" }, { - token : "comment", // comment spanning whole line - regex : ".+" + token: "comment", // comment spanning whole line + regex: ".+" + } + ], + "qStateWithInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "qStateWithoutInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "sStateWithoutInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "sStateWithInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "rState": [{ + token: "string.regexp",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.language.escape"; + } + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.regexp", + regex: /\// + }, { + token: "string.regexp", + regex: /[)\]>}^|%][imxouesn]*/, onMatch: function (val, state, stack) { + if (stack.length && val[0] === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.language.escape"; + } + }, + {include: "regex"}, + { + defaultToken: "string.regexp" + }], + "regex": [ + {// character classes + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "constant.language.escape", + regex: /\\[AGbBzZ]/ + }, { + token: "constant.language.escape", + regex: /\\g<[a-zA-Z0-9]*>/ + }, { + token: ["constant.language.escape", "regexp.keyword", "constant.language.escape"], + regex: /(\\p{\^?)(Alnum|Alpha|Blank|Cntrl|Digit|Graph|Lower|Print|Punct|Space|Upper|XDigit|Word|ASCII|Any|Assigned|Arabic|Armenian|Balinese|Bengali|Bopomofo|Braille|Buginese|Buhid|Canadian_Aboriginal|Carian|Cham|Cherokee|Common|Coptic|Cuneiform|Cypriot|Cyrillic|Deseret|Devanagari|Ethiopic|Georgian|Glagolitic|Gothic|Greek|Gujarati|Gurmukhi|Han|Hangul|Hanunoo|Hebrew|Hiragana|Inherited|Kannada|Katakana|Kayah_Li|Kharoshthi|Khmer|Lao|Latin|Lepcha|Limbu|Linear_B|Lycian|Lydian|Malayalam|Mongolian|Myanmar|New_Tai_Lue|Nko|Ogham|Ol_Chiki|Old_Italic|Old_Persian|Oriya|Osmanya|Phags_Pa|Phoenician|Rejang|Runic|Saurashtra|Shavian|Sinhala|Sundanese|Syloti_Nagri|Syriac|Tagalog|Tagbanwa|Tai_Le|Tamil|Telugu|Thaana|Thai|Tibetan|Tifinagh|Ugaritic|Vai|Yi|Ll|Lm|Lt|Lu|Lo|Mn|Mc|Me|Nd|Nl|Pc|Pd|Ps|Pe|Pi|Pf|Po|No|Sm|Sc|Sk|So|Zs|Zl|Zp|Cc|Cf|Cn|Co|Cs|N|L|M|P|S|Z|C)(})/ + }, { + token: ["constant.language.escape", "invalid", "constant.language.escape"], + regex: /(\\p{\^?)([^/]*)(})/ + }, {// escapes + token: "regexp.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, {// flag + token: "string.regexp", + regex: /[/][imxouesn]*/, + next: "start" + }, {// invalid operators + token: "invalid", + regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ + }, {// operators + token: "constant.language.escape", + regex: /\(\?(?:[:=!>]|<'?[a-zA-Z]*'?>|<[=!])|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ + }, { + token: "constant.language.delimiter", + regex: /\|/ + }, { + token: "regexp.keyword", + regex: /\[\[:(?:alnum|alpha|blank|cntrl|digit|graph|lower|print|punct|space|upper|xdigit|word|ascii):\]\]/ + }, { + token: "constant.language.escape", + regex: /\[\^?/, + push: "regex_character_class" + }, { + defaultToken: "string.regexp" + } + ], + "regex_character_class": [ + { + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "regexp.charclass.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "constant.language.escape", + regex: /&?&?\[\^?/, + push: "regex_character_class" + }, { + token: "constant.language.escape", + regex: "]", + next: "pop" + }, { + token: "constant.language.escape", + regex: "-" + }, { + defaultToken: "string.regexp.characterclass" } ] }; @@ -1613,6 +1927,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1950,6 +2265,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2842,99 +3158,277 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; }); -define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"], function(require, exports, module) { +define("ace/mode/folding/ruby",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"], function (require, exports, module) { "use strict"; var oop = require("../../lib/oop"); var BaseFoldMode = require("./fold_mode").FoldMode; var Range = require("../../range").Range; +var TokenIterator = require("../../token_iterator").TokenIterator; + + +var FoldMode = exports.FoldMode = function () { +}; -var FoldMode = exports.FoldMode = function() {}; oop.inherits(FoldMode, BaseFoldMode); -(function() { - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var range = this.indentationBlock(session, row); - if (range) - return range; - - var re = /\S/; - var line = session.getLine(row); - var startLevel = line.search(re); - if (startLevel == -1 || line[startLevel] != "#") - return; - - var startColumn = line.length; - var maxRow = session.getLength(); - var startRow = row; - var endRow = row; - - while (++row < maxRow) { - line = session.getLine(row); - var level = line.search(re); - - if (level == -1) - continue; - - if (line[level] != "#") - break; - - endRow = row; - } - - if (endRow > startRow) { - var endColumn = session.getLine(endRow).length; - return new Range(startRow, startColumn, endRow, endColumn); - } +(function () { + this.indentKeywords = { + "class": 1, + "def": 1, + "module": 1, + "do": 1, + "unless": 1, + "if": 1, + "while": 1, + "for": 1, + "until": 1, + "begin": 1, + "else": 0, + "elsif": 0, + "rescue": 0, + "ensure": 0, + "when": 0, + "end": -1, + "case": 1, + "=begin": 1, + "=end": -1 }; - this.getFoldWidget = function(session, foldStyle, row) { - var line = session.getLine(row); - var indent = line.search(/\S/); - var next = session.getLine(row + 1); - var prev = session.getLine(row - 1); - var prevIndent = prev.search(/\S/); - var nextIndent = next.search(/\S/); - if (indent == -1) { - session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : ""; - return ""; - } - if (prevIndent == -1) { - if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") { - session.foldWidgets[row - 1] = ""; - session.foldWidgets[row + 1] = ""; + this.foldingStartMarker = /(?:\s|^)(def|do|while|class|unless|module|if|for|until|begin|else|elsif|case|rescue|ensure|when)\b|({\s*$)|(=begin)/; + this.foldingStopMarker = /(=end(?=$|\s.*$))|(^\s*})|\b(end)\b/; + + this.getFoldWidget = function (session, foldStyle, row) { + var line = session.getLine(row); + var isStart = this.foldingStartMarker.test(line); + var isEnd = this.foldingStopMarker.test(line); + + if (isStart && !isEnd) { + var match = line.match(this.foldingStartMarker); + if (match[1]) { + if (match[1] == "if" || match[1] == "else" || match[1] == "while" || match[1] == "until" || match[1] == "unless") { + if (match[1] == "else" && /^\s*else\s*$/.test(line) === false) { + return; + } + if (/^\s*(?:if|else|while|until|unless)\s*/.test(line) === false) { + return; + } + } + + if (match[1] == "when") { + if (/\sthen\s/.test(line) === true) { + return; + } + } + if (session.getTokenAt(row, match.index + 2).type === "keyword") + return "start"; + } else if (match[3]) { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return "start"; + } else { return "start"; } - } else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") { - if (session.getLine(row - 2).search(/\S/) == -1) { - session.foldWidgets[row - 1] = "start"; - session.foldWidgets[row + 1] = ""; - return ""; + } + if (foldStyle != "markbeginend" || !isEnd || isStart && isEnd) + return ""; + + var match = line.match(this.foldingStopMarker); + if (match[3] === "end") { + if (session.getTokenAt(row, match.index + 1).type === "keyword") + return "end"; + } else if (match[1]) { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return "end"; + } else + return "end"; + }; + + this.getFoldWidgetRange = function (session, foldStyle, row) { + var line = session.doc.getLine(row); + var match = this.foldingStartMarker.exec(line); + if (match) { + if (match[1] || match[3]) + return this.rubyBlock(session, row, match.index + 2); + + return this.openingBracketBlock(session, "{", row, match.index); + } + + var match = this.foldingStopMarker.exec(line); + if (match) { + if (match[3] === "end") { + if (session.getTokenAt(row, match.index + 1).type === "keyword") + return this.rubyBlock(session, row, match.index + 1); + } + + if (match[1] === "=end") { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return this.rubyBlock(session, row, match.index + 1); + } + + return this.closingBracketBlock(session, "}", row, match.index + match[0].length); + } + }; + + this.rubyBlock = function (session, row, column, tokenRange) { + var stream = new TokenIterator(session, row, column); + + var token = stream.getCurrentToken(); + if (!token || (token.type != "keyword" && token.type != "comment.multiline")) + return; + + var val = token.value; + var line = session.getLine(row); + switch (token.value) { + case "if": + case "unless": + case "while": + case "until": + var checkToken = new RegExp("^\\s*" + token.value); + if (!checkToken.test(line)) { + return; + } + var dir = this.indentKeywords[val]; + break; + case "when": + if (/\sthen\s/.test(line)) { + return; + } + case "elsif": + case "rescue": + case "ensure": + var dir = 1; + break; + case "else": + var checkToken = new RegExp("^\\s*" + token.value + "\\s*$"); + if (!checkToken.test(line)) { + return; + } + var dir = 1; + break; + default: + var dir = this.indentKeywords[val]; + break; + } + + var stack = [val]; + if (!dir) + return; + + var startColumn = dir === -1 ? session.getLine(row - 1).length : session.getLine(row).length; + var startRow = row; + var ranges = []; + ranges.push(stream.getCurrentTokenRange()); + + stream.step = dir === -1 ? stream.stepBackward : stream.stepForward; + if (token.type == "comment.multiline") { + while (token = stream.step()) { + if (token.type !== "comment.multiline") + continue; + if (dir == 1) { + startColumn = 6; + if (token.value == "=end") { + break; + } + } else { + if (token.value == "=begin") { + break; + } + } + } + } else { + while (token = stream.step()) { + var ignore = false; + if (token.type !== "keyword") + continue; + var level = dir * this.indentKeywords[token.value]; + line = session.getLine(stream.getCurrentTokenRow()); + switch (token.value) { + case "do": + for (var i = stream.$tokenIndex - 1; i >= 0; i--) { + var prevToken = stream.$rowTokens[i]; + if (prevToken && (prevToken.value == "while" || prevToken.value == "until" || prevToken.value == "for")) { + level = 0; + break; + } + } + break; + case "else": + var checkToken = new RegExp("^\\s*" + token.value + "\\s*$"); + if (!checkToken.test(line) || val == "case") { + level = 0; + ignore = true; + } + break; + case "if": + case "unless": + case "while": + case "until": + var checkToken = new RegExp("^\\s*" + token.value); + if (!checkToken.test(line)) { + level = 0; + ignore = true; + } + break; + case "when": + if (/\sthen\s/.test(line) || val == "case") { + level = 0; + ignore = true; + } + break; + } + + if (level > 0) { + stack.unshift(token.value); + } else if (level <= 0 && ignore === false) { + stack.shift(); + if (!stack.length) { + if ((val == "while" || val == "until" || val == "for") && token.value != "do") { + break; + } + if (token.value == "do" && dir == -1 && level != 0) + break; + if (token.value != "do") + break; + } + + if (level === 0) { + stack.unshift(token.value); + } + } } } - if (prevIndent!= -1 && prevIndent < indent) - session.foldWidgets[row - 1] = "start"; - else - session.foldWidgets[row - 1] = ""; + if (!token) + return null; - if (indent < nextIndent) - return "start"; - else - return ""; + if (tokenRange) { + ranges.push(stream.getCurrentTokenRange()); + return ranges; + } + + var row = stream.getCurrentTokenRow(); + if (dir === -1) { + if (token.type === "comment.multiline") { + var endColumn = 6; + } else { + var endColumn = session.getLine(row).length; + } + return new Range(row, endColumn, startRow - 1, startColumn); + } else + return new Range(startRow, startColumn, row - 1, session.getLine(row - 1).length); }; }).call(FoldMode.prototype); }); -define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/coffee"], function(require, exports, module) { +define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/ruby"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); @@ -2943,13 +3437,14 @@ var RubyHighlightRules = require("./ruby_highlight_rules").RubyHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; var Range = require("../range").Range; var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var FoldMode = require("./folding/coffee").FoldMode; +var FoldMode = require("./folding/ruby").FoldMode; var Mode = function() { this.HighlightRules = RubyHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.$behaviour = new CstyleBehaviour(); this.foldingRules = new FoldMode(); + this.indentKeywords = this.foldingRules.indentKeywords; }; oop.inherits(Mode, TextMode); @@ -2964,7 +3459,7 @@ oop.inherits(Mode, TextMode); var tokenizedLine = this.getTokenizer().getLineTokens(line, state); var tokens = tokenizedLine.tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { + if (tokens.length && tokens[tokens.length - 1].type == "comment") { return indent; } @@ -2972,7 +3467,7 @@ oop.inherits(Mode, TextMode); var match = line.match(/^.*[\{\(\[]\s*$/); var startingClassOrMethod = line.match(/^\s*(class|def|module)\s.*$/); var startingDoBlock = line.match(/.*do(\s*|\s+\|.*\|\s*)$/); - var startingConditional = line.match(/^\s*(if|else|when)\s*/); + var startingConditional = line.match(/^\s*(if|else|when|elsif|unless|while|for|begin|rescue|ensure)\s*/); if (match || startingClassOrMethod || startingDoBlock || startingConditional) { indent += tab; } @@ -2982,7 +3477,7 @@ oop.inherits(Mode, TextMode); }; this.checkOutdent = function(state, line, input) { - return /^\s+(end|else)$/.test(line + input) || this.$outdent.checkOutdent(line, input); + return /^\s+(end|else|rescue|ensure)$/.test(line + input) || this.$outdent.checkOutdent(line, input); }; this.autoOutdent = function(state, session, row) { @@ -2995,11 +3490,24 @@ oop.inherits(Mode, TextMode); var tab = session.getTabString(); if (prevIndent.length <= indent.length) { if (indent.slice(-tab.length) == tab) - session.remove(new Range(row, indent.length-tab.length, row, indent.length)); + session.remove(new Range(row, indent.length - tab.length, row, indent.length)); } }; + this.getMatching = function(session, row, column) { + if (row == undefined) { + var pos = session.selection.lead; + column = pos.column; + row = pos.row; + } + + var startToken = session.getTokenAt(row, column); + if (startToken && startToken.value in this.indentKeywords) + return this.foldingRules.rubyBlock(session, row, column, true); + }; + this.$id = "ace/mode/ruby"; + this.snippetFileId = "ace/snippets/ruby"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-io.js b/htdocs/includes/ace/src/mode-io.js index aba935b2011..452a803f8d7 100644 --- a/htdocs/includes/ace/src/mode-io.js +++ b/htdocs/includes/ace/src/mode-io.js @@ -234,6 +234,7 @@ oop.inherits(Mode, TextMode); this.lineCommentStart = "//"; this.blockComment = {start: "/*", end: "*/"}; this.$id = "ace/mode/io"; + this.snippetFileId = "ace/snippets/io"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-java.js b/htdocs/includes/ace/src/mode-java.js index ed9cbe351ba..b61e2a90a78 100644 --- a/htdocs/includes/ace/src/mode-java.js +++ b/htdocs/includes/ace/src/mode-java.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -909,7 +910,7 @@ var JavaHighlightRules = function() { regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + regex : "!|\\$|%|&|\\||\\^|\\*|\\/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?|\\:|\\*=|\\/=|%=|\\+=|\\-=|&=|\\|=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" }, { token : "lparen", regex : "[[({]" @@ -1023,6 +1024,7 @@ oop.inherits(Mode, JavaScriptMode); }; this.$id = "ace/mode/java"; + this.snippetFileId = "ace/snippets/java"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-javascript.js b/htdocs/includes/ace/src/mode-javascript.js index f9640e85d95..be3d822c23d 100644 --- a/htdocs/includes/ace/src/mode-javascript.js +++ b/htdocs/includes/ace/src/mode-javascript.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-json.js b/htdocs/includes/ace/src/mode-json.js index 5ade1857f98..2446e39c6a1 100644 --- a/htdocs/includes/ace/src/mode-json.js +++ b/htdocs/includes/ace/src/mode-json.js @@ -275,6 +275,9 @@ oop.inherits(Mode, TextMode); (function() { + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); diff --git a/htdocs/includes/ace/src/mode-jsoniq.js b/htdocs/includes/ace/src/mode-jsoniq.js index 2d717609bd9..323317aa4ae 100644 --- a/htdocs/includes/ace/src/mode-jsoniq.js +++ b/htdocs/includes/ace/src/mode-jsoniq.js @@ -2618,6 +2618,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/jsoniq"; + this.snippetFileId = "ace/snippets/jsoniq"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-jsp.js b/htdocs/includes/ace/src/mode-jsp.js index 42cc5f54321..b6c4233441a 100644 --- a/htdocs/includes/ace/src/mode-jsp.js +++ b/htdocs/includes/ace/src/mode-jsp.js @@ -1122,7 +1122,7 @@ var JavaHighlightRules = function() { regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + regex : "!|\\$|%|&|\\||\\^|\\*|\\/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?|\\:|\\*=|\\/=|%=|\\+=|\\-=|&=|\\|=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" }, { token : "lparen", regex : "[[({]" @@ -1419,6 +1419,7 @@ oop.inherits(Mode, TextMode); (function() { this.$id = "ace/mode/jsp"; + this.snippetFileId = "ace/snippets/jsp"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-kotlin.js b/htdocs/includes/ace/src/mode-kotlin.js index 11021b5890a..394271de33c 100644 --- a/htdocs/includes/ace/src/mode-kotlin.js +++ b/htdocs/includes/ace/src/mode-kotlin.js @@ -781,6 +781,8 @@ var Mode = function() { oop.inherits(Mode, TextMode); (function() { + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; this.$id = "ace/mode/kotlin"; }).call(Mode.prototype); diff --git a/htdocs/includes/ace/src/mode-latte.js b/htdocs/includes/ace/src/mode-latte.js new file mode 100644 index 00000000000..0377c843865 --- /dev/null +++ b/htdocs/includes/ace/src/mode-latte.js @@ -0,0 +1,2708 @@ +define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var DocCommentHighlightRules = function() { + this.$rules = { + "start" : [ { + token : "comment.doc.tag", + regex : "@[\\w\\d_]+" // TODO: fix email addresses + }, + DocCommentHighlightRules.getTagRule(), + { + defaultToken : "comment.doc", + caseInsensitive: true + }] + }; +}; + +oop.inherits(DocCommentHighlightRules, TextHighlightRules); + +DocCommentHighlightRules.getTagRule = function(start) { + return { + token : "comment.doc.tag.storage.type", + regex : "\\b(?:TODO|FIXME|XXX|HACK)\\b" + }; +}; + +DocCommentHighlightRules.getStartRule = function(start) { + return { + token : "comment.doc", // doc comment + regex : "\\/\\*(?=\\*)", + next : start + }; +}; + +DocCommentHighlightRules.getEndRule = function (start) { + return { + token : "comment.doc", // closing comment + regex : "\\*\\/", + next : start + }; +}; + + +exports.DocCommentHighlightRules = DocCommentHighlightRules; + +}); + +define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*"; + +var JavaScriptHighlightRules = function(options) { + var keywordMapper = this.createKeywordMapper({ + "variable.language": + "Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors + "Namespace|QName|XML|XMLList|" + // E4X + "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" + + "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|" + + "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + // Errors + "SyntaxError|TypeError|URIError|" + + "decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions + "isNaN|parseFloat|parseInt|" + + "JSON|Math|" + // Other + "this|arguments|prototype|window|document" , // Pseudo + "keyword": + "const|yield|import|get|set|async|await|" + + "break|case|catch|continue|default|delete|do|else|finally|for|function|" + + "if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" + + "__parent__|__count__|escape|unescape|with|__proto__|" + + "class|enum|extends|super|export|implements|private|public|interface|package|protected|static", + "storage.type": + "const|let|var|function", + "constant.language": + "null|Infinity|NaN|undefined", + "support.function": + "alert", + "constant.language.boolean": "true|false" + }, "identifier"); + var kwBeforeRe = "case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void"; + + var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex + "u[0-9a-fA-F]{4}|" + // unicode + "u{[0-9a-fA-F]{1,6}}|" + // es6 unicode + "[0-2][0-7]{0,2}|" + // oct + "3[0-7][0-7]?|" + // oct + "[4-7][0-7]?|" + //oct + ".)"; + + this.$rules = { + "no_regex" : [ + DocCommentHighlightRules.getStartRule("doc-start"), + comments("no_regex"), + { + token : "string", + regex : "'(?=.)", + next : "qstring" + }, { + token : "string", + regex : '"(?=.)', + next : "qqstring" + }, { + token : "constant.numeric", // hexadecimal, octal and binary + regex : /0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/ + }, { + token : "constant.numeric", // decimal integers and floats + regex : /(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/ + }, { + token : [ + "storage.type", "punctuation.operator", "support.function", + "punctuation.operator", "entity.name.function", "text","keyword.operator" + ], + regex : "(" + identifierRe + ")(\\.)(prototype)(\\.)(" + identifierRe +")(\\s*)(=)", + next: "function_arguments" + }, { + token : [ + "storage.type", "punctuation.operator", "entity.name.function", "text", + "keyword.operator", "text", "storage.type", "text", "paren.lparen" + ], + regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "entity.name.function", "text", "keyword.operator", "text", "storage.type", + "text", "paren.lparen" + ], + regex : "(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "storage.type", "punctuation.operator", "entity.name.function", "text", + "keyword.operator", "text", + "storage.type", "text", "entity.name.function", "text", "paren.lparen" + ], + regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "storage.type", "text", "entity.name.function", "text", "paren.lparen" + ], + regex : "(function)(\\s+)(" + identifierRe + ")(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "entity.name.function", "text", "punctuation.operator", + "text", "storage.type", "text", "paren.lparen" + ], + regex : "(" + identifierRe + ")(\\s*)(:)(\\s*)(function)(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "text", "text", "storage.type", "text", "paren.lparen" + ], + regex : "(:)(\\s*)(function)(\\s*)(\\()", + next: "function_arguments" + }, { + token : "keyword", + regex : "from(?=\\s*('|\"))" + }, { + token : "keyword", + regex : "(?:" + kwBeforeRe + ")\\b", + next : "start" + }, { + token : ["support.constant"], + regex : /that\b/ + }, { + token : ["storage.type", "punctuation.operator", "support.function.firebug"], + regex : /(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/ + }, { + token : keywordMapper, + regex : identifierRe + }, { + token : "punctuation.operator", + regex : /[.](?![.])/, + next : "property" + }, { + token : "storage.type", + regex : /=>/, + next : "start" + }, { + token : "keyword.operator", + regex : /--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/, + next : "start" + }, { + token : "punctuation.operator", + regex : /[?:,;.]/, + next : "start" + }, { + token : "paren.lparen", + regex : /[\[({]/, + next : "start" + }, { + token : "paren.rparen", + regex : /[\])}]/ + }, { + token: "comment", + regex: /^#!.*$/ + } + ], + property: [{ + token : "text", + regex : "\\s+" + }, { + token : [ + "storage.type", "punctuation.operator", "entity.name.function", "text", + "keyword.operator", "text", + "storage.type", "text", "entity.name.function", "text", "paren.lparen" + ], + regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()", + next: "function_arguments" + }, { + token : "punctuation.operator", + regex : /[.](?![.])/ + }, { + token : "support.function", + regex : /(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/ + }, { + token : "support.function.dom", + regex : /(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/ + }, { + token : "support.constant", + regex : /(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/ + }, { + token : "identifier", + regex : identifierRe + }, { + regex: "", + token: "empty", + next: "no_regex" + } + ], + "start": [ + DocCommentHighlightRules.getStartRule("doc-start"), + comments("start"), + { + token: "string.regexp", + regex: "\\/", + next: "regex" + }, { + token : "text", + regex : "\\s+|^$", + next : "start" + }, { + token: "empty", + regex: "", + next: "no_regex" + } + ], + "regex": [ + { + token: "regexp.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "string.regexp", + regex: "/[sxngimy]*", + next: "no_regex" + }, { + token : "invalid", + regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ + }, { + token : "constant.language.escape", + regex: /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ + }, { + token : "constant.language.delimiter", + regex: /\|/ + }, { + token: "constant.language.escape", + regex: /\[\^?/, + next: "regex_character_class" + }, { + token: "empty", + regex: "$", + next: "no_regex" + }, { + defaultToken: "string.regexp" + } + ], + "regex_character_class": [ + { + token: "regexp.charclass.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "constant.language.escape", + regex: "]", + next: "regex" + }, { + token: "constant.language.escape", + regex: "-" + }, { + token: "empty", + regex: "$", + next: "no_regex" + }, { + defaultToken: "string.regexp.charachterclass" + } + ], + "function_arguments": [ + { + token: "variable.parameter", + regex: identifierRe + }, { + token: "punctuation.operator", + regex: "[, ]+" + }, { + token: "punctuation.operator", + regex: "$" + }, { + token: "empty", + regex: "", + next: "no_regex" + } + ], + "qqstring" : [ + { + token : "constant.language.escape", + regex : escapedRe + }, { + token : "string", + regex : "\\\\$", + consumeLineEnd : true + }, { + token : "string", + regex : '"|$', + next : "no_regex" + }, { + defaultToken: "string" + } + ], + "qstring" : [ + { + token : "constant.language.escape", + regex : escapedRe + }, { + token : "string", + regex : "\\\\$", + consumeLineEnd : true + }, { + token : "string", + regex : "'|$", + next : "no_regex" + }, { + defaultToken: "string" + } + ] + }; + + + if (!options || !options.noES6) { + this.$rules.no_regex.unshift({ + regex: "[{}]", onMatch: function(val, state, stack) { + this.next = val == "{" ? this.nextState : ""; + if (val == "{" && stack.length) { + stack.unshift("start", state); + } + else if (val == "}" && stack.length) { + stack.shift(); + this.next = stack.shift(); + if (this.next.indexOf("string") != -1 || this.next.indexOf("jsx") != -1) + return "paren.quasi.end"; + } + return val == "{" ? "paren.lparen" : "paren.rparen"; + }, + nextState: "start" + }, { + token : "string.quasi.start", + regex : /`/, + push : [{ + token : "constant.language.escape", + regex : escapedRe + }, { + token : "paren.quasi.start", + regex : /\${/, + push : "start" + }, { + token : "string.quasi.end", + regex : /`/, + next : "pop" + }, { + defaultToken: "string.quasi" + }] + }); + + if (!options || options.jsx != false) + JSX.call(this); + } + + this.embedRules(DocCommentHighlightRules, "doc-", + [ DocCommentHighlightRules.getEndRule("no_regex") ]); + + this.normalizeRules(); +}; + +oop.inherits(JavaScriptHighlightRules, TextHighlightRules); + +function JSX() { + var tagRegex = identifierRe.replace("\\d", "\\d\\-"); + var jsxTag = { + onMatch : function(val, state, stack) { + var offset = val.charAt(1) == "/" ? 2 : 1; + if (offset == 1) { + if (state != this.nextState) + stack.unshift(this.next, this.nextState, 0); + else + stack.unshift(this.next); + stack[2]++; + } else if (offset == 2) { + if (state == this.nextState) { + stack[1]--; + if (!stack[1] || stack[1] < 0) { + stack.shift(); + stack.shift(); + } + } + } + return [{ + type: "meta.tag.punctuation." + (offset == 1 ? "" : "end-") + "tag-open.xml", + value: val.slice(0, offset) + }, { + type: "meta.tag.tag-name.xml", + value: val.substr(offset) + }]; + }, + regex : "", + onMatch : function(value, currentState, stack) { + if (currentState == stack[0]) + stack.shift(); + if (value.length == 2) { + if (stack[0] == this.nextState) + stack[1]--; + if (!stack[1] || stack[1] < 0) { + stack.splice(0, 2); + } + } + this.next = stack[0] || "start"; + return [{type: this.token, value: value}]; + }, + nextState: "jsx" + }, + jsxJsRule, + comments("jsxAttributes"), + { + token : "entity.other.attribute-name.xml", + regex : tagRegex + }, { + token : "keyword.operator.attribute-equals.xml", + regex : "=" + }, { + token : "text.tag-whitespace.xml", + regex : "\\s+" + }, { + token : "string.attribute-value.xml", + regex : "'", + stateName : "jsx_attr_q", + push : [ + {token : "string.attribute-value.xml", regex: "'", next: "pop"}, + {include : "reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }, { + token : "string.attribute-value.xml", + regex : '"', + stateName : "jsx_attr_qq", + push : [ + {token : "string.attribute-value.xml", regex: '"', next: "pop"}, + {include : "reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }, + jsxTag + ]; + this.$rules.reference = [{ + token : "constant.language.escape.reference.xml", + regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" + }]; +} + +function comments(next) { + return [ + { + token : "comment", // multi line comment + regex : /\/\*/, + next: [ + DocCommentHighlightRules.getTagRule(), + {token : "comment", regex : "\\*\\/", next : next || "pop"}, + {defaultToken : "comment", caseInsensitive: true} + ] + }, { + token : "comment", + regex : "\\/\\/", + next: [ + DocCommentHighlightRules.getTagRule(), + {token : "comment", regex : "$|^", next : next || "pop"}, + {defaultToken : "comment", caseInsensitive: true} + ] + } + ]; +} +exports.JavaScriptHighlightRules = JavaScriptHighlightRules; +}); + +define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +var MatchingBraceOutdent = function() {}; + +(function() { + + this.checkOutdent = function(line, input) { + if (! /^\s+$/.test(line)) + return false; + + return /^\s*\}/.test(input); + }; + + this.autoOutdent = function(doc, row) { + var line = doc.getLine(row); + var match = line.match(/^(\s*\})/); + + if (!match) return 0; + + var column = match[1].length; + var openBracePos = doc.findMatchingBracket({row: row, column: column}); + + if (!openBracePos || openBracePos.row == row) return 0; + + var indent = this.$getIndent(doc.getLine(openBracePos.row)); + doc.replace(new Range(row, 0, row, column-1), indent); + }; + + this.$getIndent = function(line) { + return line.match(/^\s*/)[0]; + }; + +}).call(MatchingBraceOutdent.prototype); + +exports.MatchingBraceOutdent = MatchingBraceOutdent; +}); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = JavaScriptHighlightRules; + + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + this.foldingRules = new CStyleFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + this.$quotes = {'"': '"', "'": "'", "`": "`"}; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + + var tokenizedLine = this.getTokenizer().getLineTokens(line, state); + var tokens = tokenizedLine.tokens; + var endState = tokenizedLine.state; + + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + if (state == "start" || state == "no_regex") { + var match = line.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/); + if (match) { + indent += tab; + } + } else if (state == "doc-start") { + if (endState == "start" || endState == "no_regex") { + return ""; + } + var match = line.match(/^\s*(\/?)\*/); + if (match) { + if (match[1]) { + indent += " "; + } + indent += "* "; + } + } + + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker"); + worker.attachToDocument(session.getDocument()); + + worker.on("annotate", function(results) { + session.setAnnotations(results.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); + +define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var supportType = exports.supportType = "align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index"; +var supportFunction = exports.supportFunction = "rgb|rgba|url|attr|counter|counters"; +var supportConstant = exports.supportConstant = "absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom"; +var supportConstantColor = exports.supportConstantColor = "aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen"; +var supportConstantFonts = exports.supportConstantFonts = "arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace"; + +var numRe = exports.numRe = "\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))"; +var pseudoElements = exports.pseudoElements = "(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b"; +var pseudoClasses = exports.pseudoClasses = "(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b"; + +var CssHighlightRules = function() { + + var keywordMapper = this.createKeywordMapper({ + "support.function": supportFunction, + "support.constant": supportConstant, + "support.type": supportType, + "support.constant.color": supportConstantColor, + "support.constant.fonts": supportConstantFonts + }, "text", true); + + this.$rules = { + "start" : [{ + include : ["strings", "url", "comments"] + }, { + token: "paren.lparen", + regex: "\\{", + next: "ruleset" + }, { + token: "paren.rparen", + regex: "\\}" + }, { + token: "string", + regex: "@(?!viewport)", + next: "media" + }, { + token: "keyword", + regex: "#[a-z0-9-_]+" + }, { + token: "keyword", + regex: "%" + }, { + token: "variable", + regex: "\\.[a-z0-9-_]+" + }, { + token: "string", + regex: ":[a-z0-9-_]+" + }, { + token : "constant.numeric", + regex : numRe + }, { + token: "constant", + regex: "[a-z0-9-_]+" + }, { + caseInsensitive: true + }], + + "media": [{ + include : ["strings", "url", "comments"] + }, { + token: "paren.lparen", + regex: "\\{", + next: "start" + }, { + token: "paren.rparen", + regex: "\\}", + next: "start" + }, { + token: "string", + regex: ";", + next: "start" + }, { + token: "keyword", + regex: "(?:media|supports|document|charset|import|namespace|media|supports|document" + + "|page|font|keyframes|viewport|counter-style|font-feature-values" + + "|swash|ornaments|annotation|stylistic|styleset|character-variant)" + }], + + "comments" : [{ + token: "comment", // multi line comment + regex: "\\/\\*", + push: [{ + token : "comment", + regex : "\\*\\/", + next : "pop" + }, { + defaultToken : "comment" + }] + }], + + "ruleset" : [{ + regex : "-(webkit|ms|moz|o)-", + token : "text" + }, { + token : "punctuation.operator", + regex : "[:;]" + }, { + token : "paren.rparen", + regex : "\\}", + next : "start" + }, { + include : ["strings", "url", "comments"] + }, { + token : ["constant.numeric", "keyword"], + regex : "(" + numRe + ")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)" + }, { + token : "constant.numeric", + regex : numRe + }, { + token : "constant.numeric", // hex6 color + regex : "#[a-f0-9]{6}" + }, { + token : "constant.numeric", // hex3 color + regex : "#[a-f0-9]{3}" + }, { + token : ["punctuation", "entity.other.attribute-name.pseudo-element.css"], + regex : pseudoElements + }, { + token : ["punctuation", "entity.other.attribute-name.pseudo-class.css"], + regex : pseudoClasses + }, { + include: "url" + }, { + token : keywordMapper, + regex : "\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*" + }, { + caseInsensitive: true + }], + + url: [{ + token : "support.function", + regex : "(?:url(:?-prefix)?|domain|regexp)\\(", + push: [{ + token : "support.function", + regex : "\\)", + next : "pop" + }, { + defaultToken: "string" + }] + }], + + strings: [{ + token : "string.start", + regex : "'", + push : [{ + token : "string.end", + regex : "'|$", + next: "pop" + }, { + include : "escapes" + }, { + token : "constant.language.escape", + regex : /\\$/, + consumeLineEnd: true + }, { + defaultToken: "string" + }] + }, { + token : "string.start", + regex : '"', + push : [{ + token : "string.end", + regex : '"|$', + next: "pop" + }, { + include : "escapes" + }, { + token : "constant.language.escape", + regex : /\\$/, + consumeLineEnd: true + }, { + defaultToken: "string" + }] + }], + escapes: [{ + token : "constant.language.escape", + regex : /\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/ + }] + + }; + + this.normalizeRules(); +}; + +oop.inherits(CssHighlightRules, TextHighlightRules); + +exports.CssHighlightRules = CssHighlightRules; + +}); + +define("ace/mode/css_completions",["require","exports","module"], function(require, exports, module) { +"use strict"; + +var propertyMap = { + "background": {"#$0": 1}, + "background-color": {"#$0": 1, "transparent": 1, "fixed": 1}, + "background-image": {"url('/$0')": 1}, + "background-repeat": {"repeat": 1, "repeat-x": 1, "repeat-y": 1, "no-repeat": 1, "inherit": 1}, + "background-position": {"bottom":2, "center":2, "left":2, "right":2, "top":2, "inherit":2}, + "background-attachment": {"scroll": 1, "fixed": 1}, + "background-size": {"cover": 1, "contain": 1}, + "background-clip": {"border-box": 1, "padding-box": 1, "content-box": 1}, + "background-origin": {"border-box": 1, "padding-box": 1, "content-box": 1}, + "border": {"solid $0": 1, "dashed $0": 1, "dotted $0": 1, "#$0": 1}, + "border-color": {"#$0": 1}, + "border-style": {"solid":2, "dashed":2, "dotted":2, "double":2, "groove":2, "hidden":2, "inherit":2, "inset":2, "none":2, "outset":2, "ridged":2}, + "border-collapse": {"collapse": 1, "separate": 1}, + "bottom": {"px": 1, "em": 1, "%": 1}, + "clear": {"left": 1, "right": 1, "both": 1, "none": 1}, + "color": {"#$0": 1, "rgb(#$00,0,0)": 1}, + "cursor": {"default": 1, "pointer": 1, "move": 1, "text": 1, "wait": 1, "help": 1, "progress": 1, "n-resize": 1, "ne-resize": 1, "e-resize": 1, "se-resize": 1, "s-resize": 1, "sw-resize": 1, "w-resize": 1, "nw-resize": 1}, + "display": {"none": 1, "block": 1, "inline": 1, "inline-block": 1, "table-cell": 1}, + "empty-cells": {"show": 1, "hide": 1}, + "float": {"left": 1, "right": 1, "none": 1}, + "font-family": {"Arial":2,"Comic Sans MS":2,"Consolas":2,"Courier New":2,"Courier":2,"Georgia":2,"Monospace":2,"Sans-Serif":2, "Segoe UI":2,"Tahoma":2,"Times New Roman":2,"Trebuchet MS":2,"Verdana": 1}, + "font-size": {"px": 1, "em": 1, "%": 1}, + "font-weight": {"bold": 1, "normal": 1}, + "font-style": {"italic": 1, "normal": 1}, + "font-variant": {"normal": 1, "small-caps": 1}, + "height": {"px": 1, "em": 1, "%": 1}, + "left": {"px": 1, "em": 1, "%": 1}, + "letter-spacing": {"normal": 1}, + "line-height": {"normal": 1}, + "list-style-type": {"none": 1, "disc": 1, "circle": 1, "square": 1, "decimal": 1, "decimal-leading-zero": 1, "lower-roman": 1, "upper-roman": 1, "lower-greek": 1, "lower-latin": 1, "upper-latin": 1, "georgian": 1, "lower-alpha": 1, "upper-alpha": 1}, + "margin": {"px": 1, "em": 1, "%": 1}, + "margin-right": {"px": 1, "em": 1, "%": 1}, + "margin-left": {"px": 1, "em": 1, "%": 1}, + "margin-top": {"px": 1, "em": 1, "%": 1}, + "margin-bottom": {"px": 1, "em": 1, "%": 1}, + "max-height": {"px": 1, "em": 1, "%": 1}, + "max-width": {"px": 1, "em": 1, "%": 1}, + "min-height": {"px": 1, "em": 1, "%": 1}, + "min-width": {"px": 1, "em": 1, "%": 1}, + "overflow": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1}, + "overflow-x": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1}, + "overflow-y": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1}, + "padding": {"px": 1, "em": 1, "%": 1}, + "padding-top": {"px": 1, "em": 1, "%": 1}, + "padding-right": {"px": 1, "em": 1, "%": 1}, + "padding-bottom": {"px": 1, "em": 1, "%": 1}, + "padding-left": {"px": 1, "em": 1, "%": 1}, + "page-break-after": {"auto": 1, "always": 1, "avoid": 1, "left": 1, "right": 1}, + "page-break-before": {"auto": 1, "always": 1, "avoid": 1, "left": 1, "right": 1}, + "position": {"absolute": 1, "relative": 1, "fixed": 1, "static": 1}, + "right": {"px": 1, "em": 1, "%": 1}, + "table-layout": {"fixed": 1, "auto": 1}, + "text-decoration": {"none": 1, "underline": 1, "line-through": 1, "blink": 1}, + "text-align": {"left": 1, "right": 1, "center": 1, "justify": 1}, + "text-transform": {"capitalize": 1, "uppercase": 1, "lowercase": 1, "none": 1}, + "top": {"px": 1, "em": 1, "%": 1}, + "vertical-align": {"top": 1, "bottom": 1}, + "visibility": {"hidden": 1, "visible": 1}, + "white-space": {"nowrap": 1, "normal": 1, "pre": 1, "pre-line": 1, "pre-wrap": 1}, + "width": {"px": 1, "em": 1, "%": 1}, + "word-spacing": {"normal": 1}, + "filter": {"alpha(opacity=$0100)": 1}, + + "text-shadow": {"$02px 2px 2px #777": 1}, + "text-overflow": {"ellipsis-word": 1, "clip": 1, "ellipsis": 1}, + "-moz-border-radius": 1, + "-moz-border-radius-topright": 1, + "-moz-border-radius-bottomright": 1, + "-moz-border-radius-topleft": 1, + "-moz-border-radius-bottomleft": 1, + "-webkit-border-radius": 1, + "-webkit-border-top-right-radius": 1, + "-webkit-border-top-left-radius": 1, + "-webkit-border-bottom-right-radius": 1, + "-webkit-border-bottom-left-radius": 1, + "-moz-box-shadow": 1, + "-webkit-box-shadow": 1, + "transform": {"rotate($00deg)": 1, "skew($00deg)": 1}, + "-moz-transform": {"rotate($00deg)": 1, "skew($00deg)": 1}, + "-webkit-transform": {"rotate($00deg)": 1, "skew($00deg)": 1 } +}; + +var CssCompletions = function() { + +}; + +(function() { + + this.completionsDefined = false; + + this.defineCompletions = function() { + if (document) { + var style = document.createElement('c').style; + + for (var i in style) { + if (typeof style[i] !== 'string') + continue; + + var name = i.replace(/[A-Z]/g, function(x) { + return '-' + x.toLowerCase(); + }); + + if (!propertyMap.hasOwnProperty(name)) + propertyMap[name] = 1; + } + } + + this.completionsDefined = true; + }; + + this.getCompletions = function(state, session, pos, prefix) { + if (!this.completionsDefined) { + this.defineCompletions(); + } + + if (state==='ruleset' || session.$mode.$id == "ace/mode/scss") { + var line = session.getLine(pos.row).substr(0, pos.column); + if (/:[^;]+$/.test(line)) { + /([\w\-]+):[^:]*$/.test(line); + + return this.getPropertyValueCompletions(state, session, pos, prefix); + } else { + return this.getPropertyCompletions(state, session, pos, prefix); + } + } + + return []; + }; + + this.getPropertyCompletions = function(state, session, pos, prefix) { + var properties = Object.keys(propertyMap); + return properties.map(function(property){ + return { + caption: property, + snippet: property + ': $0;', + meta: "property", + score: 1000000 + }; + }); + }; + + this.getPropertyValueCompletions = function(state, session, pos, prefix) { + var line = session.getLine(pos.row).substr(0, pos.column); + var property = (/([\w\-]+):[^:]*$/.exec(line) || {})[1]; + + if (!property) + return []; + var values = []; + if (property in propertyMap && typeof propertyMap[property] === "object") { + values = Object.keys(propertyMap[property]); + } + return values.map(function(value){ + return { + caption: value, + snippet: value, + meta: "property value", + score: 1000000 + }; + }); + }; + +}).call(CssCompletions.prototype); + +exports.CssCompletions = CssCompletions; +}); + +define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Behaviour = require("../behaviour").Behaviour; +var CstyleBehaviour = require("./cstyle").CstyleBehaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; + +var CssBehaviour = function () { + + this.inherit(CstyleBehaviour); + + this.add("colon", "insertion", function (state, action, editor, session, text) { + if (text === ':' && editor.selection.isEmpty()) { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + if (token && token.value.match(/\s+/)) { + token = iterator.stepBackward(); + } + if (token && token.type === 'support.type') { + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar === ':') { + return { + text: '', + selection: [1, 1] + }; + } + if (/^(\s+[^;]|\s*$)/.test(line.substring(cursor.column))) { + return { + text: ':;', + selection: [1, 1] + }; + } + } + } + }); + + this.add("colon", "deletion", function (state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected === ':') { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + if (token && token.value.match(/\s+/)) { + token = iterator.stepBackward(); + } + if (token && token.type === 'support.type') { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.end.column, range.end.column + 1); + if (rightChar === ';') { + range.end.column ++; + return range; + } + } + } + }); + + this.add("semicolon", "insertion", function (state, action, editor, session, text) { + if (text === ';' && editor.selection.isEmpty()) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar === ';') { + return { + text: '', + selection: [1, 1] + }; + } + } + }); + + this.add("!important", "insertion", function (state, action, editor, session, text) { + if (text === '!' && editor.selection.isEmpty()) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + + if (/^\s*(;|}|$)/.test(line.substring(cursor.column))) { + return { + text: '!important', + selection: [10, 10] + }; + } + } + }); + +}; +oop.inherits(CssBehaviour, CstyleBehaviour); + +exports.CssBehaviour = CssBehaviour; +}); + +define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var CssCompletions = require("./css_completions").CssCompletions; +var CssBehaviour = require("./behaviour/css").CssBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = CssHighlightRules; + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CssBehaviour(); + this.$completer = new CssCompletions(); + this.foldingRules = new CStyleFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.foldingRules = "cStyle"; + this.blockComment = {start: "/*", end: "*/"}; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + var tokens = this.getTokenizer().getLineTokens(line, state).tokens; + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + var match = line.match(/^.*\{\s*$/); + if (match) { + indent += tab; + } + + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.getCompletions = function(state, session, pos, prefix) { + return this.$completer.getCompletions(state, session, pos, prefix); + }; + + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker"); + worker.attachToDocument(session.getDocument()); + + worker.on("annotate", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; +}).call(Mode.prototype); + +exports.Mode = Mode; + +}); + +define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var XmlHighlightRules = function(normalize) { + var tagRegex = "[_:a-zA-Z\xc0-\uffff][-_:.a-zA-Z0-9\xc0-\uffff]*"; + + this.$rules = { + start : [ + {token : "string.cdata.xml", regex : "<\\!\\[CDATA\\[", next : "cdata"}, + { + token : ["punctuation.instruction.xml", "keyword.instruction.xml"], + regex : "(<\\?)(" + tagRegex + ")", next : "processing_instruction" + }, + {token : "comment.start.xml", regex : "<\\!--", next : "comment"}, + { + token : ["xml-pe.doctype.xml", "xml-pe.doctype.xml"], + regex : "(<\\!)(DOCTYPE)(?=[\\s])", next : "doctype", caseInsensitive: true + }, + {include : "tag"}, + {token : "text.end-tag-open.xml", regex: "", + next : "start" + }], + + doctype : [ + {include : "whitespace"}, + {include : "string"}, + {token : "xml-pe.doctype.xml", regex : ">", next : "start"}, + {token : "xml-pe.xml", regex : "[-_a-zA-Z0-9:]+"}, + {token : "punctuation.int-subset", regex : "\\[", push : "int_subset"} + ], + + int_subset : [{ + token : "text.xml", + regex : "\\s+" + }, { + token: "punctuation.int-subset.xml", + regex: "]", + next: "pop" + }, { + token : ["punctuation.markup-decl.xml", "keyword.markup-decl.xml"], + regex : "(<\\!)(" + tagRegex + ")", + push : [{ + token : "text", + regex : "\\s+" + }, + { + token : "punctuation.markup-decl.xml", + regex : ">", + next : "pop" + }, + {include : "string"}] + }], + + cdata : [ + {token : "string.cdata.xml", regex : "\\]\\]>", next : "start"}, + {token : "text.xml", regex : "\\s+"}, + {token : "text.xml", regex : "(?:[^\\]]|\\](?!\\]>))+"} + ], + + comment : [ + {token : "comment.end.xml", regex : "-->", next : "start"}, + {defaultToken : "comment.xml"} + ], + + reference : [{ + token : "constant.language.escape.reference.xml", + regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" + }], + + attr_reference : [{ + token : "constant.language.escape.reference.attribute-value.xml", + regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" + }], + + tag : [{ + token : ["meta.tag.punctuation.tag-open.xml", "meta.tag.punctuation.end-tag-open.xml", "meta.tag.tag-name.xml"], + regex : "(?:(<)|(", next : "start"} + ] + }], + + tag_whitespace : [ + {token : "text.tag-whitespace.xml", regex : "\\s+"} + ], + whitespace : [ + {token : "text.whitespace.xml", regex : "\\s+"} + ], + string: [{ + token : "string.xml", + regex : "'", + push : [ + {token : "string.xml", regex: "'", next: "pop"}, + {defaultToken : "string.xml"} + ] + }, { + token : "string.xml", + regex : '"', + push : [ + {token : "string.xml", regex: '"', next: "pop"}, + {defaultToken : "string.xml"} + ] + }], + + attributes: [{ + token : "entity.other.attribute-name.xml", + regex : tagRegex + }, { + token : "keyword.operator.attribute-equals.xml", + regex : "=" + }, { + include: "tag_whitespace" + }, { + include: "attribute_value" + }], + + attribute_value: [{ + token : "string.attribute-value.xml", + regex : "'", + push : [ + {token : "string.attribute-value.xml", regex: "'", next: "pop"}, + {include : "attr_reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }, { + token : "string.attribute-value.xml", + regex : '"', + push : [ + {token : "string.attribute-value.xml", regex: '"', next: "pop"}, + {include : "attr_reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }] + }; + + if (this.constructor === XmlHighlightRules) + this.normalizeRules(); +}; + + +(function() { + + this.embedTagRules = function(HighlightRules, prefix, tag){ + this.$rules.tag.unshift({ + token : ["meta.tag.punctuation.tag-open.xml", "meta.tag." + tag + ".tag-name.xml"], + regex : "(<)(" + tag + "(?=\\s|>|$))", + next: [ + {include : "attributes"}, + {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : prefix + "start"} + ] + }); + + this.$rules[tag + "-end"] = [ + {include : "attributes"}, + {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next: "start", + onMatch : function(value, currentState, stack) { + stack.splice(0); + return this.token; + }} + ]; + + this.embedRules(HighlightRules, prefix, [{ + token: ["meta.tag.punctuation.end-tag-open.xml", "meta.tag." + tag + ".tag-name.xml"], + regex : "(|$))", + next: tag + "-end" + }, { + token: "string.cdata.xml", + regex : "<\\!\\[CDATA\\[" + }, { + token: "string.cdata.xml", + regex : "\\]\\]>" + }]); + }; + +}).call(TextHighlightRules.prototype); + +oop.inherits(XmlHighlightRules, TextHighlightRules); + +exports.XmlHighlightRules = XmlHighlightRules; +}); + +define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; +var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; +var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules; + +var tagMap = lang.createMap({ + a : 'anchor', + button : 'form', + form : 'form', + img : 'image', + input : 'form', + label : 'form', + option : 'form', + script : 'script', + select : 'form', + textarea : 'form', + style : 'style', + table : 'table', + tbody : 'table', + td : 'table', + tfoot : 'table', + th : 'table', + tr : 'table' +}); + +var HtmlHighlightRules = function() { + XmlHighlightRules.call(this); + + this.addRules({ + attributes: [{ + include : "tag_whitespace" + }, { + token : "entity.other.attribute-name.xml", + regex : "[-_a-zA-Z0-9:.]+" + }, { + token : "keyword.operator.attribute-equals.xml", + regex : "=", + push : [{ + include: "tag_whitespace" + }, { + token : "string.unquoted.attribute-value.html", + regex : "[^<>='\"`\\s]+", + next : "pop" + }, { + token : "empty", + regex : "", + next : "pop" + }] + }, { + include : "attribute_value" + }], + tag: [{ + token : function(start, tag) { + var group = tagMap[tag]; + return ["meta.tag.punctuation." + (start == "<" ? "" : "end-") + "tag-open.xml", + "meta.tag" + (group ? "." + group : "") + ".tag-name.xml"]; + }, + regex : "(", next : "start"} + ] + }); + + this.embedTagRules(CssHighlightRules, "css-", "style"); + this.embedTagRules(new JavaScriptHighlightRules({jsx: false}).getRules(), "js-", "script"); + + if (this.constructor === HtmlHighlightRules) + this.normalizeRules(); +}; + +oop.inherits(HtmlHighlightRules, XmlHighlightRules); + +exports.HtmlHighlightRules = HtmlHighlightRules; +}); + +define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Behaviour = require("../behaviour").Behaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; +var lang = require("../../lib/lang"); + +function is(token, type) { + return token && token.type.lastIndexOf(type + ".xml") > -1; +} + +var XmlBehaviour = function () { + + this.add("string_dquotes", "insertion", function (state, action, editor, session, text) { + if (text == '"' || text == "'") { + var quote = text; + var selected = session.doc.getTextRange(editor.getSelectionRange()); + if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { + return { + text: quote + selected + quote, + selection: false + }; + } + + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + + if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) { + return { + text: "", + selection: [1, 1] + }; + } + + if (!token) + token = iterator.stepBackward(); + + if (!token) + return; + + while (is(token, "tag-whitespace") || is(token, "whitespace")) { + token = iterator.stepBackward(); + } + var rightSpace = !rightChar || rightChar.match(/\s/); + if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) { + return { + text: quote + quote, + selection: [1, 1] + }; + } + } + }); + + this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && (selected == '"' || selected == "'")) { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == selected) { + range.end.column++; + return range; + } + } + }); + + this.add("autoclosing", "insertion", function (state, action, editor, session, text) { + if (text == '>') { + var position = editor.getSelectionRange().start; + var iterator = new TokenIterator(session, position.row, position.column); + var token = iterator.getCurrentToken() || iterator.stepBackward(); + if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value"))) + return; + if (is(token, "reference.attribute-value")) + return; + if (is(token, "attribute-value")) { + var tokenEndColumn = iterator.getCurrentTokenColumn() + token.value.length; + if (position.column < tokenEndColumn) + return; + if (position.column == tokenEndColumn) { + var nextToken = iterator.stepForward(); + if (nextToken && is(nextToken, "attribute-value")) + return; + iterator.stepBackward(); + } + } + + if (/^\s*>/.test(session.getLine(position.row).slice(position.column))) + return; + while (!is(token, "tag-name")) { + token = iterator.stepBackward(); + if (token.value == "<") { + token = iterator.stepForward(); + break; + } + } + + var tokenRow = iterator.getCurrentTokenRow(); + var tokenColumn = iterator.getCurrentTokenColumn(); + if (is(iterator.stepBackward(), "end-tag-open")) + return; + + var element = token.value; + if (tokenRow == position.row) + element = element.substring(0, position.column - tokenColumn); + + if (this.voidElements.hasOwnProperty(element.toLowerCase())) + return; + + return { + text: ">" + "", + selection: [1, 1] + }; + } + }); + + this.add("autoindent", "insertion", function (state, action, editor, session, text) { + if (text == "\n") { + var cursor = editor.getCursorPosition(); + var line = session.getLine(cursor.row); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + + if (token && token.type.indexOf("tag-close") !== -1) { + if (token.value == "/>") + return; + while (token && token.type.indexOf("tag-name") === -1) { + token = iterator.stepBackward(); + } + + if (!token) { + return; + } + + var tag = token.value; + var row = iterator.getCurrentTokenRow(); + token = iterator.stepBackward(); + if (!token || token.type.indexOf("end-tag") !== -1) { + return; + } + + if (this.voidElements && !this.voidElements[tag]) { + var nextToken = session.getTokenAt(cursor.row, cursor.column+1); + var line = session.getLine(row); + var nextIndent = this.$getIndent(line); + var indent = nextIndent + session.getTabString(); + + if (nextToken && nextToken.value === " -1; +} + +(function() { + + this.getFoldWidget = function(session, foldStyle, row) { + var tag = this._getFirstTagInLine(session, row); + + if (!tag) + return this.getCommentFoldWidget(session, row); + + if (tag.closing || (!tag.tagName && tag.selfClosing)) + return foldStyle == "markbeginend" ? "end" : ""; + + if (!tag.tagName || tag.selfClosing || this.voidElements.hasOwnProperty(tag.tagName.toLowerCase())) + return ""; + + if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column)) + return ""; + + return "start"; + }; + + this.getCommentFoldWidget = function(session, row) { + if (/comment/.test(session.getState(row)) && /'; + break; + } + } + return tag; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == '/>'; + return tag; + } + tag.start.column += token.value.length; + } + + return null; + }; + + this._findEndTagInLine = function(session, row, tagName, startColumn) { + var tokens = session.getTokens(row); + var column = 0; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + column += token.value.length; + if (column < startColumn) + continue; + if (is(token, "end-tag-open")) { + token = tokens[i + 1]; + if (token && token.value == tagName) + return true; + } + } + return false; + }; + this._readTagForward = function(iterator) { + var token = iterator.getCurrentToken(); + if (!token) + return null; + + var tag = new Tag(); + do { + if (is(token, "tag-open")) { + tag.closing = is(token, "end-tag-open"); + tag.start.row = iterator.getCurrentTokenRow(); + tag.start.column = iterator.getCurrentTokenColumn(); + } else if (is(token, "tag-name")) { + tag.tagName = token.value; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == "/>"; + tag.end.row = iterator.getCurrentTokenRow(); + tag.end.column = iterator.getCurrentTokenColumn() + token.value.length; + iterator.stepForward(); + return tag; + } + } while(token = iterator.stepForward()); + + return null; + }; + + this._readTagBackward = function(iterator) { + var token = iterator.getCurrentToken(); + if (!token) + return null; + + var tag = new Tag(); + do { + if (is(token, "tag-open")) { + tag.closing = is(token, "end-tag-open"); + tag.start.row = iterator.getCurrentTokenRow(); + tag.start.column = iterator.getCurrentTokenColumn(); + iterator.stepBackward(); + return tag; + } else if (is(token, "tag-name")) { + tag.tagName = token.value; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == "/>"; + tag.end.row = iterator.getCurrentTokenRow(); + tag.end.column = iterator.getCurrentTokenColumn() + token.value.length; + } + } while(token = iterator.stepBackward()); + + return null; + }; + + this._pop = function(stack, tag) { + while (stack.length) { + + var top = stack[stack.length-1]; + if (!tag || top.tagName == tag.tagName) { + return stack.pop(); + } + else if (this.optionalEndTags.hasOwnProperty(top.tagName)) { + stack.pop(); + continue; + } else { + return null; + } + } + }; + + this.getFoldWidgetRange = function(session, foldStyle, row) { + var firstTag = this._getFirstTagInLine(session, row); + + if (!firstTag) { + return this.getCommentFoldWidget(session, row) + && session.getCommentFoldRange(row, session.getLine(row).length); + } + + var isBackward = firstTag.closing || firstTag.selfClosing; + var stack = []; + var tag; + + if (!isBackward) { + var iterator = new TokenIterator(session, row, firstTag.start.column); + var start = { + row: row, + column: firstTag.start.column + firstTag.tagName.length + 2 + }; + if (firstTag.start.row == firstTag.end.row) + start.column = firstTag.end.column; + while (tag = this._readTagForward(iterator)) { + if (tag.selfClosing) { + if (!stack.length) { + tag.start.column += tag.tagName.length + 2; + tag.end.column -= 2; + return Range.fromPoints(tag.start, tag.end); + } else + continue; + } + + if (tag.closing) { + this._pop(stack, tag); + if (stack.length == 0) + return Range.fromPoints(start, tag.start); + } + else { + stack.push(tag); + } + } + } + else { + var iterator = new TokenIterator(session, row, firstTag.end.column); + var end = { + row: row, + column: firstTag.start.column + }; + + while (tag = this._readTagBackward(iterator)) { + if (tag.selfClosing) { + if (!stack.length) { + tag.start.column += tag.tagName.length + 2; + tag.end.column -= 2; + return Range.fromPoints(tag.start, tag.end); + } else + continue; + } + + if (!tag.closing) { + this._pop(stack, tag); + if (stack.length == 0) { + tag.start.column += tag.tagName.length + 2; + if (tag.start.row == tag.end.row && tag.start.column < tag.end.column) + tag.start.column = tag.end.column; + return Range.fromPoints(tag.start, end); + } + } + else { + stack.push(tag); + } + } + } + + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var MixedFoldMode = require("./mixed").FoldMode; +var XmlFoldMode = require("./xml").FoldMode; +var CStyleFoldMode = require("./cstyle").FoldMode; + +var FoldMode = exports.FoldMode = function(voidElements, optionalTags) { + MixedFoldMode.call(this, new XmlFoldMode(voidElements, optionalTags), { + "js-": new CStyleFoldMode(), + "css-": new CStyleFoldMode() + }); +}; + +oop.inherits(FoldMode, MixedFoldMode); + +}); + +define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"], function(require, exports, module) { +"use strict"; + +var TokenIterator = require("../token_iterator").TokenIterator; + +var commonAttributes = [ + "accesskey", + "class", + "contenteditable", + "contextmenu", + "dir", + "draggable", + "dropzone", + "hidden", + "id", + "inert", + "itemid", + "itemprop", + "itemref", + "itemscope", + "itemtype", + "lang", + "spellcheck", + "style", + "tabindex", + "title", + "translate" +]; + +var eventAttributes = [ + "onabort", + "onblur", + "oncancel", + "oncanplay", + "oncanplaythrough", + "onchange", + "onclick", + "onclose", + "oncontextmenu", + "oncuechange", + "ondblclick", + "ondrag", + "ondragend", + "ondragenter", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onended", + "onerror", + "onfocus", + "oninput", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeyup", + "onload", + "onloadeddata", + "onloadedmetadata", + "onloadstart", + "onmousedown", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onpause", + "onplay", + "onplaying", + "onprogress", + "onratechange", + "onreset", + "onscroll", + "onseeked", + "onseeking", + "onselect", + "onshow", + "onstalled", + "onsubmit", + "onsuspend", + "ontimeupdate", + "onvolumechange", + "onwaiting" +]; + +var globalAttributes = commonAttributes.concat(eventAttributes); + +var attributeMap = { + "a": {"href": 1, "target": {"_blank": 1, "top": 1}, "ping": 1, "rel": {"nofollow": 1, "alternate": 1, "author": 1, "bookmark": 1, "help": 1, "license": 1, "next": 1, "noreferrer": 1, "prefetch": 1, "prev": 1, "search": 1, "tag": 1}, "media": 1, "hreflang": 1, "type": 1}, + "abbr": {}, + "address": {}, + "area": {"shape": 1, "coords": 1, "href": 1, "hreflang": 1, "alt": 1, "target": 1, "media": 1, "rel": 1, "ping": 1, "type": 1}, + "article": {"pubdate": 1}, + "aside": {}, + "audio": {"src": 1, "autobuffer": 1, "autoplay": {"autoplay": 1}, "loop": {"loop": 1}, "controls": {"controls": 1}, "muted": {"muted": 1}, "preload": {"auto": 1, "metadata": 1, "none": 1 }}, + "b": {}, + "base": {"href": 1, "target": 1}, + "bdi": {}, + "bdo": {}, + "blockquote": {"cite": 1}, + "body": {"onafterprint": 1, "onbeforeprint": 1, "onbeforeunload": 1, "onhashchange": 1, "onmessage": 1, "onoffline": 1, "onpopstate": 1, "onredo": 1, "onresize": 1, "onstorage": 1, "onundo": 1, "onunload": 1}, + "br": {}, + "button": {"autofocus": 1, "disabled": {"disabled": 1}, "form": 1, "formaction": 1, "formenctype": 1, "formmethod": 1, "formnovalidate": 1, "formtarget": 1, "name": 1, "value": 1, "type": {"button": 1, "submit": 1}}, + "canvas": {"width": 1, "height": 1}, + "caption": {}, + "cite": {}, + "code": {}, + "col": {"span": 1}, + "colgroup": {"span": 1}, + "command": {"type": 1, "label": 1, "icon": 1, "disabled": 1, "checked": 1, "radiogroup": 1, "command": 1}, + "data": {}, + "datalist": {}, + "dd": {}, + "del": {"cite": 1, "datetime": 1}, + "details": {"open": 1}, + "dfn": {}, + "dialog": {"open": 1}, + "div": {}, + "dl": {}, + "dt": {}, + "em": {}, + "embed": {"src": 1, "height": 1, "width": 1, "type": 1}, + "fieldset": {"disabled": 1, "form": 1, "name": 1}, + "figcaption": {}, + "figure": {}, + "footer": {}, + "form": {"accept-charset": 1, "action": 1, "autocomplete": 1, "enctype": {"multipart/form-data": 1, "application/x-www-form-urlencoded": 1}, "method": {"get": 1, "post": 1}, "name": 1, "novalidate": 1, "target": {"_blank": 1, "top": 1}}, + "h1": {}, + "h2": {}, + "h3": {}, + "h4": {}, + "h5": {}, + "h6": {}, + "head": {}, + "header": {}, + "hr": {}, + "html": {"manifest": 1}, + "i": {}, + "iframe": {"name": 1, "src": 1, "height": 1, "width": 1, "sandbox": {"allow-same-origin": 1, "allow-top-navigation": 1, "allow-forms": 1, "allow-scripts": 1}, "seamless": {"seamless": 1}}, + "img": {"alt": 1, "src": 1, "height": 1, "width": 1, "usemap": 1, "ismap": 1}, + "input": { + "type": {"text": 1, "password": 1, "hidden": 1, "checkbox": 1, "submit": 1, "radio": 1, "file": 1, "button": 1, "reset": 1, "image": 31, "color": 1, "date": 1, "datetime": 1, "datetime-local": 1, "email": 1, "month": 1, "number": 1, "range": 1, "search": 1, "tel": 1, "time": 1, "url": 1, "week": 1}, + "accept": 1, "alt": 1, "autocomplete": {"on": 1, "off": 1}, "autofocus": {"autofocus": 1}, "checked": {"checked": 1}, "disabled": {"disabled": 1}, "form": 1, "formaction": 1, "formenctype": {"application/x-www-form-urlencoded": 1, "multipart/form-data": 1, "text/plain": 1}, "formmethod": {"get": 1, "post": 1}, "formnovalidate": {"formnovalidate": 1}, "formtarget": {"_blank": 1, "_self": 1, "_parent": 1, "_top": 1}, "height": 1, "list": 1, "max": 1, "maxlength": 1, "min": 1, "multiple": {"multiple": 1}, "name": 1, "pattern": 1, "placeholder": 1, "readonly": {"readonly": 1}, "required": {"required": 1}, "size": 1, "src": 1, "step": 1, "width": 1, "files": 1, "value": 1}, + "ins": {"cite": 1, "datetime": 1}, + "kbd": {}, + "keygen": {"autofocus": 1, "challenge": {"challenge": 1}, "disabled": {"disabled": 1}, "form": 1, "keytype": {"rsa": 1, "dsa": 1, "ec": 1}, "name": 1}, + "label": {"form": 1, "for": 1}, + "legend": {}, + "li": {"value": 1}, + "link": {"href": 1, "hreflang": 1, "rel": {"stylesheet": 1, "icon": 1}, "media": {"all": 1, "screen": 1, "print": 1}, "type": {"text/css": 1, "image/png": 1, "image/jpeg": 1, "image/gif": 1}, "sizes": 1}, + "main": {}, + "map": {"name": 1}, + "mark": {}, + "math": {}, + "menu": {"type": 1, "label": 1}, + "meta": {"http-equiv": {"content-type": 1}, "name": {"description": 1, "keywords": 1}, "content": {"text/html; charset=UTF-8": 1}, "charset": 1}, + "meter": {"value": 1, "min": 1, "max": 1, "low": 1, "high": 1, "optimum": 1}, + "nav": {}, + "noscript": {"href": 1}, + "object": {"param": 1, "data": 1, "type": 1, "height" : 1, "width": 1, "usemap": 1, "name": 1, "form": 1, "classid": 1}, + "ol": {"start": 1, "reversed": 1}, + "optgroup": {"disabled": 1, "label": 1}, + "option": {"disabled": 1, "selected": 1, "label": 1, "value": 1}, + "output": {"for": 1, "form": 1, "name": 1}, + "p": {}, + "param": {"name": 1, "value": 1}, + "pre": {}, + "progress": {"value": 1, "max": 1}, + "q": {"cite": 1}, + "rp": {}, + "rt": {}, + "ruby": {}, + "s": {}, + "samp": {}, + "script": {"charset": 1, "type": {"text/javascript": 1}, "src": 1, "defer": 1, "async": 1}, + "select": {"autofocus": 1, "disabled": 1, "form": 1, "multiple": {"multiple": 1}, "name": 1, "size": 1, "readonly":{"readonly": 1}}, + "small": {}, + "source": {"src": 1, "type": 1, "media": 1}, + "span": {}, + "strong": {}, + "style": {"type": 1, "media": {"all": 1, "screen": 1, "print": 1}, "scoped": 1}, + "sub": {}, + "sup": {}, + "svg": {}, + "table": {"summary": 1}, + "tbody": {}, + "td": {"headers": 1, "rowspan": 1, "colspan": 1}, + "textarea": {"autofocus": {"autofocus": 1}, "disabled": {"disabled": 1}, "form": 1, "maxlength": 1, "name": 1, "placeholder": 1, "readonly": {"readonly": 1}, "required": {"required": 1}, "rows": 1, "cols": 1, "wrap": {"on": 1, "off": 1, "hard": 1, "soft": 1}}, + "tfoot": {}, + "th": {"headers": 1, "rowspan": 1, "colspan": 1, "scope": 1}, + "thead": {}, + "time": {"datetime": 1}, + "title": {}, + "tr": {}, + "track": {"kind": 1, "src": 1, "srclang": 1, "label": 1, "default": 1}, + "section": {}, + "summary": {}, + "u": {}, + "ul": {}, + "var": {}, + "video": {"src": 1, "autobuffer": 1, "autoplay": {"autoplay": 1}, "loop": {"loop": 1}, "controls": {"controls": 1}, "width": 1, "height": 1, "poster": 1, "muted": {"muted": 1}, "preload": {"auto": 1, "metadata": 1, "none": 1}}, + "wbr": {} +}; + +var elements = Object.keys(attributeMap); + +function is(token, type) { + return token.type.lastIndexOf(type + ".xml") > -1; +} + +function findTagName(session, pos) { + var iterator = new TokenIterator(session, pos.row, pos.column); + var token = iterator.getCurrentToken(); + while (token && !is(token, "tag-name")){ + token = iterator.stepBackward(); + } + if (token) + return token.value; +} + +function findAttributeName(session, pos) { + var iterator = new TokenIterator(session, pos.row, pos.column); + var token = iterator.getCurrentToken(); + while (token && !is(token, "attribute-name")){ + token = iterator.stepBackward(); + } + if (token) + return token.value; +} + +var HtmlCompletions = function() { + +}; + +(function() { + + this.getCompletions = function(state, session, pos, prefix) { + var token = session.getTokenAt(pos.row, pos.column); + + if (!token) + return []; + if (is(token, "tag-name") || is(token, "tag-open") || is(token, "end-tag-open")) + return this.getTagCompletions(state, session, pos, prefix); + if (is(token, "tag-whitespace") || is(token, "attribute-name")) + return this.getAttributeCompletions(state, session, pos, prefix); + if (is(token, "attribute-value")) + return this.getAttributeValueCompletions(state, session, pos, prefix); + var line = session.getLine(pos.row).substr(0, pos.column); + if (/&[a-z]*$/i.test(line)) + return this.getHTMLEntityCompletions(state, session, pos, prefix); + + return []; + }; + + this.getTagCompletions = function(state, session, pos, prefix) { + return elements.map(function(element){ + return { + value: element, + meta: "tag", + score: 1000000 + }; + }); + }; + + this.getAttributeCompletions = function(state, session, pos, prefix) { + var tagName = findTagName(session, pos); + if (!tagName) + return []; + var attributes = globalAttributes; + if (tagName in attributeMap) { + attributes = attributes.concat(Object.keys(attributeMap[tagName])); + } + return attributes.map(function(attribute){ + return { + caption: attribute, + snippet: attribute + '="$0"', + meta: "attribute", + score: 1000000 + }; + }); + }; + + this.getAttributeValueCompletions = function(state, session, pos, prefix) { + var tagName = findTagName(session, pos); + var attributeName = findAttributeName(session, pos); + + if (!tagName) + return []; + var values = []; + if (tagName in attributeMap && attributeName in attributeMap[tagName] && typeof attributeMap[tagName][attributeName] === "object") { + values = Object.keys(attributeMap[tagName][attributeName]); + } + return values.map(function(value){ + return { + caption: value, + snippet: value, + meta: "attribute value", + score: 1000000 + }; + }); + }; + + this.getHTMLEntityCompletions = function(state, session, pos, prefix) { + var values = ['Aacute;', 'aacute;', 'Acirc;', 'acirc;', 'acute;', 'AElig;', 'aelig;', 'Agrave;', 'agrave;', 'alefsym;', 'Alpha;', 'alpha;', 'amp;', 'and;', 'ang;', 'Aring;', 'aring;', 'asymp;', 'Atilde;', 'atilde;', 'Auml;', 'auml;', 'bdquo;', 'Beta;', 'beta;', 'brvbar;', 'bull;', 'cap;', 'Ccedil;', 'ccedil;', 'cedil;', 'cent;', 'Chi;', 'chi;', 'circ;', 'clubs;', 'cong;', 'copy;', 'crarr;', 'cup;', 'curren;', 'Dagger;', 'dagger;', 'dArr;', 'darr;', 'deg;', 'Delta;', 'delta;', 'diams;', 'divide;', 'Eacute;', 'eacute;', 'Ecirc;', 'ecirc;', 'Egrave;', 'egrave;', 'empty;', 'emsp;', 'ensp;', 'Epsilon;', 'epsilon;', 'equiv;', 'Eta;', 'eta;', 'ETH;', 'eth;', 'Euml;', 'euml;', 'euro;', 'exist;', 'fnof;', 'forall;', 'frac12;', 'frac14;', 'frac34;', 'frasl;', 'Gamma;', 'gamma;', 'ge;', 'gt;', 'hArr;', 'harr;', 'hearts;', 'hellip;', 'Iacute;', 'iacute;', 'Icirc;', 'icirc;', 'iexcl;', 'Igrave;', 'igrave;', 'image;', 'infin;', 'int;', 'Iota;', 'iota;', 'iquest;', 'isin;', 'Iuml;', 'iuml;', 'Kappa;', 'kappa;', 'Lambda;', 'lambda;', 'lang;', 'laquo;', 'lArr;', 'larr;', 'lceil;', 'ldquo;', 'le;', 'lfloor;', 'lowast;', 'loz;', 'lrm;', 'lsaquo;', 'lsquo;', 'lt;', 'macr;', 'mdash;', 'micro;', 'middot;', 'minus;', 'Mu;', 'mu;', 'nabla;', 'nbsp;', 'ndash;', 'ne;', 'ni;', 'not;', 'notin;', 'nsub;', 'Ntilde;', 'ntilde;', 'Nu;', 'nu;', 'Oacute;', 'oacute;', 'Ocirc;', 'ocirc;', 'OElig;', 'oelig;', 'Ograve;', 'ograve;', 'oline;', 'Omega;', 'omega;', 'Omicron;', 'omicron;', 'oplus;', 'or;', 'ordf;', 'ordm;', 'Oslash;', 'oslash;', 'Otilde;', 'otilde;', 'otimes;', 'Ouml;', 'ouml;', 'para;', 'part;', 'permil;', 'perp;', 'Phi;', 'phi;', 'Pi;', 'pi;', 'piv;', 'plusmn;', 'pound;', 'Prime;', 'prime;', 'prod;', 'prop;', 'Psi;', 'psi;', 'quot;', 'radic;', 'rang;', 'raquo;', 'rArr;', 'rarr;', 'rceil;', 'rdquo;', 'real;', 'reg;', 'rfloor;', 'Rho;', 'rho;', 'rlm;', 'rsaquo;', 'rsquo;', 'sbquo;', 'Scaron;', 'scaron;', 'sdot;', 'sect;', 'shy;', 'Sigma;', 'sigma;', 'sigmaf;', 'sim;', 'spades;', 'sub;', 'sube;', 'sum;', 'sup;', 'sup1;', 'sup2;', 'sup3;', 'supe;', 'szlig;', 'Tau;', 'tau;', 'there4;', 'Theta;', 'theta;', 'thetasym;', 'thinsp;', 'THORN;', 'thorn;', 'tilde;', 'times;', 'trade;', 'Uacute;', 'uacute;', 'uArr;', 'uarr;', 'Ucirc;', 'ucirc;', 'Ugrave;', 'ugrave;', 'uml;', 'upsih;', 'Upsilon;', 'upsilon;', 'Uuml;', 'uuml;', 'weierp;', 'Xi;', 'xi;', 'Yacute;', 'yacute;', 'yen;', 'Yuml;', 'yuml;', 'Zeta;', 'zeta;', 'zwj;', 'zwnj;']; + + return values.map(function(value){ + return { + caption: value, + snippet: value, + meta: "html entity", + score: 1000000 + }; + }); + }; + +}).call(HtmlCompletions.prototype); + +exports.HtmlCompletions = HtmlCompletions; +}); + +define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var TextMode = require("./text").Mode; +var JavaScriptMode = require("./javascript").Mode; +var CssMode = require("./css").Mode; +var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; +var XmlBehaviour = require("./behaviour/xml").XmlBehaviour; +var HtmlFoldMode = require("./folding/html").FoldMode; +var HtmlCompletions = require("./html_completions").HtmlCompletions; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var voidElements = ["area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "meta", "menuitem", "param", "source", "track", "wbr"]; +var optionalEndTags = ["li", "dt", "dd", "p", "rt", "rp", "optgroup", "option", "colgroup", "td", "th"]; + +var Mode = function(options) { + this.fragmentContext = options && options.fragmentContext; + this.HighlightRules = HtmlHighlightRules; + this.$behaviour = new XmlBehaviour(); + this.$completer = new HtmlCompletions(); + + this.createModeDelegates({ + "js-": JavaScriptMode, + "css-": CssMode + }); + + this.foldingRules = new HtmlFoldMode(this.voidElements, lang.arrayToMap(optionalEndTags)); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.blockComment = {start: ""}; + + this.voidElements = lang.arrayToMap(voidElements); + + this.getNextLineIndent = function(state, line, tab) { + return this.$getIndent(line); + }; + + this.checkOutdent = function(state, line, input) { + return false; + }; + + this.getCompletions = function(state, session, pos, prefix) { + return this.$completer.getCompletions(state, session, pos, prefix); + }; + + this.createWorker = function(session) { + if (this.constructor != Mode) + return; + var worker = new WorkerClient(["ace"], "ace/mode/html_worker", "Worker"); + worker.attachToDocument(session.getDocument()); + + if (this.fragmentContext) + worker.call("setOptions", [{context: this.fragmentContext}]); + + worker.on("error", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); + +define("ace/mode/latte_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var LatteHighlightRules = function() { + HtmlHighlightRules.call(this); + for (var rule in this.$rules) { + this.$rules[rule].unshift( + { + token : "comment.start.latte", + regex : "\\{\\*", + push : [{ + token : "comment.end.latte", + regex : ".*\\*\\}", + next : "pop" + }, { + defaultToken : "comment" + }] + }, { + token : "meta.tag.punctuation.tag-open.latte", + regex : "\\{(?![\\s'\"{}]|$)/?", + push : [{ + token : "meta.tag.latte", + regex : "(?:_|=|[a-z]\\w*(?:[.:-]\\w+)*)?", + next: [{ + token : "meta.tag.punctuation.tag-close.latte", + regex : "\\}", + next : "pop" + }, { + include: "latte-content" + }] + }] + }); + } + this.$rules['tag_stuff'].unshift({ + token : "meta.attribute.latte", + regex : "n:[\\w-]+", + next : [{ + include: "tag_whitespace" + }, { + token : "keyword.operator.attribute-equals.xml", + regex : "=", + next : [{ + token : "string.attribute-value.xml", + regex : "'", + next : [ + {token : "string.attribute-value.xml", regex: "'", next: "tag_stuff"}, + {include : "latte-content"} + ] + }, { + token : "string.attribute-value.xml", + regex : '"', + next : [ + {token : "string.attribute-value.xml", regex: '"', next: "tag_stuff"}, + {include : "latte-content"} + ] + }, { + token : "text.tag-whitespace.xml", + regex : "\\s", + next: "tag_stuff" + }, { + token : "meta.tag.punctuation.tag-close.xml", + regex : "/?>", + next: "tag_stuff" + }, { + include : "latte-content" + }] + }, { + token : "empty", + regex : "", + next : "tag_stuff" + }] + }); + this.$rules["latte-content"] = [ + { + token : "comment.start.latte", // multi line comment + regex : "\\/\\*", + push : [ + { + token : "comment.end.latte", + regex : "\\*\\/", + next : "pop" + }, { + defaultToken : "comment" + } + ] + }, { + token : "string.start", // " string start + regex : '"', + push : [ + { + token : "constant.language.escape", + regex : '\\\\(?:[nrtvef\\\\"$]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2})' + }, { + token : "variable", + regex : /\$[\w]+(?:\[[\w\]+]|[=\-]>\w+)?/ + }, { + token : "variable", + regex : /\$\{[^"\}]+\}?/ // this is wrong but ok for now + }, + {token : "string.end", regex : '"', next : "pop"}, + {defaultToken : "string"} + ] + }, { + token : "string.start", // ' string start + regex : "'", + push : [ + {token : "constant.language.escape", regex : /\\['\\]/}, + {token : "string.end", regex : "'", next : "pop"}, + {defaultToken : "string"} + ] + }, { + token : "keyword.control", + regex : "\\b(?:INF|NAN|and|or|xor|AND|OR|XOR|clone|new|instanceof|return|continue|break|as)\\b" + }, { + token : "constant.language", + regex : "\\b(?:true|false|null|TRUE|FALSE|NULL)\\b" + }, { + token : "variable", + regex : /\$\w+/ + }, { + token : "constant.numeric", + regex : "[+-]?[0-9]+(?:\\.[0-9]+)?(?:e[0-9]+)?" + }, { + token : ["support.class", "keyword.operator"], + regex : "\\b(\\w+)(::)" + }, { + token : "constant.language", // constants + regex : "\\b(?:[A-Z0-9_]+)\\b" + }, { + token : "string.unquoted", + regex : "\\w+(?:-+\\w+)*" + }, { + token : "paren.lparen", + regex : "[[({]" + }, { + token : "paren.rparen", + regex : "[\\])}]" + }, { + token : "keyword.operator", + regex : "::|=>|->|\\?->|\\?\\?->|\\+\\+|--|<<|>>|<=>|<=|>=|===|!==|==|!=|<>|&&|\\|\\||\\?\\?|\\?>|\\*\\*|\\.\\.\\.|[^'\"]" // =>, any char except quotes + } + ]; + + this.normalizeRules(); +}; + +oop.inherits(LatteHighlightRules, TextHighlightRules); + +exports.LatteHighlightRules = LatteHighlightRules; +}); + +define("ace/mode/latte",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/latte_highlight_rules","ace/mode/matching_brace_outdent"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var HtmlMode = require("./html").Mode; +var LatteHighlightRules = require("./latte_highlight_rules").LatteHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; + +var Mode = function() { + HtmlMode.call(this); + this.HighlightRules = LatteHighlightRules; + this.$outdent = new MatchingBraceOutdent(); +}; +oop.inherits(Mode, HtmlMode); + +(function() { + this.blockComment = {start: "{*", end: "*}"}; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + + if (state == "start") { + var match = line.match(/^.*\{(?:if|else|elseif|ifset|elseifset|ifchanged|switch|case|foreach|iterateWhile|for|while|first|last|sep|try|capture|spaceless|snippet|block|define|embed|snippetArea)\b[^{]*$/); + if (match) { + indent += tab; + } + } + + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return /^\s+\{\/$/.test(line + input); + }; + + this.autoOutdent = function(state, doc, row) { + }; + + this.$id = "ace/mode/latte"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); (function() { + window.require(["ace/mode/latte"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-liquid.js b/htdocs/includes/ace/src/mode-liquid.js index 6bbf7d1e9d6..f22cfa98a4a 100644 --- a/htdocs/includes/ace/src/mode-liquid.js +++ b/htdocs/includes/ace/src/mode-liquid.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2725,6 +2728,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/liquid"; + this.snippetFileId = "ace/snippets/liquid"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-lsl.js b/htdocs/includes/ace/src/mode-lsl.js index f6d7a7497f5..a08ff25f31b 100644 --- a/htdocs/includes/ace/src/mode-lsl.js +++ b/htdocs/includes/ace/src/mode-lsl.js @@ -329,6 +329,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/lsl"; + this.snippetFileId = "ace/snippets/lsl"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-lua.js b/htdocs/includes/ace/src/mode-lua.js index e96b6c37a9b..a87f127a893 100644 --- a/htdocs/includes/ace/src/mode-lua.js +++ b/htdocs/includes/ace/src/mode-lua.js @@ -438,6 +438,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/lua"; + this.snippetFileId = "ace/snippets/lua"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-luapage.js b/htdocs/includes/ace/src/mode-luapage.js index 5f5ecce9079..49bbde3f148 100644 --- a/htdocs/includes/ace/src/mode-luapage.js +++ b/htdocs/includes/ace/src/mode-luapage.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2938,6 +2941,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/lua"; + this.snippetFileId = "ace/snippets/lua"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-makefile.js b/htdocs/includes/ace/src/mode-makefile.js index 0314c6a216b..f8d853bd52c 100644 --- a/htdocs/includes/ace/src/mode-makefile.js +++ b/htdocs/includes/ace/src/mode-makefile.js @@ -398,6 +398,7 @@ oop.inherits(Mode, TextMode); this.$indentWithTabs = true; this.$id = "ace/mode/makefile"; + this.snippetFileId = "ace/snippets/makefile"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-markdown.js b/htdocs/includes/ace/src/mode-markdown.js index ac4072175ec..42fa514fdf5 100644 --- a/htdocs/includes/ace/src/mode-markdown.js +++ b/htdocs/includes/ace/src/mode-markdown.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1986,6 +1987,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2539,6 +2541,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -3124,6 +3127,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/sh"; + this.snippetFileId = "ace/snippets/sh"; }).call(Mode.prototype); exports.Mode = Mode; @@ -3176,6 +3180,7 @@ oop.inherits(Mode, TextMode); } }; this.$id = "ace/mode/markdown"; + this.snippetFileId = "ace/snippets/markdown"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-maze.js b/htdocs/includes/ace/src/mode-maze.js index faa82968572..75e1da782da 100644 --- a/htdocs/includes/ace/src/mode-maze.js +++ b/htdocs/includes/ace/src/mode-maze.js @@ -278,6 +278,7 @@ oop.inherits(Mode, TextMode); (function() { this.lineCommentStart = "//"; this.$id = "ace/mode/maze"; + this.snippetFileId = "ace/snippets/maze"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-mediawiki.js b/htdocs/includes/ace/src/mode-mediawiki.js new file mode 100644 index 00000000000..199e90b9101 --- /dev/null +++ b/htdocs/includes/ace/src/mode-mediawiki.js @@ -0,0 +1,592 @@ +define("ace/mode/mediawiki_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var MediaWikiHighlightRules = function() { + this.$rules = { + start: [{ + include: "#switch" + }, { + include: "#redirect" + }, { + include: "#variable" + }, { + include: "#comment" + }, { + include: "#entity" + }, { + include: "#emphasis" + }, { + include: "#tag" + }, { + include: "#table" + }, { + include: "#hr" + }, { + include: "#heading" + }, { + include: "#link" + }, { + include: "#list" + }, { + include: "#template" + }], + "#hr": [{ + token: "markup.bold", + regex: /^[-]{4,}/ + }], + "#switch": [{ + token: "constant.language", + regex: /(__NOTOC__|__FORCETOC__|__TOC__|__NOEDITSECTION__|__NEWSECTIONLINK__|__NONEWSECTIONLINK__|__NOWYSIWYG__|__NOGALLERY__|__HIDDENCAT__|__EXPECTUNUSEDCATEGORY__|__NOCONTENTCONVERT__|__NOCC__|__NOTITLECONVERT__|__NOTC__|__START__|__END__|__INDEX__|__NOINDEX__|__STATICREDIRECT__|__NOGLOBAL__|__DISAMBIG__)/ + }], + "#redirect": [{ + token: [ + "keyword.control.redirect", + "meta.keyword.control" + ], + regex: /(^#REDIRECT|^#redirect|^#Redirect)(\s+)/ + }], + "#variable": [{ + token: "storage.type.variable", + regex: /{{{/, + push: [{ + token: "storage.type.variable", + regex: /}}}/, + next: "pop" + }, { + token: [ + "text", + "variable.other", + "text", + "keyword.operator" + ], + regex: /(\s*)(\w+)(\s*)((?:\|)?)/ + }, { + defaultToken: "storage.type.variable" + }] + }], + "#entity": [{ + token: "constant.character.entity", + regex: /&\w+;/ + }], + "#list": [{ + token: "markup.bold", + regex: /^[#*;:]+/, + push: [{ + token: "markup.list", + regex: /$/, + next: "pop" + }, { + include: "$self" + }, { + defaultToken: "markup.list" + }] + }], + "#template": [{ + token: [ + "storage.type.function", + "meta.template", + "entity.name.function", + "meta.template" + ], + regex: /({{)(\s*)([#\w: ]+)(\s*)/, + push: [{ + token: "storage.type.function", + regex: /}}/, + next: "pop" + }, { + token: [ + "storage", + "meta.structure.dictionary", + "support.type.property-name", + "meta.structure.dictionary", + "punctuation.separator.dictionary.key-value", + "meta.structure.dictionary", + "meta.structure.dictionary.value" + ], + regex: /(\|)(\s*)([a-zA-Z-]*)(\s*)(=)(\s*)([^|}]*)/, + push: [{ + token: "meta.structure.dictionary", + regex: /(?=}}|[|])/, + next: "pop" + }, { + defaultToken: "meta.structure.dictionary" + }] + }, { + token: ["storage", "meta.template.value"], + regex: /(\|)(.*?)/, + push: [{ + token: [], + regex: /(?=}}|[|])/, + next: "pop" + }, { + include: "$self" + }, { + defaultToken: "meta.template.value" + }] + }, { + defaultToken: "meta.template" + }] + }], + "#link": [{ + token: [ + "punctuation.definition.tag.begin", + "meta.tag.link.internal", + "entity.name.tag", + "meta.tag.link.internal", + "string.other.link.title", + "meta.tag.link.internal", + "punctuation.definition.tag" + ], + regex: /(\[\[)(\s*)((?:Category|Wikipedia)?)(:?)([^\]\]\|]+)(\s*)((?:\|)*)/, + push: [{ + token: "punctuation.definition.tag.end", + regex: /\]\]/, + next: "pop" + }, { + include: "$self" + }, { + defaultToken: "meta.tag.link.internal" + }] + }, { + token: [ + "punctuation.definition.tag.begin", + "meta.tag.link.external", + "meta.tag.link.external", + "string.unquoted", + "punctuation.definition.tag.end" + ], + regex: /(\[)(.*?)([\s]+)(.*?)(\])/ + }], + "#comment": [{ + token: "punctuation.definition.comment.html", + regex: //, + next: "pop" + }, { + defaultToken: "comment.block.html" + }] + }], + "#emphasis": [{ + token: [ + "punctuation.definition.tag.begin", + "markup.italic.bold", + "punctuation.definition.tag.end" + ], + regex: /(''''')(?!')(.*?)('''''|$)/ + }, { + token: [ + "punctuation.definition.tag.begin", + "markup.bold", + "punctuation.definition.tag.end" + ], + regex: /(''')(?!')(.*?)('''|$)/ + }, { + token: [ + "punctuation.definition.tag.begin", + "markup.italic", + "punctuation.definition.tag.end" + ], + regex: /('')(?!')(.*?)(''|$)/ + }], + "#heading": [{ + token: [ + "punctuation.definition.heading", + "entity.name.section", + "punctuation.definition.heading" + ], + regex: /(={1,6})(.+?)(\1)(?!=)/ + }], + "#tag": [{ + token: [ + "punctuation.definition.tag.begin", + "entity.name.tag", + "meta.tag.block.ref", + "punctuation.definition.tag.end" + ], + regex: /(<)(ref)((?:\s+.*?)?)(>)/, + caseInsensitive: true, + push: [{ + token: [ + "punctuation.definition.tag.begin", + "entity.name.tag", + "meta.tag.block.ref", + "punctuation.definition.tag.end" + ], + regex: /(<\/)(ref)(\s*)(>)/, + caseInsensitive: true, + next: "pop" + }, { + include: "$self" + }, { + defaultToken: "meta.tag.block.ref" + }] + }, + { + token: [ + "punctuation.definition.tag.begin", + "entity.name.tag", + "meta.tag.block.nowiki", + "punctuation.definition.tag.end" + ], + regex: /(<)(nowiki)((?:\s+.*?)?)(>)/, + caseInsensitive: true, + push: [{ + token: [ + "punctuation.definition.tag.begin", + "entity.name.tag", + "meta.tag.block.nowiki", + "punctuation.definition.tag.end" + ], + regex: /(<\/)(nowiki)(\s*)(>)/, + caseInsensitive: true, + next: "pop" + }, { + defaultToken: "meta.tag.block.nowiki" + }] + }, { + token: [ + "punctuation.definition.tag.begin", + "entity.name.tag" + ], + regex: /(<\/?)(noinclude|includeonly|onlyinclude)(?=\W)/, + caseInsensitive: true, + push: [{ + token: [ + "invalid.illegal", + "punctuation.definition.tag.end" + ], + regex: /((?:\/)?)(>)/, + next: "pop" + }, { + include: "#attribute" + }, { + defaultToken: "meta.tag.block.any" + }] + }, { + token: [ + "punctuation.definition.tag.begin", + "entity.name.tag" + ], + regex: /(<)(br|wbr|hr|meta|link)(?=\W)/, + caseInsensitive: true, + push: [{ + token: "punctuation.definition.tag.end", + regex: /\/?>/, + next: "pop" + }, { + include: "#attribute" + }, { + defaultToken: "meta.tag.other" + }] + }, { + token: [ + "punctuation.definition.tag.begin", + "entity.name.tag" + ], + regex: /(<\/?)(div|center|span|h1|h2|h3|h4|h5|h6|bdo|em|strong|cite|dfn|code|samp|kbd|var|abbr|blockquote|q|sub|sup|p|pre|ins|del|ul|ol|li|dl|dd|dt|table|caption|thead|tfoot|tbody|colgroup|col|tr|td|th|a|img|video|source|track|tt|b|i|big|small|strike|s|u|font|ruby|rb|rp|rt|rtc|math|figure|figcaption|bdi|data|time|mark|html)(?=\W)/, + caseInsensitive: true, + push: [{ + token: [ + "invalid.illegal", + "punctuation.definition.tag.end" + ], + regex: /((?:\/)?)(>)/, + next: "pop" + }, { + include: "#attribute" + }, { + defaultToken: "meta.tag.block" + }] + }, { + token: [ + "punctuation.definition.tag.begin", + "invalid.illegal" + ], + regex: /(<\/)(br|wbr|hr|meta|link)(?=\W)/, + caseInsensitive: true, + push: [{ + token: "punctuation.definition.tag.end", + regex: /\/?>/, + next: "pop" + }, { + include: "#attribute" + }, { + defaultToken: "meta.tag.other" + }] + }], + "#caption": [{ + token: [ + "meta.tag.block.table-caption", + "punctuation.definition.tag.begin" + ], + regex: /^(\s*)(\|\+)/, + push: [{ + token: "meta.tag.block.table-caption", + regex: /$/, + next: "pop" + }, { + defaultToken: "meta.tag.block.table-caption" + }] + }], + "#tr": [{ + token: [ + "meta.tag.block.tr", + "punctuation.definition.tag.begin", + "meta.tag.block.tr", + "invalid.illegal" + ], + regex: /^(\s*)(\|\-)([\s]*)(.*)/ + }], + "#th": [{ + token: [ + "meta.tag.block.th.heading", + "punctuation.definition.tag.begin", + "meta.tag.block.th.heading", + "punctuation.definition.tag", + "markup.bold" + ], + regex: /^(\s*)(!)(?:(.*?)(\|))?(.*?)(?=!!|$)/, + push: [{ + token: "meta.tag.block.th.heading", + regex: /$/, + next: "pop" + }, { + token: [ + "punctuation.definition.tag.begin", + "meta.tag.block.th.inline", + "punctuation.definition.tag", + "markup.bold" + ], + regex: /(!!)(?:(.*?)(\|))?(.*?)(?=!!|$)/ + }, { + include: "$self" + }, { + defaultToken: "meta.tag.block.th.heading" + }] + }], + "#td": [{ + token: [ + "meta.tag.block.td", + "punctuation.definition.tag.begin" + ], + regex: /^(\s*)(\|)/, + push: [{ + token: "meta.tag.block.td", + regex: /$/, + next: "pop" + }, { + include: "$self" + }, { + defaultToken: "meta.tag.block.td" + }] + }], + "#table": [{ + patterns: [{ + name: "meta.tag.block.table", + begin: "^\\s*({\\|)(.*?)$", + end: "^\\s*\\|}", + beginCaptures: { + 1: { + name: "punctuation.definition.tag.begin" + }, + 2: { + patterns: [{ + include: "#attribute" + }] + }, + 3: { + name: "invalid.illegal" + } + }, + endCaptures: { + 0: { + name: "punctuation.definition.tag.end" + } + }, + patterns: [{ + include: "#comment" + }, { + include: "#template" + }, { + include: "#caption" + }, { + include: "#tr" + }, { + include: "#th" + }, { + include: "#td" + }] + }], + repository: { + caption: { + name: "meta.tag.block.table-caption", + begin: "^\\s*(\\|\\+)", + end: "$", + beginCaptures: { + 1: { + name: "punctuation.definition.tag.begin" + } + } + }, + tr: { + name: "meta.tag.block.tr", + match: "^\\s*(\\|\\-)[\\s]*(.*)", + captures: { + 1: { + name: "punctuation.definition.tag.begin" + }, + 2: { + name: "invalid.illegal" + } + } + }, + th: { + name: "meta.tag.block.th.heading", + begin: "^\\s*(!)((.*?)(\\|))?(.*?)(?=(!!)|$)", + end: "$", + beginCaptures: { + 1: { + name: "punctuation.definition.tag.begin" + }, + 3: { + patterns: [{ + include: "#attribute" + }] + }, + 4: { + name: "punctuation.definition.tag" + }, + 5: { + name: "markup.bold" + } + }, + patterns: [{ + name: "meta.tag.block.th.inline", + match: "(!!)((.*?)(\\|))?(.*?)(?=(!!)|$)", + captures: { + 1: { + name: "punctuation.definition.tag.begin" + }, + 3: { + patterns: [{ + include: "#attribute" + }] + }, + 4: { + name: "punctuation.definition.tag" + }, + 5: { + name: "markup.bold" + } + } + }, { + include: "$self" + }] + }, + td: { + name: "meta.tag.block.td", + begin: "^\\s*(\\|)", + end: "$", + beginCaptures: { + 1: { + name: "punctuation.definition.tag.begin" + }, + 2: { + patterns: [{ + include: "#attribute" + }] + }, + 3: { + name: "punctuation.definition.tag" + } + }, + patterns: [{ + include: "$self" + }] + } + } + }], + "#attribute": [{ + include: "#string" + }, { + token: "entity.other.attribute-name", + regex: /\w+/ + }], + "#string": [{ + token: "string.quoted.double", + regex: /\"/, + push: [{ + token: "string.quoted.double", + regex: /\"/, + next: "pop" + }, { + defaultToken: "string.quoted.double" + }] + }, { + token: "string.quoted.single", + regex: /\'/, + push: [{ + token: "string.quoted.single", + regex: /\'/, + next: "pop" + }, { + defaultToken: "string.quoted.single" + }] + }], + "#url": [{ + token: "markup.underline.link", + regex: /(?:http(?:s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:\/?#\[\]@!\$&'\(\)\*\+,;=.]+/ + }, { + token: "invalid.illegal", + regex: /.*/ + }] + }; + + + this.normalizeRules(); +}; + +MediaWikiHighlightRules.metaData = { + name: "MediaWiki", + scopeName: "text.html.mediawiki", + fileTypes: ["mediawiki", "wiki"] +}; + + +oop.inherits(MediaWikiHighlightRules, TextHighlightRules); + +exports.MediaWikiHighlightRules = MediaWikiHighlightRules; +}); + +define("ace/mode/mediawiki",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/mediawiki_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var MediaWikiHighlightRules = require("./mediawiki_highlight_rules").MediaWikiHighlightRules; + +var Mode = function() { + this.HighlightRules = MediaWikiHighlightRules; +}; +oop.inherits(Mode, TextMode); + +(function() { + this.type = "text"; + this.blockComment = {start: ""}; + this.$id = "ace/mode/mediawiki"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); (function() { + window.require(["ace/mode/mediawiki"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-mips.js b/htdocs/includes/ace/src/mode-mips.js new file mode 100644 index 00000000000..4d28b88d676 --- /dev/null +++ b/htdocs/includes/ace/src/mode-mips.js @@ -0,0 +1,264 @@ +define("ace/mode/mips_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var MIPSHighlightRules = function() { + + var escapeRe = /\\(?:['"?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F\d]{2}|u[a-fA-F\d]{4}U[a-fA-F\d]{8}|.)/.source; + + this.$rules = { + start: [{ + token: "storage.modifier.mips", + regex: /\.\b(?:align|ascii|asciiz|byte|double|extern|float|globl|space|word)\b/, + comment: "Assembler directives for data storage" + }, { + token: "entity.name.section.mips", + regex: /\.\b(?:data|text|kdata|ktext|)\b/, + comment: "Segements: .data .text" + }, { + token: "variable.parameter.mips", + regex: /\$(?:(?:3[01]|[12]?[0-9]|[0-9])|zero|at|v[01]|a[0-3]|s[0-7]|t[0-9]|k[01]|gp|sp|fp|ra)/, + comment: "Registers by id $1, $2, ..." + }, { + token: "variable.parameter.mips", + regex: /\$f(?:[0-9]|[1-2][0-9]|3[0-1])/, + comment: "Floating point registers" + }, { + token: "support.function.source.mips", + regex: /\b(?:(?:add|sub|div|l|mov|mult|neg|s|c\.eq|c\.le|c\.lt)\.[ds]|cvt\.s\.[dw]|cvt\.d\.[sw]|cvt\.w\.[ds]|bc1[tf])\b/, + comment: "The MIPS floating-point instruction set" + }, { + token: "support.function.source.mips", + regex: /\b(?:add|addu|addi|addiu|sub|subu|and|andi|or|not|ori|nor|xor|xori|slt|sltu|slti|sltiu|sll|sllv|rol|srl|sra|srlv|ror|j|jr|jal|beq|bne|lw|sw|lb|sb|lui|move|mfhi|mflo|mthi|mtlo)\b/, + comment: "Just the hardcoded instructions provided by the MIPS assembly language" + }, { + token: "support.function.other.mips", + regex: /\b(?:abs|b|beqz|bge|bgt|bgtu|ble|bleu|blt|bltu|bnez|div|divu|la|li|move|mul|neg|not|rem|remu|seq|sge|sgt|sle|sne)\b/, + comment: "Pseudo instructions" + }, { + token: "entity.name.function.mips", + regex: /\bsyscall\b/, + comment: "Other" + }, { + token : "string", // character + regex : "(?:'\")(?:" + escapeRe + "|.)?(?:'\")" + }, { + token : "string.start", + regex : '\'', + stateName: "qstring", + next: [ + { token: "string", regex: /\\\s*$/, next: "qqstring" }, + { token: "constant.language.escape", regex: escapeRe }, + { token: "string.end", regex: '\'|$', next: "start" }, + { defaultToken: "string"} + ] + }, { + token : "string.start", + regex : '"', + stateName: "qqstring", + next: [ + { token: "string", regex: /\\\s*$/, next: "qqstring" }, + { token: "constant.language.escape", regex: escapeRe }, + { token: "string.end", regex: '"|$', next: "start" }, + { defaultToken: "string"} + ] + }, { + token: "constant.numeric.mips", + regex: /\b(?:\d+|0(?:x|X)[a-fA-F0-9]+)\b/, + comment: "Numbers like +12, -3, 55, 0x3F" + }, { + token: "entity.name.tag.mips", + regex: /\b[\w]+\b:/, + comment: "Labels at line start: begin_repeat: add ..." + }, { + token: "comment.assembly", + regex: /#.*$/, + comment: "Single line comments" + }] + }; + + this.normalizeRules(); +}; + +MIPSHighlightRules.metaData = { + fileTypes: ["s", "asm"], + name: "MIPS", + scopeName: "source.mips" +}; + + +oop.inherits(MIPSHighlightRules, TextHighlightRules); + +exports.MIPSHighlightRules = MIPSHighlightRules; +}); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/mips",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/mips_highlight_rules","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var MIPSHighlightRules = require("./mips_highlight_rules").MIPSHighlightRules; +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = MIPSHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = ["#"]; + this.$id = "ace/mode/mips"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); (function() { + window.require(["ace/mode/mips"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-nix.js b/htdocs/includes/ace/src/mode-nix.js index b1a426fb9b3..d5698eb141b 100644 --- a/htdocs/includes/ace/src/mode-nix.js +++ b/htdocs/includes/ace/src/mode-nix.js @@ -65,7 +65,7 @@ var c_cppHighlightRules = function() { var storageType = ( "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + - "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|" + + "_Imaginary|int|int8_t|int16_t|int32_t|int64_t|long|short|signed|size_t|struct|typedef|uint8_t|uint16_t|uint32_t|uint64_t|union|unsigned|void|" + "class|wchar_t|template|char16_t|char32_t" ); @@ -489,6 +489,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/c_cpp"; + this.snippetFileId = "ace/snippets/c_cpp"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-nsis.js b/htdocs/includes/ace/src/mode-nsis.js index 67c2abec063..10816422adf 100644 --- a/htdocs/includes/ace/src/mode-nsis.js +++ b/htdocs/includes/ace/src/mode-nsis.js @@ -13,7 +13,7 @@ var NSISHighlightRules = function() { caseInsensitive: true }, { token: "keyword.command.nsis", - regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadAndSetImage|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestLongPathAware|ManifestMaxVersionTested|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEAddResource|PEDllCharacteristics|PERemoveResource|PESubsysVer|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\b/, + regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetKnownFolderPath|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfRtlLanguage|IfShellVarContextAll|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadAndSetImage|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestLongPathAware|ManifestMaxVersionTested|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEAddResource|PEDllCharacteristics|PERemoveResource|PESubsysVer|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\b/, caseInsensitive: true }, { token: "keyword.control.nsis", diff --git a/htdocs/includes/ace/src/mode-nunjucks.js b/htdocs/includes/ace/src/mode-nunjucks.js index 57f1e9f32bb..c59a814e67d 100644 --- a/htdocs/includes/ace/src/mode-nunjucks.js +++ b/htdocs/includes/ace/src/mode-nunjucks.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-objectivec.js b/htdocs/includes/ace/src/mode-objectivec.js index 28a56917f03..0a2dbd08fba 100644 --- a/htdocs/includes/ace/src/mode-objectivec.js +++ b/htdocs/includes/ace/src/mode-objectivec.js @@ -65,7 +65,7 @@ var c_cppHighlightRules = function() { var storageType = ( "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + - "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|" + + "_Imaginary|int|int8_t|int16_t|int32_t|int64_t|long|short|signed|size_t|struct|typedef|uint8_t|uint16_t|uint32_t|uint64_t|union|unsigned|void|" + "class|wchar_t|template|char16_t|char32_t" ); diff --git a/htdocs/includes/ace/src/mode-perl.js b/htdocs/includes/ace/src/mode-perl.js index 978979b1e47..bc8d178c968 100644 --- a/htdocs/includes/ace/src/mode-perl.js +++ b/htdocs/includes/ace/src/mode-perl.js @@ -367,6 +367,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/perl"; + this.snippetFileId = "ace/snippets/perl"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-pgsql.js b/htdocs/includes/ace/src/mode-pgsql.js index 952319ef862..069b750eab6 100644 --- a/htdocs/includes/ace/src/mode-pgsql.js +++ b/htdocs/includes/ace/src/mode-pgsql.js @@ -526,10 +526,10 @@ var PythonHighlightRules = function() { regex: "\\s+" }, { token: "string", - regex: "'(.)*'" + regex: "'[^']*'" }, { token: "string", - regex: '"(.)*"' + regex: '"[^"]*"' }, { token: "function.support", regex: "(!s|!r|!a)" diff --git a/htdocs/includes/ace/src/mode-php.js b/htdocs/includes/ace/src/mode-php.js index b9acd2c8073..7db8bf2c7bd 100644 --- a/htdocs/includes/ace/src/mode-php.js +++ b/htdocs/includes/ace/src/mode-php.js @@ -2138,15 +2138,15 @@ var functionMap = { "Escapes single quote, double quotes and backslash characters in a string with backslashes" ], "apache_child_terminate": [ - "bool apache_child_terminate(void)", + "bool apache_child_terminate()", "Terminate apache process after this request" ], "apache_get_modules": [ - "array apache_get_modules(void)", + "array apache_get_modules()", "Get a list of loaded Apache modules" ], "apache_get_version": [ - "string apache_get_version(void)", + "string apache_get_version()", "Fetch Apache version" ], "apache_getenv": [ @@ -2178,7 +2178,7 @@ var functionMap = { "* fetch all headers that go out in case of an error or a subrequest" ], "apache_request_headers": [ - "array apache_request_headers(void)", + "array apache_request_headers()", "Fetch all HTTP request headers" ], "apache_request_headers_in": [ @@ -2194,7 +2194,7 @@ var functionMap = { "" ], "apache_request_log_error": [ - "boolean apache_request_log_error(string message, [long facility])", + "bool apache_request_log_error(string message, [long facility])", "" ], "apache_request_meets_conditions": [ @@ -2246,11 +2246,11 @@ var functionMap = { "" ], "apache_reset_timeout": [ - "bool apache_reset_timeout(void)", + "bool apache_reset_timeout()", "Reset the Apache write timer" ], "apache_response_headers": [ - "array apache_response_headers(void)", + "array apache_response_headers()", "Fetch all HTTP response headers" ], "apache_setenv": [ @@ -2337,6 +2337,14 @@ var functionMap = { "array array_keys(array input [, mixed search_value[, bool strict]])", "Return just the keys from the input array, optionally only for the specified search_value" ], + "array_key_first": [ + "mixed array_key_first(array arr)", + "Returns the first key of arr if the array is not empty; NULL otherwise" + ], + "array_key_last": [ + "mixed array_key_last(array arr)", + "Returns the last key of arr if the array is not empty; NULL otherwise" + ], "array_map": [ "array array_map(mixed callback, array input1 [, array input2 ,...])", "Applies the callback to the elements in given arrays." @@ -2694,7 +2702,7 @@ var functionMap = { "Change file mode" ], "chown": [ - "bool chown (string filename, mixed user)", + "bool chown(string filename, mixed user)", "Change file owner" ], "chr": [ @@ -2722,7 +2730,7 @@ var functionMap = { "Return all classes and interfaces implemented by SPL" ], "class_parents": [ - "array class_parents(object instance [, boolean autoload = true])", + "array class_parents(object instance [, bool autoload = true])", "Return an array containing the names of all parent classes" ], "clearstatcache": [ @@ -2734,7 +2742,7 @@ var functionMap = { "Close directory connection identified by the dir_handle" ], "closelog": [ - "bool closelog(void)", + "bool closelog()", "Close connection to system logger" ], "collator_asort": [ @@ -2826,11 +2834,11 @@ var functionMap = { "Return a string to confirm that the module is compiled in" ], "connection_aborted": [ - "int connection_aborted(void)", + "int connection_aborted()", "Returns true if client disconnected" ], "connection_status": [ - "int connection_status(void)", + "int connection_status()", "Returns the connection status bitfield" ], "constant": [ @@ -2875,7 +2883,7 @@ var functionMap = { ], "create_function": [ "string create_function(string args, string code)", - "Creates an anonymous function, and returns its name (funny, eh?)" + "Creates an anonymous function, and returns its name" ], "crypt": [ "string crypt(string str [, string salt])", @@ -2974,7 +2982,7 @@ var functionMap = { "Get information about the current transfers" ], "curl_multi_init": [ - "resource curl_multi_init(void)", + "resource curl_multi_init()", "Returns a new cURL multi handle" ], "curl_multi_remove_handle": [ @@ -3170,7 +3178,7 @@ var functionMap = { "* Set formatter pattern." ], "datefmt_set_timezone_id": [ - "boolean datefmt_set_timezone_id( IntlDateFormatter $mf,$timezone_id)", + "bool datefmt_set_timezone_id( IntlDateFormatter $mf,$timezone_id)", "* Set formatter timezone_id." ], "dba_close": [ @@ -3238,7 +3246,7 @@ var functionMap = { "Return the translation of msgid for domain_name and category, or msgid unaltered if a translation does not exist" ], "dcngettext": [ - "string dcngettext (string domain, string msgid1, string msgid2, int n, int category)", + "string dcngettext(string domain, string msgid1, string msgid2, int n, int category)", "Plural version of dcgettext()" ], "debug_backtrace": [ @@ -3246,44 +3254,231 @@ var functionMap = { "Return backtrace as array" ], "debug_print_backtrace": [ - "void debug_print_backtrace(void) */", - "ZEND_FUNCTION(debug_print_backtrace) { zend_execute_data *ptr, *skip; int lineno; char *function_name; char *filename; char *class_name = NULL; char *call_type; char *include_filename = NULL; zval *arg_array = NULL; int indent = 0; if (zend_parse_parameters_none() == FAILURE) { return; } ptr = EG(current_execute_data);", + "void debug_print_backtrace()", + "Prints a PHP backtrace" + ], + "debug_zval_dump": [ + "void debug_zval_dump(mixed var)", + "Dumps a string representation of an internal Zend value to output" + ], + "decbin": [ + "string decbin(int decimal_number)", + "Returns a string containing a binary representation of the number" + ], + "dechex": [ + "string dechex(int decimal_number)", + "Returns a string containing a hexadecimal representation of the given number" + ], + "decoct": [ + "string decoct(int decimal_number)", + "Returns a string containing an octal representation of the given number" + ], + "define": [ + "bool define(string constant_name, mixed value, bool case_insensitive=false)", + "Define a new constant" + ], + "define_syslog_variables": [ + "void define_syslog_variables()", + "Initializes all syslog-related variables" + ], + "defined": [ + "bool defined(string constant_name)", + "Check whether a constant exists" + ], + "deg2rad": [ + "float deg2rad(float number)", + "Converts the number in degrees to the radian equivalent" + ], + "dgettext": [ + "string dgettext(string domain_name, string msgid)", + "Return the translation of msgid for domain_name, or msgid unaltered if a translation does not exist" + ], + "die": [ + "void die([mixed status])", + "Output a message and terminate the current script" + ], + "dir": [ + "object dir(string directory[, resource context])", + "Directory class with properties, handle and class and methods read, rewind and close" + ], + "dirname": [ + "string dirname(string path)", + "Returns the directory name component of the path" + ], + "disk_free_space": [ + "float disk_free_space(string path)", + "Get free disk space for filesystem that path is on" + ], + "disk_total_space": [ + "float disk_total_space(string path)", + "Get total disk space for filesystem that path is on" + ], + "display_disabled_function": [ + "void display_disabled_function()", + "Dummy function which displays an error when a disabled function is called." + ], + "dl": [ + "int dl(string extension_filename)", + "Load a PHP extension at runtime" + ], + "dngettext": [ + "string dngettext(string domain, string msgid1, string msgid2, int count)", + "Plural version of dgettext()" + ], + "dns_check_record": [ + "bool dns_check_record(string host [, string type])", + "Check DNS records corresponding to a given Internet host name or IP address" + ], + "dns_get_mx": [ + "bool dns_get_mx(string hostname, array mxhosts [, array weight])", + "Get MX records corresponding to a given Internet host name" + ], + "dns_get_record": [ + "array|false dns_get_record(string hostname [, int type[, array authns, array addtl]])", + "Get any Resource Record corresponding to a given Internet host name" + ], + "dom_attr_is_id": [ + "bool dom_attr_is_id()", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId Since: DOM Level 3" + ], + "dom_characterdata_append_data": [ + "void dom_characterdata_append_data(string arg)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F Since:" + ], + "dom_characterdata_delete_data": [ + "void dom_characterdata_delete_data(int offset, int count)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781 Since:" + ], + "dom_characterdata_insert_data": [ + "void dom_characterdata_insert_data(int offset, string arg)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F Since:" + ], + "dom_characterdata_replace_data": [ + "void dom_characterdata_replace_data(int offset, int count, string arg)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB Since:" + ], + "dom_characterdata_substring_data": [ + "string dom_characterdata_substring_data(int offset, int count)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF Since:" + ], + "dom_document_adopt_node": [ + "DOMNode dom_document_adopt_node(DOMNode source)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode Since: DOM Level 3" + ], + "dom_document_create_attribute": [ + "DOMAttr dom_document_create_attribute(string name)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198 Since:" + ], + "dom_document_create_attribute_ns": [ + "DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS Since: DOM Level 2" + ], + "dom_document_create_cdatasection": [ + "DOMCdataSection dom_document_create_cdatasection(string data)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8 Since:" + ], + "dom_document_create_comment": [ + "DOMComment dom_document_create_comment(string data)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328 Since:" + ], + "dom_document_create_document_fragment": [ + "DOMDocumentFragment dom_document_create_document_fragment()", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5 Since:" + ], + "dom_document_create_element": [ + "DOMElement dom_document_create_element(string tagName [, string value])", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547 Since:" + ], + "dom_document_create_element_ns": [ + "DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value])", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS Since: DOM Level 2" + ], + "dom_document_create_entity_reference": [ + "DOMEntityReference dom_document_create_entity_reference(string name)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE Since:" + ], + "dom_document_create_processing_instruction": [ + "DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439 Since:" + ], + "dom_document_create_text_node": [ + "DOMText dom_document_create_text_node(string data)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127 Since:" + ], + "dom_document_get_element_by_id": [ + "DOMElement dom_document_get_element_by_id(string elementId)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId Since: DOM Level 2" + ], + "dom_document_get_elements_by_tag_name": [ + "DOMNodeList dom_document_get_elements_by_tag_name(string tagname)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094 Since:" + ], + "dom_document_get_elements_by_tag_name_ns": [ + "DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS Since: DOM Level 2" + ], + "dom_document_import_node": [ + "DOMNode dom_document_import_node(DOMNode importedNode, bool deep)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode Since: DOM Level 2" + ], + "dom_document_load": [ + "DOMNode dom_document_load(string source [, int options])", + "URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load Since: DOM Level 3" + ], + "dom_document_load_html": [ + "DOMNode dom_document_load_html(string source)", + "Since: DOM extended" + ], + "dom_document_load_html_file": [ + "DOMNode dom_document_load_html_file(string source)", + "Since: DOM extended" + ], + "dom_document_loadxml": [ + "DOMNode dom_document_loadxml(string source [, int options])", + "URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML Since: DOM Level 3" + ], + "dom_document_normalize_document": [ + "void dom_document_normalize_document()", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument Since: DOM Level 3" + ], + "dom_document_relaxNG_validate_file": [ + "bool dom_document_relaxNG_validate_file(string filename); */", "PHP_FUNCTION(dom_document_relaxNG_validate_file) { _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); } /* }}} end dom_document_relaxNG_validate_file" ], "dom_document_relaxNG_validate_xml": [ - "boolean dom_document_relaxNG_validate_xml(string source); */", + "bool dom_document_relaxNG_validate_xml(string source); */", "PHP_FUNCTION(dom_document_relaxNG_validate_xml) { _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); } /* }}} end dom_document_relaxNG_validate_xml" ], "dom_document_rename_node": [ - "DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName);", + "DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode Since: DOM Level 3" ], "dom_document_save": [ - "int dom_document_save(string file);", + "int dom_document_save(string file)", "Convenience method to save to file" ], "dom_document_save_html": [ - "string dom_document_save_html();", + "string dom_document_save_html()", "Convenience method to output as html" ], "dom_document_save_html_file": [ - "int dom_document_save_html_file(string file);", + "int dom_document_save_html_file(string file)", "Convenience method to save to file as html" ], "dom_document_savexml": [ - "string dom_document_savexml([node n]);", + "string dom_document_savexml([node n])", "URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML Since: DOM Level 3" ], "dom_document_schema_validate": [ - "boolean dom_document_schema_validate(string source); */", + "bool dom_document_schema_validate(string source); */", "PHP_FUNCTION(dom_document_schema_validate_xml) { _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); } /* }}} end dom_document_schema_validate" ], "dom_document_schema_validate_file": [ - "boolean dom_document_schema_validate_file(string filename); */", + "bool dom_document_schema_validate_file(string filename); */", "PHP_FUNCTION(dom_document_schema_validate_file) { _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); } /* }}} end dom_document_schema_validate_file" ], "dom_document_validate": [ - "boolean dom_document_validate();", + "bool dom_document_validate()", "Since: DOM extended" ], "dom_document_xinclude": [ @@ -3291,123 +3486,123 @@ var functionMap = { "Substitutues xincludes in a DomDocument" ], "dom_domconfiguration_can_set_parameter": [ - "boolean dom_domconfiguration_can_set_parameter(string name, domuserdata value);", + "bool dom_domconfiguration_can_set_parameter(string name, domuserdata value)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-canSetParameter Since:" ], "dom_domconfiguration_get_parameter": [ - "domdomuserdata dom_domconfiguration_get_parameter(string name);", + "domdomuserdata dom_domconfiguration_get_parameter(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-getParameter Since:" ], "dom_domconfiguration_set_parameter": [ - "dom_void dom_domconfiguration_set_parameter(string name, domuserdata value);", + "dom_void dom_domconfiguration_set_parameter(string name, domuserdata value)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-property Since:" ], "dom_domerrorhandler_handle_error": [ - "dom_boolean dom_domerrorhandler_handle_error(domerror error);", + "dom_bool dom_domerrorhandler_handle_error(domerror error)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-ERRORS-DOMErrorHandler-handleError Since:" ], "dom_domimplementation_create_document": [ - "DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype);", + "DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument Since: DOM Level 2" ], "dom_domimplementation_create_document_type": [ - "DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId);", + "DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType Since: DOM Level 2" ], "dom_domimplementation_get_feature": [ - "DOMNode dom_domimplementation_get_feature(string feature, string version);", + "DOMNode dom_domimplementation_get_feature(string feature, string version)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature Since: DOM Level 3" ], "dom_domimplementation_has_feature": [ - "boolean dom_domimplementation_has_feature(string feature, string version);", + "bool dom_domimplementation_has_feature(string feature, string version)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5CED94D7 Since:" ], "dom_domimplementationlist_item": [ - "domdomimplementation dom_domimplementationlist_item(int index);", + "domdomimplementation dom_domimplementationlist_item(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList-item Since:" ], "dom_domimplementationsource_get_domimplementation": [ - "domdomimplementation dom_domimplementationsource_get_domimplementation(string features);", + "domdomimplementation dom_domimplementationsource_get_domimplementation(string features)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpl Since:" ], "dom_domimplementationsource_get_domimplementations": [ - "domimplementationlist dom_domimplementationsource_get_domimplementations(string features);", + "domimplementationlist dom_domimplementationsource_get_domimplementations(string features)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpls Since:" ], "dom_domstringlist_item": [ - "domstring dom_domstringlist_item(int index);", + "domstring dom_domstringlist_item(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList-item Since:" ], "dom_element_get_attribute": [ - "string dom_element_get_attribute(string name);", + "string dom_element_get_attribute(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9 Since:" ], "dom_element_get_attribute_node": [ - "DOMAttr dom_element_get_attribute_node(string name);", + "DOMAttr dom_element_get_attribute_node(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8 Since:" ], "dom_element_get_attribute_node_ns": [ - "DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName);", + "DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS Since: DOM Level 2" ], "dom_element_get_attribute_ns": [ - "string dom_element_get_attribute_ns(string namespaceURI, string localName);", + "string dom_element_get_attribute_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS Since: DOM Level 2" ], "dom_element_get_elements_by_tag_name": [ - "DOMNodeList dom_element_get_elements_by_tag_name(string name);", + "DOMNodeList dom_element_get_elements_by_tag_name(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D Since:" ], "dom_element_get_elements_by_tag_name_ns": [ - "DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName);", + "DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942 Since: DOM Level 2" ], "dom_element_has_attribute": [ - "boolean dom_element_has_attribute(string name);", + "bool dom_element_has_attribute(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr Since: DOM Level 2" ], "dom_element_has_attribute_ns": [ - "boolean dom_element_has_attribute_ns(string namespaceURI, string localName);", + "bool dom_element_has_attribute_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS Since: DOM Level 2" ], "dom_element_remove_attribute": [ - "void dom_element_remove_attribute(string name);", + "void dom_element_remove_attribute(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9 Since:" ], "dom_element_remove_attribute_node": [ - "DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr);", + "DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198 Since:" ], "dom_element_remove_attribute_ns": [ - "void dom_element_remove_attribute_ns(string namespaceURI, string localName);", + "void dom_element_remove_attribute_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS Since: DOM Level 2" ], "dom_element_set_attribute": [ - "void dom_element_set_attribute(string name, string value);", + "void dom_element_set_attribute(string name, string value)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082 Since:" ], "dom_element_set_attribute_node": [ - "DOMAttr dom_element_set_attribute_node(DOMAttr newAttr);", + "DOMAttr dom_element_set_attribute_node(DOMAttr newAttr)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154 Since:" ], "dom_element_set_attribute_node_ns": [ - "DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr);", + "DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS Since: DOM Level 2" ], "dom_element_set_attribute_ns": [ - "void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value);", + "void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS Since: DOM Level 2" ], "dom_element_set_id_attribute": [ - "void dom_element_set_id_attribute(string name, boolean isId);", + "void dom_element_set_id_attribute(string name, bool isId)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttr Since: DOM Level 3" ], "dom_element_set_id_attribute_node": [ - "void dom_element_set_id_attribute_node(attr idAttr, boolean isId);", + "void dom_element_set_id_attribute_node(attr idAttr, bool isId)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode Since: DOM Level 3" ], "dom_element_set_id_attribute_ns": [ - "void dom_element_set_id_attribute_ns(string namespaceURI, string localName, boolean isId);", + "void dom_element_set_id_attribute_ns(string namespaceURI, string localName, bool isId)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNS Since: DOM Level 3" ], "dom_import_simplexml": [ @@ -3415,156 +3610,156 @@ var functionMap = { "Get a simplexml_element object from dom to allow for processing" ], "dom_namednodemap_get_named_item": [ - "DOMNode dom_namednodemap_get_named_item(string name);", + "DOMNode dom_namednodemap_get_named_item(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549 Since:" ], "dom_namednodemap_get_named_item_ns": [ - "DOMNode dom_namednodemap_get_named_item_ns(string namespaceURI, string localName);", + "DOMNode dom_namednodemap_get_named_item_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getNamedItemNS Since: DOM Level 2" ], "dom_namednodemap_item": [ - "DOMNode dom_namednodemap_item(int index);", + "DOMNode dom_namednodemap_item(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9 Since:" ], "dom_namednodemap_remove_named_item": [ - "DOMNode dom_namednodemap_remove_named_item(string name);", + "DOMNode dom_namednodemap_remove_named_item(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D58B193 Since:" ], "dom_namednodemap_remove_named_item_ns": [ - "DOMNode dom_namednodemap_remove_named_item_ns(string namespaceURI, string localName);", + "DOMNode dom_namednodemap_remove_named_item_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-removeNamedItemNS Since: DOM Level 2" ], "dom_namednodemap_set_named_item": [ - "DOMNode dom_namednodemap_set_named_item(DOMNode arg);", + "DOMNode dom_namednodemap_set_named_item(DOMNode arg)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1025163788 Since:" ], "dom_namednodemap_set_named_item_ns": [ - "DOMNode dom_namednodemap_set_named_item_ns(DOMNode arg);", + "DOMNode dom_namednodemap_set_named_item_ns(DOMNode arg)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-setNamedItemNS Since: DOM Level 2" ], "dom_namelist_get_name": [ - "string dom_namelist_get_name(int index);", + "string dom_namelist_get_name(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getName Since:" ], "dom_namelist_get_namespace_uri": [ - "string dom_namelist_get_namespace_uri(int index);", + "string dom_namelist_get_namespace_uri(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getNamespaceURI Since:" ], "dom_node_append_child": [ - "DomNode dom_node_append_child(DomNode newChild);", + "DomNode dom_node_append_child(DomNode newChild)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107 Since:" ], "dom_node_clone_node": [ - "DomNode dom_node_clone_node(boolean deep);", + "DomNode dom_node_clone_node(bool deep)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4 Since:" ], "dom_node_compare_document_position": [ - "short dom_node_compare_document_position(DomNode other);", + "short dom_node_compare_document_position(DomNode other)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition Since: DOM Level 3" ], "dom_node_get_feature": [ - "DomNode dom_node_get_feature(string feature, string version);", + "DomNode dom_node_get_feature(string feature, string version)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature Since: DOM Level 3" ], "dom_node_get_user_data": [ - "mixed dom_node_get_user_data(string key);", + "mixed dom_node_get_user_data(string key)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData Since: DOM Level 3" ], "dom_node_has_attributes": [ - "boolean dom_node_has_attributes();", + "bool dom_node_has_attributes()", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs Since: DOM Level 2" ], "dom_node_has_child_nodes": [ - "boolean dom_node_has_child_nodes();", + "bool dom_node_has_child_nodes()", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187 Since:" ], "dom_node_insert_before": [ - "domnode dom_node_insert_before(DomNode newChild, DomNode refChild);", + "domnode dom_node_insert_before(DomNode newChild, DomNode refChild)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727 Since:" ], "dom_node_is_default_namespace": [ - "boolean dom_node_is_default_namespace(string namespaceURI);", + "bool dom_node_is_default_namespace(string namespaceURI)", "URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace Since: DOM Level 3" ], "dom_node_is_equal_node": [ - "boolean dom_node_is_equal_node(DomNode arg);", + "bool dom_node_is_equal_node(DomNode arg)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode Since: DOM Level 3" ], "dom_node_is_same_node": [ - "boolean dom_node_is_same_node(DomNode other);", + "bool dom_node_is_same_node(DomNode other)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode Since: DOM Level 3" ], "dom_node_is_supported": [ - "boolean dom_node_is_supported(string feature, string version);", + "bool dom_node_is_supported(string feature, string version)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports Since: DOM Level 2" ], "dom_node_lookup_namespace_uri": [ - "string dom_node_lookup_namespace_uri(string prefix);", + "string dom_node_lookup_namespace_uri(string prefix)", "URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI Since: DOM Level 3" ], "dom_node_lookup_prefix": [ - "string dom_node_lookup_prefix(string namespaceURI);", + "string dom_node_lookup_prefix(string namespaceURI)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix Since: DOM Level 3" ], "dom_node_normalize": [ - "void dom_node_normalize();", + "void dom_node_normalize()", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize Since:" ], "dom_node_remove_child": [ - "DomNode dom_node_remove_child(DomNode oldChild);", + "DomNode dom_node_remove_child(DomNode oldChild)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066 Since:" ], "dom_node_replace_child": [ - "DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild);", + "DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307 Since:" ], "dom_node_set_user_data": [ - "mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler);", + "mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData Since: DOM Level 3" ], "dom_nodelist_item": [ - "DOMNode dom_nodelist_item(int index);", + "DOMNode dom_nodelist_item(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136 Since:" ], "dom_string_extend_find_offset16": [ - "int dom_string_extend_find_offset16(int offset32);", + "int dom_string_extend_find_offset16(int offset32)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset16 Since:" ], "dom_string_extend_find_offset32": [ - "int dom_string_extend_find_offset32(int offset16);", + "int dom_string_extend_find_offset32(int offset16)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset32 Since:" ], "dom_text_is_whitespace_in_element_content": [ - "boolean dom_text_is_whitespace_in_element_content();", + "bool dom_text_is_whitespace_in_element_content()", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-isWhitespaceInElementContent Since: DOM Level 3" ], "dom_text_replace_whole_text": [ - "DOMText dom_text_replace_whole_text(string content);", + "DOMText dom_text_replace_whole_text(string content)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-replaceWholeText Since: DOM Level 3" ], "dom_text_split_text": [ - "DOMText dom_text_split_text(int offset);", + "DOMText dom_text_split_text(int offset)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-38853C1D Since:" ], "dom_userdatahandler_handle": [ - "dom_void dom_userdatahandler_handle(short operation, string key, domobject data, node src, node dst);", + "dom_void dom_userdatahandler_handle(short operation, string key, domobject data, node src, node dst)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-handleUserDataEvent Since:" ], "dom_xpath_evaluate": [ - "mixed dom_xpath_evaluate(string expr [,DOMNode context]); */", - "PHP_FUNCTION(dom_xpath_evaluate) { php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_EVALUATE); } /* }}} end dom_xpath_evaluate" + "mixed dom_xpath_evaluate(string expr [,DOMNode context])", + "" ], "dom_xpath_query": [ - "DOMNodeList dom_xpath_query(string expr [,DOMNode context]); */", - "PHP_FUNCTION(dom_xpath_query) { php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_QUERY); } /* }}} end dom_xpath_query" + "DOMNodeList dom_xpath_query(string expr [,DOMNode context])", + "" ], "dom_xpath_register_ns": [ - "boolean dom_xpath_register_ns(string prefix, string uri); */", - "PHP_FUNCTION(dom_xpath_register_ns) { zval *id; xmlXPathContextPtr ctxp; int prefix_len, ns_uri_len; dom_xpath_object *intern; unsigned char *prefix, *ns_uri; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), \"Oss\", &id, dom_xpath_class_entry, &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) { return; } intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); ctxp = (xmlXPathContextPtr) intern->ptr; if (ctxp == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, \"Invalid XPath Context\"); RETURN_FALSE; } if (xmlXPathRegisterNs(ctxp, prefix, ns_uri) != 0) { RETURN_FALSE } RETURN_TRUE; } /* }}}" + "bool dom_xpath_register_ns(string prefix, string uri)", + "" ], "dom_xpath_register_php_functions": [ - "void dom_xpath_register_php_functions() */", - "PHP_FUNCTION(dom_xpath_register_php_functions) { zval *id; dom_xpath_object *intern; zval *array_value, **entry, *new_string; int name_len = 0; char *name; DOM_GET_THIS(id); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \"a\", &array_value) == SUCCESS) { intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value)); while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) { SEPARATE_ZVAL(entry); convert_to_string_ex(entry); MAKE_STD_ZVAL(new_string); ZVAL_LONG(new_string,1); zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL); zend_hash_move_forward(Z_ARRVAL_P(array_value)); } intern->registerPhpFunctions = 2; RETURN_TRUE; } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \"s\", &name, &name_len) == SUCCESS) { intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); MAKE_STD_ZVAL(new_string); ZVAL_LONG(new_string,1); zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL); intern->registerPhpFunctions = 2; } else { intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); intern->registerPhpFunctions = 1; } } /* }}} end dom_xpath_register_php_functions" + "void dom_xpath_register_php_functions()", + "" ], "each": [ "array each(array arr)", @@ -3583,7 +3778,7 @@ var functionMap = { "Output one or more strings" ], "empty": [ - "bool empty( mixed var )", + "bool empty(mixed var)", "Determine whether a variable is empty" ], "enchant_broker_describe": [ @@ -3595,7 +3790,7 @@ var functionMap = { "Whether a dictionary exists or not. Using non-empty tag" ], "enchant_broker_free": [ - "boolean enchant_broker_free(resource broker)", + "bool enchant_broker_free(resource broker)", "Destroys the broker object and its dictionnaries" ], "enchant_broker_free_dict": [ @@ -3891,7 +4086,7 @@ var functionMap = { "Returns the next lowest integer value from the number" ], "flush": [ - "void flush(void)", + "void flush()", "Flush the output buffer" ], "fmod": [ @@ -4099,7 +4294,7 @@ var functionMap = { "Get an array of the arguments that were passed to the function" ], "func_num_args": [ - "int func_num_args(void)", + "int func_num_args()", "Get the number of arguments that were passed to the function" ], "function ": ["", ""], @@ -4113,19 +4308,19 @@ var functionMap = { "Binary-safe file write" ], "gc_collect_cycles": [ - "int gc_collect_cycles(void)", + "int gc_collect_cycles()", "Forces collection of any existing garbage cycles. Returns number of freed zvals" ], "gc_disable": [ - "void gc_disable(void)", + "void gc_disable()", "Deactivates the circular reference collector" ], "gc_enable": [ - "void gc_enable(void)", + "void gc_enable()", "Activates the circular reference collector" ], "gc_enabled": [ - "void gc_enabled(void)", + "void gc_enabled()", "Returns status of the circular reference collector" ], "gd_info": [ @@ -4134,7 +4329,7 @@ var functionMap = { ], "getKeywords": [ "static array getKeywords(string $locale) {", - "* return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array (doh!) * }}}" + "* return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array * }}}" ], "get_browser": [ "mixed get_browser([string browser_name [, bool return_array]])", @@ -4161,7 +4356,7 @@ var functionMap = { "Returns an array of default properties of the class." ], "get_current_user": [ - "string get_current_user(void)", + "string get_current_user()", "Get the name of the owner of the current PHP script" ], "get_declared_classes": [ @@ -4177,11 +4372,11 @@ var functionMap = { "Return an array containing the names and values of all defined constants" ], "get_defined_functions": [ - "array get_defined_functions(void)", + "array get_defined_functions()", "Returns an array of all defined functions" ], "get_defined_vars": [ - "array get_defined_vars(void)", + "array get_defined_vars()", "Returns an associative array of names and values of all currently defined variable names (variables in the current scope)" ], "get_display_language": [ @@ -4217,7 +4412,7 @@ var functionMap = { "Get the current include_path configuration option" ], "get_included_files": [ - "array get_included_files(void)", + "array get_included_files()", "Returns an array with the file names that were include_once()'d" ], "get_loaded_extensions": [ @@ -4225,11 +4420,11 @@ var functionMap = { "Return an array containing names of loaded extensions" ], "get_magic_quotes_gpc": [ - "int get_magic_quotes_gpc(void)", + "int get_magic_quotes_gpc()", "Get the current active configuration setting of magic_quotes_gpc" ], "get_magic_quotes_runtime": [ - "int get_magic_quotes_runtime(void)", + "int get_magic_quotes_runtime()", "Get the current active configuration setting of magic_quotes_runtime" ], "get_meta_tags": [ @@ -4249,11 +4444,11 @@ var functionMap = { "Get the resource type name for a given resource" ], "getallheaders": [ - "array getallheaders(void)", + "array getallheaders()", "" ], "getcwd": [ - "mixed getcwd(void)", + "mixed getcwd()", "Gets the current directory" ], "getdate": [ @@ -4285,23 +4480,23 @@ var functionMap = { "Get the size of an image as 4-element array" ], "getlastmod": [ - "int getlastmod(void)", + "int getlastmod()", "Get time of last page modification" ], "getmygid": [ - "int getmygid(void)", + "int getmygid()", "Get PHP script owner's GID" ], "getmyinode": [ - "int getmyinode(void)", + "int getmyinode()", "Get the inode of the current script being parsed" ], "getmypid": [ - "int getmypid(void)", + "int getmypid()", "Get current process ID" ], "getmyuid": [ - "int getmyuid(void)", + "int getmyuid()", "Get PHP script owner's UID" ], "getopt": [ @@ -4317,7 +4512,7 @@ var functionMap = { "Returns protocol name associated with protocol number proto" ], "getrandmax": [ - "int getrandmax(void)", + "int getrandmax()", "Returns the maximum value a random number can have" ], "getrusage": [ @@ -4593,7 +4788,7 @@ var functionMap = { "Generate a hash of a given input string Returns lowercase hexits by default" ], "hash_algos": [ - "array hash_algos(void)", + "array hash_algos()", "Return a list of registered hashing algorithms" ], "hash_copy": [ @@ -4641,7 +4836,7 @@ var functionMap = { "Removes an HTTP header previously set using header()" ], "headers_list": [ - "array headers_list(void)", + "array headers_list()", "Return list of headers to be sent / already sent" ], "headers_sent": [ @@ -4769,11 +4964,11 @@ var functionMap = { "Drop an InterBase database" ], "ibase_errcode": [ - "int ibase_errcode(void)", + "int ibase_errcode()", "Return error code" ], "ibase_errmsg": [ - "string ibase_errmsg(void)", + "string ibase_errmsg()", "Return error message" ], "ibase_execute": [ @@ -5242,7 +5437,7 @@ var functionMap = { ], "imagepsextendfont": [ "bool imagepsextendfont(resource font_index, float extend)", - "Extend or or condense (if extend < 1) a font" + "Extend or or condense if (extend < 1) a font" ], "imagepsfreefont": [ "bool imagepsfreefont(resource font_index)", @@ -5321,7 +5516,7 @@ var functionMap = { "Write text to the image using a TrueType font" ], "imagetypes": [ - "int imagetypes(void)", + "int imagetypes()", "Return the types of images supported in a bitfield - 1=GIF, 2=JPEG, 4=PNG, 8=WBMP, 16=XPM" ], "imagewbmp": [ @@ -5337,7 +5532,7 @@ var functionMap = { "Convert an 8-bit string to a quoted-printable string" ], "imap_alerts": [ - "array imap_alerts(void)", + "array imap_alerts()", "Returns an array of all IMAP alerts that have been generated since the last page load or since the last imap_alerts() call, whichever came last. The alert stack is cleared after imap_alerts() is called." ], "imap_append": [ @@ -5385,7 +5580,7 @@ var functionMap = { "Delete a mailbox" ], "imap_errors": [ - "array imap_errors(void)", + "array imap_errors()", "Returns an array of all IMAP errors generated since the last page load, or since the last imap_errors() call, whichever came last. The error stack is cleared after imap_errors() is called." ], "imap_expunge": [ @@ -5441,7 +5636,7 @@ var functionMap = { "Returns headers for all messages in a mailbox" ], "imap_last_error": [ - "string imap_last_error(void)", + "string imap_last_error()", "Returns the last error that was generated by an IMAP function. The error stack is NOT cleared after this call." ], "imap_list": [ @@ -5692,6 +5887,10 @@ var functionMap = { "bool is_callable(mixed var [, bool syntax_only [, string callable_name]])", "Returns true if var is callable." ], + "is_countable": [ + "bool is_countable(mixed var)", + "Returns true if var is countable, false otherwise" + ], "is_dir": [ "bool is_dir(string filename)", "Returns true if file is directory" @@ -5773,15 +5972,15 @@ var functionMap = { "Determine whether a variable is set" ], "iterator_apply": [ - "int iterator_apply(Traversable it, mixed function [, mixed params])", + "int iterator_apply(Traversable iterator, callable function [, array args = null)", "Calls a function for every element in an iterator" ], "iterator_count": [ - "int iterator_count(Traversable it)", + "int iterator_count(Traversable iterator)", "Count the elements in an iterator" ], "iterator_to_array": [ - "array iterator_to_array(Traversable it [, bool use_keys = true])", + "array iterator_to_array(Traversable iterator [, bool use_keys = true])", "Copy the iterator into an array" ], "jddayofweek": [ @@ -5817,11 +6016,11 @@ var functionMap = { "Converts a jewish calendar date to a julian day count" ], "join": [ - "string join(array src, string glue)", - "An alias for implode" + "string join([string glue,] array pieces)", + "Returns a string containing a string representation of all the arrayelements in the same order, with the glue string between each element" ], "jpeg2wbmp": [ - "bool jpeg2wbmp (string f_org, string f_dest, int d_height, int d_width, int threshold)", + "bool jpeg2wbmp(string f_org, string f_dest, int d_height, int d_width, int threshold)", "Convert JPEG image to WBMP image" ], "json_decode": [ @@ -5989,7 +6188,7 @@ var functionMap = { "Read an entry" ], "ldap_rename": [ - "bool ldap_rename(resource link, string dn, string newrdn, string newparent, bool deleteoldrdn);", + "bool ldap_rename(resource link, string dn, string newrdn, string newparent, bool deleteoldrdn)", "Modify the name of an entry" ], "ldap_sasl_bind": [ @@ -6037,7 +6236,7 @@ var functionMap = { "Clear last error from libxml" ], "libxml_disable_entity_loader": [ - "bool libxml_disable_entity_loader([boolean disable])", + "bool libxml_disable_entity_loader([bool disable])", "Disable/Enable ability to load external entities" ], "libxml_get_errors": [ @@ -6053,7 +6252,7 @@ var functionMap = { "Set the streams context for the next libxml document load or write" ], "libxml_use_internal_errors": [ - "bool libxml_use_internal_errors([boolean use_errors])", + "bool libxml_use_internal_errors([bool use_errors])", "Disable libxml errors and allow user to fetch error information as needed" ], "link": [ @@ -6065,11 +6264,11 @@ var functionMap = { "Returns the st_dev field of the UNIX C stat structure describing the link" ], "litespeed_request_headers": [ - "array litespeed_request_headers(void)", + "array litespeed_request_headers()", "Fetch all HTTP request headers" ], "litespeed_response_headers": [ - "array litespeed_response_headers(void)", + "array litespeed_response_headers()", "Fetch all HTTP response headers" ], "locale_accept_from_http": [ @@ -6081,7 +6280,7 @@ var functionMap = { "* @param string $locale The locale string to canonicalize" ], "locale_filter_matches": [ - "boolean locale_filter_matches(string $langtag, string $locale[, bool $canonicalize])", + "bool locale_filter_matches(string $langtag, string $locale[, bool $canonicalize])", "* Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm" ], "locale_get_all_variants": [ @@ -6094,7 +6293,7 @@ var functionMap = { ], "locale_get_keywords": [ "static array locale_get_keywords(string $locale) {", - "* return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array (doh!)" + "* return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array" ], "locale_get_primary_language": [ "static string locale_get_primary_language($locale)", @@ -6117,7 +6316,7 @@ var functionMap = { "Set default locale" ], "localeconv": [ - "array localeconv(void)", + "array localeconv()", "Returns numeric formatting information based on the current locale" ], "localtime": [ @@ -6221,11 +6420,11 @@ var functionMap = { "Regular expression search for multibyte string" ], "mb_ereg_search_getpos": [ - "int mb_ereg_search_getpos(void)", + "int mb_ereg_search_getpos()", "Get search start position" ], "mb_ereg_search_getregs": [ - "array mb_ereg_search_getregs(void)", + "array mb_ereg_search_getregs()", "Get matched substring of the last time" ], "mb_ereg_search_init": [ @@ -6545,7 +6744,7 @@ var functionMap = { "Hash data with hash" ], "mhash_count": [ - "int mhash_count(void)", + "int mhash_count()", "Gets the number of available hashes" ], "mhash_get_block_size": [ @@ -6721,7 +6920,7 @@ var functionMap = { "Free a MS-SQL statement index" ], "mssql_get_last_message": [ - "string mssql_get_last_message(void)", + "string mssql_get_last_message()", "Gets the last message from the MS-SQL server" ], "mssql_guid_string": [ @@ -6773,7 +6972,7 @@ var functionMap = { "Select a MS-SQL database" ], "mt_getrandmax": [ - "int mt_getrandmax(void)", + "int mt_getrandmax()", "Returns the maximum value a random number from Mersenne Twister can have" ], "mt_rand": [ @@ -6881,7 +7080,7 @@ var functionMap = { "Free result memory" ], "mysql_get_client_info": [ - "string mysql_get_client_info(void)", + "string mysql_get_client_info()", "Returns a string that represents the client library version" ], "mysql_get_host_info": [ @@ -6977,7 +7176,7 @@ var functionMap = { "Turn auto commit on or of" ], "mysqli_cache_stats": [ - "array mysqli_cache_stats(void)", + "array mysqli_cache_stats()", "Returns statistics about the zval cache" ], "mysqli_change_user": [ @@ -7001,11 +7200,11 @@ var functionMap = { "Open a connection to a mysql server" ], "mysqli_connect_errno": [ - "int mysqli_connect_errno(void)", + "int mysqli_connect_errno()", "Returns the numerical value of the error message from last connect command" ], "mysqli_connect_error": [ - "string mysqli_connect_error(void)", + "string mysqli_connect_error()", "Returns the text of the error message from previous MySQL operation" ], "mysqli_data_seek": [ @@ -7021,7 +7220,7 @@ var functionMap = { "" ], "mysqli_embedded_server_end": [ - "void mysqli_embedded_server_end(void)", + "void mysqli_embedded_server_end()", "" ], "mysqli_embedded_server_start": [ @@ -7037,39 +7236,39 @@ var functionMap = { "Returns the text of the error message from previous MySQL operation" ], "mysqli_fetch_all": [ - "mixed mysqli_fetch_all (object result [,int resulttype])", + "mixed mysqli_fetch_all(object result [,int resulttype])", "Fetches all result rows as an associative array, a numeric array, or both" ], "mysqli_fetch_array": [ - "mixed mysqli_fetch_array (object result [,int resulttype])", + "mixed mysqli_fetch_array(object result [,int resulttype])", "Fetch a result row as an associative array, a numeric array, or both" ], "mysqli_fetch_assoc": [ - "mixed mysqli_fetch_assoc (object result)", + "mixed mysqli_fetch_assoc(object result)", "Fetch a result row as an associative array" ], "mysqli_fetch_field": [ - "mixed mysqli_fetch_field (object result)", + "mixed mysqli_fetch_field(object result)", "Get column information from a result and return as an object" ], "mysqli_fetch_field_direct": [ - "mixed mysqli_fetch_field_direct (object result, int offset)", + "mixed mysqli_fetch_field_direct(object result, int offset)", "Fetch meta-data for a single field" ], "mysqli_fetch_fields": [ - "mixed mysqli_fetch_fields (object result)", + "mixed mysqli_fetch_fields(object result)", "Return array of objects containing field meta-data" ], "mysqli_fetch_lengths": [ - "mixed mysqli_fetch_lengths (object result)", + "mixed mysqli_fetch_lengths(object result)", "Get the length of each output in a result" ], "mysqli_fetch_object": [ - "mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])", + "mixed mysqli_fetch_object(object result [, string class_name [, NULL|array ctor_params]])", "Fetch a result row as an object" ], "mysqli_fetch_row": [ - "array mysqli_fetch_row (object result)", + "array mysqli_fetch_row(object result)", "Get a result row as an enumerated array" ], "mysqli_field_count": [ @@ -7093,23 +7292,23 @@ var functionMap = { "returns a character set object" ], "mysqli_get_client_info": [ - "string mysqli_get_client_info(void)", + "string mysqli_get_client_info()", "Get MySQL client info" ], "mysqli_get_client_stats": [ - "array mysqli_get_client_stats(void)", + "array mysqli_get_client_stats()", "Returns statistics about the zval cache" ], "mysqli_get_client_version": [ - "int mysqli_get_client_version(void)", + "int mysqli_get_client_version()", "Get MySQL client info" ], "mysqli_get_connection_stats": [ - "array mysqli_get_connection_stats(void)", + "array mysqli_get_connection_stats()", "Returns statistics about the zval cache" ], "mysqli_get_host_info": [ - "string mysqli_get_host_info (object link)", + "string mysqli_get_host_info(object link)", "Get MySQL host info" ], "mysqli_get_proto_info": [ @@ -7125,15 +7324,15 @@ var functionMap = { "Return the MySQL version for the server referenced by the given link" ], "mysqli_get_warnings": [ - "object mysqli_get_warnings(object link) */", - "PHP_FUNCTION(mysqli_get_warnings) { MY_MYSQL *mysql; zval *mysql_link; MYSQLI_RESOURCE *mysqli_resource; MYSQLI_WARNING *w; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), \"O\", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, \"mysqli_link\", MYSQLI_STATUS_VALID); if (mysql_warning_count(mysql->mysql)) { w = php_get_warnings(mysql->mysql TSRMLS_CC); } else { RETURN_FALSE; } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = mysqli_resource->info = (void *)w; mysqli_resource->status = MYSQLI_STATUS_VALID; MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); } /* }}}" + "object mysqli_get_warnings(object link)", + "" ], "mysqli_info": [ "string mysqli_info(object link)", "Get information about the most recent query" ], "mysqli_init": [ - "resource mysqli_init(void)", + "resource mysqli_init()", "Initialize mysqli and return a resource for use with mysql_real_connect" ], "mysqli_insert_id": [ @@ -7185,8 +7384,8 @@ var functionMap = { "Prepare a SQL statement for execution" ], "mysqli_query": [ - "mixed mysqli_query(object link, string query [,int resultmode]) */", - "PHP_FUNCTION(mysqli_query) { MY_MYSQL *mysql; zval *mysql_link; MYSQLI_RESOURCE *mysqli_resource; MYSQL_RES *result; char *query = NULL; unsigned int query_len; unsigned long resultmode = MYSQLI_STORE_RESULT; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), \"Os|l\", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) { return; } if (!query_len) { php_error_docref(NULL TSRMLS_CC, E_WARNING, \"Empty query\"); RETURN_FALSE; } if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) { php_error_docref(NULL TSRMLS_CC, E_WARNING, \"Invalid value for resultmode\"); RETURN_FALSE; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, \"mysqli_link\", MYSQLI_STATUS_VALID); MYSQLI_DISABLE_MQ; #ifdef MYSQLI_USE_MYSQLND if (resultmode & MYSQLI_ASYNC) { if (mysqli_async_query(mysql->mysql, query, query_len)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC; RETURN_TRUE; } #endif if (mysql_real_query(mysql->mysql, query, query_len)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } if (!mysql_field_count(mysql->mysql)) { /* no result set - not a SELECT" + "mixed mysqli_query(object link, string query [,int resultmode])", + "" ], "mysqli_real_connect": [ "bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])", @@ -7301,8 +7500,8 @@ var functionMap = { "Buffer result set on client" ], "mysqli_stmt_get_warnings": [ - "object mysqli_stmt_get_warnings(object link) */", - "PHP_FUNCTION(mysqli_stmt_get_warnings) { MY_STMT *stmt; zval *stmt_link; MYSQLI_RESOURCE *mysqli_resource; MYSQLI_WARNING *w; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), \"O\", &stmt_link, mysqli_stmt_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT*, &stmt_link, \"mysqli_stmt\", MYSQLI_STATUS_VALID); if (mysqli_stmt_warning_count(stmt->stmt)) { w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC); } else { RETURN_FALSE; } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = mysqli_resource->info = (void *)w; mysqli_resource->status = MYSQLI_STATUS_VALID; MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); } /* }}}" + "object mysqli_stmt_get_warnings(object link)", + "" ], "mysqli_stmt_init": [ "mixed mysqli_stmt_init(object link)", @@ -7357,7 +7556,7 @@ var functionMap = { "Return the current thread ID" ], "mysqli_thread_safe": [ - "bool mysqli_thread_safe(void)", + "bool mysqli_thread_safe()", "Return whether thread safety is given or not" ], "mysqli_use_result": [ @@ -7365,7 +7564,7 @@ var functionMap = { "Directly retrieve query results - do not buffer results on client side" ], "mysqli_warning_count": [ - "int mysqli_warning_count (object link)", + "int mysqli_warning_count(object link)", "Return number of warnings from the last query for the given link" ], "natcasesort": [ @@ -7401,11 +7600,11 @@ var functionMap = { "* Normalize a string." ], "nsapi_request_headers": [ - "array nsapi_request_headers(void)", + "array nsapi_request_headers()", "Get all headers from the request" ], "nsapi_response_headers": [ - "array nsapi_response_headers(void)", + "array nsapi_response_headers()", "Get all headers from the response" ], "nsapi_virtual": [ @@ -7485,39 +7684,39 @@ var functionMap = { "* Get formatter attribute value." ], "ob_clean": [ - "bool ob_clean(void)", + "bool ob_clean()", "Clean (delete) the current output buffer" ], "ob_end_clean": [ - "bool ob_end_clean(void)", + "bool ob_end_clean()", "Clean the output buffer, and delete current output buffer" ], "ob_end_flush": [ - "bool ob_end_flush(void)", + "bool ob_end_flush()", "Flush (send) the output buffer, and delete current output buffer" ], "ob_flush": [ - "bool ob_flush(void)", + "bool ob_flush()", "Flush (send) contents of the output buffer. The last buffer content is sent to next buffer" ], "ob_get_clean": [ - "bool ob_get_clean(void)", + "bool ob_get_clean()", "Get current buffer contents and delete current output buffer" ], "ob_get_contents": [ - "string ob_get_contents(void)", + "string ob_get_contents()", "Return the contents of the output buffer" ], "ob_get_flush": [ - "bool ob_get_flush(void)", + "bool ob_get_flush()", "Get current buffer contents, flush (send) the output buffer, and delete current output buffer" ], "ob_get_length": [ - "int ob_get_length(void)", + "int ob_get_length()", "Return the length of the output buffer" ], "ob_get_level": [ - "int ob_get_level(void)", + "int ob_get_level()", "Return the nesting level of the output buffer" ], "ob_get_status": [ @@ -7837,7 +8036,7 @@ var functionMap = { "Returns current state of buffering for a LOB" ], "ocisetbufferinglob": [ - "bool ocisetbufferinglob( boolean flag )", + "bool ocisetbufferinglob( bool flag )", "Enables/disables buffering for a LOB" ], "octdec": [ @@ -7857,7 +8056,7 @@ var functionMap = { "Close an ODBC connection" ], "odbc_close_all": [ - "void odbc_close_all(void)", + "void odbc_close_all()", "Close all ODBC connections" ], "odbc_columnprivileges": [ @@ -8065,7 +8264,7 @@ var functionMap = { "Encrypts given data with given method and key, returns raw or base64 encoded string" ], "openssl_error_string": [ - "mixed openssl_error_string(void)", + "mixed openssl_error_string()", "Returns a description of the last error, and alters the index of the error messages. Returns false when the are no more messages" ], "openssl_get_cipher_methods": [ @@ -8205,7 +8404,7 @@ var functionMap = { "Add URL rewriter values" ], "output_reset_rewrite_vars": [ - "bool output_reset_rewrite_vars(void)", + "bool output_reset_rewrite_vars()", "Reset(clear) URL rewriter values" ], "pack": [ @@ -8257,7 +8456,7 @@ var functionMap = { "Executes specified program in current process space as defined by exec(2)" ], "pcntl_fork": [ - "int pcntl_fork(void)", + "int pcntl_fork()", "Forks the currently running process following the same behavior as the UNIX fork() system call" ], "pcntl_getpriority": [ @@ -8374,7 +8573,7 @@ var functionMap = { ], "pg_delete": [ "mixed pg_delete(resource db, string table, array ids[, int options])", - "Delete records has ids (id=>value)" + "Delete records has ids (id => value)" ], "pg_end_copy": [ "bool pg_end_copy([resource connection])", @@ -8474,7 +8673,7 @@ var functionMap = { ], "pg_insert": [ "mixed pg_insert(resource db, string table, array values[, int options])", - "Insert values (filed=>value) to table" + "Insert values (filed => value) to table" ], "pg_last_error": [ "string pg_last_error([resource connection])", @@ -8598,7 +8797,7 @@ var functionMap = { ], "pg_select": [ "mixed pg_select(resource db, string table, array ids[, int options])", - "Select records that has ids (id=>value)" + "Select records that has ids (id => value)" ], "pg_send_execute": [ "bool pg_send_execute(resource connection, string stmtname, array params)", @@ -8646,34 +8845,34 @@ var functionMap = { ], "pg_update": [ "mixed pg_update(resource db, string table, array fields, array ids[, int options])", - "Update table using values (field=>value) and ids (id=>value)" + "Update table using values (field => value) and ids (id => value)" ], "pg_version": [ "array pg_version([resource connection])", "Returns an array with client, protocol and server version (when available)" ], "php_egg_logo_guid": [ - "string php_egg_logo_guid(void)", + "string php_egg_logo_guid()", "Return the special ID used to request the PHP logo in phpinfo screens" ], "php_ini_loaded_file": [ - "string php_ini_loaded_file(void)", + "string php_ini_loaded_file()", "Return the actual loaded ini filename" ], "php_ini_scanned_files": [ - "string php_ini_scanned_files(void)", + "string php_ini_scanned_files()", "Return comma-separated string of .ini files parsed from the additional ini dir" ], "php_logo_guid": [ - "string php_logo_guid(void)", + "string php_logo_guid()", "Return the special ID used to request the PHP logo in phpinfo screens" ], "php_real_logo_guid": [ - "string php_real_logo_guid(void)", + "string php_real_logo_guid()", "Return the special ID used to request the PHP logo in phpinfo screens" ], "php_sapi_name": [ - "string php_sapi_name(void)", + "string php_sapi_name()", "Return the current SAPI module name" ], "php_snmpv3": [ @@ -8685,7 +8884,7 @@ var functionMap = { "Return source with stripped comments and whitespace" ], "php_uname": [ - "string php_uname(void)", + "string php_uname()", "Return information about the system PHP was built on" ], "phpcredits": [ @@ -8701,11 +8900,11 @@ var functionMap = { "Return the current PHP version" ], "pi": [ - "float pi(void)", + "float pi()", "Returns an approximation of pi" ], "png2wbmp": [ - "bool png2wbmp (string f_org, string f_dest, int d_height, int d_width, int threshold)", + "bool png2wbmp(string f_org, string f_dest, int d_height, int d_width, int threshold)", "Convert PNG image to WBMP image" ], "popen": [ @@ -8717,27 +8916,27 @@ var functionMap = { "Determine accessibility of a file (POSIX.1 5.6.3)" ], "posix_ctermid": [ - "string posix_ctermid(void)", + "string posix_ctermid()", "Generate terminal path name (POSIX.1, 4.7.1)" ], "posix_get_last_error": [ - "int posix_get_last_error(void)", + "int posix_get_last_error()", "Retrieve the error number set by the last posix function which failed." ], "posix_getcwd": [ - "string posix_getcwd(void)", + "string posix_getcwd()", "Get working directory pathname (POSIX.1, 5.2.2)" ], "posix_getegid": [ - "int posix_getegid(void)", + "int posix_getegid()", "Get the current effective group id (POSIX.1, 4.2.1)" ], "posix_geteuid": [ - "int posix_geteuid(void)", + "int posix_geteuid()", "Get the current effective user id (POSIX.1, 4.2.1)" ], "posix_getgid": [ - "int posix_getgid(void)", + "int posix_getgid()", "Get the current group id (POSIX.1, 4.2.1)" ], "posix_getgrgid": [ @@ -8749,27 +8948,27 @@ var functionMap = { "Group database access (POSIX.1, 9.2.1)" ], "posix_getgroups": [ - "array posix_getgroups(void)", + "array posix_getgroups()", "Get supplementary group id's (POSIX.1, 4.2.3)" ], "posix_getlogin": [ - "string posix_getlogin(void)", + "string posix_getlogin()", "Get user name (POSIX.1, 4.2.4)" ], "posix_getpgid": [ - "int posix_getpgid(void)", + "int posix_getpgid()", "Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally)" ], "posix_getpgrp": [ - "int posix_getpgrp(void)", + "int posix_getpgrp()", "Get current process group id (POSIX.1, 4.3.1)" ], "posix_getpid": [ - "int posix_getpid(void)", + "int posix_getpid()", "Get the current process id (POSIX.1, 4.1.1)" ], "posix_getppid": [ - "int posix_getppid(void)", + "int posix_getppid()", "Get the parent process id (POSIX.1, 4.1.1)" ], "posix_getpwnam": [ @@ -8781,15 +8980,15 @@ var functionMap = { "User database access (POSIX.1, 9.2.2)" ], "posix_getrlimit": [ - "array posix_getrlimit(void)", + "array posix_getrlimit()", "Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally)" ], "posix_getsid": [ - "int posix_getsid(void)", + "int posix_getsid()", "Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally)" ], "posix_getuid": [ - "int posix_getuid(void)", + "int posix_getuid()", "Get the current user id (POSIX.1, 4.2.1)" ], "posix_initgroups": [ @@ -8829,7 +9028,7 @@ var functionMap = { "Set process group id for job control (POSIX.1, 4.3.3)" ], "posix_setsid": [ - "int posix_setsid(void)", + "int posix_setsid()", "Create session and set process group id (POSIX.1, 4.3.2)" ], "posix_setuid": [ @@ -8841,7 +9040,7 @@ var functionMap = { "Retrieve the system error message associated with the given errno." ], "posix_times": [ - "array posix_times(void)", + "array posix_times()", "Get process times (POSIX.1, 4.5.2)" ], "posix_ttyname": [ @@ -8849,7 +9048,7 @@ var functionMap = { "Determine terminal device name (POSIX.1, 4.7.2)" ], "posix_uname": [ - "array posix_uname(void)", + "array posix_uname()", "Get system name (POSIX.1, 4.4.1)" ], "pow": [ @@ -9017,8 +9216,8 @@ var functionMap = { "Convert a quoted-printable string to an 8 bit string" ], "quoted_printable_encode": [ - "string quoted_printable_encode(string str) */", - "PHP_FUNCTION(quoted_printable_encode) { char *str, *new_str; int str_len; size_t new_str_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"s\", &str, &str_len) != SUCCESS) { return; } if (!str_len) { RETURN_EMPTY_STRING(); } new_str = (char *)php_quot_print_encode((unsigned char *)str, (size_t)str_len, &new_str_len); RETURN_STRINGL(new_str, new_str_len, 0); } /* }}}" + "string quoted_printable_encode(string str)", + "" ], "quotemeta": [ "string quotemeta(string str)", @@ -9077,7 +9276,7 @@ var functionMap = { "Informs the readline callback interface that a character is ready for input" ], "readline_clear_history": [ - "bool readline_clear_history(void)", + "bool readline_clear_history()", "Clears the history" ], "readline_completion_function": [ @@ -9089,11 +9288,11 @@ var functionMap = { "Gets/sets various internal readline variables." ], "readline_list_history": [ - "array readline_list_history(void)", + "array readline_list_history()", "Lists the history" ], "readline_on_new_line": [ - "void readline_on_new_line(void)", + "void readline_on_new_line()", "Inform readline that the cursor has moved to a new line" ], "readline_read_history": [ @@ -9101,7 +9300,7 @@ var functionMap = { "Reads the history" ], "readline_redisplay": [ - "void readline_redisplay(void)", + "void readline_redisplay()", "Ask readline to redraw the display" ], "readline_write_history": [ @@ -9157,11 +9356,11 @@ var functionMap = { "Set array argument's internal pointer to the first element and return it" ], "restore_error_handler": [ - "void restore_error_handler(void)", + "void restore_error_handler()", "Restores the previously defined error handler function" ], "restore_exception_handler": [ - "void restore_exception_handler(void)", + "void restore_exception_handler()", "Restores the previously defined exception handler function" ], "restore_include_path": [ @@ -9229,15 +9428,15 @@ var functionMap = { "Deserializes data and reinitializes the variables" ], "session_destroy": [ - "bool session_destroy(void)", + "bool session_destroy()", "Destroy the current session and all data associated with it" ], "session_encode": [ - "string session_encode(void)", + "string session_encode()", "Serializes the current setup and returns the serialized representation" ], "session_get_cookie_params": [ - "array session_get_cookie_params(void)", + "array session_get_cookie_params()", "Return the session cookie parameters" ], "session_id": [ @@ -9277,7 +9476,7 @@ var functionMap = { "Sets user-level functions" ], "session_start": [ - "bool session_start(void)", + "bool session_start()", "Begin session - reinitializes freezed variables, registers browsers etc" ], "session_unregister": [ @@ -9285,11 +9484,11 @@ var functionMap = { "Removes varname from the list of variables which are freezed at the session end" ], "session_unset": [ - "void session_unset(void)", + "void session_unset()", "Unset all registered variables" ], "session_write_close": [ - "void session_write_close(void)", + "void session_write_close()", "Write session data and end session" ], "set_error_handler": [ @@ -9369,27 +9568,27 @@ var functionMap = { "Removes variable from shared memory" ], "shmop_close": [ - "void shmop_close (int shmid)", + "void shmop_close(int shmid)", "closes a shared memory segment" ], "shmop_delete": [ - "bool shmop_delete (int shmid)", + "bool shmop_delete(int shmid)", "mark segment for deletion" ], "shmop_open": [ - "int shmop_open (int key, string flags, int mode, int size)", + "int shmop_open(int key, string flags, int mode, int size)", "gets and attaches a shared memory segment" ], "shmop_read": [ - "string shmop_read (int shmid, int start, int count)", + "string shmop_read(int shmid, int start, int count)", "reads from a shm segment" ], "shmop_size": [ - "int shmop_size (int shmid)", + "int shmop_size(int shmid)", "returns the shm size" ], "shmop_write": [ - "int shmop_write (int shmid, string data, int offset)", + "int shmop_write(int shmid, string data, int offset)", "writes to a shared memory segment" ], "shuffle": [ @@ -9501,7 +9700,7 @@ var functionMap = { "Fetch the value of a SNMP object" ], "snmp_get_quick_print": [ - "bool snmp_get_quick_print(void)", + "bool snmp_get_quick_print()", "Return the current status of quick_print" ], "snmp_get_valueretrieval": [ @@ -9749,7 +9948,7 @@ var functionMap = { "Escapes a string for use as a query parameter." ], "sqlite_exec": [ - "boolean sqlite_exec(string query, resource db[, string &error_message])", + "bool sqlite_exec(string query, resource db[, string &error_message])", "Executes a result-less query against a given database" ], "sqlite_factory": [ @@ -10001,7 +10200,7 @@ var functionMap = { "Reads all remaining bytes (or up to maxlen bytes) from a stream and returns them as a string." ], "stream_get_filters": [ - "array stream_get_filters(void)", + "array stream_get_filters()", "Returns a list of registered filters" ], "stream_get_line": [ @@ -10265,7 +10464,7 @@ var functionMap = { "Free result memory" ], "sybase_get_last_message": [ - "string sybase_get_last_message(void)", + "string sybase_get_last_message()", "Returns the last message from server (over min_message_severity)" ], "sybase_min_client_severity": [ @@ -10349,7 +10548,7 @@ var functionMap = { "Returns the Number of Tidy accessibility warnings encountered for specified document." ], "tidy_clean_repair": [ - "boolean tidy_clean_repair()", + "bool tidy_clean_repair()", "Execute configured cleanup and repair operations on parsed markup" ], "tidy_config_count": [ @@ -10357,7 +10556,7 @@ var functionMap = { "Returns the Number of Tidy configuration errors encountered for specified document." ], "tidy_diagnose": [ - "boolean tidy_diagnose()", + "bool tidy_diagnose()", "Run configured diagnostics on parsed and repaired markup." ], "tidy_error_count": [ @@ -10373,7 +10572,7 @@ var functionMap = { "Get current Tidy configuarion" ], "tidy_get_error_buffer": [ - "string tidy_get_error_buffer([boolean detailed])", + "string tidy_get_error_buffer([bool detailed])", "Return warnings and errors which occured parsing the specified document" ], "tidy_get_head": [ @@ -10413,15 +10612,15 @@ var functionMap = { "Returns the value of the specified configuration option for the tidy document." ], "tidy_is_xhtml": [ - "boolean tidy_is_xhtml()", + "bool tidy_is_xhtml()", "Indicates if the document is a XHTML document." ], "tidy_is_xml": [ - "boolean tidy_is_xml()", + "bool tidy_is_xml()", "Indicates if the document is a generic (non HTML/XHTML) XML document." ], "tidy_parse_file": [ - "boolean tidy_parse_file(string file [, mixed config_options [, string encoding [, bool use_include_path]]])", + "bool tidy_parse_file(string file [, mixed config_options [, string encoding [, bool use_include_path]]])", "Parse markup in file or URI" ], "tidy_parse_string": [ @@ -10429,11 +10628,11 @@ var functionMap = { "Parse a document stored in a string" ], "tidy_repair_file": [ - "boolean tidy_repair_file(string filename [, mixed config_file [, string encoding [, bool use_include_path]]])", + "bool tidy_repair_file(string filename [, mixed config_file [, string encoding [, bool use_include_path]]])", "Repair a file using an optionally provided configuration file" ], "tidy_repair_string": [ - "boolean tidy_repair_string(string data [, mixed config_file [, string encoding]])", + "bool tidy_repair_string(string data [, mixed config_file [, string encoding]])", "Repair a string using an optionally provided configuration file" ], "tidy_warning_count": [ @@ -10441,7 +10640,7 @@ var functionMap = { "Returns the Number of Tidy warnings encountered for specified document." ], "time": [ - "int time(void)", + "int time()", "Return current UNIX timestamp" ], "time_nanosleep": [ @@ -10489,7 +10688,7 @@ var functionMap = { "Returns the Olson database version number." ], "tmpfile": [ - "resource tmpfile(void)", + "resource tmpfile()", "Create a temporary file that will be deleted automatically after use" ], "token_get_all": [ @@ -10557,7 +10756,7 @@ var functionMap = { "Takes a string representation of variable and recreates it" ], "unset": [ - "void unset (mixed var [, mixed var])", + "void unset(mixed var [, mixed var])", "Unset a given variable" ], "urldecode": [ @@ -10589,7 +10788,7 @@ var functionMap = { "Dumps a string representation of variable to output" ], "var_export": [ - "mixed var_export(mixed var [, bool return])", + "string var_export(mixed var [, bool return])", "Outputs or returns a string representation of a variable" ], "variant_abs": [ @@ -10717,7 +10916,7 @@ var functionMap = { "Return a formatted string" ], "wddx_add_vars": [ - "int wddx_add_vars(resource packet_id, mixed var_names [, mixed ...])", + "int wddx_add_vars(resource packet_id, mixed var_names [, mixed ...])", "Serializes given variables and adds them to packet given by packet_id" ], "wddx_deserialize": [ @@ -10741,7 +10940,7 @@ var functionMap = { "Creates a new packet and serializes given variables into a struct" ], "wordwrap": [ - "string wordwrap(string str [, int width [, string break [, boolean cut]]])", + "string wordwrap(string str [, int width [, string break [, bool cut]]])", "Wraps buffer to selected number of characters using string break char" ], "xml_error_string": [ @@ -10869,7 +11068,7 @@ var functionMap = { "Parses XML requests and call methods" ], "xmlrpc_server_create": [ - "resource xmlrpc_server_create(void)", + "resource xmlrpc_server_create()", "Creates an xmlrpc server" ], "xmlrpc_server_destroy": [ @@ -11057,51 +11256,51 @@ var functionMap = { "Write text - returns FALSE on error" ], "xsl_xsltprocessor_get_parameter": [ - "string xsl_xsltprocessor_get_parameter(string namespace, string name);", + "string xsl_xsltprocessor_get_parameter(string namespace, string name)", "" ], "xsl_xsltprocessor_has_exslt_support": [ - "bool xsl_xsltprocessor_has_exslt_support();", + "bool xsl_xsltprocessor_has_exslt_support()", "" ], "xsl_xsltprocessor_import_stylesheet": [ - "void xsl_xsltprocessor_import_stylesheet(domdocument doc);", - "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# Since:" + "void xsl_xsltprocessor_import_stylesheet(domdocument doc)", + "" ], "xsl_xsltprocessor_register_php_functions": [ - "void xsl_xsltprocessor_register_php_functions([mixed $restrict]);", + "void xsl_xsltprocessor_register_php_functions([mixed $restrict])", "" ], "xsl_xsltprocessor_remove_parameter": [ - "bool xsl_xsltprocessor_remove_parameter(string namespace, string name);", + "bool xsl_xsltprocessor_remove_parameter(string namespace, string name)", "" ], "xsl_xsltprocessor_set_parameter": [ - "bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value]);", + "bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value])", "" ], "xsl_xsltprocessor_set_profiling": [ - "bool xsl_xsltprocessor_set_profiling(string filename) */", - "PHP_FUNCTION(xsl_xsltprocessor_set_profiling) { zval *id; xsl_object *intern; char *filename = NULL; int filename_len; DOM_GET_THIS(id); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \"s!\", &filename, &filename_len) == SUCCESS) { intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); if (intern->profiling) { efree(intern->profiling); } if (filename != NULL) { intern->profiling = estrndup(filename,filename_len); } else { intern->profiling = NULL; } RETURN_TRUE; } else { WRONG_PARAM_COUNT; } } /* }}} end xsl_xsltprocessor_set_profiling" + "bool xsl_xsltprocessor_set_profiling(string filename)", + "" ], "xsl_xsltprocessor_transform_to_doc": [ - "domdocument xsl_xsltprocessor_transform_to_doc(domnode doc);", - "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# Since:" + "domdocument xsl_xsltprocessor_transform_to_doc(domnode doc)", + "" ], "xsl_xsltprocessor_transform_to_uri": [ - "int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri);", + "int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri)", "" ], "xsl_xsltprocessor_transform_to_xml": [ - "string xsl_xsltprocessor_transform_to_xml(domdocument doc);", + "string xsl_xsltprocessor_transform_to_xml(domdocument doc)", "" ], "zend_logo_guid": [ - "string zend_logo_guid(void)", + "string zend_logo_guid()", "Return the special ID used to request the Zend logo in phpinfo screens" ], "zend_version": [ - "string zend_version(void)", + "string zend_version()", "Get the version of the Zend Engine" ], "zip_close": [ @@ -11145,7 +11344,7 @@ var functionMap = { "Returns the next file in the archive" ], "zlib_get_coding_type": [ - "string zlib_get_coding_type(void)", + "string zlib_get_coding_type()", "Returns the coding type used for output compression" ] }; @@ -11196,7 +11395,9 @@ var variableMap = { "SERVER_PORT": 1, "SERVER_PROTOCOL": 1, "SERVER_SIGNATURE": 1, - "SERVER_SOFTWARE": 1 + "SERVER_SOFTWARE": 1, + "argv": 1, + "argc": 1 } }, "$_SESSION": { @@ -11204,6 +11405,12 @@ var variableMap = { }, "$GLOBALS": { type: "array" + }, + '$argv': { + type: "array" + }, + '$argc': { + type: "int" } }; @@ -11531,6 +11738,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -11868,6 +12076,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -12760,6 +12969,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -12886,6 +13096,7 @@ oop.inherits(Mode, HtmlMode); }; this.$id = "ace/mode/php"; + this.snippetFileId = "ace/snippets/php"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-php_laravel_blade.js b/htdocs/includes/ace/src/mode-php_laravel_blade.js index cd09a1f11fa..b9393a8a281 100644 --- a/htdocs/includes/ace/src/mode-php_laravel_blade.js +++ b/htdocs/includes/ace/src/mode-php_laravel_blade.js @@ -2309,15 +2309,15 @@ var functionMap = { "Escapes single quote, double quotes and backslash characters in a string with backslashes" ], "apache_child_terminate": [ - "bool apache_child_terminate(void)", + "bool apache_child_terminate()", "Terminate apache process after this request" ], "apache_get_modules": [ - "array apache_get_modules(void)", + "array apache_get_modules()", "Get a list of loaded Apache modules" ], "apache_get_version": [ - "string apache_get_version(void)", + "string apache_get_version()", "Fetch Apache version" ], "apache_getenv": [ @@ -2349,7 +2349,7 @@ var functionMap = { "* fetch all headers that go out in case of an error or a subrequest" ], "apache_request_headers": [ - "array apache_request_headers(void)", + "array apache_request_headers()", "Fetch all HTTP request headers" ], "apache_request_headers_in": [ @@ -2365,7 +2365,7 @@ var functionMap = { "" ], "apache_request_log_error": [ - "boolean apache_request_log_error(string message, [long facility])", + "bool apache_request_log_error(string message, [long facility])", "" ], "apache_request_meets_conditions": [ @@ -2417,11 +2417,11 @@ var functionMap = { "" ], "apache_reset_timeout": [ - "bool apache_reset_timeout(void)", + "bool apache_reset_timeout()", "Reset the Apache write timer" ], "apache_response_headers": [ - "array apache_response_headers(void)", + "array apache_response_headers()", "Fetch all HTTP response headers" ], "apache_setenv": [ @@ -2508,6 +2508,14 @@ var functionMap = { "array array_keys(array input [, mixed search_value[, bool strict]])", "Return just the keys from the input array, optionally only for the specified search_value" ], + "array_key_first": [ + "mixed array_key_first(array arr)", + "Returns the first key of arr if the array is not empty; NULL otherwise" + ], + "array_key_last": [ + "mixed array_key_last(array arr)", + "Returns the last key of arr if the array is not empty; NULL otherwise" + ], "array_map": [ "array array_map(mixed callback, array input1 [, array input2 ,...])", "Applies the callback to the elements in given arrays." @@ -2865,7 +2873,7 @@ var functionMap = { "Change file mode" ], "chown": [ - "bool chown (string filename, mixed user)", + "bool chown(string filename, mixed user)", "Change file owner" ], "chr": [ @@ -2893,7 +2901,7 @@ var functionMap = { "Return all classes and interfaces implemented by SPL" ], "class_parents": [ - "array class_parents(object instance [, boolean autoload = true])", + "array class_parents(object instance [, bool autoload = true])", "Return an array containing the names of all parent classes" ], "clearstatcache": [ @@ -2905,7 +2913,7 @@ var functionMap = { "Close directory connection identified by the dir_handle" ], "closelog": [ - "bool closelog(void)", + "bool closelog()", "Close connection to system logger" ], "collator_asort": [ @@ -2997,11 +3005,11 @@ var functionMap = { "Return a string to confirm that the module is compiled in" ], "connection_aborted": [ - "int connection_aborted(void)", + "int connection_aborted()", "Returns true if client disconnected" ], "connection_status": [ - "int connection_status(void)", + "int connection_status()", "Returns the connection status bitfield" ], "constant": [ @@ -3046,7 +3054,7 @@ var functionMap = { ], "create_function": [ "string create_function(string args, string code)", - "Creates an anonymous function, and returns its name (funny, eh?)" + "Creates an anonymous function, and returns its name" ], "crypt": [ "string crypt(string str [, string salt])", @@ -3145,7 +3153,7 @@ var functionMap = { "Get information about the current transfers" ], "curl_multi_init": [ - "resource curl_multi_init(void)", + "resource curl_multi_init()", "Returns a new cURL multi handle" ], "curl_multi_remove_handle": [ @@ -3341,7 +3349,7 @@ var functionMap = { "* Set formatter pattern." ], "datefmt_set_timezone_id": [ - "boolean datefmt_set_timezone_id( IntlDateFormatter $mf,$timezone_id)", + "bool datefmt_set_timezone_id( IntlDateFormatter $mf,$timezone_id)", "* Set formatter timezone_id." ], "dba_close": [ @@ -3409,7 +3417,7 @@ var functionMap = { "Return the translation of msgid for domain_name and category, or msgid unaltered if a translation does not exist" ], "dcngettext": [ - "string dcngettext (string domain, string msgid1, string msgid2, int n, int category)", + "string dcngettext(string domain, string msgid1, string msgid2, int n, int category)", "Plural version of dcgettext()" ], "debug_backtrace": [ @@ -3417,44 +3425,231 @@ var functionMap = { "Return backtrace as array" ], "debug_print_backtrace": [ - "void debug_print_backtrace(void) */", - "ZEND_FUNCTION(debug_print_backtrace) { zend_execute_data *ptr, *skip; int lineno; char *function_name; char *filename; char *class_name = NULL; char *call_type; char *include_filename = NULL; zval *arg_array = NULL; int indent = 0; if (zend_parse_parameters_none() == FAILURE) { return; } ptr = EG(current_execute_data);", + "void debug_print_backtrace()", + "Prints a PHP backtrace" + ], + "debug_zval_dump": [ + "void debug_zval_dump(mixed var)", + "Dumps a string representation of an internal Zend value to output" + ], + "decbin": [ + "string decbin(int decimal_number)", + "Returns a string containing a binary representation of the number" + ], + "dechex": [ + "string dechex(int decimal_number)", + "Returns a string containing a hexadecimal representation of the given number" + ], + "decoct": [ + "string decoct(int decimal_number)", + "Returns a string containing an octal representation of the given number" + ], + "define": [ + "bool define(string constant_name, mixed value, bool case_insensitive=false)", + "Define a new constant" + ], + "define_syslog_variables": [ + "void define_syslog_variables()", + "Initializes all syslog-related variables" + ], + "defined": [ + "bool defined(string constant_name)", + "Check whether a constant exists" + ], + "deg2rad": [ + "float deg2rad(float number)", + "Converts the number in degrees to the radian equivalent" + ], + "dgettext": [ + "string dgettext(string domain_name, string msgid)", + "Return the translation of msgid for domain_name, or msgid unaltered if a translation does not exist" + ], + "die": [ + "void die([mixed status])", + "Output a message and terminate the current script" + ], + "dir": [ + "object dir(string directory[, resource context])", + "Directory class with properties, handle and class and methods read, rewind and close" + ], + "dirname": [ + "string dirname(string path)", + "Returns the directory name component of the path" + ], + "disk_free_space": [ + "float disk_free_space(string path)", + "Get free disk space for filesystem that path is on" + ], + "disk_total_space": [ + "float disk_total_space(string path)", + "Get total disk space for filesystem that path is on" + ], + "display_disabled_function": [ + "void display_disabled_function()", + "Dummy function which displays an error when a disabled function is called." + ], + "dl": [ + "int dl(string extension_filename)", + "Load a PHP extension at runtime" + ], + "dngettext": [ + "string dngettext(string domain, string msgid1, string msgid2, int count)", + "Plural version of dgettext()" + ], + "dns_check_record": [ + "bool dns_check_record(string host [, string type])", + "Check DNS records corresponding to a given Internet host name or IP address" + ], + "dns_get_mx": [ + "bool dns_get_mx(string hostname, array mxhosts [, array weight])", + "Get MX records corresponding to a given Internet host name" + ], + "dns_get_record": [ + "array|false dns_get_record(string hostname [, int type[, array authns, array addtl]])", + "Get any Resource Record corresponding to a given Internet host name" + ], + "dom_attr_is_id": [ + "bool dom_attr_is_id()", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId Since: DOM Level 3" + ], + "dom_characterdata_append_data": [ + "void dom_characterdata_append_data(string arg)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F Since:" + ], + "dom_characterdata_delete_data": [ + "void dom_characterdata_delete_data(int offset, int count)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781 Since:" + ], + "dom_characterdata_insert_data": [ + "void dom_characterdata_insert_data(int offset, string arg)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F Since:" + ], + "dom_characterdata_replace_data": [ + "void dom_characterdata_replace_data(int offset, int count, string arg)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB Since:" + ], + "dom_characterdata_substring_data": [ + "string dom_characterdata_substring_data(int offset, int count)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF Since:" + ], + "dom_document_adopt_node": [ + "DOMNode dom_document_adopt_node(DOMNode source)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode Since: DOM Level 3" + ], + "dom_document_create_attribute": [ + "DOMAttr dom_document_create_attribute(string name)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198 Since:" + ], + "dom_document_create_attribute_ns": [ + "DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS Since: DOM Level 2" + ], + "dom_document_create_cdatasection": [ + "DOMCdataSection dom_document_create_cdatasection(string data)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8 Since:" + ], + "dom_document_create_comment": [ + "DOMComment dom_document_create_comment(string data)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328 Since:" + ], + "dom_document_create_document_fragment": [ + "DOMDocumentFragment dom_document_create_document_fragment()", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5 Since:" + ], + "dom_document_create_element": [ + "DOMElement dom_document_create_element(string tagName [, string value])", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547 Since:" + ], + "dom_document_create_element_ns": [ + "DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value])", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS Since: DOM Level 2" + ], + "dom_document_create_entity_reference": [ + "DOMEntityReference dom_document_create_entity_reference(string name)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE Since:" + ], + "dom_document_create_processing_instruction": [ + "DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439 Since:" + ], + "dom_document_create_text_node": [ + "DOMText dom_document_create_text_node(string data)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127 Since:" + ], + "dom_document_get_element_by_id": [ + "DOMElement dom_document_get_element_by_id(string elementId)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId Since: DOM Level 2" + ], + "dom_document_get_elements_by_tag_name": [ + "DOMNodeList dom_document_get_elements_by_tag_name(string tagname)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094 Since:" + ], + "dom_document_get_elements_by_tag_name_ns": [ + "DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS Since: DOM Level 2" + ], + "dom_document_import_node": [ + "DOMNode dom_document_import_node(DOMNode importedNode, bool deep)", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode Since: DOM Level 2" + ], + "dom_document_load": [ + "DOMNode dom_document_load(string source [, int options])", + "URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load Since: DOM Level 3" + ], + "dom_document_load_html": [ + "DOMNode dom_document_load_html(string source)", + "Since: DOM extended" + ], + "dom_document_load_html_file": [ + "DOMNode dom_document_load_html_file(string source)", + "Since: DOM extended" + ], + "dom_document_loadxml": [ + "DOMNode dom_document_loadxml(string source [, int options])", + "URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML Since: DOM Level 3" + ], + "dom_document_normalize_document": [ + "void dom_document_normalize_document()", + "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument Since: DOM Level 3" + ], + "dom_document_relaxNG_validate_file": [ + "bool dom_document_relaxNG_validate_file(string filename); */", "PHP_FUNCTION(dom_document_relaxNG_validate_file) { _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); } /* }}} end dom_document_relaxNG_validate_file" ], "dom_document_relaxNG_validate_xml": [ - "boolean dom_document_relaxNG_validate_xml(string source); */", + "bool dom_document_relaxNG_validate_xml(string source); */", "PHP_FUNCTION(dom_document_relaxNG_validate_xml) { _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); } /* }}} end dom_document_relaxNG_validate_xml" ], "dom_document_rename_node": [ - "DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName);", + "DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode Since: DOM Level 3" ], "dom_document_save": [ - "int dom_document_save(string file);", + "int dom_document_save(string file)", "Convenience method to save to file" ], "dom_document_save_html": [ - "string dom_document_save_html();", + "string dom_document_save_html()", "Convenience method to output as html" ], "dom_document_save_html_file": [ - "int dom_document_save_html_file(string file);", + "int dom_document_save_html_file(string file)", "Convenience method to save to file as html" ], "dom_document_savexml": [ - "string dom_document_savexml([node n]);", + "string dom_document_savexml([node n])", "URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML Since: DOM Level 3" ], "dom_document_schema_validate": [ - "boolean dom_document_schema_validate(string source); */", + "bool dom_document_schema_validate(string source); */", "PHP_FUNCTION(dom_document_schema_validate_xml) { _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING); } /* }}} end dom_document_schema_validate" ], "dom_document_schema_validate_file": [ - "boolean dom_document_schema_validate_file(string filename); */", + "bool dom_document_schema_validate_file(string filename); */", "PHP_FUNCTION(dom_document_schema_validate_file) { _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE); } /* }}} end dom_document_schema_validate_file" ], "dom_document_validate": [ - "boolean dom_document_validate();", + "bool dom_document_validate()", "Since: DOM extended" ], "dom_document_xinclude": [ @@ -3462,123 +3657,123 @@ var functionMap = { "Substitutues xincludes in a DomDocument" ], "dom_domconfiguration_can_set_parameter": [ - "boolean dom_domconfiguration_can_set_parameter(string name, domuserdata value);", + "bool dom_domconfiguration_can_set_parameter(string name, domuserdata value)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-canSetParameter Since:" ], "dom_domconfiguration_get_parameter": [ - "domdomuserdata dom_domconfiguration_get_parameter(string name);", + "domdomuserdata dom_domconfiguration_get_parameter(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-getParameter Since:" ], "dom_domconfiguration_set_parameter": [ - "dom_void dom_domconfiguration_set_parameter(string name, domuserdata value);", + "dom_void dom_domconfiguration_set_parameter(string name, domuserdata value)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-property Since:" ], "dom_domerrorhandler_handle_error": [ - "dom_boolean dom_domerrorhandler_handle_error(domerror error);", + "dom_bool dom_domerrorhandler_handle_error(domerror error)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-ERRORS-DOMErrorHandler-handleError Since:" ], "dom_domimplementation_create_document": [ - "DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype);", + "DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument Since: DOM Level 2" ], "dom_domimplementation_create_document_type": [ - "DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId);", + "DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType Since: DOM Level 2" ], "dom_domimplementation_get_feature": [ - "DOMNode dom_domimplementation_get_feature(string feature, string version);", + "DOMNode dom_domimplementation_get_feature(string feature, string version)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature Since: DOM Level 3" ], "dom_domimplementation_has_feature": [ - "boolean dom_domimplementation_has_feature(string feature, string version);", + "bool dom_domimplementation_has_feature(string feature, string version)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5CED94D7 Since:" ], "dom_domimplementationlist_item": [ - "domdomimplementation dom_domimplementationlist_item(int index);", + "domdomimplementation dom_domimplementationlist_item(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList-item Since:" ], "dom_domimplementationsource_get_domimplementation": [ - "domdomimplementation dom_domimplementationsource_get_domimplementation(string features);", + "domdomimplementation dom_domimplementationsource_get_domimplementation(string features)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpl Since:" ], "dom_domimplementationsource_get_domimplementations": [ - "domimplementationlist dom_domimplementationsource_get_domimplementations(string features);", + "domimplementationlist dom_domimplementationsource_get_domimplementations(string features)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpls Since:" ], "dom_domstringlist_item": [ - "domstring dom_domstringlist_item(int index);", + "domstring dom_domstringlist_item(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList-item Since:" ], "dom_element_get_attribute": [ - "string dom_element_get_attribute(string name);", + "string dom_element_get_attribute(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9 Since:" ], "dom_element_get_attribute_node": [ - "DOMAttr dom_element_get_attribute_node(string name);", + "DOMAttr dom_element_get_attribute_node(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8 Since:" ], "dom_element_get_attribute_node_ns": [ - "DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName);", + "DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS Since: DOM Level 2" ], "dom_element_get_attribute_ns": [ - "string dom_element_get_attribute_ns(string namespaceURI, string localName);", + "string dom_element_get_attribute_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS Since: DOM Level 2" ], "dom_element_get_elements_by_tag_name": [ - "DOMNodeList dom_element_get_elements_by_tag_name(string name);", + "DOMNodeList dom_element_get_elements_by_tag_name(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D Since:" ], "dom_element_get_elements_by_tag_name_ns": [ - "DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName);", + "DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942 Since: DOM Level 2" ], "dom_element_has_attribute": [ - "boolean dom_element_has_attribute(string name);", + "bool dom_element_has_attribute(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr Since: DOM Level 2" ], "dom_element_has_attribute_ns": [ - "boolean dom_element_has_attribute_ns(string namespaceURI, string localName);", + "bool dom_element_has_attribute_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS Since: DOM Level 2" ], "dom_element_remove_attribute": [ - "void dom_element_remove_attribute(string name);", + "void dom_element_remove_attribute(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9 Since:" ], "dom_element_remove_attribute_node": [ - "DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr);", + "DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198 Since:" ], "dom_element_remove_attribute_ns": [ - "void dom_element_remove_attribute_ns(string namespaceURI, string localName);", + "void dom_element_remove_attribute_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS Since: DOM Level 2" ], "dom_element_set_attribute": [ - "void dom_element_set_attribute(string name, string value);", + "void dom_element_set_attribute(string name, string value)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082 Since:" ], "dom_element_set_attribute_node": [ - "DOMAttr dom_element_set_attribute_node(DOMAttr newAttr);", + "DOMAttr dom_element_set_attribute_node(DOMAttr newAttr)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154 Since:" ], "dom_element_set_attribute_node_ns": [ - "DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr);", + "DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS Since: DOM Level 2" ], "dom_element_set_attribute_ns": [ - "void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value);", + "void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS Since: DOM Level 2" ], "dom_element_set_id_attribute": [ - "void dom_element_set_id_attribute(string name, boolean isId);", + "void dom_element_set_id_attribute(string name, bool isId)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttr Since: DOM Level 3" ], "dom_element_set_id_attribute_node": [ - "void dom_element_set_id_attribute_node(attr idAttr, boolean isId);", + "void dom_element_set_id_attribute_node(attr idAttr, bool isId)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode Since: DOM Level 3" ], "dom_element_set_id_attribute_ns": [ - "void dom_element_set_id_attribute_ns(string namespaceURI, string localName, boolean isId);", + "void dom_element_set_id_attribute_ns(string namespaceURI, string localName, bool isId)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNS Since: DOM Level 3" ], "dom_import_simplexml": [ @@ -3586,156 +3781,156 @@ var functionMap = { "Get a simplexml_element object from dom to allow for processing" ], "dom_namednodemap_get_named_item": [ - "DOMNode dom_namednodemap_get_named_item(string name);", + "DOMNode dom_namednodemap_get_named_item(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549 Since:" ], "dom_namednodemap_get_named_item_ns": [ - "DOMNode dom_namednodemap_get_named_item_ns(string namespaceURI, string localName);", + "DOMNode dom_namednodemap_get_named_item_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getNamedItemNS Since: DOM Level 2" ], "dom_namednodemap_item": [ - "DOMNode dom_namednodemap_item(int index);", + "DOMNode dom_namednodemap_item(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9 Since:" ], "dom_namednodemap_remove_named_item": [ - "DOMNode dom_namednodemap_remove_named_item(string name);", + "DOMNode dom_namednodemap_remove_named_item(string name)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D58B193 Since:" ], "dom_namednodemap_remove_named_item_ns": [ - "DOMNode dom_namednodemap_remove_named_item_ns(string namespaceURI, string localName);", + "DOMNode dom_namednodemap_remove_named_item_ns(string namespaceURI, string localName)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-removeNamedItemNS Since: DOM Level 2" ], "dom_namednodemap_set_named_item": [ - "DOMNode dom_namednodemap_set_named_item(DOMNode arg);", + "DOMNode dom_namednodemap_set_named_item(DOMNode arg)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1025163788 Since:" ], "dom_namednodemap_set_named_item_ns": [ - "DOMNode dom_namednodemap_set_named_item_ns(DOMNode arg);", + "DOMNode dom_namednodemap_set_named_item_ns(DOMNode arg)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-setNamedItemNS Since: DOM Level 2" ], "dom_namelist_get_name": [ - "string dom_namelist_get_name(int index);", + "string dom_namelist_get_name(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getName Since:" ], "dom_namelist_get_namespace_uri": [ - "string dom_namelist_get_namespace_uri(int index);", + "string dom_namelist_get_namespace_uri(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getNamespaceURI Since:" ], "dom_node_append_child": [ - "DomNode dom_node_append_child(DomNode newChild);", + "DomNode dom_node_append_child(DomNode newChild)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107 Since:" ], "dom_node_clone_node": [ - "DomNode dom_node_clone_node(boolean deep);", + "DomNode dom_node_clone_node(bool deep)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4 Since:" ], "dom_node_compare_document_position": [ - "short dom_node_compare_document_position(DomNode other);", + "short dom_node_compare_document_position(DomNode other)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition Since: DOM Level 3" ], "dom_node_get_feature": [ - "DomNode dom_node_get_feature(string feature, string version);", + "DomNode dom_node_get_feature(string feature, string version)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature Since: DOM Level 3" ], "dom_node_get_user_data": [ - "mixed dom_node_get_user_data(string key);", + "mixed dom_node_get_user_data(string key)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData Since: DOM Level 3" ], "dom_node_has_attributes": [ - "boolean dom_node_has_attributes();", + "bool dom_node_has_attributes()", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs Since: DOM Level 2" ], "dom_node_has_child_nodes": [ - "boolean dom_node_has_child_nodes();", + "bool dom_node_has_child_nodes()", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187 Since:" ], "dom_node_insert_before": [ - "domnode dom_node_insert_before(DomNode newChild, DomNode refChild);", + "domnode dom_node_insert_before(DomNode newChild, DomNode refChild)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727 Since:" ], "dom_node_is_default_namespace": [ - "boolean dom_node_is_default_namespace(string namespaceURI);", + "bool dom_node_is_default_namespace(string namespaceURI)", "URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace Since: DOM Level 3" ], "dom_node_is_equal_node": [ - "boolean dom_node_is_equal_node(DomNode arg);", + "bool dom_node_is_equal_node(DomNode arg)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode Since: DOM Level 3" ], "dom_node_is_same_node": [ - "boolean dom_node_is_same_node(DomNode other);", + "bool dom_node_is_same_node(DomNode other)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode Since: DOM Level 3" ], "dom_node_is_supported": [ - "boolean dom_node_is_supported(string feature, string version);", + "bool dom_node_is_supported(string feature, string version)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports Since: DOM Level 2" ], "dom_node_lookup_namespace_uri": [ - "string dom_node_lookup_namespace_uri(string prefix);", + "string dom_node_lookup_namespace_uri(string prefix)", "URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI Since: DOM Level 3" ], "dom_node_lookup_prefix": [ - "string dom_node_lookup_prefix(string namespaceURI);", + "string dom_node_lookup_prefix(string namespaceURI)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix Since: DOM Level 3" ], "dom_node_normalize": [ - "void dom_node_normalize();", + "void dom_node_normalize()", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize Since:" ], "dom_node_remove_child": [ - "DomNode dom_node_remove_child(DomNode oldChild);", + "DomNode dom_node_remove_child(DomNode oldChild)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066 Since:" ], "dom_node_replace_child": [ - "DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild);", + "DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307 Since:" ], "dom_node_set_user_data": [ - "mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler);", + "mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData Since: DOM Level 3" ], "dom_nodelist_item": [ - "DOMNode dom_nodelist_item(int index);", + "DOMNode dom_nodelist_item(int index)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136 Since:" ], "dom_string_extend_find_offset16": [ - "int dom_string_extend_find_offset16(int offset32);", + "int dom_string_extend_find_offset16(int offset32)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset16 Since:" ], "dom_string_extend_find_offset32": [ - "int dom_string_extend_find_offset32(int offset16);", + "int dom_string_extend_find_offset32(int offset16)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset32 Since:" ], "dom_text_is_whitespace_in_element_content": [ - "boolean dom_text_is_whitespace_in_element_content();", + "bool dom_text_is_whitespace_in_element_content()", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-isWhitespaceInElementContent Since: DOM Level 3" ], "dom_text_replace_whole_text": [ - "DOMText dom_text_replace_whole_text(string content);", + "DOMText dom_text_replace_whole_text(string content)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-replaceWholeText Since: DOM Level 3" ], "dom_text_split_text": [ - "DOMText dom_text_split_text(int offset);", + "DOMText dom_text_split_text(int offset)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-38853C1D Since:" ], "dom_userdatahandler_handle": [ - "dom_void dom_userdatahandler_handle(short operation, string key, domobject data, node src, node dst);", + "dom_void dom_userdatahandler_handle(short operation, string key, domobject data, node src, node dst)", "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-handleUserDataEvent Since:" ], "dom_xpath_evaluate": [ - "mixed dom_xpath_evaluate(string expr [,DOMNode context]); */", - "PHP_FUNCTION(dom_xpath_evaluate) { php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_EVALUATE); } /* }}} end dom_xpath_evaluate" + "mixed dom_xpath_evaluate(string expr [,DOMNode context])", + "" ], "dom_xpath_query": [ - "DOMNodeList dom_xpath_query(string expr [,DOMNode context]); */", - "PHP_FUNCTION(dom_xpath_query) { php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_QUERY); } /* }}} end dom_xpath_query" + "DOMNodeList dom_xpath_query(string expr [,DOMNode context])", + "" ], "dom_xpath_register_ns": [ - "boolean dom_xpath_register_ns(string prefix, string uri); */", - "PHP_FUNCTION(dom_xpath_register_ns) { zval *id; xmlXPathContextPtr ctxp; int prefix_len, ns_uri_len; dom_xpath_object *intern; unsigned char *prefix, *ns_uri; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), \"Oss\", &id, dom_xpath_class_entry, &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) { return; } intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); ctxp = (xmlXPathContextPtr) intern->ptr; if (ctxp == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, \"Invalid XPath Context\"); RETURN_FALSE; } if (xmlXPathRegisterNs(ctxp, prefix, ns_uri) != 0) { RETURN_FALSE } RETURN_TRUE; } /* }}}" + "bool dom_xpath_register_ns(string prefix, string uri)", + "" ], "dom_xpath_register_php_functions": [ - "void dom_xpath_register_php_functions() */", - "PHP_FUNCTION(dom_xpath_register_php_functions) { zval *id; dom_xpath_object *intern; zval *array_value, **entry, *new_string; int name_len = 0; char *name; DOM_GET_THIS(id); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \"a\", &array_value) == SUCCESS) { intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value)); while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) { SEPARATE_ZVAL(entry); convert_to_string_ex(entry); MAKE_STD_ZVAL(new_string); ZVAL_LONG(new_string,1); zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL); zend_hash_move_forward(Z_ARRVAL_P(array_value)); } intern->registerPhpFunctions = 2; RETURN_TRUE; } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \"s\", &name, &name_len) == SUCCESS) { intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); MAKE_STD_ZVAL(new_string); ZVAL_LONG(new_string,1); zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL); intern->registerPhpFunctions = 2; } else { intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC); intern->registerPhpFunctions = 1; } } /* }}} end dom_xpath_register_php_functions" + "void dom_xpath_register_php_functions()", + "" ], "each": [ "array each(array arr)", @@ -3754,7 +3949,7 @@ var functionMap = { "Output one or more strings" ], "empty": [ - "bool empty( mixed var )", + "bool empty(mixed var)", "Determine whether a variable is empty" ], "enchant_broker_describe": [ @@ -3766,7 +3961,7 @@ var functionMap = { "Whether a dictionary exists or not. Using non-empty tag" ], "enchant_broker_free": [ - "boolean enchant_broker_free(resource broker)", + "bool enchant_broker_free(resource broker)", "Destroys the broker object and its dictionnaries" ], "enchant_broker_free_dict": [ @@ -4062,7 +4257,7 @@ var functionMap = { "Returns the next lowest integer value from the number" ], "flush": [ - "void flush(void)", + "void flush()", "Flush the output buffer" ], "fmod": [ @@ -4270,7 +4465,7 @@ var functionMap = { "Get an array of the arguments that were passed to the function" ], "func_num_args": [ - "int func_num_args(void)", + "int func_num_args()", "Get the number of arguments that were passed to the function" ], "function ": ["", ""], @@ -4284,19 +4479,19 @@ var functionMap = { "Binary-safe file write" ], "gc_collect_cycles": [ - "int gc_collect_cycles(void)", + "int gc_collect_cycles()", "Forces collection of any existing garbage cycles. Returns number of freed zvals" ], "gc_disable": [ - "void gc_disable(void)", + "void gc_disable()", "Deactivates the circular reference collector" ], "gc_enable": [ - "void gc_enable(void)", + "void gc_enable()", "Activates the circular reference collector" ], "gc_enabled": [ - "void gc_enabled(void)", + "void gc_enabled()", "Returns status of the circular reference collector" ], "gd_info": [ @@ -4305,7 +4500,7 @@ var functionMap = { ], "getKeywords": [ "static array getKeywords(string $locale) {", - "* return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array (doh!) * }}}" + "* return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array * }}}" ], "get_browser": [ "mixed get_browser([string browser_name [, bool return_array]])", @@ -4332,7 +4527,7 @@ var functionMap = { "Returns an array of default properties of the class." ], "get_current_user": [ - "string get_current_user(void)", + "string get_current_user()", "Get the name of the owner of the current PHP script" ], "get_declared_classes": [ @@ -4348,11 +4543,11 @@ var functionMap = { "Return an array containing the names and values of all defined constants" ], "get_defined_functions": [ - "array get_defined_functions(void)", + "array get_defined_functions()", "Returns an array of all defined functions" ], "get_defined_vars": [ - "array get_defined_vars(void)", + "array get_defined_vars()", "Returns an associative array of names and values of all currently defined variable names (variables in the current scope)" ], "get_display_language": [ @@ -4388,7 +4583,7 @@ var functionMap = { "Get the current include_path configuration option" ], "get_included_files": [ - "array get_included_files(void)", + "array get_included_files()", "Returns an array with the file names that were include_once()'d" ], "get_loaded_extensions": [ @@ -4396,11 +4591,11 @@ var functionMap = { "Return an array containing names of loaded extensions" ], "get_magic_quotes_gpc": [ - "int get_magic_quotes_gpc(void)", + "int get_magic_quotes_gpc()", "Get the current active configuration setting of magic_quotes_gpc" ], "get_magic_quotes_runtime": [ - "int get_magic_quotes_runtime(void)", + "int get_magic_quotes_runtime()", "Get the current active configuration setting of magic_quotes_runtime" ], "get_meta_tags": [ @@ -4420,11 +4615,11 @@ var functionMap = { "Get the resource type name for a given resource" ], "getallheaders": [ - "array getallheaders(void)", + "array getallheaders()", "" ], "getcwd": [ - "mixed getcwd(void)", + "mixed getcwd()", "Gets the current directory" ], "getdate": [ @@ -4456,23 +4651,23 @@ var functionMap = { "Get the size of an image as 4-element array" ], "getlastmod": [ - "int getlastmod(void)", + "int getlastmod()", "Get time of last page modification" ], "getmygid": [ - "int getmygid(void)", + "int getmygid()", "Get PHP script owner's GID" ], "getmyinode": [ - "int getmyinode(void)", + "int getmyinode()", "Get the inode of the current script being parsed" ], "getmypid": [ - "int getmypid(void)", + "int getmypid()", "Get current process ID" ], "getmyuid": [ - "int getmyuid(void)", + "int getmyuid()", "Get PHP script owner's UID" ], "getopt": [ @@ -4488,7 +4683,7 @@ var functionMap = { "Returns protocol name associated with protocol number proto" ], "getrandmax": [ - "int getrandmax(void)", + "int getrandmax()", "Returns the maximum value a random number can have" ], "getrusage": [ @@ -4764,7 +4959,7 @@ var functionMap = { "Generate a hash of a given input string Returns lowercase hexits by default" ], "hash_algos": [ - "array hash_algos(void)", + "array hash_algos()", "Return a list of registered hashing algorithms" ], "hash_copy": [ @@ -4812,7 +5007,7 @@ var functionMap = { "Removes an HTTP header previously set using header()" ], "headers_list": [ - "array headers_list(void)", + "array headers_list()", "Return list of headers to be sent / already sent" ], "headers_sent": [ @@ -4940,11 +5135,11 @@ var functionMap = { "Drop an InterBase database" ], "ibase_errcode": [ - "int ibase_errcode(void)", + "int ibase_errcode()", "Return error code" ], "ibase_errmsg": [ - "string ibase_errmsg(void)", + "string ibase_errmsg()", "Return error message" ], "ibase_execute": [ @@ -5413,7 +5608,7 @@ var functionMap = { ], "imagepsextendfont": [ "bool imagepsextendfont(resource font_index, float extend)", - "Extend or or condense (if extend < 1) a font" + "Extend or or condense if (extend < 1) a font" ], "imagepsfreefont": [ "bool imagepsfreefont(resource font_index)", @@ -5492,7 +5687,7 @@ var functionMap = { "Write text to the image using a TrueType font" ], "imagetypes": [ - "int imagetypes(void)", + "int imagetypes()", "Return the types of images supported in a bitfield - 1=GIF, 2=JPEG, 4=PNG, 8=WBMP, 16=XPM" ], "imagewbmp": [ @@ -5508,7 +5703,7 @@ var functionMap = { "Convert an 8-bit string to a quoted-printable string" ], "imap_alerts": [ - "array imap_alerts(void)", + "array imap_alerts()", "Returns an array of all IMAP alerts that have been generated since the last page load or since the last imap_alerts() call, whichever came last. The alert stack is cleared after imap_alerts() is called." ], "imap_append": [ @@ -5556,7 +5751,7 @@ var functionMap = { "Delete a mailbox" ], "imap_errors": [ - "array imap_errors(void)", + "array imap_errors()", "Returns an array of all IMAP errors generated since the last page load, or since the last imap_errors() call, whichever came last. The error stack is cleared after imap_errors() is called." ], "imap_expunge": [ @@ -5612,7 +5807,7 @@ var functionMap = { "Returns headers for all messages in a mailbox" ], "imap_last_error": [ - "string imap_last_error(void)", + "string imap_last_error()", "Returns the last error that was generated by an IMAP function. The error stack is NOT cleared after this call." ], "imap_list": [ @@ -5863,6 +6058,10 @@ var functionMap = { "bool is_callable(mixed var [, bool syntax_only [, string callable_name]])", "Returns true if var is callable." ], + "is_countable": [ + "bool is_countable(mixed var)", + "Returns true if var is countable, false otherwise" + ], "is_dir": [ "bool is_dir(string filename)", "Returns true if file is directory" @@ -5944,15 +6143,15 @@ var functionMap = { "Determine whether a variable is set" ], "iterator_apply": [ - "int iterator_apply(Traversable it, mixed function [, mixed params])", + "int iterator_apply(Traversable iterator, callable function [, array args = null)", "Calls a function for every element in an iterator" ], "iterator_count": [ - "int iterator_count(Traversable it)", + "int iterator_count(Traversable iterator)", "Count the elements in an iterator" ], "iterator_to_array": [ - "array iterator_to_array(Traversable it [, bool use_keys = true])", + "array iterator_to_array(Traversable iterator [, bool use_keys = true])", "Copy the iterator into an array" ], "jddayofweek": [ @@ -5988,11 +6187,11 @@ var functionMap = { "Converts a jewish calendar date to a julian day count" ], "join": [ - "string join(array src, string glue)", - "An alias for implode" + "string join([string glue,] array pieces)", + "Returns a string containing a string representation of all the arrayelements in the same order, with the glue string between each element" ], "jpeg2wbmp": [ - "bool jpeg2wbmp (string f_org, string f_dest, int d_height, int d_width, int threshold)", + "bool jpeg2wbmp(string f_org, string f_dest, int d_height, int d_width, int threshold)", "Convert JPEG image to WBMP image" ], "json_decode": [ @@ -6160,7 +6359,7 @@ var functionMap = { "Read an entry" ], "ldap_rename": [ - "bool ldap_rename(resource link, string dn, string newrdn, string newparent, bool deleteoldrdn);", + "bool ldap_rename(resource link, string dn, string newrdn, string newparent, bool deleteoldrdn)", "Modify the name of an entry" ], "ldap_sasl_bind": [ @@ -6208,7 +6407,7 @@ var functionMap = { "Clear last error from libxml" ], "libxml_disable_entity_loader": [ - "bool libxml_disable_entity_loader([boolean disable])", + "bool libxml_disable_entity_loader([bool disable])", "Disable/Enable ability to load external entities" ], "libxml_get_errors": [ @@ -6224,7 +6423,7 @@ var functionMap = { "Set the streams context for the next libxml document load or write" ], "libxml_use_internal_errors": [ - "bool libxml_use_internal_errors([boolean use_errors])", + "bool libxml_use_internal_errors([bool use_errors])", "Disable libxml errors and allow user to fetch error information as needed" ], "link": [ @@ -6236,11 +6435,11 @@ var functionMap = { "Returns the st_dev field of the UNIX C stat structure describing the link" ], "litespeed_request_headers": [ - "array litespeed_request_headers(void)", + "array litespeed_request_headers()", "Fetch all HTTP request headers" ], "litespeed_response_headers": [ - "array litespeed_response_headers(void)", + "array litespeed_response_headers()", "Fetch all HTTP response headers" ], "locale_accept_from_http": [ @@ -6252,7 +6451,7 @@ var functionMap = { "* @param string $locale The locale string to canonicalize" ], "locale_filter_matches": [ - "boolean locale_filter_matches(string $langtag, string $locale[, bool $canonicalize])", + "bool locale_filter_matches(string $langtag, string $locale[, bool $canonicalize])", "* Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm" ], "locale_get_all_variants": [ @@ -6265,7 +6464,7 @@ var functionMap = { ], "locale_get_keywords": [ "static array locale_get_keywords(string $locale) {", - "* return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array (doh!)" + "* return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array" ], "locale_get_primary_language": [ "static string locale_get_primary_language($locale)", @@ -6288,7 +6487,7 @@ var functionMap = { "Set default locale" ], "localeconv": [ - "array localeconv(void)", + "array localeconv()", "Returns numeric formatting information based on the current locale" ], "localtime": [ @@ -6392,11 +6591,11 @@ var functionMap = { "Regular expression search for multibyte string" ], "mb_ereg_search_getpos": [ - "int mb_ereg_search_getpos(void)", + "int mb_ereg_search_getpos()", "Get search start position" ], "mb_ereg_search_getregs": [ - "array mb_ereg_search_getregs(void)", + "array mb_ereg_search_getregs()", "Get matched substring of the last time" ], "mb_ereg_search_init": [ @@ -6716,7 +6915,7 @@ var functionMap = { "Hash data with hash" ], "mhash_count": [ - "int mhash_count(void)", + "int mhash_count()", "Gets the number of available hashes" ], "mhash_get_block_size": [ @@ -6892,7 +7091,7 @@ var functionMap = { "Free a MS-SQL statement index" ], "mssql_get_last_message": [ - "string mssql_get_last_message(void)", + "string mssql_get_last_message()", "Gets the last message from the MS-SQL server" ], "mssql_guid_string": [ @@ -6944,7 +7143,7 @@ var functionMap = { "Select a MS-SQL database" ], "mt_getrandmax": [ - "int mt_getrandmax(void)", + "int mt_getrandmax()", "Returns the maximum value a random number from Mersenne Twister can have" ], "mt_rand": [ @@ -7052,7 +7251,7 @@ var functionMap = { "Free result memory" ], "mysql_get_client_info": [ - "string mysql_get_client_info(void)", + "string mysql_get_client_info()", "Returns a string that represents the client library version" ], "mysql_get_host_info": [ @@ -7148,7 +7347,7 @@ var functionMap = { "Turn auto commit on or of" ], "mysqli_cache_stats": [ - "array mysqli_cache_stats(void)", + "array mysqli_cache_stats()", "Returns statistics about the zval cache" ], "mysqli_change_user": [ @@ -7172,11 +7371,11 @@ var functionMap = { "Open a connection to a mysql server" ], "mysqli_connect_errno": [ - "int mysqli_connect_errno(void)", + "int mysqli_connect_errno()", "Returns the numerical value of the error message from last connect command" ], "mysqli_connect_error": [ - "string mysqli_connect_error(void)", + "string mysqli_connect_error()", "Returns the text of the error message from previous MySQL operation" ], "mysqli_data_seek": [ @@ -7192,7 +7391,7 @@ var functionMap = { "" ], "mysqli_embedded_server_end": [ - "void mysqli_embedded_server_end(void)", + "void mysqli_embedded_server_end()", "" ], "mysqli_embedded_server_start": [ @@ -7208,39 +7407,39 @@ var functionMap = { "Returns the text of the error message from previous MySQL operation" ], "mysqli_fetch_all": [ - "mixed mysqli_fetch_all (object result [,int resulttype])", + "mixed mysqli_fetch_all(object result [,int resulttype])", "Fetches all result rows as an associative array, a numeric array, or both" ], "mysqli_fetch_array": [ - "mixed mysqli_fetch_array (object result [,int resulttype])", + "mixed mysqli_fetch_array(object result [,int resulttype])", "Fetch a result row as an associative array, a numeric array, or both" ], "mysqli_fetch_assoc": [ - "mixed mysqli_fetch_assoc (object result)", + "mixed mysqli_fetch_assoc(object result)", "Fetch a result row as an associative array" ], "mysqli_fetch_field": [ - "mixed mysqli_fetch_field (object result)", + "mixed mysqli_fetch_field(object result)", "Get column information from a result and return as an object" ], "mysqli_fetch_field_direct": [ - "mixed mysqli_fetch_field_direct (object result, int offset)", + "mixed mysqli_fetch_field_direct(object result, int offset)", "Fetch meta-data for a single field" ], "mysqli_fetch_fields": [ - "mixed mysqli_fetch_fields (object result)", + "mixed mysqli_fetch_fields(object result)", "Return array of objects containing field meta-data" ], "mysqli_fetch_lengths": [ - "mixed mysqli_fetch_lengths (object result)", + "mixed mysqli_fetch_lengths(object result)", "Get the length of each output in a result" ], "mysqli_fetch_object": [ - "mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])", + "mixed mysqli_fetch_object(object result [, string class_name [, NULL|array ctor_params]])", "Fetch a result row as an object" ], "mysqli_fetch_row": [ - "array mysqli_fetch_row (object result)", + "array mysqli_fetch_row(object result)", "Get a result row as an enumerated array" ], "mysqli_field_count": [ @@ -7264,23 +7463,23 @@ var functionMap = { "returns a character set object" ], "mysqli_get_client_info": [ - "string mysqli_get_client_info(void)", + "string mysqli_get_client_info()", "Get MySQL client info" ], "mysqli_get_client_stats": [ - "array mysqli_get_client_stats(void)", + "array mysqli_get_client_stats()", "Returns statistics about the zval cache" ], "mysqli_get_client_version": [ - "int mysqli_get_client_version(void)", + "int mysqli_get_client_version()", "Get MySQL client info" ], "mysqli_get_connection_stats": [ - "array mysqli_get_connection_stats(void)", + "array mysqli_get_connection_stats()", "Returns statistics about the zval cache" ], "mysqli_get_host_info": [ - "string mysqli_get_host_info (object link)", + "string mysqli_get_host_info(object link)", "Get MySQL host info" ], "mysqli_get_proto_info": [ @@ -7296,15 +7495,15 @@ var functionMap = { "Return the MySQL version for the server referenced by the given link" ], "mysqli_get_warnings": [ - "object mysqli_get_warnings(object link) */", - "PHP_FUNCTION(mysqli_get_warnings) { MY_MYSQL *mysql; zval *mysql_link; MYSQLI_RESOURCE *mysqli_resource; MYSQLI_WARNING *w; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), \"O\", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, \"mysqli_link\", MYSQLI_STATUS_VALID); if (mysql_warning_count(mysql->mysql)) { w = php_get_warnings(mysql->mysql TSRMLS_CC); } else { RETURN_FALSE; } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = mysqli_resource->info = (void *)w; mysqli_resource->status = MYSQLI_STATUS_VALID; MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); } /* }}}" + "object mysqli_get_warnings(object link)", + "" ], "mysqli_info": [ "string mysqli_info(object link)", "Get information about the most recent query" ], "mysqli_init": [ - "resource mysqli_init(void)", + "resource mysqli_init()", "Initialize mysqli and return a resource for use with mysql_real_connect" ], "mysqli_insert_id": [ @@ -7356,8 +7555,8 @@ var functionMap = { "Prepare a SQL statement for execution" ], "mysqli_query": [ - "mixed mysqli_query(object link, string query [,int resultmode]) */", - "PHP_FUNCTION(mysqli_query) { MY_MYSQL *mysql; zval *mysql_link; MYSQLI_RESOURCE *mysqli_resource; MYSQL_RES *result; char *query = NULL; unsigned int query_len; unsigned long resultmode = MYSQLI_STORE_RESULT; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), \"Os|l\", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) { return; } if (!query_len) { php_error_docref(NULL TSRMLS_CC, E_WARNING, \"Empty query\"); RETURN_FALSE; } if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) { php_error_docref(NULL TSRMLS_CC, E_WARNING, \"Invalid value for resultmode\"); RETURN_FALSE; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, \"mysqli_link\", MYSQLI_STATUS_VALID); MYSQLI_DISABLE_MQ; #ifdef MYSQLI_USE_MYSQLND if (resultmode & MYSQLI_ASYNC) { if (mysqli_async_query(mysql->mysql, query, query_len)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC; RETURN_TRUE; } #endif if (mysql_real_query(mysql->mysql, query, query_len)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } if (!mysql_field_count(mysql->mysql)) { /* no result set - not a SELECT" + "mixed mysqli_query(object link, string query [,int resultmode])", + "" ], "mysqli_real_connect": [ "bool mysqli_real_connect(object link [,string hostname [,string username [,string passwd [,string dbname [,int port [,string socket [,int flags]]]]]]])", @@ -7472,8 +7671,8 @@ var functionMap = { "Buffer result set on client" ], "mysqli_stmt_get_warnings": [ - "object mysqli_stmt_get_warnings(object link) */", - "PHP_FUNCTION(mysqli_stmt_get_warnings) { MY_STMT *stmt; zval *stmt_link; MYSQLI_RESOURCE *mysqli_resource; MYSQLI_WARNING *w; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), \"O\", &stmt_link, mysqli_stmt_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT*, &stmt_link, \"mysqli_stmt\", MYSQLI_STATUS_VALID); if (mysqli_stmt_warning_count(stmt->stmt)) { w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC); } else { RETURN_FALSE; } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); mysqli_resource->ptr = mysqli_resource->info = (void *)w; mysqli_resource->status = MYSQLI_STATUS_VALID; MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); } /* }}}" + "object mysqli_stmt_get_warnings(object link)", + "" ], "mysqli_stmt_init": [ "mixed mysqli_stmt_init(object link)", @@ -7528,7 +7727,7 @@ var functionMap = { "Return the current thread ID" ], "mysqli_thread_safe": [ - "bool mysqli_thread_safe(void)", + "bool mysqli_thread_safe()", "Return whether thread safety is given or not" ], "mysqli_use_result": [ @@ -7536,7 +7735,7 @@ var functionMap = { "Directly retrieve query results - do not buffer results on client side" ], "mysqli_warning_count": [ - "int mysqli_warning_count (object link)", + "int mysqli_warning_count(object link)", "Return number of warnings from the last query for the given link" ], "natcasesort": [ @@ -7572,11 +7771,11 @@ var functionMap = { "* Normalize a string." ], "nsapi_request_headers": [ - "array nsapi_request_headers(void)", + "array nsapi_request_headers()", "Get all headers from the request" ], "nsapi_response_headers": [ - "array nsapi_response_headers(void)", + "array nsapi_response_headers()", "Get all headers from the response" ], "nsapi_virtual": [ @@ -7656,39 +7855,39 @@ var functionMap = { "* Get formatter attribute value." ], "ob_clean": [ - "bool ob_clean(void)", + "bool ob_clean()", "Clean (delete) the current output buffer" ], "ob_end_clean": [ - "bool ob_end_clean(void)", + "bool ob_end_clean()", "Clean the output buffer, and delete current output buffer" ], "ob_end_flush": [ - "bool ob_end_flush(void)", + "bool ob_end_flush()", "Flush (send) the output buffer, and delete current output buffer" ], "ob_flush": [ - "bool ob_flush(void)", + "bool ob_flush()", "Flush (send) contents of the output buffer. The last buffer content is sent to next buffer" ], "ob_get_clean": [ - "bool ob_get_clean(void)", + "bool ob_get_clean()", "Get current buffer contents and delete current output buffer" ], "ob_get_contents": [ - "string ob_get_contents(void)", + "string ob_get_contents()", "Return the contents of the output buffer" ], "ob_get_flush": [ - "bool ob_get_flush(void)", + "bool ob_get_flush()", "Get current buffer contents, flush (send) the output buffer, and delete current output buffer" ], "ob_get_length": [ - "int ob_get_length(void)", + "int ob_get_length()", "Return the length of the output buffer" ], "ob_get_level": [ - "int ob_get_level(void)", + "int ob_get_level()", "Return the nesting level of the output buffer" ], "ob_get_status": [ @@ -8008,7 +8207,7 @@ var functionMap = { "Returns current state of buffering for a LOB" ], "ocisetbufferinglob": [ - "bool ocisetbufferinglob( boolean flag )", + "bool ocisetbufferinglob( bool flag )", "Enables/disables buffering for a LOB" ], "octdec": [ @@ -8028,7 +8227,7 @@ var functionMap = { "Close an ODBC connection" ], "odbc_close_all": [ - "void odbc_close_all(void)", + "void odbc_close_all()", "Close all ODBC connections" ], "odbc_columnprivileges": [ @@ -8236,7 +8435,7 @@ var functionMap = { "Encrypts given data with given method and key, returns raw or base64 encoded string" ], "openssl_error_string": [ - "mixed openssl_error_string(void)", + "mixed openssl_error_string()", "Returns a description of the last error, and alters the index of the error messages. Returns false when the are no more messages" ], "openssl_get_cipher_methods": [ @@ -8376,7 +8575,7 @@ var functionMap = { "Add URL rewriter values" ], "output_reset_rewrite_vars": [ - "bool output_reset_rewrite_vars(void)", + "bool output_reset_rewrite_vars()", "Reset(clear) URL rewriter values" ], "pack": [ @@ -8428,7 +8627,7 @@ var functionMap = { "Executes specified program in current process space as defined by exec(2)" ], "pcntl_fork": [ - "int pcntl_fork(void)", + "int pcntl_fork()", "Forks the currently running process following the same behavior as the UNIX fork() system call" ], "pcntl_getpriority": [ @@ -8545,7 +8744,7 @@ var functionMap = { ], "pg_delete": [ "mixed pg_delete(resource db, string table, array ids[, int options])", - "Delete records has ids (id=>value)" + "Delete records has ids (id => value)" ], "pg_end_copy": [ "bool pg_end_copy([resource connection])", @@ -8645,7 +8844,7 @@ var functionMap = { ], "pg_insert": [ "mixed pg_insert(resource db, string table, array values[, int options])", - "Insert values (filed=>value) to table" + "Insert values (filed => value) to table" ], "pg_last_error": [ "string pg_last_error([resource connection])", @@ -8769,7 +8968,7 @@ var functionMap = { ], "pg_select": [ "mixed pg_select(resource db, string table, array ids[, int options])", - "Select records that has ids (id=>value)" + "Select records that has ids (id => value)" ], "pg_send_execute": [ "bool pg_send_execute(resource connection, string stmtname, array params)", @@ -8817,34 +9016,34 @@ var functionMap = { ], "pg_update": [ "mixed pg_update(resource db, string table, array fields, array ids[, int options])", - "Update table using values (field=>value) and ids (id=>value)" + "Update table using values (field => value) and ids (id => value)" ], "pg_version": [ "array pg_version([resource connection])", "Returns an array with client, protocol and server version (when available)" ], "php_egg_logo_guid": [ - "string php_egg_logo_guid(void)", + "string php_egg_logo_guid()", "Return the special ID used to request the PHP logo in phpinfo screens" ], "php_ini_loaded_file": [ - "string php_ini_loaded_file(void)", + "string php_ini_loaded_file()", "Return the actual loaded ini filename" ], "php_ini_scanned_files": [ - "string php_ini_scanned_files(void)", + "string php_ini_scanned_files()", "Return comma-separated string of .ini files parsed from the additional ini dir" ], "php_logo_guid": [ - "string php_logo_guid(void)", + "string php_logo_guid()", "Return the special ID used to request the PHP logo in phpinfo screens" ], "php_real_logo_guid": [ - "string php_real_logo_guid(void)", + "string php_real_logo_guid()", "Return the special ID used to request the PHP logo in phpinfo screens" ], "php_sapi_name": [ - "string php_sapi_name(void)", + "string php_sapi_name()", "Return the current SAPI module name" ], "php_snmpv3": [ @@ -8856,7 +9055,7 @@ var functionMap = { "Return source with stripped comments and whitespace" ], "php_uname": [ - "string php_uname(void)", + "string php_uname()", "Return information about the system PHP was built on" ], "phpcredits": [ @@ -8872,11 +9071,11 @@ var functionMap = { "Return the current PHP version" ], "pi": [ - "float pi(void)", + "float pi()", "Returns an approximation of pi" ], "png2wbmp": [ - "bool png2wbmp (string f_org, string f_dest, int d_height, int d_width, int threshold)", + "bool png2wbmp(string f_org, string f_dest, int d_height, int d_width, int threshold)", "Convert PNG image to WBMP image" ], "popen": [ @@ -8888,27 +9087,27 @@ var functionMap = { "Determine accessibility of a file (POSIX.1 5.6.3)" ], "posix_ctermid": [ - "string posix_ctermid(void)", + "string posix_ctermid()", "Generate terminal path name (POSIX.1, 4.7.1)" ], "posix_get_last_error": [ - "int posix_get_last_error(void)", + "int posix_get_last_error()", "Retrieve the error number set by the last posix function which failed." ], "posix_getcwd": [ - "string posix_getcwd(void)", + "string posix_getcwd()", "Get working directory pathname (POSIX.1, 5.2.2)" ], "posix_getegid": [ - "int posix_getegid(void)", + "int posix_getegid()", "Get the current effective group id (POSIX.1, 4.2.1)" ], "posix_geteuid": [ - "int posix_geteuid(void)", + "int posix_geteuid()", "Get the current effective user id (POSIX.1, 4.2.1)" ], "posix_getgid": [ - "int posix_getgid(void)", + "int posix_getgid()", "Get the current group id (POSIX.1, 4.2.1)" ], "posix_getgrgid": [ @@ -8920,27 +9119,27 @@ var functionMap = { "Group database access (POSIX.1, 9.2.1)" ], "posix_getgroups": [ - "array posix_getgroups(void)", + "array posix_getgroups()", "Get supplementary group id's (POSIX.1, 4.2.3)" ], "posix_getlogin": [ - "string posix_getlogin(void)", + "string posix_getlogin()", "Get user name (POSIX.1, 4.2.4)" ], "posix_getpgid": [ - "int posix_getpgid(void)", + "int posix_getpgid()", "Get the process group id of the specified process (This is not a POSIX function, but a SVR4ism, so we compile conditionally)" ], "posix_getpgrp": [ - "int posix_getpgrp(void)", + "int posix_getpgrp()", "Get current process group id (POSIX.1, 4.3.1)" ], "posix_getpid": [ - "int posix_getpid(void)", + "int posix_getpid()", "Get the current process id (POSIX.1, 4.1.1)" ], "posix_getppid": [ - "int posix_getppid(void)", + "int posix_getppid()", "Get the parent process id (POSIX.1, 4.1.1)" ], "posix_getpwnam": [ @@ -8952,15 +9151,15 @@ var functionMap = { "User database access (POSIX.1, 9.2.2)" ], "posix_getrlimit": [ - "array posix_getrlimit(void)", + "array posix_getrlimit()", "Get system resource consumption limits (This is not a POSIX function, but a BSDism and a SVR4ism. We compile conditionally)" ], "posix_getsid": [ - "int posix_getsid(void)", + "int posix_getsid()", "Get process group id of session leader (This is not a POSIX function, but a SVR4ism, so be compile conditionally)" ], "posix_getuid": [ - "int posix_getuid(void)", + "int posix_getuid()", "Get the current user id (POSIX.1, 4.2.1)" ], "posix_initgroups": [ @@ -9000,7 +9199,7 @@ var functionMap = { "Set process group id for job control (POSIX.1, 4.3.3)" ], "posix_setsid": [ - "int posix_setsid(void)", + "int posix_setsid()", "Create session and set process group id (POSIX.1, 4.3.2)" ], "posix_setuid": [ @@ -9012,7 +9211,7 @@ var functionMap = { "Retrieve the system error message associated with the given errno." ], "posix_times": [ - "array posix_times(void)", + "array posix_times()", "Get process times (POSIX.1, 4.5.2)" ], "posix_ttyname": [ @@ -9020,7 +9219,7 @@ var functionMap = { "Determine terminal device name (POSIX.1, 4.7.2)" ], "posix_uname": [ - "array posix_uname(void)", + "array posix_uname()", "Get system name (POSIX.1, 4.4.1)" ], "pow": [ @@ -9188,8 +9387,8 @@ var functionMap = { "Convert a quoted-printable string to an 8 bit string" ], "quoted_printable_encode": [ - "string quoted_printable_encode(string str) */", - "PHP_FUNCTION(quoted_printable_encode) { char *str, *new_str; int str_len; size_t new_str_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"s\", &str, &str_len) != SUCCESS) { return; } if (!str_len) { RETURN_EMPTY_STRING(); } new_str = (char *)php_quot_print_encode((unsigned char *)str, (size_t)str_len, &new_str_len); RETURN_STRINGL(new_str, new_str_len, 0); } /* }}}" + "string quoted_printable_encode(string str)", + "" ], "quotemeta": [ "string quotemeta(string str)", @@ -9248,7 +9447,7 @@ var functionMap = { "Informs the readline callback interface that a character is ready for input" ], "readline_clear_history": [ - "bool readline_clear_history(void)", + "bool readline_clear_history()", "Clears the history" ], "readline_completion_function": [ @@ -9260,11 +9459,11 @@ var functionMap = { "Gets/sets various internal readline variables." ], "readline_list_history": [ - "array readline_list_history(void)", + "array readline_list_history()", "Lists the history" ], "readline_on_new_line": [ - "void readline_on_new_line(void)", + "void readline_on_new_line()", "Inform readline that the cursor has moved to a new line" ], "readline_read_history": [ @@ -9272,7 +9471,7 @@ var functionMap = { "Reads the history" ], "readline_redisplay": [ - "void readline_redisplay(void)", + "void readline_redisplay()", "Ask readline to redraw the display" ], "readline_write_history": [ @@ -9328,11 +9527,11 @@ var functionMap = { "Set array argument's internal pointer to the first element and return it" ], "restore_error_handler": [ - "void restore_error_handler(void)", + "void restore_error_handler()", "Restores the previously defined error handler function" ], "restore_exception_handler": [ - "void restore_exception_handler(void)", + "void restore_exception_handler()", "Restores the previously defined exception handler function" ], "restore_include_path": [ @@ -9400,15 +9599,15 @@ var functionMap = { "Deserializes data and reinitializes the variables" ], "session_destroy": [ - "bool session_destroy(void)", + "bool session_destroy()", "Destroy the current session and all data associated with it" ], "session_encode": [ - "string session_encode(void)", + "string session_encode()", "Serializes the current setup and returns the serialized representation" ], "session_get_cookie_params": [ - "array session_get_cookie_params(void)", + "array session_get_cookie_params()", "Return the session cookie parameters" ], "session_id": [ @@ -9448,7 +9647,7 @@ var functionMap = { "Sets user-level functions" ], "session_start": [ - "bool session_start(void)", + "bool session_start()", "Begin session - reinitializes freezed variables, registers browsers etc" ], "session_unregister": [ @@ -9456,11 +9655,11 @@ var functionMap = { "Removes varname from the list of variables which are freezed at the session end" ], "session_unset": [ - "void session_unset(void)", + "void session_unset()", "Unset all registered variables" ], "session_write_close": [ - "void session_write_close(void)", + "void session_write_close()", "Write session data and end session" ], "set_error_handler": [ @@ -9540,27 +9739,27 @@ var functionMap = { "Removes variable from shared memory" ], "shmop_close": [ - "void shmop_close (int shmid)", + "void shmop_close(int shmid)", "closes a shared memory segment" ], "shmop_delete": [ - "bool shmop_delete (int shmid)", + "bool shmop_delete(int shmid)", "mark segment for deletion" ], "shmop_open": [ - "int shmop_open (int key, string flags, int mode, int size)", + "int shmop_open(int key, string flags, int mode, int size)", "gets and attaches a shared memory segment" ], "shmop_read": [ - "string shmop_read (int shmid, int start, int count)", + "string shmop_read(int shmid, int start, int count)", "reads from a shm segment" ], "shmop_size": [ - "int shmop_size (int shmid)", + "int shmop_size(int shmid)", "returns the shm size" ], "shmop_write": [ - "int shmop_write (int shmid, string data, int offset)", + "int shmop_write(int shmid, string data, int offset)", "writes to a shared memory segment" ], "shuffle": [ @@ -9672,7 +9871,7 @@ var functionMap = { "Fetch the value of a SNMP object" ], "snmp_get_quick_print": [ - "bool snmp_get_quick_print(void)", + "bool snmp_get_quick_print()", "Return the current status of quick_print" ], "snmp_get_valueretrieval": [ @@ -9920,7 +10119,7 @@ var functionMap = { "Escapes a string for use as a query parameter." ], "sqlite_exec": [ - "boolean sqlite_exec(string query, resource db[, string &error_message])", + "bool sqlite_exec(string query, resource db[, string &error_message])", "Executes a result-less query against a given database" ], "sqlite_factory": [ @@ -10172,7 +10371,7 @@ var functionMap = { "Reads all remaining bytes (or up to maxlen bytes) from a stream and returns them as a string." ], "stream_get_filters": [ - "array stream_get_filters(void)", + "array stream_get_filters()", "Returns a list of registered filters" ], "stream_get_line": [ @@ -10436,7 +10635,7 @@ var functionMap = { "Free result memory" ], "sybase_get_last_message": [ - "string sybase_get_last_message(void)", + "string sybase_get_last_message()", "Returns the last message from server (over min_message_severity)" ], "sybase_min_client_severity": [ @@ -10520,7 +10719,7 @@ var functionMap = { "Returns the Number of Tidy accessibility warnings encountered for specified document." ], "tidy_clean_repair": [ - "boolean tidy_clean_repair()", + "bool tidy_clean_repair()", "Execute configured cleanup and repair operations on parsed markup" ], "tidy_config_count": [ @@ -10528,7 +10727,7 @@ var functionMap = { "Returns the Number of Tidy configuration errors encountered for specified document." ], "tidy_diagnose": [ - "boolean tidy_diagnose()", + "bool tidy_diagnose()", "Run configured diagnostics on parsed and repaired markup." ], "tidy_error_count": [ @@ -10544,7 +10743,7 @@ var functionMap = { "Get current Tidy configuarion" ], "tidy_get_error_buffer": [ - "string tidy_get_error_buffer([boolean detailed])", + "string tidy_get_error_buffer([bool detailed])", "Return warnings and errors which occured parsing the specified document" ], "tidy_get_head": [ @@ -10584,15 +10783,15 @@ var functionMap = { "Returns the value of the specified configuration option for the tidy document." ], "tidy_is_xhtml": [ - "boolean tidy_is_xhtml()", + "bool tidy_is_xhtml()", "Indicates if the document is a XHTML document." ], "tidy_is_xml": [ - "boolean tidy_is_xml()", + "bool tidy_is_xml()", "Indicates if the document is a generic (non HTML/XHTML) XML document." ], "tidy_parse_file": [ - "boolean tidy_parse_file(string file [, mixed config_options [, string encoding [, bool use_include_path]]])", + "bool tidy_parse_file(string file [, mixed config_options [, string encoding [, bool use_include_path]]])", "Parse markup in file or URI" ], "tidy_parse_string": [ @@ -10600,11 +10799,11 @@ var functionMap = { "Parse a document stored in a string" ], "tidy_repair_file": [ - "boolean tidy_repair_file(string filename [, mixed config_file [, string encoding [, bool use_include_path]]])", + "bool tidy_repair_file(string filename [, mixed config_file [, string encoding [, bool use_include_path]]])", "Repair a file using an optionally provided configuration file" ], "tidy_repair_string": [ - "boolean tidy_repair_string(string data [, mixed config_file [, string encoding]])", + "bool tidy_repair_string(string data [, mixed config_file [, string encoding]])", "Repair a string using an optionally provided configuration file" ], "tidy_warning_count": [ @@ -10612,7 +10811,7 @@ var functionMap = { "Returns the Number of Tidy warnings encountered for specified document." ], "time": [ - "int time(void)", + "int time()", "Return current UNIX timestamp" ], "time_nanosleep": [ @@ -10660,7 +10859,7 @@ var functionMap = { "Returns the Olson database version number." ], "tmpfile": [ - "resource tmpfile(void)", + "resource tmpfile()", "Create a temporary file that will be deleted automatically after use" ], "token_get_all": [ @@ -10728,7 +10927,7 @@ var functionMap = { "Takes a string representation of variable and recreates it" ], "unset": [ - "void unset (mixed var [, mixed var])", + "void unset(mixed var [, mixed var])", "Unset a given variable" ], "urldecode": [ @@ -10760,7 +10959,7 @@ var functionMap = { "Dumps a string representation of variable to output" ], "var_export": [ - "mixed var_export(mixed var [, bool return])", + "string var_export(mixed var [, bool return])", "Outputs or returns a string representation of a variable" ], "variant_abs": [ @@ -10888,7 +11087,7 @@ var functionMap = { "Return a formatted string" ], "wddx_add_vars": [ - "int wddx_add_vars(resource packet_id, mixed var_names [, mixed ...])", + "int wddx_add_vars(resource packet_id, mixed var_names [, mixed ...])", "Serializes given variables and adds them to packet given by packet_id" ], "wddx_deserialize": [ @@ -10912,7 +11111,7 @@ var functionMap = { "Creates a new packet and serializes given variables into a struct" ], "wordwrap": [ - "string wordwrap(string str [, int width [, string break [, boolean cut]]])", + "string wordwrap(string str [, int width [, string break [, bool cut]]])", "Wraps buffer to selected number of characters using string break char" ], "xml_error_string": [ @@ -11040,7 +11239,7 @@ var functionMap = { "Parses XML requests and call methods" ], "xmlrpc_server_create": [ - "resource xmlrpc_server_create(void)", + "resource xmlrpc_server_create()", "Creates an xmlrpc server" ], "xmlrpc_server_destroy": [ @@ -11228,51 +11427,51 @@ var functionMap = { "Write text - returns FALSE on error" ], "xsl_xsltprocessor_get_parameter": [ - "string xsl_xsltprocessor_get_parameter(string namespace, string name);", + "string xsl_xsltprocessor_get_parameter(string namespace, string name)", "" ], "xsl_xsltprocessor_has_exslt_support": [ - "bool xsl_xsltprocessor_has_exslt_support();", + "bool xsl_xsltprocessor_has_exslt_support()", "" ], "xsl_xsltprocessor_import_stylesheet": [ - "void xsl_xsltprocessor_import_stylesheet(domdocument doc);", - "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# Since:" + "void xsl_xsltprocessor_import_stylesheet(domdocument doc)", + "" ], "xsl_xsltprocessor_register_php_functions": [ - "void xsl_xsltprocessor_register_php_functions([mixed $restrict]);", + "void xsl_xsltprocessor_register_php_functions([mixed $restrict])", "" ], "xsl_xsltprocessor_remove_parameter": [ - "bool xsl_xsltprocessor_remove_parameter(string namespace, string name);", + "bool xsl_xsltprocessor_remove_parameter(string namespace, string name)", "" ], "xsl_xsltprocessor_set_parameter": [ - "bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value]);", + "bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value])", "" ], "xsl_xsltprocessor_set_profiling": [ - "bool xsl_xsltprocessor_set_profiling(string filename) */", - "PHP_FUNCTION(xsl_xsltprocessor_set_profiling) { zval *id; xsl_object *intern; char *filename = NULL; int filename_len; DOM_GET_THIS(id); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, \"s!\", &filename, &filename_len) == SUCCESS) { intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); if (intern->profiling) { efree(intern->profiling); } if (filename != NULL) { intern->profiling = estrndup(filename,filename_len); } else { intern->profiling = NULL; } RETURN_TRUE; } else { WRONG_PARAM_COUNT; } } /* }}} end xsl_xsltprocessor_set_profiling" + "bool xsl_xsltprocessor_set_profiling(string filename)", + "" ], "xsl_xsltprocessor_transform_to_doc": [ - "domdocument xsl_xsltprocessor_transform_to_doc(domnode doc);", - "URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# Since:" + "domdocument xsl_xsltprocessor_transform_to_doc(domnode doc)", + "" ], "xsl_xsltprocessor_transform_to_uri": [ - "int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri);", + "int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri)", "" ], "xsl_xsltprocessor_transform_to_xml": [ - "string xsl_xsltprocessor_transform_to_xml(domdocument doc);", + "string xsl_xsltprocessor_transform_to_xml(domdocument doc)", "" ], "zend_logo_guid": [ - "string zend_logo_guid(void)", + "string zend_logo_guid()", "Return the special ID used to request the Zend logo in phpinfo screens" ], "zend_version": [ - "string zend_version(void)", + "string zend_version()", "Get the version of the Zend Engine" ], "zip_close": [ @@ -11316,7 +11515,7 @@ var functionMap = { "Returns the next file in the archive" ], "zlib_get_coding_type": [ - "string zlib_get_coding_type(void)", + "string zlib_get_coding_type()", "Returns the coding type used for output compression" ] }; @@ -11367,7 +11566,9 @@ var variableMap = { "SERVER_PORT": 1, "SERVER_PROTOCOL": 1, "SERVER_SIGNATURE": 1, - "SERVER_SOFTWARE": 1 + "SERVER_SOFTWARE": 1, + "argv": 1, + "argc": 1 } }, "$_SESSION": { @@ -11375,6 +11576,12 @@ var variableMap = { }, "$GLOBALS": { type: "array" + }, + '$argv': { + type: "array" + }, + '$argc': { + type: "int" } }; @@ -11702,6 +11909,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -12039,6 +12247,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -12931,6 +13140,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -13057,6 +13267,7 @@ oop.inherits(Mode, HtmlMode); }; this.$id = "ace/mode/php"; + this.snippetFileId = "ace/snippets/php"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-prisma.js b/htdocs/includes/ace/src/mode-prisma.js new file mode 100644 index 00000000000..fc7048378e3 --- /dev/null +++ b/htdocs/includes/ace/src/mode-prisma.js @@ -0,0 +1,489 @@ +define("ace/mode/prisma_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var PrismaHighlightRules = function() { + + this.$rules = { + start: [{ + include: "#triple_comment" + }, { + include: "#double_comment" + }, { + include: "#model_block_definition" + }, { + include: "#config_block_definition" + }, { + include: "#enum_block_definition" + }, { + include: "#type_definition" + }], + "#model_block_definition": [{ + token: [ + "source.prisma.embedded.source", + "storage.type.model.prisma", + "source.prisma.embedded.source", + "entity.name.type.model.prisma", + "source.prisma.embedded.source", + "punctuation.definition.tag.prisma" + ], + regex: /^(\s*)(model|type)(\s+)([A-Za-z][\w]*)(\s+)({)/, + push: [{ + token: "punctuation.definition.tag.prisma", + regex: /\s*\}/, + next: "pop" + }, { + include: "#triple_comment" + }, { + include: "#double_comment" + }, { + include: "#field_definition" + }, { + defaultToken: "source.prisma.embedded.source" + }] + }], + "#enum_block_definition": [{ + token: [ + "source.prisma.embedded.source", + "storage.type.enum.prisma", + "source.prisma.embedded.source", + "entity.name.type.enum.prisma", + "source.prisma.embedded.source", + "punctuation.definition.tag.prisma" + ], + regex: /^(\s*)(enum)(\s+)([A-Za-z][\w]*)(\s+)({)/, + push: [{ + token: "punctuation.definition.tag.prisma", + regex: /\s*\}/, + next: "pop" + }, { + include: "#triple_comment" + }, { + include: "#double_comment" + }, { + include: "#enum_value_definition" + }, { + defaultToken: "source.prisma.embedded.source" + }] + }], + "#config_block_definition": [{ + token: [ + "source.prisma.embedded.source", + "storage.type.config.prisma", + "source.prisma.embedded.source", + "entity.name.type.config.prisma", + "source.prisma.embedded.source", + "punctuation.definition.tag.prisma" + ], + regex: /^(\s*)(generator|datasource)(\s+)([A-Za-z][\w]*)(\s+)({)/, + push: [{ + token: "source.prisma.embedded.source", + regex: /\s*\}/, + next: "pop" + }, { + include: "#triple_comment" + }, { + include: "#double_comment" + }, { + include: "#assignment" + }, { + defaultToken: "source.prisma.embedded.source" + }] + }], + "#assignment": [{ + token: [ + "text", + "variable.other.assignment.prisma", + "text", + "keyword.operator.terraform", + "text" + ], + regex: /^(\s*)(\w+)(\s*)(=)(\s*)/, + push: [{ + token: "text", + regex: /$/, + next: "pop" + }, { + include: "#value" + }, { + include: "#double_comment_inline" + }] + }], + "#field_definition": [{ + token: [ + "text", + "variable.other.assignment.prisma", + "invalid.illegal.colon.prisma", + "text", + "support.type.primitive.prisma", + "keyword.operator.list_type.prisma", + "keyword.operator.optional_type.prisma", + "invalid.illegal.required_type.prisma" + ], + regex: /^(\s*)(\w+)((?:\s*:)?)(\s+)(\w+)((?:\[\])?)((?:\?)?)((?:\!)?)/ + }, { + include: "#attribute_with_arguments" + }, { + include: "#attribute" + }], + "#type_definition": [{ + token: [ + "text", + "storage.type.type.prisma", + "text", + "entity.name.type.type.prisma", + "text", + "support.type.primitive.prisma" + ], + regex: /^(\s*)(type)(\s+)(\w+)(\s*=\s*)(\w+)/ + }, { + include: "#attribute_with_arguments" + }, { + include: "#attribute" + }], + "#enum_value_definition": [{ + token: [ + "text", + "variable.other.assignment.prisma", + "text" + ], + regex: /^(\s*)(\w+)(\s*$)/ + }, { + include: "#attribute_with_arguments" + }, { + include: "#attribute" + }], + "#attribute_with_arguments": [{ + token: [ + "entity.name.function.attribute.prisma", + "punctuation.definition.tag.prisma" + ], + regex: /(@@?[\w\.]+)(\()/, + push: [{ + token: "punctuation.definition.tag.prisma", + regex: /\)/, + next: "pop" + }, { + include: "#named_argument" + }, { + include: "#value" + }, { + defaultToken: "source.prisma.attribute.with_arguments" + }] + }], + "#attribute": [{ + token: "entity.name.function.attribute.prisma", + regex: /@@?[\w\.]+/ + }], + "#array": [{ + token: "source.prisma.array", + regex: /\[/, + push: [{ + token: "source.prisma.array", + regex: /\]/, + next: "pop" + }, { + include: "#value" + }, { + defaultToken: "source.prisma.array" + }] + }], + "#value": [{ + include: "#array" + }, { + include: "#functional" + }, { + include: "#literal" + }], + "#functional": [{ + token: [ + "support.function.functional.prisma", + "punctuation.definition.tag.prisma" + ], + regex: /(\w+)(\()/, + push: [{ + token: "punctuation.definition.tag.prisma", + regex: /\)/, + next: "pop" + }, { + include: "#value" + }, { + defaultToken: "source.prisma.functional" + }] + }], + "#literal": [{ + include: "#boolean" + }, { + include: "#number" + }, { + include: "#double_quoted_string" + }, { + include: "#identifier" + }], + "#identifier": [{ + token: "support.constant.constant.prisma", + regex: /\b(?:\w)+\b/ + }], + "#map_key": [{ + token: [ + "variable.parameter.key.prisma", + "text", + "punctuation.definition.separator.key-value.prisma", + "text" + ], + regex: /(\w+)(\s*)(:)(\s*)/ + }], + "#named_argument": [{ + include: "#map_key" + }, { + include: "#value" + }], + "#triple_comment": [{ + token: "comment.prisma", + regex: /\/\/\//, + push: [{ + token: "comment.prisma", + regex: /$/, + next: "pop" + }, { + defaultToken: "comment.prisma" + }] + }], + "#double_comment": [{ + token: "comment.prisma", + regex: /\/\//, + push: [{ + token: "comment.prisma", + regex: /$/, + next: "pop" + }, { + defaultToken: "comment.prisma" + }] + }], + "#double_comment_inline": [{ + token: "comment.prisma", + regex: /\/\/[^$]*/ + }], + "#boolean": [{ + token: "constant.language.boolean.prisma", + regex: /\b(?:true|false)\b/ + }], + "#number": [{ + token: "constant.numeric.prisma", + regex: /(?:0(?:x|X)[0-9a-fA-F]*|(?:\+|-)?\b(?:[0-9]+\.?[0-9]*|\.[0-9]+)(?:(?:e|E)(?:\+|-)?[0-9]+)?)(?:[LlFfUuDdg]|UL|ul)?\b/ + }], + "#double_quoted_string": [{ + token: "string.quoted.double.start.prisma", + regex: /"/, + push: [{ + token: "string.quoted.double.end.prisma", + regex: /"/, + next: "pop" + }, { + include: "#string_interpolation" + }, { + token: "string.quoted.double.prisma", + regex: /[\w\-\/\._\\%@:\?=]+/ + }, { + defaultToken: "unnamed" + }] + }], + "#string_interpolation": [{ + token: "keyword.control.interpolation.start.prisma", + regex: /\$\{/, + push: [{ + token: "keyword.control.interpolation.end.prisma", + regex: /\s*\}/, + next: "pop" + }, { + include: "#value" + }, { + defaultToken: "source.tag.embedded.source.prisma" + }] + }] + }; + + this.normalizeRules(); +}; + +PrismaHighlightRules.metaData = { + name: "Prisma", + scopeName: "source.prisma" +}; + + +oop.inherits(PrismaHighlightRules, TextHighlightRules); + +exports.PrismaHighlightRules = PrismaHighlightRules; +}); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/prisma",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/prisma_highlight_rules","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var PrismaHighlightRules = require("./prisma_highlight_rules").PrismaHighlightRules; +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = PrismaHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "//"; + this.$id = "ace/mode/prisma"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); (function() { + window.require(["ace/mode/prisma"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-protobuf.js b/htdocs/includes/ace/src/mode-protobuf.js index 0d1a19a5cc4..a4463de826b 100644 --- a/htdocs/includes/ace/src/mode-protobuf.js +++ b/htdocs/includes/ace/src/mode-protobuf.js @@ -65,7 +65,7 @@ var c_cppHighlightRules = function() { var storageType = ( "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + - "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|" + + "_Imaginary|int|int8_t|int16_t|int32_t|int64_t|long|short|signed|size_t|struct|typedef|uint8_t|uint16_t|uint32_t|uint64_t|union|unsigned|void|" + "class|wchar_t|template|char16_t|char32_t" ); @@ -489,6 +489,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/c_cpp"; + this.snippetFileId = "ace/snippets/c_cpp"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-puppet.js b/htdocs/includes/ace/src/mode-puppet.js index ea6b2356261..d647dea6f7e 100644 --- a/htdocs/includes/ace/src/mode-puppet.js +++ b/htdocs/includes/ace/src/mode-puppet.js @@ -44,7 +44,7 @@ var PuppetHighlightRules = function () { }, { token: "multiline.comment.begin.puppet", - regex: '^\\s*\\/\\*\\s*$', + regex: '^\\s*\\/\\*', push: "blockComment" }, { @@ -82,11 +82,7 @@ var PuppetHighlightRules = function () { } ], blockComment: [{ - regex: "^\\s*\\/\\*\\s*$", - token: "multiline.comment.begin.puppet", - push: "blockComment" - }, { - regex: "^\\s*\\*\\/\\s*$", + regex: "\\*\\/", token: "multiline.comment.end.puppet", next: "pop" }, { @@ -355,6 +351,9 @@ oop.inherits(Mode, TextMode); (function () { + this.lineCommentStart = "#"; + this.blockComment = {start: "/*", end: "*/"}; + this.$id = "ace/mode/puppet"; }).call(Mode.prototype); diff --git a/htdocs/includes/ace/src/mode-python.js b/htdocs/includes/ace/src/mode-python.js index e2045c8ac18..6c46043a46b 100644 --- a/htdocs/includes/ace/src/mode-python.js +++ b/htdocs/includes/ace/src/mode-python.js @@ -343,10 +343,10 @@ var PythonHighlightRules = function() { regex: "\\s+" }, { token: "string", - regex: "'(.)*'" + regex: "'[^']*'" }, { token: "string", - regex: '"(.)*"' + regex: '"[^"]*"' }, { token: "function.support", regex: "(!s|!r|!a)" @@ -494,6 +494,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/python"; + this.snippetFileId = "ace/snippets/python"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-qml.js b/htdocs/includes/ace/src/mode-qml.js new file mode 100644 index 00000000000..ba61ca66439 --- /dev/null +++ b/htdocs/includes/ace/src/mode-qml.js @@ -0,0 +1,381 @@ +define("ace/mode/qml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { + "use strict"; + + var oop = require("../lib/oop"); + var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + + var QmlHighlightRules = function() { + var keywordMapper = this.createKeywordMapper({ + "variable.language": + "Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors + "Namespace|QName|XML|XMLList|" + // E4X + "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" + + "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|" + + "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + // Errors + "SyntaxError|TypeError|URIError|" + + "decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions + "isNaN|parseFloat|parseInt|" + + "JSON|Math|" + // Other + "this|arguments|prototype|window|document" , // Pseudo + "keyword": + "const|yield|import|get|set|async|await|" + + "break|case|catch|continue|default|delete|do|else|finally|for|function|" + + "if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" + + "__parent__|__count__|escape|unescape|with|__proto__|" + + "class|enum|extends|super|export|implements|private|public|interface|package|protected|static|" + + "readonly|string|int|bool|date|color|url|real|double|var|variant|" + + "height|width|anchors|parent|" + + "Abstract3DSeries|AbstractActionInput|AbstractAnimation|AbstractAxis|AbstractAxis3D|AbstractAxisInput|" + + "AbstractBarSeries|AbstractButton|AbstractClipAnimator|AbstractClipBlendNode|AbstractDataProxy|AbstractGraph3D|" + + "AbstractInputHandler3D|AbstractPhysicalDevice|AbstractRayCaster|AbstractSeries|AbstractSkeleton|AbstractTextureImage|" + + "Accelerometer|AccelerometerReading|Accessible|Action|ActionGroup|ActionInput|" + + "AdditiveClipBlend|Address|Affector|Age|AlphaCoverage|AlphaTest|" + + "Altimeter|AltimeterReading|AmbientLightReading|AmbientLightSensor|AmbientTemperatureReading|AmbientTemperatureSensor|" + + "AnalogAxisInput|AnchorAnimation|AnchorChanges|AngleDirection|AnimatedImage|AnimatedSprite|" + + "Animation|AnimationController|AnimationGroup|Animator|ApplicationWindow|ApplicationWindowStyle|" + + "AreaSeries|Armature|AttenuationModelInverse|AttenuationModelLinear|Attractor|Attribute|" + + "Audio|AudioCategory|AudioEngine|AudioListener|AudioSample|AuthenticationDialogRequest|" + + "Axis|AxisAccumulator|AxisSetting|BackspaceKey|Bar3DSeries|BarCategoryAxis|" + + "BarDataProxy|BarSeries|BarSet|Bars3D|BaseKey|Behavior|" + + "Binding|Blend|BlendEquation|BlendEquationArguments|BlendedClipAnimator|BlitFramebuffer|" + + "BluetoothDiscoveryModel|BluetoothService|BluetoothSocket|BorderImage|BorderImageMesh|BoxPlotSeries|" + + "BoxSet|BrightnessContrast|Buffer|BusyIndicator|BusyIndicatorStyle|Button|" + + "ButtonAxisInput|ButtonGroup|ButtonStyle|Calendar|CalendarStyle|Camera|" + + "Camera3D|CameraCapabilities|CameraCapture|CameraExposure|CameraFlash|CameraFocus|" + + "CameraImageProcessing|CameraLens|CameraRecorder|CameraSelector|CandlestickSeries|CandlestickSet|" + + "Canvas|Canvas3D|Canvas3DAbstractObject|Canvas3DActiveInfo|Canvas3DBuffer|Canvas3DContextAttributes|" + + "Canvas3DFrameBuffer|Canvas3DProgram|Canvas3DRenderBuffer|Canvas3DShader|Canvas3DShaderPrecisionFormat|Canvas3DTexture|" + + "Canvas3DTextureProvider|Canvas3DUniformLocation|CanvasGradient|CanvasImageData|CanvasPixelArray|Category|" + + "CategoryAxis|CategoryAxis3D|CategoryModel|CategoryRange|ChangeLanguageKey|ChartView|" + + "CheckBox|CheckBoxStyle|CheckDelegate|CircularGauge|CircularGaugeStyle|ClearBuffers|" + + "ClipAnimator|ClipPlane|CloseEvent|ColorAnimation|ColorDialog|ColorDialogRequest|" + + "ColorGradient|ColorGradientStop|ColorMask|ColorOverlay|Colorize|Column|" + + "ColumnLayout|ComboBox|ComboBoxStyle|Compass|CompassReading|Component|Component3D|" + + "ComputeCommand|ConeGeometry|ConeMesh|ConicalGradient|Connections|ContactDetail|" + + "ContactDetails|Container|Context2D|Context3D|ContextMenuRequest|Control|" + + "CoordinateAnimation|CuboidGeometry|CuboidMesh|CullFace|CumulativeDirection|" + + "Custom3DItem|Custom3DLabel|Custom3DVolume|CustomParticle|CylinderGeometry|CylinderMesh|" + + "Date|DateTimeAxis|DelayButton|DelayButtonStyle|DelegateChoice|DelegateChooser|DelegateModel|" + + "DelegateModelGroup|DepthTest|Desaturate|Dial|DialStyle|Dialog|DialogButtonBox|DiffuseMapMaterial|" + + "DiffuseSpecularMapMaterial|DiffuseSpecularMaterial|Direction|DirectionalBlur|DirectionalLight|DispatchCompute|" + + "Displace|DistanceReading|DistanceSensor|Dithering|DoubleValidator|Drag|DragEvent|DragHandler|Drawer|DropArea|" + + "DropShadow|DwmFeatures|DynamicParameter|EditorialModel|Effect|EllipseShape|Emitter|EnterKey|EnterKeyAction|" + + "Entity|EntityLoader|EnvironmentLight|EventConnection|EventPoint|EventTouchPoint|ExclusiveGroup|ExtendedAttributes|" + + "ExtrudedTextGeometry|ExtrudedTextMesh|FastBlur|FileDialog|FileDialogRequest|FillerKey|FilterKey|FinalState|" + + "FirstPersonCameraController|Flickable|Flipable|Flow|FocusScope|FolderListModel|FontDialog|FontLoader|" + + "FontMetrics|FormValidationMessageRequest|ForwardRenderer|Frame|FrameAction|FrameGraphNode|Friction|" + + "FrontFace|FrustumCulling|FullScreenRequest|GLStateDumpExt|GammaAdjust|Gauge|GaugeStyle|GaussianBlur|" + + "GeocodeModel|Geometry|GeometryRenderer|GestureEvent|Glow|GoochMaterial|Gradient|GradientStop|GraphicsApiFilter|" + + "GraphicsInfo|Gravity|Grid|GridLayout|GridMesh|GridView|GroupBox|GroupGoal|Gyroscope|GyroscopeReading|HBarModelMapper|" + + "HBoxPlotModelMapper|HCandlestickModelMapper|HPieModelMapper|HXYModelMapper|HandlerPoint|HandwritingInputPanel|" + + "HandwritingModeKey|HeightMapSurfaceDataProxy|HideKeyboardKey|HistoryState|HolsterReading|HolsterSensor|HorizontalBarSeries|" + + "|HorizontalPercentBarSeries|HorizontalStackedBarSeries|HoverHandler|HueSaturation|HumidityReading|HumiditySensor|" + + "IRProximityReading|IRProximitySensor|Icon|Image|ImageModel|ImageParticle|InnerShadow|InputChord|InputContext|InputEngine|" + + "InputHandler3D|InputMethod|InputModeKey|InputPanel|InputSequence|InputSettings|Instantiator|IntValidator|InvokedServices|" + + "Item|ItemDelegate|ItemGrabResult|ItemModelBarDataProxy|ItemModelScatterDataProxy|ItemModelSurfaceDataProxy|ItemParticle|" + + "ItemSelectionModel|IviApplication|IviSurface|JavaScriptDialogRequest|Joint|JumpList|JumpListCategory|JumpListDestination|" + + "JumpListLink|JumpListSeparator|Key|KeyEvent|KeyIcon|KeyNavigation|KeyPanel|KeyboardColumn|KeyboardDevice|KeyboardHandler|" + + "KeyboardLayout|KeyboardLayoutLoader|KeyboardRow|KeyboardStyle|KeyframeAnimation|Keys|Label|Layer|LayerFilter|Layout|" + + "LayoutMirroring|Legend|LerpBlend|LevelAdjust|LevelOfDetail|LevelOfDetailBoundingSphere|LevelOfDetailLoader|" + + "LevelOfDetailSwitch|LidReading|LidSensor|Light|Light3D|LightReading|LightSensor|LineSeries|LineShape|LineWidth|" + + "LinearGradient|ListElement|ListModel|ListView|Loader|Locale|Location|LogValueAxis|LogValueAxis3DFormatter|LoggingCategory|" + + "LogicalDevice|Magnetometer|MagnetometerReading|Map|MapCircle|MapCircleObject|MapCopyrightNotice|MapGestureArea|MapIconObject|" + + "MapItemGroup|MapItemView|MapObjectView|MapParameter|MapPinchEvent|MapPolygon|MapPolygonObject|MapPolyline|MapPolylineObject|" + + "MapQuickItem|MapRectangle|MapRoute|MapRouteObject|MapType|Margins|MaskShape|MaskedBlur|Material|Matrix4x4|MediaPlayer|" + + "MemoryBarrier|Menu|MenuBar|MenuBarItem|MenuBarStyle|MenuItem|MenuSeparator|MenuStyle|Mesh|MessageDialog|ModeKey|MorphTarget|" + + "MorphingAnimation|MouseArea|MouseDevice|MouseEvent|MouseHandler|MultiPointHandler|MultiPointTouchArea|MultiSampleAntiAliasing|" + + "Navigator|NdefFilter|NdefMimeRecord|NdefRecord|NdefTextRecord|NdefUriRecord|NearField|NoDepthMask|NoDraw|Node|NodeInstantiator|" + + "NormalDiffuseMapAlphaMaterial|NormalDiffuseMapMaterial|NormalDiffuseSpecularMapMaterial|Number|NumberAnimation|NumberKey|Object3D|" + + "ObjectModel|ObjectPicker|OpacityAnimator|OpacityMask|OpenGLInfo|OrbitCameraController|OrientationReading|OrientationSensor|Overlay|" + + "Package|Page|PageIndicator|Pane|ParallelAnimation|Parameter|ParentAnimation|ParentChange|Particle|ParticleGroup|ParticlePainter|" + + "ParticleSystem|Path|PathAngleArc|PathAnimation|PathArc|PathAttribute|PathCubic|PathCurve|PathElement|PathInterpolator|PathLine|" + + "PathMove|PathPercent|PathQuad|PathSvg|PathView|PauseAnimation|PerVertexColorMaterial|PercentBarSeries|PhongAlphaMaterial|" + + "PhongMaterial|PickEvent|PickLineEvent|PickPointEvent|PickTriangleEvent|PickingSettings|Picture|PieMenu|PieMenuStyle|PieSeries|" + + "PieSlice|PinchArea|PinchEvent|PinchHandler|Place|PlaceAttribute|PlaceSearchModel|PlaceSearchSuggestionModel|PlaneGeometry|" + + "PlaneMesh|PlayVariation|Playlist|PlaylistItem|Plugin|PluginParameter|PointDirection|PointHandler|PointLight|PointSize|" + + "PointerDevice|PointerDeviceHandler|PointerEvent|PointerHandler|PolarChartView|PolygonOffset|Popup|Position|PositionSource|" + + "Positioner|PressureReading|PressureSensor|Product|ProgressBar|ProgressBarStyle|PropertyAction|PropertyAnimation|PropertyChanges|" + + "ProximityFilter|ProximityReading|ProximitySensor|QAbstractState|QAbstractTransition|QSignalTransition|" + + "QVirtualKeyboardSelectionListModel|Qt|QtMultimedia|QtObject|QtPositioning|QuaternionAnimation|QuotaRequest|RadialBlur|" + + "RadialGradient|Radio|RadioButton|RadioButtonStyle|RadioData|RadioDelegate|RangeSlider|Ratings|RayCaster|Rectangle|" + + "RectangleShape|RectangularGlow|RecursiveBlur|RegExpValidator|RegisterProtocolHandlerRequest|RenderCapture|" + + "RenderCaptureReply|RenderPass|RenderPassFilter|RenderSettings|RenderState|RenderStateSet|RenderSurfaceSelector|" + + "RenderTarget|RenderTargetOutput|RenderTargetSelector|Repeater|ReviewModel|Rotation|RotationAnimation|RotationAnimator|" + + "RotationReading|RotationSensor|RoundButton|Route|RouteLeg|RouteManeuver|RouteModel|RouteQuery|RouteSegment|Row|" + + "RowLayout|Scale|ScaleAnimator|Scatter3D|Scatter3DSeries|ScatterDataProxy|ScatterSeries|Scene2D|Scene3D|SceneLoader|" + + "ScissorTest|Screen|ScreenRayCaster|ScriptAction|ScrollBar|ScrollIndicator|ScrollView|ScrollViewStyle|ScxmlStateMachine|" + + "SeamlessCubemap|SelectionListItem|Sensor|SensorGesture|SensorGlobal|SensorReading|SequentialAnimation|Settings|" + + "SettingsStore|ShaderEffect|ShaderEffectSource|ShaderProgram|ShaderProgramBuilder|Shape|ShellSurface|ShellSurfaceItem|" + + "ShiftHandler|ShiftKey|Shortcut|SignalSpy|SignalTransition|SinglePointHandler|Skeleton|SkeletonLoader|Slider|SliderStyle|" + + "SmoothedAnimation|SortPolicy|Sound|SoundEffect|SoundInstance|SpaceKey|SphereGeometry|SphereMesh|SpinBox|SpinBoxStyle|" + + "SplineSeries|SplitView|SpotLight|SpringAnimation|Sprite|SpriteGoal|SpriteSequence|Stack|StackLayout|StackView|" + + "StackViewDelegate|StackedBarSeries|State|StateChangeScript|StateGroup|StateMachine|StateMachineLoader|StatusBar|" + + "StatusBarStyle|StatusIndicator|StatusIndicatorStyle|StencilMask|StencilOperation|StencilOperationArguments|StencilTest|" + + "StencilTestArguments|Store|String|Supplier|Surface3D|Surface3DSeries|SurfaceDataProxy|SwipeDelegate|SwipeView|Switch|" + + "SwitchDelegate|SwitchStyle|SymbolModeKey|SystemPalette|Tab|TabBar|TabButton|TabView|TabViewStyle|TableView|TableViewColumn|" + + "TableViewStyle|TapHandler|TapReading|TapSensor|TargetDirection|TaskbarButton|Technique|TechniqueFilter|TestCase|Text|TextArea|" + + "TextAreaStyle|TextEdit|TextField|TextFieldStyle|TextInput|TextMetrics|TextureImage|TextureImageFactory|Theme3D|ThemeColor|" + + "ThresholdMask|ThumbnailToolBar|ThumbnailToolButton|TiltReading|TiltSensor|TimeoutTransition|Timer|ToggleButton|" + + "ToggleButtonStyle|ToolBar|ToolBarStyle|ToolButton|ToolSeparator|ToolTip|Torch|TorusGeometry|TorusMesh|TouchEventSequence|" + + "TouchInputHandler3D|TouchPoint|Trace|TraceCanvas|TraceInputArea|TraceInputKey|TraceInputKeyPanel|TrailEmitter|Transaction|" + + "Transform|Transition|Translate|TreeView|TreeViewStyle|Tumbler|TumblerColumn|TumblerStyle|Turbulence|UniformAnimator|User|" + + "VBarModelMapper|VBoxPlotModelMapper|VCandlestickModelMapper|VPieModelMapper|VXYModelMapper|ValueAxis|ValueAxis3D|" + + "ValueAxis3DFormatter|Vector3dAnimation|VertexBlendAnimation|Video|VideoOutput|ViewTransition|Viewport|" + + "VirtualKeyboardSettings|Wander|WavefrontMesh|WaylandClient|WaylandCompositor|WaylandHardwareLayer|" + + "WaylandOutput|WaylandQuickItem|WaylandSeat|WaylandSurface|WaylandView|Waypoint|" + + "WebChannel|WebEngine|WebEngineAction|WebEngineCertificateError|WebEngineDownloadItem|WebEngineHistory|" + + "WebEngineHistoryListModel|WebEngineLoadRequest|WebEngineNavigationRequest|WebEngineNewViewRequest|WebEngineProfile|WebEngineScript|" + + "WebEngineSettings|WebEngineView|WebSocket|WebSocketServer|WebView|WebViewLoadRequest|" + + "WheelEvent|Window|WlShell|WlShellSurface|WorkerScript|XAnimator|" + + "XYPoint|XYSeries|XdgDecorationManagerV1|XdgPopup|XdgPopupV5|XdgPopupV6|" + + "XdgShell|XdgShellV5|XdgShellV6|XdgSurface|XdgSurfaceV5|XdgSurfaceV6|" + + "XdgToplevel|XdgToplevelV6|XmlListModel|XmlRole|YAnimator|ZoomBlur", + "storage.type": + "const|let|var|function|" + // js + "property|", // qml + "constant.language": + "null|Infinity|NaN|undefined", + "support.function": + "print|console\\.log", + "constant.language.boolean": "true|false" + }, "identifier"); + this.$rules = { + "start" : [ + { + token : "string", // single line + regex : '"', + next : "string" + }, { + token : "constant.numeric", // hex + regex : "0[xX][0-9a-fA-F]+\\b" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : "constant.language.boolean", + regex : "(?:true|false)\\b" + }, { + token : "text", + regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" + }, { + token : "comment", + regex : "\\/\\/.*$" + }, { + token : "comment.start", + regex : "\\/\\*", + next : "comment" + }, { + token : "paren.lparen", + regex : "[[({]" + }, { + token : "paren.rparen", + regex : "[\\])}]" + }, { + token : "text", + regex : "\\s+" + }, { + token : keywordMapper, + regex : "\\b\\w+\\b" + } + ], + "string" : [ + { + token : "constant.language.escape", + regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/ + }, { + token : "string", + regex : '"|$', + next : "start" + }, { + defaultToken : "string" + } + ], + "comment" : [ + { + token : "comment.end", + regex : "\\*\\/", + next : "start" + }, { + defaultToken: "comment" + } + ] + }; + + }; + + oop.inherits(QmlHighlightRules, TextHighlightRules); + + exports.QmlHighlightRules = QmlHighlightRules; + }); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/qml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/qml_highlight_rules","ace/mode/folding/cstyle"], function(require, exports, module) { + "use strict"; + + var oop = require("../lib/oop"); + var TextMode = require("./text").Mode; + var QmlHighlightRules = require("./qml_highlight_rules").QmlHighlightRules; + var FoldMode = require("./folding/cstyle").FoldMode; + + var Mode = function() { + this.HighlightRules = QmlHighlightRules; + this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; + }; + oop.inherits(Mode, TextMode); + + (function() { + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + this.$quotes = { '"': '"', "'": "'" }; + this.$id = "ace/mode/qml"; + }).call(Mode.prototype); + + exports.Mode = Mode; + }); (function() { + window.require(["ace/mode/qml"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-r.js b/htdocs/includes/ace/src/mode-r.js index 5a6ca976129..2fd49378749 100644 --- a/htdocs/includes/ace/src/mode-r.js +++ b/htdocs/includes/ace/src/mode-r.js @@ -299,6 +299,7 @@ define("ace/mode/r",["require","exports","module","ace/unicode","ace/range","ace this.nonTokenRe = new RegExp("^(?:[^" + unicode.wordChars + "._]|\s])+", "g"); this.$id = "ace/mode/r"; + this.snippetFileId = "ace/snippets/r"; }).call(Mode.prototype); exports.Mode = Mode; }); (function() { diff --git a/htdocs/includes/ace/src/mode-perl6.js b/htdocs/includes/ace/src/mode-raku.js similarity index 96% rename from htdocs/includes/ace/src/mode-perl6.js rename to htdocs/includes/ace/src/mode-raku.js index 4d25513c3ee..d2a829c08cc 100644 --- a/htdocs/includes/ace/src/mode-perl6.js +++ b/htdocs/includes/ace/src/mode-raku.js @@ -1,10 +1,10 @@ -define("ace/mode/perl6_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +define("ace/mode/raku_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var Perl6HighlightRules = function() { +var RakuHighlightRules = function() { var keywords = ( "my|our|class|role|grammar|is|does|sub|method|submethod|try|" + @@ -34,7 +34,7 @@ var Perl6HighlightRules = function() { "Pod::Block|Pod::Block::Code|Pod::Block::Comment|Pod::Block::Declarator|"+ "Pod::Block::Named|Pod::Block::Para|Pod::Block::Table|Pod::Heading|Pod::Item|"+ "Positional|PositionalBindFailover|Proc|Proc::Async|Promise|Proxy|PseudoStash|"+ - "QuantHash|Range|Rat|Rational|RatStr|Real|Regex|Routine|Scalar|Scheduler|"+ + "Raku|QuantHash|Range|Rat|Rational|RatStr|Real|Regex|Routine|Scalar|Scheduler|"+ "Semaphore|Seq|Set|SetHash|Setty|Signature|Slip|Stash|Str|StrDistance|Stringy|"+ "Sub|Submethod|Supplier|Supplier::Preserving|Supply|Systemic|Tap|Telemetry|"+ "Telemetry::Instrument::Thread|Telemetry::Instrument::Usage|Telemetry::Period|"+ @@ -120,7 +120,7 @@ var Perl6HighlightRules = function() { "positional|posix|postfix|postmatch|precomp-ext|precomp-target|pred|prefix|prematch|prepend|"+ "print|printf|print-nl|print-to|private|private_method_table|proc|produce|Promise|prompt|"+ "protect|pull-one|push|push-all|push-at-least|push-exactly|push-until-lazy|put|"+ - "qualifier-type|quit|r|race|radix|rand|range|raw|re|read|readchars|readonly|"+ + "qualifier-type|quit|r|race|radix|raku|rand|range|raw|re|read|readchars|readonly|"+ "ready|Real|reallocate|reals|reason|rebless|receive|recv|redispatcher|redo|reduce|"+ "rel2abs|relative|release|rename|repeated|replacement|report|reserved|resolve|"+ "restore|result|resume|rethrow|reverse|right|rindex|rmdir|roles_to_compose|"+ @@ -339,9 +339,9 @@ var Perl6HighlightRules = function() { }; }; -oop.inherits(Perl6HighlightRules, TextHighlightRules); +oop.inherits(RakuHighlightRules, TextHighlightRules); -exports.Perl6HighlightRules = Perl6HighlightRules; +exports.RakuHighlightRules = RakuHighlightRules; }); define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { @@ -524,17 +524,17 @@ oop.inherits(FoldMode, BaseFoldMode); }); -define("ace/mode/perl6",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/perl6_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/cstyle"], function(require, exports, module) { +define("ace/mode/raku",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/raku_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/cstyle"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextMode = require("./text").Mode; -var Perl6HighlightRules = require("./perl6_highlight_rules").Perl6HighlightRules; +var RakuHighlightRules = require("./raku_highlight_rules").RakuHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { - this.HighlightRules = Perl6HighlightRules; + this.HighlightRules = RakuHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.foldingRules = new CStyleFoldMode({start: "^=(begin)\\b", end: "^=(end)\\b"}); @@ -579,12 +579,12 @@ oop.inherits(Mode, TextMode); this.$outdent.autoOutdent(doc, row); }; - this.$id = "ace/mode/perl6"; + this.$id = "ace/mode/raku"; }).call(Mode.prototype); exports.Mode = Mode; }); (function() { - window.require(["ace/mode/perl6"], function(m) { + window.require(["ace/mode/raku"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; } diff --git a/htdocs/includes/ace/src/mode-razor.js b/htdocs/includes/ace/src/mode-razor.js index 5733efd213e..49b7588eee5 100644 --- a/htdocs/includes/ace/src/mode-razor.js +++ b/htdocs/includes/ace/src/mode-razor.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2858,6 +2861,7 @@ oop.inherits(Mode, HtmlMode); }; this.$id = "ace/mode/razor"; + this.snippetFileId = "ace/snippets/razor"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-rhtml.js b/htdocs/includes/ace/src/mode-rhtml.js index f389e63d28e..de4788dfd88 100644 --- a/htdocs/includes/ace/src/mode-rhtml.js +++ b/htdocs/includes/ace/src/mode-rhtml.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-rst.js b/htdocs/includes/ace/src/mode-rst.js index 8a093c05701..23e17db0989 100644 --- a/htdocs/includes/ace/src/mode-rst.js +++ b/htdocs/includes/ace/src/mode-rst.js @@ -242,6 +242,7 @@ oop.inherits(Mode, TextMode); this.type = "text"; this.$id = "ace/mode/rst"; + this.snippetFileId = "ace/snippets/rst"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-ruby.js b/htdocs/includes/ace/src/mode-ruby.js index 6e8afa36877..12398cc9193 100644 --- a/htdocs/includes/ace/src/mode-ruby.js +++ b/htdocs/includes/ace/src/mode-ruby.js @@ -8,17 +8,17 @@ var constantOtherSymbol = exports.constantOtherSymbol = { regex : "[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?" }; -var qString = exports.qString = { +exports.qString = { token : "string", // single line regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" }; -var qqString = exports.qqString = { +exports.qqString = { token : "string", // single line regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' }; -var tString = exports.tString = { +exports.tString = { token : "string", // backtick string regex : "[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]" }; @@ -28,9 +28,34 @@ var constantNumericHex = exports.constantNumericHex = { regex : "0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b" }; +var constantNumericBinary = exports.constantNumericBinary = { + token: "constant.numeric", + regex: /\b(0[bB][01](?:[01]|_(?=[01]))*)\b/ +}; + +var constantNumericDecimal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[dD](?:[1-9](?:[\d]|_(?=[\d]))*|0))\b/ +}; + +var constantNumericOctal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[oO]?(?:[1-7](?:[0-7]|_(?=[0-7]))*|0))\b/ +}; + +var constantNumericRational = exports.constantNumericRational = { + token: "constant.numeric", //rational + complex + regex: /\b([\d]+(?:[./][\d]+)?ri?)\b/ +}; + +var constantNumericComplex = exports.constantNumericComplex = { + token: "constant.numeric", //simple complex numbers + regex: /\b([\d]i)\b/ +}; + var constantNumericFloat = exports.constantNumericFloat = { - token : "constant.numeric", // float - regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b" + token : "constant.numeric", // float + complex + regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?i?\\b" }; var instanceVariable = exports.instanceVariable = { @@ -70,18 +95,19 @@ var RubyHighlightRules = function() { "filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|" + "translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|" + "cache|expire_fragment|expire_cache_for|observe|cache_sweeper|" + - "has_many|has_one|belongs_to|has_and_belongs_to_many" + "has_many|has_one|belongs_to|has_and_belongs_to_many|p|warn|refine|using|module_function|extend|alias_method|" + + "private_class_method|remove_method|undef_method" ); var keywords = ( "alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|" + "__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|" + - "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield" + "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|__ENCODING__|prepend" ); var buildinConstants = ( "true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|" + - "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING" + "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING|RUBY_PATCHLEVEL|RUBY_REVISION|RUBY_COPYRIGHT|RUBY_ENGINE|RUBY_ENGINE_VERSION|RUBY_DESCRIPTION" ); var builtinVariables = ( @@ -97,126 +123,191 @@ var RubyHighlightRules = function() { "invalid.deprecated": "debugger" // TODO is this a remnant from js mode? }, "identifier"); + var escapedChars = "\\\\(?:n(?:[1-7][0-7]{0,2}|0)|[nsrtvfbae'\"\\\\]|c(?:\\\\M-)?.|M-(?:\\\\C-|\\\\c)?.|C-(?:\\\\M-)?.|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}(?:\\s[\\da-fA-F]{1,6})*})"; + + var closeParen = { + "(": ")", + "[": "]", + "{": "}", + "<": ">", + "^": "^", + "|": "|", + "%": "%" + }; + this.$rules = { - "start" : [ + "start": [ { - token : "comment", - regex : "#.*$" + token: "comment", + regex: "#.*$" }, { - token : "comment", // multi line comment - regex : "^=begin(?:$|\\s.*$)", - next : "comment" + token: "comment.multiline", // multi line comment + regex: "^=begin(?=$|\\s.*$)", + next: "comment" }, { - token : "string.regexp", - regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" + token: "string.regexp", + regex: /[/](?=.*\/)/, + next: "regex" }, [{ - regex: "[{}]", onMatch: function(val, state, stack) { - this.next = val == "{" ? this.nextState : ""; - if (val == "{" && stack.length) { - stack.unshift("start", state); - return "paren.lparen"; - } - if (val == "}" && stack.length) { - stack.shift(); - this.next = stack.shift(); - if (this.next.indexOf("string") != -1) - return "paren.end"; - } - return val == "{" ? "paren.lparen" : "paren.rparen"; - }, - nextState: "start" - }, { - token : "string.start", - regex : /"/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(")/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /"/, - next : "pop" + token: "string.end", + regex: /"/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /`/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: "string.start", + regex: /`/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /`/, - next : "pop" + token: "string.end", + regex: /`/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /'/, - push : [{ - token : "constant.language.escape", - regex : /\\['\\]/ - }, { - token : "string.end", - regex : /'/, - next : "pop" + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(')/, + push: [{ + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "string.end", + regex: /'/, + next: "pop" }, { defaultToken: "string" }] + }, { + token: "string.start",//doesn't see any differences between strings and array of strings in highlighting + regex: /%[qwx]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithoutInterpolation"; + return this.token; + } + }, { + token: "string.start", //doesn't see any differences between strings and array of strings in highlighting + regex: /%[QWX]?([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[si]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithoutInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[SI]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithInterpolation"; + return this.token; + } + }, { + token: "string.regexp", + regex: /%[r]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "rState"; + return this.token; + } }], { - token : "text", // namespaces aren't symbols - regex : "::" + token: "punctuation", // namespaces aren't symbols + regex: "::" + }, + instanceVariable, + { + token: "variable.global", // global variable + regex: "[$][a-zA-Z_\\d]+" }, { - token : "variable.instance", // instance variable - regex : "@{1,2}[a-zA-Z_\\d]+" + token: "support.class", // class name + regex: "[A-Z][a-zA-Z_\\d]*" }, { - token : "support.class", // class name - regex : "[A-Z][a-zA-Z_\\d]+" + token: ["punctuation.operator", "support.function"], + regex: /(\.)([a-zA-Z_\d]+)(?=\()/ + }, { + token: ["punctuation.operator", "identifier"], + regex: /(\.)([a-zA-Z_][a-zA-Z_\d]*)/ + }, { + token: "string.character", + regex: "\\B\\?(?:" + escapedChars + "|\\S)" + }, { + token: "punctuation.operator", + regex: /\?(?=.+:)/ }, + constantNumericRational, + constantNumericComplex, constantOtherSymbol, constantNumericHex, constantNumericFloat, - + constantNumericBinary, + constantNumericDecimal, + constantNumericOctal, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" + token: "constant.language.boolean", + regex: "(?:true|false)\\b" }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + token: keywordMapper, + regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { - token : "punctuation.separator.key-value", - regex : "=>" + token: "punctuation.separator.key-value", + regex: "=>" }, { stateName: "heredoc", - onMatch : function(value, currentState, stack) { - var next = value[2] == '-' ? "indentedHeredoc" : "heredoc"; + onMatch: function (value, currentState, stack) { + var next = (value[2] == '-' || value[2] == '~') ? "indentedHeredoc" : "heredoc"; var tokens = value.split(this.splitRegex); stack.push(next, tokens[3]); return [ - {type:"constant", value: tokens[1]}, - {type:"string", value: tokens[2]}, - {type:"support.class", value: tokens[3]}, - {type:"string", value: tokens[4]} + {type: "constant", value: tokens[1]}, + {type: "string", value: tokens[2]}, + {type: "support.class", value: tokens[3]}, + {type: "string", value: tokens[4]} ]; }, - regex : "(<<-?)(['\"`]?)([\\w]+)(['\"`]?)", + regex: "(<<[-~]?)(['\"`]?)([\\w]+)(['\"`]?)", rules: { heredoc: [{ - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -233,7 +324,7 @@ var RubyHighlightRules = function() { token: "string", regex: "^ +" }, { - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -248,38 +339,261 @@ var RubyHighlightRules = function() { }] } }, { - regex : "$", - token : "empty", - next : function(currentState, stack) { + regex: "$", + token: "empty", + next: function(currentState, stack) { if (stack[0] === "heredoc" || stack[0] === "indentedHeredoc") return stack[0]; return currentState; } + }, { + token: "keyword.operator", + regex: "!|\\$|%|&|\\*|/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\||\\b(?:in|instanceof|new|delete|typeof|void)" }, { - token : "string.character", - regex : "\\B\\?." + token: "paren.lparen", + regex: "[[({]" }, { - token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + token: "paren.rparen", + regex: "[\\])}]", + onMatch: function(value, currentState, stack) { + this.next = ''; + if (value == "}" && stack.length > 1 && stack[1] != "start") { + stack.shift(); + this.next = stack.shift(); + } + return this.token; + } }, { - token : "paren.lparen", - regex : "[[({]" + token: "text", + regex: "\\s+" }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" + token: "punctuation.operator", + regex: /[?:,;.]/ } ], - "comment" : [ + "comment": [ { - token : "comment", // closing comment - regex : "^=end(?:$|\\s.*$)", - next : "start" + token: "comment.multiline", // closing comment + regex: "^=end(?=$|\\s.*$)", + next: "start" }, { - token : "comment", // comment spanning whole line - regex : ".+" + token: "comment", // comment spanning whole line + regex: ".+" + } + ], + "qStateWithInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "qStateWithoutInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "sStateWithoutInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "sStateWithInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "rState": [{ + token: "string.regexp",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.language.escape"; + } + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.regexp", + regex: /\// + }, { + token: "string.regexp", + regex: /[)\]>}^|%][imxouesn]*/, onMatch: function (val, state, stack) { + if (stack.length && val[0] === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.language.escape"; + } + }, + {include: "regex"}, + { + defaultToken: "string.regexp" + }], + "regex": [ + {// character classes + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "constant.language.escape", + regex: /\\[AGbBzZ]/ + }, { + token: "constant.language.escape", + regex: /\\g<[a-zA-Z0-9]*>/ + }, { + token: ["constant.language.escape", "regexp.keyword", "constant.language.escape"], + regex: /(\\p{\^?)(Alnum|Alpha|Blank|Cntrl|Digit|Graph|Lower|Print|Punct|Space|Upper|XDigit|Word|ASCII|Any|Assigned|Arabic|Armenian|Balinese|Bengali|Bopomofo|Braille|Buginese|Buhid|Canadian_Aboriginal|Carian|Cham|Cherokee|Common|Coptic|Cuneiform|Cypriot|Cyrillic|Deseret|Devanagari|Ethiopic|Georgian|Glagolitic|Gothic|Greek|Gujarati|Gurmukhi|Han|Hangul|Hanunoo|Hebrew|Hiragana|Inherited|Kannada|Katakana|Kayah_Li|Kharoshthi|Khmer|Lao|Latin|Lepcha|Limbu|Linear_B|Lycian|Lydian|Malayalam|Mongolian|Myanmar|New_Tai_Lue|Nko|Ogham|Ol_Chiki|Old_Italic|Old_Persian|Oriya|Osmanya|Phags_Pa|Phoenician|Rejang|Runic|Saurashtra|Shavian|Sinhala|Sundanese|Syloti_Nagri|Syriac|Tagalog|Tagbanwa|Tai_Le|Tamil|Telugu|Thaana|Thai|Tibetan|Tifinagh|Ugaritic|Vai|Yi|Ll|Lm|Lt|Lu|Lo|Mn|Mc|Me|Nd|Nl|Pc|Pd|Ps|Pe|Pi|Pf|Po|No|Sm|Sc|Sk|So|Zs|Zl|Zp|Cc|Cf|Cn|Co|Cs|N|L|M|P|S|Z|C)(})/ + }, { + token: ["constant.language.escape", "invalid", "constant.language.escape"], + regex: /(\\p{\^?)([^/]*)(})/ + }, {// escapes + token: "regexp.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, {// flag + token: "string.regexp", + regex: /[/][imxouesn]*/, + next: "start" + }, {// invalid operators + token: "invalid", + regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ + }, {// operators + token: "constant.language.escape", + regex: /\(\?(?:[:=!>]|<'?[a-zA-Z]*'?>|<[=!])|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ + }, { + token: "constant.language.delimiter", + regex: /\|/ + }, { + token: "regexp.keyword", + regex: /\[\[:(?:alnum|alpha|blank|cntrl|digit|graph|lower|print|punct|space|upper|xdigit|word|ascii):\]\]/ + }, { + token: "constant.language.escape", + regex: /\[\^?/, + push: "regex_character_class" + }, { + defaultToken: "string.regexp" + } + ], + "regex_character_class": [ + { + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "regexp.charclass.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "constant.language.escape", + regex: /&?&?\[\^?/, + push: "regex_character_class" + }, { + token: "constant.language.escape", + regex: "]", + next: "pop" + }, { + token: "constant.language.escape", + regex: "-" + }, { + defaultToken: "string.regexp.characterclass" } ] }; @@ -332,94 +646,271 @@ var MatchingBraceOutdent = function() {}; exports.MatchingBraceOutdent = MatchingBraceOutdent; }); -define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"], function(require, exports, module) { +define("ace/mode/folding/ruby",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"], function (require, exports, module) { "use strict"; var oop = require("../../lib/oop"); var BaseFoldMode = require("./fold_mode").FoldMode; var Range = require("../../range").Range; +var TokenIterator = require("../../token_iterator").TokenIterator; + + +var FoldMode = exports.FoldMode = function () { +}; -var FoldMode = exports.FoldMode = function() {}; oop.inherits(FoldMode, BaseFoldMode); -(function() { - - this.getFoldWidgetRange = function(session, foldStyle, row) { - var range = this.indentationBlock(session, row); - if (range) - return range; - - var re = /\S/; - var line = session.getLine(row); - var startLevel = line.search(re); - if (startLevel == -1 || line[startLevel] != "#") - return; - - var startColumn = line.length; - var maxRow = session.getLength(); - var startRow = row; - var endRow = row; - - while (++row < maxRow) { - line = session.getLine(row); - var level = line.search(re); - - if (level == -1) - continue; - - if (line[level] != "#") - break; - - endRow = row; - } - - if (endRow > startRow) { - var endColumn = session.getLine(endRow).length; - return new Range(startRow, startColumn, endRow, endColumn); - } +(function () { + this.indentKeywords = { + "class": 1, + "def": 1, + "module": 1, + "do": 1, + "unless": 1, + "if": 1, + "while": 1, + "for": 1, + "until": 1, + "begin": 1, + "else": 0, + "elsif": 0, + "rescue": 0, + "ensure": 0, + "when": 0, + "end": -1, + "case": 1, + "=begin": 1, + "=end": -1 }; - this.getFoldWidget = function(session, foldStyle, row) { - var line = session.getLine(row); - var indent = line.search(/\S/); - var next = session.getLine(row + 1); - var prev = session.getLine(row - 1); - var prevIndent = prev.search(/\S/); - var nextIndent = next.search(/\S/); - if (indent == -1) { - session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : ""; - return ""; - } - if (prevIndent == -1) { - if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") { - session.foldWidgets[row - 1] = ""; - session.foldWidgets[row + 1] = ""; + this.foldingStartMarker = /(?:\s|^)(def|do|while|class|unless|module|if|for|until|begin|else|elsif|case|rescue|ensure|when)\b|({\s*$)|(=begin)/; + this.foldingStopMarker = /(=end(?=$|\s.*$))|(^\s*})|\b(end)\b/; + + this.getFoldWidget = function (session, foldStyle, row) { + var line = session.getLine(row); + var isStart = this.foldingStartMarker.test(line); + var isEnd = this.foldingStopMarker.test(line); + + if (isStart && !isEnd) { + var match = line.match(this.foldingStartMarker); + if (match[1]) { + if (match[1] == "if" || match[1] == "else" || match[1] == "while" || match[1] == "until" || match[1] == "unless") { + if (match[1] == "else" && /^\s*else\s*$/.test(line) === false) { + return; + } + if (/^\s*(?:if|else|while|until|unless)\s*/.test(line) === false) { + return; + } + } + + if (match[1] == "when") { + if (/\sthen\s/.test(line) === true) { + return; + } + } + if (session.getTokenAt(row, match.index + 2).type === "keyword") + return "start"; + } else if (match[3]) { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return "start"; + } else { return "start"; } - } else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") { - if (session.getLine(row - 2).search(/\S/) == -1) { - session.foldWidgets[row - 1] = "start"; - session.foldWidgets[row + 1] = ""; - return ""; + } + if (foldStyle != "markbeginend" || !isEnd || isStart && isEnd) + return ""; + + var match = line.match(this.foldingStopMarker); + if (match[3] === "end") { + if (session.getTokenAt(row, match.index + 1).type === "keyword") + return "end"; + } else if (match[1]) { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return "end"; + } else + return "end"; + }; + + this.getFoldWidgetRange = function (session, foldStyle, row) { + var line = session.doc.getLine(row); + var match = this.foldingStartMarker.exec(line); + if (match) { + if (match[1] || match[3]) + return this.rubyBlock(session, row, match.index + 2); + + return this.openingBracketBlock(session, "{", row, match.index); + } + + var match = this.foldingStopMarker.exec(line); + if (match) { + if (match[3] === "end") { + if (session.getTokenAt(row, match.index + 1).type === "keyword") + return this.rubyBlock(session, row, match.index + 1); + } + + if (match[1] === "=end") { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return this.rubyBlock(session, row, match.index + 1); + } + + return this.closingBracketBlock(session, "}", row, match.index + match[0].length); + } + }; + + this.rubyBlock = function (session, row, column, tokenRange) { + var stream = new TokenIterator(session, row, column); + + var token = stream.getCurrentToken(); + if (!token || (token.type != "keyword" && token.type != "comment.multiline")) + return; + + var val = token.value; + var line = session.getLine(row); + switch (token.value) { + case "if": + case "unless": + case "while": + case "until": + var checkToken = new RegExp("^\\s*" + token.value); + if (!checkToken.test(line)) { + return; + } + var dir = this.indentKeywords[val]; + break; + case "when": + if (/\sthen\s/.test(line)) { + return; + } + case "elsif": + case "rescue": + case "ensure": + var dir = 1; + break; + case "else": + var checkToken = new RegExp("^\\s*" + token.value + "\\s*$"); + if (!checkToken.test(line)) { + return; + } + var dir = 1; + break; + default: + var dir = this.indentKeywords[val]; + break; + } + + var stack = [val]; + if (!dir) + return; + + var startColumn = dir === -1 ? session.getLine(row - 1).length : session.getLine(row).length; + var startRow = row; + var ranges = []; + ranges.push(stream.getCurrentTokenRange()); + + stream.step = dir === -1 ? stream.stepBackward : stream.stepForward; + if (token.type == "comment.multiline") { + while (token = stream.step()) { + if (token.type !== "comment.multiline") + continue; + if (dir == 1) { + startColumn = 6; + if (token.value == "=end") { + break; + } + } else { + if (token.value == "=begin") { + break; + } + } + } + } else { + while (token = stream.step()) { + var ignore = false; + if (token.type !== "keyword") + continue; + var level = dir * this.indentKeywords[token.value]; + line = session.getLine(stream.getCurrentTokenRow()); + switch (token.value) { + case "do": + for (var i = stream.$tokenIndex - 1; i >= 0; i--) { + var prevToken = stream.$rowTokens[i]; + if (prevToken && (prevToken.value == "while" || prevToken.value == "until" || prevToken.value == "for")) { + level = 0; + break; + } + } + break; + case "else": + var checkToken = new RegExp("^\\s*" + token.value + "\\s*$"); + if (!checkToken.test(line) || val == "case") { + level = 0; + ignore = true; + } + break; + case "if": + case "unless": + case "while": + case "until": + var checkToken = new RegExp("^\\s*" + token.value); + if (!checkToken.test(line)) { + level = 0; + ignore = true; + } + break; + case "when": + if (/\sthen\s/.test(line) || val == "case") { + level = 0; + ignore = true; + } + break; + } + + if (level > 0) { + stack.unshift(token.value); + } else if (level <= 0 && ignore === false) { + stack.shift(); + if (!stack.length) { + if ((val == "while" || val == "until" || val == "for") && token.value != "do") { + break; + } + if (token.value == "do" && dir == -1 && level != 0) + break; + if (token.value != "do") + break; + } + + if (level === 0) { + stack.unshift(token.value); + } + } } } - if (prevIndent!= -1 && prevIndent < indent) - session.foldWidgets[row - 1] = "start"; - else - session.foldWidgets[row - 1] = ""; + if (!token) + return null; - if (indent < nextIndent) - return "start"; - else - return ""; + if (tokenRange) { + ranges.push(stream.getCurrentTokenRange()); + return ranges; + } + + var row = stream.getCurrentTokenRow(); + if (dir === -1) { + if (token.type === "comment.multiline") { + var endColumn = 6; + } else { + var endColumn = session.getLine(row).length; + } + return new Range(row, endColumn, startRow - 1, startColumn); + } else + return new Range(startRow, startColumn, row - 1, session.getLine(row - 1).length); }; }).call(FoldMode.prototype); }); -define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/coffee"], function(require, exports, module) { +define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/ruby"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); @@ -428,13 +919,14 @@ var RubyHighlightRules = require("./ruby_highlight_rules").RubyHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; var Range = require("../range").Range; var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var FoldMode = require("./folding/coffee").FoldMode; +var FoldMode = require("./folding/ruby").FoldMode; var Mode = function() { this.HighlightRules = RubyHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.$behaviour = new CstyleBehaviour(); this.foldingRules = new FoldMode(); + this.indentKeywords = this.foldingRules.indentKeywords; }; oop.inherits(Mode, TextMode); @@ -449,7 +941,7 @@ oop.inherits(Mode, TextMode); var tokenizedLine = this.getTokenizer().getLineTokens(line, state); var tokens = tokenizedLine.tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { + if (tokens.length && tokens[tokens.length - 1].type == "comment") { return indent; } @@ -457,7 +949,7 @@ oop.inherits(Mode, TextMode); var match = line.match(/^.*[\{\(\[]\s*$/); var startingClassOrMethod = line.match(/^\s*(class|def|module)\s.*$/); var startingDoBlock = line.match(/.*do(\s*|\s+\|.*\|\s*)$/); - var startingConditional = line.match(/^\s*(if|else|when)\s*/); + var startingConditional = line.match(/^\s*(if|else|when|elsif|unless|while|for|begin|rescue|ensure)\s*/); if (match || startingClassOrMethod || startingDoBlock || startingConditional) { indent += tab; } @@ -467,7 +959,7 @@ oop.inherits(Mode, TextMode); }; this.checkOutdent = function(state, line, input) { - return /^\s+(end|else)$/.test(line + input) || this.$outdent.checkOutdent(line, input); + return /^\s+(end|else|rescue|ensure)$/.test(line + input) || this.$outdent.checkOutdent(line, input); }; this.autoOutdent = function(state, session, row) { @@ -480,11 +972,24 @@ oop.inherits(Mode, TextMode); var tab = session.getTabString(); if (prevIndent.length <= indent.length) { if (indent.slice(-tab.length) == tab) - session.remove(new Range(row, indent.length-tab.length, row, indent.length)); + session.remove(new Range(row, indent.length - tab.length, row, indent.length)); } }; + this.getMatching = function(session, row, column) { + if (row == undefined) { + var pos = session.selection.lead; + column = pos.column; + row = pos.row; + } + + var startToken = session.getTokenAt(row, column); + if (startToken && startToken.value in this.indentKeywords) + return this.foldingRules.rubyBlock(session, row, column, true); + }; + this.$id = "ace/mode/ruby"; + this.snippetFileId = "ace/snippets/ruby"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-rust.js b/htdocs/includes/ace/src/mode-rust.js index e24ed47a680..19f6a989963 100644 --- a/htdocs/includes/ace/src/mode-rust.js +++ b/htdocs/includes/ace/src/mode-rust.js @@ -5,15 +5,16 @@ var oop = require("../lib/oop"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var stringEscape = /\\(?:[nrt0'"\\]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\})/.source; +var wordPattern = /[a-zA-Z_\xa1-\uffff][a-zA-Z0-9_\xa1-\uffff]*/.source; var RustHighlightRules = function() { this.$rules = { start: [ { token: 'variable.other.source.rust', - regex: '\'[a-zA-Z_][a-zA-Z0-9_]*(?![\\\'])' }, + regex: '\'' + wordPattern + '(?![\\\'])' }, { token: 'string.quoted.single.source.rust', regex: "'(?:[^'\\\\]|" + stringEscape + ")'" }, { token: 'identifier', - regex: /r#[a-zA-Z_][a-zA-Z0-9_]*\b/ }, + regex: "r#" + wordPattern + "\\b" }, { stateName: "bracketedComment", onMatch : function(value, currentState, stack){ @@ -53,8 +54,8 @@ var RustHighlightRules = function() { regex: stringEscape }, { defaultToken: 'string.quoted.double.source.rust' } ] }, { token: [ 'keyword.source.rust', 'text', 'entity.name.function.source.rust' ], - regex: '\\b(fn)(\\s+)((?:r#)?[a-zA-Z_][a-zA-Z0-9_]*)' }, - { token: 'support.constant', regex: '\\b[a-zA-Z_][\\w\\d]*::' }, + regex: '\\b(fn)(\\s+)((?:r#)?'+ wordPattern + ')' }, + { token: 'support.constant', regex: wordPattern + '::' }, { token: 'keyword.source.rust', regex: '\\b(?:abstract|alignof|as|async|await|become|box|break|catch|continue|const|crate|default|do|dyn|else|enum|extern|for|final|if|impl|in|let|loop|macro|match|mod|move|mut|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\\b' }, { token: 'storage.type.source.rust', diff --git a/htdocs/includes/ace/src/mode-scala.js b/htdocs/includes/ace/src/mode-scala.js index b3cd18a601b..68a320ca8fd 100644 --- a/htdocs/includes/ace/src/mode-scala.js +++ b/htdocs/includes/ace/src/mode-scala.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-scrypt.js b/htdocs/includes/ace/src/mode-scrypt.js new file mode 100644 index 00000000000..80feb0ed02d --- /dev/null +++ b/htdocs/includes/ace/src/mode-scrypt.js @@ -0,0 +1,364 @@ +define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var DocCommentHighlightRules = function() { + this.$rules = { + "start" : [ { + token : "comment.doc.tag", + regex : "@[\\w\\d_]+" // TODO: fix email addresses + }, + DocCommentHighlightRules.getTagRule(), + { + defaultToken : "comment.doc", + caseInsensitive: true + }] + }; +}; + +oop.inherits(DocCommentHighlightRules, TextHighlightRules); + +DocCommentHighlightRules.getTagRule = function(start) { + return { + token : "comment.doc.tag.storage.type", + regex : "\\b(?:TODO|FIXME|XXX|HACK)\\b" + }; +}; + +DocCommentHighlightRules.getStartRule = function(start) { + return { + token : "comment.doc", // doc comment + regex : "\\/\\*(?=\\*)", + next : start + }; +}; + +DocCommentHighlightRules.getEndRule = function (start) { + return { + token : "comment.doc", // closing comment + regex : "\\*\\/", + next : start + }; +}; + + +exports.DocCommentHighlightRules = DocCommentHighlightRules; + +}); + +define("ace/mode/scrypt_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function (require, exports, module) { + "use strict"; + + var oop = require("../lib/oop"); + var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; + var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + + var scryptHighlightRules = function () { + + var keywords = ( + "contract|library|loop|new|private|" + + "public|if|else|struct|type|" + + "require|static|const|import|exit|return|asm" + ); + + var buildinConstants = ("true|false"); + + + var langClasses = ( + "function|auto|constructor|bytes|int|bool|SigHashPreimage|PrivKey|PubKey|Sig|Ripemd160|Sha1|Sha256|" + + "SigHashType|SigHashPreimage|OpCodeType" + ); + + var keywordMapper = this.createKeywordMapper({ + "variable.language": "this", + "keyword": keywords, + "constant.language": buildinConstants, + "support.function": langClasses + }, "identifier"); + + this.$rules = { + "start": [ + { + token: "comment", + regex: "\\/\\/.*$" + }, + DocCommentHighlightRules.getStartRule("doc-start"), + { + token: "comment", // multi line comment + regex: "\\/\\*", + next: "comment" + }, { + token: "string", // single line + regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + }, { + token: "string", // single line + regex: "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" + }, { + token: "constant.numeric", // hex + regex: /0(?:[xX][0-9a-fA-F][0-9a-fA-F_]*|[bB][01][01_]*)[LlSsDdFfYy]?\b/ + }, { + token: "constant.numeric", // float + regex: /[+-]?\d[\d_]*(?:(?:\.[\d_]*)?(?:[eE][+-]?[\d_]+)?)?[LlSsDdFfYy]?\b/ + }, { + token: "constant.language.boolean", + regex: "(?:true|false)\\b" + }, + { + token: ["support.function.math.scrypt", "text", "text"], + regex: /\b(abs|min|max|within|ripemd160|sha1|sha256|hash160|hash256|checkSig|checkMultiSig|num2bin|pack|unpack|len|reverseBytes|repeat)(\s*)(\()/ + }, { + token: [ + "entity.name.type.scrypt", + "text", + "text", + "text", + "variable.object.property.scrypt" + ], + regex: /\b(SigHash)(\s*)(\.)(\s*)(ANYONECANPAY|ALL|FORKID|NONE|SINGLE)\b/ + }, + { + token: [ + "entity.name.type.scrypt", + "text", + "text", + "text", + "variable.object.property.scrypt" + ], + regex: /\b(OpCode)(\s*)(\.)(\s*)(OP_PUSHDATA1|OP_PUSHDATA2|OP_PUSHDATA4|OP_0|OP_FALSE|OP_1NEGATE|OP_1|OP_TRUE|OP_2|OP_3|OP_4|OP_5|OP_6|OP_7|OP_8|OP_9|OP_10|OP_11|OP_12|OP_13|OP_14|OP_15|OP_16|OP_1ADD|OP_1SUB|OP_NEGATE|OP_ABS|OP_NOT|OP_0NOTEQUAL|OP_ADD|OP_SUB|OP_MUL|OP_DIV|OP_MOD|OP_LSHIFT|OP_RSHIFT|OP_BOOLAND|OP_BOOLOR|OP_NUMEQUAL|OP_NUMEQUALVERIFY|OP_NUMNOTEQUAL|OP_LESSTHAN|OP_GREATERTHAN|OP_LESSTHANOREQUAL|OP_GREATERTHANOREQUAL|OP_MIN|OP_MAX|OP_WITHIN|OP_CAT|OP_SPLIT|OP_BIN2NUM|OP_NUM2BIN|OP_SIZE|OP_NOP|OP_IF|OP_NOTIF|OP_ELSE|OP_ENDIF|OP_VERIFY|OP_RETURN|OP_TOALTSTACK|OP_FROMALTSTACK|OP_IFDUP|OP_DEPTH|OP_DROP|OP_DUP|OP_NIP|OP_OVER|OP_PICK|OP_ROLL|OP_ROT|OP_SWAP|OP_TUCK|OP_2DROP|OP_2DUP|OP_3DUP|OP_2OVER|OP_2ROT|OP_2SWAP|OP_RIPEMD160|OP_SHA1|OP_SHA256|OP_HASH160|OP_HASH256|OP_CODESEPARATOR|OP_CHECKSIG|OP_CHECKSIGVERIFY|OP_CHECKMULTISIG|OP_CHECKMULTISIGVERIFY|OP_INVERT|OP_AND|OP_OR|OP_XOR|OP_EQUAL|OP_EQUALVERIFY)\b/ + }, { + token: "entity.name.type.scrypt", + regex: /\b(?:P2PKH|P2PK|Tx|HashPuzzleRipemd160|HashPuzzleSha1|HashPuzzleSha256|HashPuzzleHash160|OpCode|SigHash)\b/ + }, { + token: [ + "punctuation.separator.period.scrypt", + 'text', + "entity.name.function.scrypt", + "text", + "punctuation.definition.parameters.begin.bracket.round.scrypt" + ], + regex: /(\.)([^\S$\r]*)([\w][\w\d]*)(\s*)(\()/, + push: [{ + token: "punctuation.definition.parameters.end.bracket.round.scrypt", + regex: /\)/, + next: "pop" + }, { + defaultToken: "start" + }] + }, { + token: keywordMapper, + regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + token: "keyword.operator", + regex: "!|\\$|%|&|\\||\\^|\\*|\\/|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<>|<|>|!|&&|\\|\\||\\?|\\:|\\*=|\\/=|%=|\\+=|\\-=|&=|\\|=|\\^=" + }, { + token: "lparen", + regex: "[[({]" + }, { + token: "rparen", + regex: "[\\])}]" + }, { + token: "text", + regex: "\\s+" + } + ], + "comment": [ + { + token: "comment", // closing comment + regex: "\\*\\/", + next: "start" + }, { + defaultToken: "comment" + } + ] + }; + + + this.embedRules(DocCommentHighlightRules, "doc-", + [DocCommentHighlightRules.getEndRule("start")]); + this.normalizeRules(); + }; + + oop.inherits(scryptHighlightRules, TextHighlightRules); + + exports.scryptHighlightRules = scryptHighlightRules; +}); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/scrypt",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/scrypt_highlight_rules","ace/mode/folding/cstyle"], function (require, exports, module) { + "use strict"; + + var oop = require("../lib/oop"); + var TextMode = require("./text").Mode; + var scryptHighlightRules = require("./scrypt_highlight_rules").scryptHighlightRules; + var FoldMode = require("./folding/cstyle").FoldMode; + + var Mode = function () { + this.HighlightRules = scryptHighlightRules; + this.foldingRules = new FoldMode(); + }; + oop.inherits(Mode, TextMode); + + (function () { + this.lineCommentStart = "//"; + this.blockComment = { start: "/*", end: "*/" }; + this.$quotes = { '"': '"', "'": "'" }; + + this.createWorker = function (session) { + + return null; + }; + + + this.$id = "ace/mode/scrypt"; + }).call(Mode.prototype); + + exports.Mode = Mode; +}); (function() { + window.require(["ace/mode/scrypt"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-sh.js b/htdocs/includes/ace/src/mode-sh.js index db130f99563..56df9c69694 100644 --- a/htdocs/includes/ace/src/mode-sh.js +++ b/htdocs/includes/ace/src/mode-sh.js @@ -435,6 +435,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/sh"; + this.snippetFileId = "ace/snippets/sh"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-sjs.js b/htdocs/includes/ace/src/mode-sjs.js index 218cab19b44..93855df3cee 100644 --- a/htdocs/includes/ace/src/mode-sjs.js +++ b/htdocs/includes/ace/src/mode-sjs.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-slim.js b/htdocs/includes/ace/src/mode-slim.js index 7f243bde705..85d09c8693d 100644 --- a/htdocs/includes/ace/src/mode-slim.js +++ b/htdocs/includes/ace/src/mode-slim.js @@ -990,6 +990,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2192,6 +2193,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2745,6 +2747,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -3330,6 +3333,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/sh"; + this.snippetFileId = "ace/snippets/sh"; }).call(Mode.prototype); exports.Mode = Mode; @@ -3382,6 +3386,7 @@ oop.inherits(Mode, TextMode); } }; this.$id = "ace/mode/markdown"; + this.snippetFileId = "ace/snippets/markdown"; }).call(Mode.prototype); exports.Mode = Mode; @@ -3734,6 +3739,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/coffee"; + this.snippetFileId = "ace/snippets/coffee"; }).call(Mode.prototype); exports.Mode = Mode; @@ -4247,17 +4253,17 @@ var constantOtherSymbol = exports.constantOtherSymbol = { regex : "[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?" }; -var qString = exports.qString = { +exports.qString = { token : "string", // single line regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" }; -var qqString = exports.qqString = { +exports.qqString = { token : "string", // single line regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' }; -var tString = exports.tString = { +exports.tString = { token : "string", // backtick string regex : "[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]" }; @@ -4267,9 +4273,34 @@ var constantNumericHex = exports.constantNumericHex = { regex : "0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b" }; +var constantNumericBinary = exports.constantNumericBinary = { + token: "constant.numeric", + regex: /\b(0[bB][01](?:[01]|_(?=[01]))*)\b/ +}; + +var constantNumericDecimal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[dD](?:[1-9](?:[\d]|_(?=[\d]))*|0))\b/ +}; + +var constantNumericOctal = exports.constantNumericDecimal = { + token: "constant.numeric", + regex: /\b(0[oO]?(?:[1-7](?:[0-7]|_(?=[0-7]))*|0))\b/ +}; + +var constantNumericRational = exports.constantNumericRational = { + token: "constant.numeric", //rational + complex + regex: /\b([\d]+(?:[./][\d]+)?ri?)\b/ +}; + +var constantNumericComplex = exports.constantNumericComplex = { + token: "constant.numeric", //simple complex numbers + regex: /\b([\d]i)\b/ +}; + var constantNumericFloat = exports.constantNumericFloat = { - token : "constant.numeric", // float - regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b" + token : "constant.numeric", // float + complex + regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?i?\\b" }; var instanceVariable = exports.instanceVariable = { @@ -4309,18 +4340,19 @@ var RubyHighlightRules = function() { "filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|" + "translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|" + "cache|expire_fragment|expire_cache_for|observe|cache_sweeper|" + - "has_many|has_one|belongs_to|has_and_belongs_to_many" + "has_many|has_one|belongs_to|has_and_belongs_to_many|p|warn|refine|using|module_function|extend|alias_method|" + + "private_class_method|remove_method|undef_method" ); var keywords = ( "alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|" + "__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|" + - "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield" + "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|__ENCODING__|prepend" ); var buildinConstants = ( "true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|" + - "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING" + "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING|RUBY_PATCHLEVEL|RUBY_REVISION|RUBY_COPYRIGHT|RUBY_ENGINE|RUBY_ENGINE_VERSION|RUBY_DESCRIPTION" ); var builtinVariables = ( @@ -4336,126 +4368,191 @@ var RubyHighlightRules = function() { "invalid.deprecated": "debugger" // TODO is this a remnant from js mode? }, "identifier"); + var escapedChars = "\\\\(?:n(?:[1-7][0-7]{0,2}|0)|[nsrtvfbae'\"\\\\]|c(?:\\\\M-)?.|M-(?:\\\\C-|\\\\c)?.|C-(?:\\\\M-)?.|[0-7]{3}|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u{[\\da-fA-F]{1,6}(?:\\s[\\da-fA-F]{1,6})*})"; + + var closeParen = { + "(": ")", + "[": "]", + "{": "}", + "<": ">", + "^": "^", + "|": "|", + "%": "%" + }; + this.$rules = { - "start" : [ + "start": [ { - token : "comment", - regex : "#.*$" + token: "comment", + regex: "#.*$" }, { - token : "comment", // multi line comment - regex : "^=begin(?:$|\\s.*$)", - next : "comment" + token: "comment.multiline", // multi line comment + regex: "^=begin(?=$|\\s.*$)", + next: "comment" }, { - token : "string.regexp", - regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" + token: "string.regexp", + regex: /[/](?=.*\/)/, + next: "regex" }, [{ - regex: "[{}]", onMatch: function(val, state, stack) { - this.next = val == "{" ? this.nextState : ""; - if (val == "{" && stack.length) { - stack.unshift("start", state); - return "paren.lparen"; - } - if (val == "}" && stack.length) { - stack.shift(); - this.next = stack.shift(); - if (this.next.indexOf("string") != -1) - return "paren.end"; - } - return val == "{" ? "paren.lparen" : "paren.rparen"; - }, - nextState: "start" - }, { - token : "string.start", - regex : /"/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(")/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /"/, - next : "pop" + token: "string.end", + regex: /"/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /`/, - push : [{ - token : "constant.language.escape", - regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + token: "string.start", + regex: /`/, + push: [{ + token: "constant.language.escape", + regex: escapedChars }, { - token : "paren.start", - regex : /#{/, - push : "start" + token: "paren.start", + regex: /#{/, + push: "start" }, { - token : "string.end", - regex : /`/, - next : "pop" + token: "string.end", + regex: /`/, + next: "pop" }, { defaultToken: "string" }] }, { - token : "string.start", - regex : /'/, - push : [{ - token : "constant.language.escape", - regex : /\\['\\]/ - }, { - token : "string.end", - regex : /'/, - next : "pop" + token: ["constant.other.symbol.ruby", "string.start"], + regex: /(:)?(')/, + push: [{ + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "string.end", + regex: /'/, + next: "pop" }, { defaultToken: "string" }] + }, { + token: "string.start",//doesn't see any differences between strings and array of strings in highlighting + regex: /%[qwx]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithoutInterpolation"; + return this.token; + } + }, { + token: "string.start", //doesn't see any differences between strings and array of strings in highlighting + regex: /%[QWX]?([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "qStateWithInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[si]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithoutInterpolation"; + return this.token; + } + }, { + token: "constant.other.symbol.ruby", //doesn't see any differences between symbols and array of symbols in highlighting + regex: /%[SI]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "sStateWithInterpolation"; + return this.token; + } + }, { + token: "string.regexp", + regex: /%[r]([(\[<{^|%])/, onMatch: function (val, state, stack) { + if (stack.length) + stack = []; + var paren = val[val.length - 1]; + stack.unshift(paren, state); + this.next = "rState"; + return this.token; + } }], { - token : "text", // namespaces aren't symbols - regex : "::" + token: "punctuation", // namespaces aren't symbols + regex: "::" + }, + instanceVariable, + { + token: "variable.global", // global variable + regex: "[$][a-zA-Z_\\d]+" }, { - token : "variable.instance", // instance variable - regex : "@{1,2}[a-zA-Z_\\d]+" + token: "support.class", // class name + regex: "[A-Z][a-zA-Z_\\d]*" }, { - token : "support.class", // class name - regex : "[A-Z][a-zA-Z_\\d]+" + token: ["punctuation.operator", "support.function"], + regex: /(\.)([a-zA-Z_\d]+)(?=\()/ + }, { + token: ["punctuation.operator", "identifier"], + regex: /(\.)([a-zA-Z_][a-zA-Z_\d]*)/ + }, { + token: "string.character", + regex: "\\B\\?(?:" + escapedChars + "|\\S)" + }, { + token: "punctuation.operator", + regex: /\?(?=.+:)/ }, + constantNumericRational, + constantNumericComplex, constantOtherSymbol, constantNumericHex, constantNumericFloat, - + constantNumericBinary, + constantNumericDecimal, + constantNumericOctal, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" + token: "constant.language.boolean", + regex: "(?:true|false)\\b" }, { - token : keywordMapper, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + token: keywordMapper, + regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" }, { - token : "punctuation.separator.key-value", - regex : "=>" + token: "punctuation.separator.key-value", + regex: "=>" }, { stateName: "heredoc", - onMatch : function(value, currentState, stack) { - var next = value[2] == '-' ? "indentedHeredoc" : "heredoc"; + onMatch: function (value, currentState, stack) { + var next = (value[2] == '-' || value[2] == '~') ? "indentedHeredoc" : "heredoc"; var tokens = value.split(this.splitRegex); stack.push(next, tokens[3]); return [ - {type:"constant", value: tokens[1]}, - {type:"string", value: tokens[2]}, - {type:"support.class", value: tokens[3]}, - {type:"string", value: tokens[4]} + {type: "constant", value: tokens[1]}, + {type: "string", value: tokens[2]}, + {type: "support.class", value: tokens[3]}, + {type: "string", value: tokens[4]} ]; }, - regex : "(<<-?)(['\"`]?)([\\w]+)(['\"`]?)", + regex: "(<<[-~]?)(['\"`]?)([\\w]+)(['\"`]?)", rules: { heredoc: [{ - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -4472,7 +4569,7 @@ var RubyHighlightRules = function() { token: "string", regex: "^ +" }, { - onMatch: function(value, currentState, stack) { + onMatch: function(value, currentState, stack) { if (value === stack[1]) { stack.shift(); stack.shift(); @@ -4487,38 +4584,261 @@ var RubyHighlightRules = function() { }] } }, { - regex : "$", - token : "empty", - next : function(currentState, stack) { + regex: "$", + token: "empty", + next: function(currentState, stack) { if (stack[0] === "heredoc" || stack[0] === "indentedHeredoc") return stack[0]; return currentState; } + }, { + token: "keyword.operator", + regex: "!|\\$|%|&|\\*|/|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\||\\b(?:in|instanceof|new|delete|typeof|void)" }, { - token : "string.character", - regex : "\\B\\?." + token: "paren.lparen", + regex: "[[({]" }, { - token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + token: "paren.rparen", + regex: "[\\])}]", + onMatch: function(value, currentState, stack) { + this.next = ''; + if (value == "}" && stack.length > 1 && stack[1] != "start") { + stack.shift(); + this.next = stack.shift(); + } + return this.token; + } }, { - token : "paren.lparen", - regex : "[[({]" + token: "text", + regex: "\\s+" }, { - token : "paren.rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" + token: "punctuation.operator", + regex: /[?:,;.]/ } ], - "comment" : [ + "comment": [ { - token : "comment", // closing comment - regex : "^=end(?:$|\\s.*$)", - next : "start" + token: "comment.multiline", // closing comment + regex: "^=end(?=$|\\s.*$)", + next: "start" }, { - token : "comment", // comment spanning whole line - regex : ".+" + token: "comment", // comment spanning whole line + regex: ".+" + } + ], + "qStateWithInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "qStateWithoutInterpolation": [{ + token: "string.start",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "string"; + } + }, { + token: "constant.language.escape", + regex: /\\['\\]/ + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "string.end", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "string"; + } + }, { + defaultToken: "string" + }], + "sStateWithoutInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "sStateWithInterpolation": [{ + token: "constant.other.symbol.ruby",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.other.symbol.ruby"; + } + }, { + token: "constant.language.escape", + regex: escapedChars + }, { + token: "constant.language.escape", + regex: /\\./ + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "constant.other.symbol.ruby", + regex: /[)\]>}^|%]/, onMatch: function (val, state, stack) { + if (stack.length && val === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.other.symbol.ruby"; + } + }, { + defaultToken: "constant.other.symbol.ruby" + }], + "rState": [{ + token: "string.regexp",// excluded nested |^% due to difficulty in realization + regex: /[(\[<{]/, onMatch: function (val, state, stack) { + if (stack.length && val === stack[0]) { + stack.unshift(val, state); + return this.token; + } + return "constant.language.escape"; + } + }, { + token: "paren.start", + regex: /#{/, + push: "start" + }, { + token: "string.regexp", + regex: /\// + }, { + token: "string.regexp", + regex: /[)\]>}^|%][imxouesn]*/, onMatch: function (val, state, stack) { + if (stack.length && val[0] === closeParen[stack[0]]) { + stack.shift(); + this.next = stack.shift(); + return this.token; + } + this.next = ''; + return "constant.language.escape"; + } + }, + {include: "regex"}, + { + defaultToken: "string.regexp" + }], + "regex": [ + {// character classes + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "constant.language.escape", + regex: /\\[AGbBzZ]/ + }, { + token: "constant.language.escape", + regex: /\\g<[a-zA-Z0-9]*>/ + }, { + token: ["constant.language.escape", "regexp.keyword", "constant.language.escape"], + regex: /(\\p{\^?)(Alnum|Alpha|Blank|Cntrl|Digit|Graph|Lower|Print|Punct|Space|Upper|XDigit|Word|ASCII|Any|Assigned|Arabic|Armenian|Balinese|Bengali|Bopomofo|Braille|Buginese|Buhid|Canadian_Aboriginal|Carian|Cham|Cherokee|Common|Coptic|Cuneiform|Cypriot|Cyrillic|Deseret|Devanagari|Ethiopic|Georgian|Glagolitic|Gothic|Greek|Gujarati|Gurmukhi|Han|Hangul|Hanunoo|Hebrew|Hiragana|Inherited|Kannada|Katakana|Kayah_Li|Kharoshthi|Khmer|Lao|Latin|Lepcha|Limbu|Linear_B|Lycian|Lydian|Malayalam|Mongolian|Myanmar|New_Tai_Lue|Nko|Ogham|Ol_Chiki|Old_Italic|Old_Persian|Oriya|Osmanya|Phags_Pa|Phoenician|Rejang|Runic|Saurashtra|Shavian|Sinhala|Sundanese|Syloti_Nagri|Syriac|Tagalog|Tagbanwa|Tai_Le|Tamil|Telugu|Thaana|Thai|Tibetan|Tifinagh|Ugaritic|Vai|Yi|Ll|Lm|Lt|Lu|Lo|Mn|Mc|Me|Nd|Nl|Pc|Pd|Ps|Pe|Pi|Pf|Po|No|Sm|Sc|Sk|So|Zs|Zl|Zp|Cc|Cf|Cn|Co|Cs|N|L|M|P|S|Z|C)(})/ + }, { + token: ["constant.language.escape", "invalid", "constant.language.escape"], + regex: /(\\p{\^?)([^/]*)(})/ + }, {// escapes + token: "regexp.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, {// flag + token: "string.regexp", + regex: /[/][imxouesn]*/, + next: "start" + }, {// invalid operators + token: "invalid", + regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ + }, {// operators + token: "constant.language.escape", + regex: /\(\?(?:[:=!>]|<'?[a-zA-Z]*'?>|<[=!])|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ + }, { + token: "constant.language.delimiter", + regex: /\|/ + }, { + token: "regexp.keyword", + regex: /\[\[:(?:alnum|alpha|blank|cntrl|digit|graph|lower|print|punct|space|upper|xdigit|word|ascii):\]\]/ + }, { + token: "constant.language.escape", + regex: /\[\^?/, + push: "regex_character_class" + }, { + defaultToken: "string.regexp" + } + ], + "regex_character_class": [ + { + token: "regexp.keyword", + regex: /\\[wWdDhHsS]/ + }, { + token: "regexp.charclass.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "constant.language.escape", + regex: /&?&?\[\^?/, + push: "regex_character_class" + }, { + token: "constant.language.escape", + regex: "]", + next: "pop" + }, { + token: "constant.language.escape", + regex: "-" + }, { + defaultToken: "string.regexp.characterclass" } ] }; @@ -4531,7 +4851,271 @@ oop.inherits(RubyHighlightRules, TextHighlightRules); exports.RubyHighlightRules = RubyHighlightRules; }); -define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/coffee"], function(require, exports, module) { +define("ace/mode/folding/ruby",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"], function (require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var BaseFoldMode = require("./fold_mode").FoldMode; +var Range = require("../../range").Range; +var TokenIterator = require("../../token_iterator").TokenIterator; + + +var FoldMode = exports.FoldMode = function () { +}; + +oop.inherits(FoldMode, BaseFoldMode); + +(function () { + this.indentKeywords = { + "class": 1, + "def": 1, + "module": 1, + "do": 1, + "unless": 1, + "if": 1, + "while": 1, + "for": 1, + "until": 1, + "begin": 1, + "else": 0, + "elsif": 0, + "rescue": 0, + "ensure": 0, + "when": 0, + "end": -1, + "case": 1, + "=begin": 1, + "=end": -1 + }; + + this.foldingStartMarker = /(?:\s|^)(def|do|while|class|unless|module|if|for|until|begin|else|elsif|case|rescue|ensure|when)\b|({\s*$)|(=begin)/; + this.foldingStopMarker = /(=end(?=$|\s.*$))|(^\s*})|\b(end)\b/; + + this.getFoldWidget = function (session, foldStyle, row) { + var line = session.getLine(row); + var isStart = this.foldingStartMarker.test(line); + var isEnd = this.foldingStopMarker.test(line); + + if (isStart && !isEnd) { + var match = line.match(this.foldingStartMarker); + if (match[1]) { + if (match[1] == "if" || match[1] == "else" || match[1] == "while" || match[1] == "until" || match[1] == "unless") { + if (match[1] == "else" && /^\s*else\s*$/.test(line) === false) { + return; + } + if (/^\s*(?:if|else|while|until|unless)\s*/.test(line) === false) { + return; + } + } + + if (match[1] == "when") { + if (/\sthen\s/.test(line) === true) { + return; + } + } + if (session.getTokenAt(row, match.index + 2).type === "keyword") + return "start"; + } else if (match[3]) { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return "start"; + } else { + return "start"; + } + } + if (foldStyle != "markbeginend" || !isEnd || isStart && isEnd) + return ""; + + var match = line.match(this.foldingStopMarker); + if (match[3] === "end") { + if (session.getTokenAt(row, match.index + 1).type === "keyword") + return "end"; + } else if (match[1]) { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return "end"; + } else + return "end"; + }; + + this.getFoldWidgetRange = function (session, foldStyle, row) { + var line = session.doc.getLine(row); + var match = this.foldingStartMarker.exec(line); + if (match) { + if (match[1] || match[3]) + return this.rubyBlock(session, row, match.index + 2); + + return this.openingBracketBlock(session, "{", row, match.index); + } + + var match = this.foldingStopMarker.exec(line); + if (match) { + if (match[3] === "end") { + if (session.getTokenAt(row, match.index + 1).type === "keyword") + return this.rubyBlock(session, row, match.index + 1); + } + + if (match[1] === "=end") { + if (session.getTokenAt(row, match.index + 1).type === "comment.multiline") + return this.rubyBlock(session, row, match.index + 1); + } + + return this.closingBracketBlock(session, "}", row, match.index + match[0].length); + } + }; + + this.rubyBlock = function (session, row, column, tokenRange) { + var stream = new TokenIterator(session, row, column); + + var token = stream.getCurrentToken(); + if (!token || (token.type != "keyword" && token.type != "comment.multiline")) + return; + + var val = token.value; + var line = session.getLine(row); + switch (token.value) { + case "if": + case "unless": + case "while": + case "until": + var checkToken = new RegExp("^\\s*" + token.value); + if (!checkToken.test(line)) { + return; + } + var dir = this.indentKeywords[val]; + break; + case "when": + if (/\sthen\s/.test(line)) { + return; + } + case "elsif": + case "rescue": + case "ensure": + var dir = 1; + break; + case "else": + var checkToken = new RegExp("^\\s*" + token.value + "\\s*$"); + if (!checkToken.test(line)) { + return; + } + var dir = 1; + break; + default: + var dir = this.indentKeywords[val]; + break; + } + + var stack = [val]; + if (!dir) + return; + + var startColumn = dir === -1 ? session.getLine(row - 1).length : session.getLine(row).length; + var startRow = row; + var ranges = []; + ranges.push(stream.getCurrentTokenRange()); + + stream.step = dir === -1 ? stream.stepBackward : stream.stepForward; + if (token.type == "comment.multiline") { + while (token = stream.step()) { + if (token.type !== "comment.multiline") + continue; + if (dir == 1) { + startColumn = 6; + if (token.value == "=end") { + break; + } + } else { + if (token.value == "=begin") { + break; + } + } + } + } else { + while (token = stream.step()) { + var ignore = false; + if (token.type !== "keyword") + continue; + var level = dir * this.indentKeywords[token.value]; + line = session.getLine(stream.getCurrentTokenRow()); + switch (token.value) { + case "do": + for (var i = stream.$tokenIndex - 1; i >= 0; i--) { + var prevToken = stream.$rowTokens[i]; + if (prevToken && (prevToken.value == "while" || prevToken.value == "until" || prevToken.value == "for")) { + level = 0; + break; + } + } + break; + case "else": + var checkToken = new RegExp("^\\s*" + token.value + "\\s*$"); + if (!checkToken.test(line) || val == "case") { + level = 0; + ignore = true; + } + break; + case "if": + case "unless": + case "while": + case "until": + var checkToken = new RegExp("^\\s*" + token.value); + if (!checkToken.test(line)) { + level = 0; + ignore = true; + } + break; + case "when": + if (/\sthen\s/.test(line) || val == "case") { + level = 0; + ignore = true; + } + break; + } + + if (level > 0) { + stack.unshift(token.value); + } else if (level <= 0 && ignore === false) { + stack.shift(); + if (!stack.length) { + if ((val == "while" || val == "until" || val == "for") && token.value != "do") { + break; + } + if (token.value == "do" && dir == -1 && level != 0) + break; + if (token.value != "do") + break; + } + + if (level === 0) { + stack.unshift(token.value); + } + } + } + } + + if (!token) + return null; + + if (tokenRange) { + ranges.push(stream.getCurrentTokenRange()); + return ranges; + } + + var row = stream.getCurrentTokenRow(); + if (dir === -1) { + if (token.type === "comment.multiline") { + var endColumn = 6; + } else { + var endColumn = session.getLine(row).length; + } + return new Range(row, endColumn, startRow - 1, startColumn); + } else + return new Range(startRow, startColumn, row - 1, session.getLine(row - 1).length); + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/ruby"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); @@ -4540,13 +5124,14 @@ var RubyHighlightRules = require("./ruby_highlight_rules").RubyHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; var Range = require("../range").Range; var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var FoldMode = require("./folding/coffee").FoldMode; +var FoldMode = require("./folding/ruby").FoldMode; var Mode = function() { this.HighlightRules = RubyHighlightRules; this.$outdent = new MatchingBraceOutdent(); this.$behaviour = new CstyleBehaviour(); this.foldingRules = new FoldMode(); + this.indentKeywords = this.foldingRules.indentKeywords; }; oop.inherits(Mode, TextMode); @@ -4561,7 +5146,7 @@ oop.inherits(Mode, TextMode); var tokenizedLine = this.getTokenizer().getLineTokens(line, state); var tokens = tokenizedLine.tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { + if (tokens.length && tokens[tokens.length - 1].type == "comment") { return indent; } @@ -4569,7 +5154,7 @@ oop.inherits(Mode, TextMode); var match = line.match(/^.*[\{\(\[]\s*$/); var startingClassOrMethod = line.match(/^\s*(class|def|module)\s.*$/); var startingDoBlock = line.match(/.*do(\s*|\s+\|.*\|\s*)$/); - var startingConditional = line.match(/^\s*(if|else|when)\s*/); + var startingConditional = line.match(/^\s*(if|else|when|elsif|unless|while|for|begin|rescue|ensure)\s*/); if (match || startingClassOrMethod || startingDoBlock || startingConditional) { indent += tab; } @@ -4579,7 +5164,7 @@ oop.inherits(Mode, TextMode); }; this.checkOutdent = function(state, line, input) { - return /^\s+(end|else)$/.test(line + input) || this.$outdent.checkOutdent(line, input); + return /^\s+(end|else|rescue|ensure)$/.test(line + input) || this.$outdent.checkOutdent(line, input); }; this.autoOutdent = function(state, session, row) { @@ -4592,11 +5177,24 @@ oop.inherits(Mode, TextMode); var tab = session.getTabString(); if (prevIndent.length <= indent.length) { if (indent.slice(-tab.length) == tab) - session.remove(new Range(row, indent.length-tab.length, row, indent.length)); + session.remove(new Range(row, indent.length - tab.length, row, indent.length)); } }; + this.getMatching = function(session, row, column) { + if (row == undefined) { + var pos = session.selection.lead; + column = pos.column; + row = pos.row; + } + + var startToken = session.getTokenAt(row, column); + if (startToken && startToken.value in this.indentKeywords) + return this.foldingRules.rubyBlock(session, row, column, true); + }; + this.$id = "ace/mode/ruby"; + this.snippetFileId = "ace/snippets/ruby"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-smarty.js b/htdocs/includes/ace/src/mode-smarty.js index 8c044c1698b..03a1654ffac 100644 --- a/htdocs/includes/ace/src/mode-smarty.js +++ b/htdocs/includes/ace/src/mode-smarty.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-smithy.js b/htdocs/includes/ace/src/mode-smithy.js new file mode 100644 index 00000000000..6dd0bcfaa81 --- /dev/null +++ b/htdocs/includes/ace/src/mode-smithy.js @@ -0,0 +1,507 @@ +define("ace/mode/smithy_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var SmithyHighlightRules = function() { + + this.$rules = { + start: [{ + include: "#comment" + }, { + token: [ + "meta.keyword.statement.smithy", + "variable.other.smithy", + "text", + "keyword.operator.smithy" + ], + regex: /^(\$)(\s+.+)(\s*)(=)/ + }, { + token: [ + "keyword.statement.smithy", + "text", + "entity.name.type.namespace.smithy" + ], + regex: /^(namespace)(\s+)([A-Z-a-z0-9_\.#$-]+)/ + }, { + token: [ + "keyword.statement.smithy", + "text", + "keyword.statement.smithy", + "text", + "entity.name.type.smithy" + ], + regex: /^(use)(\s+)(shape|trait)(\s+)([A-Z-a-z0-9_\.#$-]+)\b/ + }, { + token: [ + "keyword.statement.smithy", + "variable.other.smithy", + "text", + "keyword.operator.smithy" + ], + regex: /^(metadata)(\s+.+)(\s*)(=)/ + }, { + token: [ + "keyword.statement.smithy", + "text", + "entity.name.type.smithy" + ], + regex: /^(apply|byte|short|integer|long|float|double|bigInteger|bigDecimal|boolean|blob|string|timestamp|service|resource|trait|list|map|set|structure|union|document)(\s+)([A-Z-a-z0-9_\.#$-]+)\b/ + }, { + token: [ + "keyword.operator.smithy", + "text", + "entity.name.type.smithy", + "text", + "text", + "support.function.smithy", + "text", + "text", + "support.function.smithy" + ], + regex: /^(operation)(\s+)([A-Z-a-z0-9_\.#$-]+)(\(.*\))(?:(\s*)(->)(\s*[A-Z-a-z0-9_\.#$-]+))?(?:(\s+)(errors))?/ + }, { + include: "#trait" + }, { + token: [ + "support.type.property-name.smithy", + "punctuation.separator.dictionary.pair.smithy" + ], + regex: /([A-Z-a-z0-9_\.#$-]+)(:)/ + }, { + include: "#value" + }, { + token: "keyword.other.smithy", + regex: /\->/ + }], + "#comment": [{ + include: "#doc_comment" + }, { + include: "#line_comment" + }], + "#doc_comment": [{ + token: "comment.block.documentation.smithy", + regex: /\/\/\/.*/ + }], + "#line_comment": [{ + token: "comment.line.double-slash.smithy", + regex: /\/\/.*/ + }], + "#trait": [{ + token: [ + "punctuation.definition.annotation.smithy", + "storage.type.annotation.smithy" + ], + regex: /(@)([0-9a-zA-Z\.#-]+)/ + }, { + token: [ + "punctuation.definition.annotation.smithy", + "punctuation.definition.object.end.smithy", + "meta.structure.smithy" + ], + regex: /(@)([0-9a-zA-Z\.#-]+)(\()/, + push: [{ + token: "punctuation.definition.object.end.smithy", + regex: /\)/, + next: "pop" + }, { + include: "#value" + }, { + include: "#object_inner" + }, { + defaultToken: "meta.structure.smithy" + }] + }], + "#value": [{ + include: "#constant" + }, { + include: "#number" + }, { + include: "#string" + }, { + include: "#array" + }, { + include: "#object" + }], + "#array": [{ + token: "punctuation.definition.array.begin.smithy", + regex: /\[/, + push: [{ + token: "punctuation.definition.array.end.smithy", + regex: /\]/, + next: "pop" + }, { + include: "#comment" + }, { + include: "#value" + }, { + token: "punctuation.separator.array.smithy", + regex: /,/ + }, { + token: "invalid.illegal.expected-array-separator.smithy", + regex: /[^\s\]]/ + }, { + defaultToken: "meta.structure.array.smithy" + }] + }], + "#constant": [{ + token: "constant.language.smithy", + regex: /\b(?:true|false|null)\b/ + }], + "#number": [{ + token: "constant.numeric.smithy", + regex: /-?(?:0|[1-9]\d*)(?:(?:\.\d+)?(?:[eE][+-]?\d+)?)?/ + }], + "#object": [{ + token: "punctuation.definition.dictionary.begin.smithy", + regex: /\{/, + push: [{ + token: "punctuation.definition.dictionary.end.smithy", + regex: /\}/, + next: "pop" + }, { + include: "#trait" + }, { + include: "#object_inner" + }, { + defaultToken: "meta.structure.dictionary.smithy" + }] + }], + "#object_inner": [{ + include: "#comment" + }, { + include: "#string_key" + }, { + token: "punctuation.separator.dictionary.key-value.smithy", + regex: /:/, + push: [{ + token: "punctuation.separator.dictionary.pair.smithy", + regex: /,|(?=\})/, + next: "pop" + }, { + include: "#value" + }, { + token: "invalid.illegal.expected-dictionary-separator.smithy", + regex: /[^\s,]/ + }, { + defaultToken: "meta.structure.dictionary.value.smithy" + }] + }, { + token: "invalid.illegal.expected-dictionary-separator.smithy", + regex: /[^\s\}]/ + }], + "#string_key": [{ + include: "#identifier_key" + }, { + include: "#dquote_key" + }, { + include: "#squote_key" + }], + "#identifier_key": [{ + token: "support.type.property-name.smithy", + regex: /[A-Z-a-z0-9_\.#$-]+/ + }], + "#dquote_key": [{ + include: "#dquote" + }], + "#squote_key": [{ + include: "#squote" + }], + "#string": [{ + include: "#textblock" + }, { + include: "#dquote" + }, { + include: "#squote" + }, { + include: "#identifier" + }], + "#textblock": [{ + token: "punctuation.definition.string.begin.smithy", + regex: /"""/, + push: [{ + token: "punctuation.definition.string.end.smithy", + regex: /"""/, + next: "pop" + }, { + token: "constant.character.escape.smithy", + regex: /\\./ + }, { + defaultToken: "string.quoted.double.smithy" + }] + }], + "#dquote": [{ + token: "punctuation.definition.string.begin.smithy", + regex: /"/, + push: [{ + token: "punctuation.definition.string.end.smithy", + regex: /"/, + next: "pop" + }, { + token: "constant.character.escape.smithy", + regex: /\\./ + }, { + defaultToken: "string.quoted.double.smithy" + }] + }], + "#squote": [{ + token: "punctuation.definition.string.begin.smithy", + regex: /'/, + push: [{ + token: "punctuation.definition.string.end.smithy", + regex: /'/, + next: "pop" + }, { + token: "constant.character.escape.smithy", + regex: /\\./ + }, { + defaultToken: "string.quoted.single.smithy" + }] + }], + "#identifier": [{ + token: "storage.type.smithy", + regex: /[A-Z-a-z_][A-Z-a-z0-9_\.#$-]*/ + }] + }; + + this.normalizeRules(); +}; + +SmithyHighlightRules.metaData = { + name: "Smithy", + fileTypes: ["smithy"], + scopeName: "source.smithy", + foldingStartMarker: "(\\{|\\[)\\s*", + foldingStopMarker: "\\s*(\\}|\\])" +}; + + +oop.inherits(SmithyHighlightRules, TextHighlightRules); + +exports.SmithyHighlightRules = SmithyHighlightRules; +}); + +define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +var MatchingBraceOutdent = function() {}; + +(function() { + + this.checkOutdent = function(line, input) { + if (! /^\s+$/.test(line)) + return false; + + return /^\s*\}/.test(input); + }; + + this.autoOutdent = function(doc, row) { + var line = doc.getLine(row); + var match = line.match(/^(\s*\})/); + + if (!match) return 0; + + var column = match[1].length; + var openBracePos = doc.findMatchingBracket({row: row, column: column}); + + if (!openBracePos || openBracePos.row == row) return 0; + + var indent = this.$getIndent(doc.getLine(openBracePos.row)); + doc.replace(new Range(row, 0, row, column-1), indent); + }; + + this.$getIndent = function(line) { + return line.match(/^\s*/)[0]; + }; + +}).call(MatchingBraceOutdent.prototype); + +exports.MatchingBraceOutdent = MatchingBraceOutdent; +}); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/smithy",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/smithy_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var SmithyHighlightRules = require("./smithy_highlight_rules").SmithyHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = SmithyHighlightRules; + + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + this.foldingRules = new CStyleFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "//"; + this.$quotes = {'"': '"'}; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.$id = "ace/mode/smithy"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); (function() { + window.require(["ace/mode/smithy"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-snippets.js b/htdocs/includes/ace/src/mode-snippets.js index 600463bf3e5..32276191d16 100644 --- a/htdocs/includes/ace/src/mode-snippets.js +++ b/htdocs/includes/ace/src/mode-snippets.js @@ -192,6 +192,7 @@ oop.inherits(Mode, TextMode); this.$indentWithTabs = true; this.lineCommentStart = "#"; this.$id = "ace/mode/snippets"; + this.snippetFileId = "ace/snippets/snippets"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-soy_template.js b/htdocs/includes/ace/src/mode-soy_template.js index 83b35c0c673..a9674ac5730 100644 --- a/htdocs/includes/ace/src/mode-soy_template.js +++ b/htdocs/includes/ace/src/mode-soy_template.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-sql.js b/htdocs/includes/ace/src/mode-sql.js index 77ba37a8ed1..3bb9e83b7af 100644 --- a/htdocs/includes/ace/src/mode-sql.js +++ b/htdocs/includes/ace/src/mode-sql.js @@ -78,15 +78,174 @@ oop.inherits(SqlHighlightRules, TextHighlightRules); exports.SqlHighlightRules = SqlHighlightRules; }); -define("ace/mode/sql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sql_highlight_rules"], function(require, exports, module) { +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/folding/sql",["require","exports","module","ace/lib/oop","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var BaseFoldMode = require("./cstyle").FoldMode; + +var FoldMode = exports.FoldMode = function() {}; + +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/sql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sql_highlight_rules","ace/mode/folding/sql"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var SqlHighlightRules = require("./sql_highlight_rules").SqlHighlightRules; +var SqlFoldMode = require("./folding/sql").FoldMode; var Mode = function() { this.HighlightRules = SqlHighlightRules; + this.foldingRules = new SqlFoldMode(); this.$behaviour = this.$defaultBehaviour; }; oop.inherits(Mode, TextMode); @@ -94,8 +253,10 @@ oop.inherits(Mode, TextMode); (function() { this.lineCommentStart = "--"; + this.blockComment = {start: "/*", end: "*/"}; this.$id = "ace/mode/sql"; + this.snippetFileId = "ace/snippets/sql"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-sqlserver.js b/htdocs/includes/ace/src/mode-sqlserver.js index 41f53c3e598..69aa4384ff1 100644 --- a/htdocs/includes/ace/src/mode-sqlserver.js +++ b/htdocs/includes/ace/src/mode-sqlserver.js @@ -429,7 +429,8 @@ oop.inherits(Mode, TextMode); return session.$mode.$highlightRules.completions; }; - this.$id = "ace/mode/sql"; + this.$id = "ace/mode/sqlserver"; + this.snippetFileId = "ace/snippets/sqlserver"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-svg.js b/htdocs/includes/ace/src/mode-svg.js index 6dc3c60c6dd..d8e0358d1b5 100644 --- a/htdocs/includes/ace/src/mode-svg.js +++ b/htdocs/includes/ace/src/mode-svg.js @@ -1454,6 +1454,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-swift.js b/htdocs/includes/ace/src/mode-swift.js index b207deb7652..06644d6fdda 100644 --- a/htdocs/includes/ace/src/mode-swift.js +++ b/htdocs/includes/ace/src/mode-swift.js @@ -165,6 +165,12 @@ var SwiftHighlightRules = function() { this.$rules = { start: [ + string('"""', { + escape: /\\(?:[0\\tnr"']|u{[a-fA-F1-9]{0,8}})/, + interpolation: {lead: "\\", open: "(", close: ")"}, + error: /\\./, + multiline: true + }), string('"', { escape: /\\(?:[0\\tnr"']|u{[a-fA-F1-9]{0,8}})/, interpolation: {lead: "\\", open: "(", close: ")"}, diff --git a/htdocs/includes/ace/src/mode-tcl.js b/htdocs/includes/ace/src/mode-tcl.js index b898da9c528..632f928adbc 100644 --- a/htdocs/includes/ace/src/mode-tcl.js +++ b/htdocs/includes/ace/src/mode-tcl.js @@ -373,6 +373,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/tcl"; + this.snippetFileId = "ace/snippets/tcl"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-terraform.js b/htdocs/includes/ace/src/mode-terraform.js index 76e2cf2db63..bd252bc32b5 100644 --- a/htdocs/includes/ace/src/mode-terraform.js +++ b/htdocs/includes/ace/src/mode-terraform.js @@ -40,11 +40,15 @@ var TerraformHighlightRules = function () { { token: "singleline.comment.terraform", - regex: '#(.)*$' + regex: '#.*$' + }, + { + token: "singleline.comment.terraform", + regex: '//.*$' }, { token: "multiline.comment.begin.terraform", - regex: '^\\s*\\/\\*', + regex: /\/\*/, push: "blockComment" }, { @@ -66,11 +70,7 @@ var TerraformHighlightRules = function () { {include: "variables"} ], blockComment: [{ - regex: "^\\s*\\/\\*", - token: "multiline.comment.begin.terraform", - push: "blockComment" - }, { - regex: "\\*\\/\\s*$", + regex: /\*\//, token: "multiline.comment.end.terraform", next: "pop" }, { @@ -383,6 +383,9 @@ oop.inherits(Mode, TextMode); (function () { + this.lineCommentStart = ["#", "//"]; + this.blockComment = {start: "/*", end: "*/"}; + this.$id = "ace/mode/terraform"; }).call(Mode.prototype); diff --git a/htdocs/includes/ace/src/mode-tex.js b/htdocs/includes/ace/src/mode-tex.js index 22673ec6222..9b3fb3b3722 100644 --- a/htdocs/includes/ace/src/mode-tex.js +++ b/htdocs/includes/ace/src/mode-tex.js @@ -146,6 +146,7 @@ oop.inherits(Mode, TextMode); return false; }; this.$id = "ace/mode/tex"; + this.snippetFileId = "ace/snippets/tex"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-textile.js b/htdocs/includes/ace/src/mode-textile.js index 203bbbeb31a..8ce8ad64dfd 100644 --- a/htdocs/includes/ace/src/mode-textile.js +++ b/htdocs/includes/ace/src/mode-textile.js @@ -135,6 +135,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/textile"; + this.snippetFileId = "ace/snippets/textile"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-tsx.js b/htdocs/includes/ace/src/mode-tsx.js index b4292219847..2b5d18d632c 100644 --- a/htdocs/includes/ace/src/mode-tsx.js +++ b/htdocs/includes/ace/src/mode-tsx.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-twig.js b/htdocs/includes/ace/src/mode-twig.js index a7c3c2b4bd2..b5eac5b2b68 100644 --- a/htdocs/includes/ace/src/mode-twig.js +++ b/htdocs/includes/ace/src/mode-twig.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-typescript.js b/htdocs/includes/ace/src/mode-typescript.js index d4e8cdb3876..3bebbdaba3d 100644 --- a/htdocs/includes/ace/src/mode-typescript.js +++ b/htdocs/includes/ace/src/mode-typescript.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-vala.js b/htdocs/includes/ace/src/mode-vala.js index 5e51a584107..2fe15bac55d 100644 --- a/htdocs/includes/ace/src/mode-vala.js +++ b/htdocs/includes/ace/src/mode-vala.js @@ -663,6 +663,7 @@ oop.inherits(Mode, TextMode); this.$outdent.autoOutdent(doc, row); }; this.$id = "ace/mode/vala"; + this.snippetFileId = "ace/snippets/vala"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-vbscript.js b/htdocs/includes/ace/src/mode-vbscript.js index 482c2f95c96..19a3a002781 100644 --- a/htdocs/includes/ace/src/mode-vbscript.js +++ b/htdocs/includes/ace/src/mode-vbscript.js @@ -8,11 +8,13 @@ var VBScriptHighlightRules = function() { var keywordMapper = this.createKeywordMapper({ "keyword.control.asp": "If|Then|Else|ElseIf|End|While|Wend|For|To|Each|Case|Select|Return" - + "|Continue|Do|Until|Loop|Next|With|Exit|Function|Property|Type|Enum|Sub|IIf", - "storage.type.asp": "Dim|Call|Class|Const|Dim|Redim|Set|Let|Get|New|Randomize|Option|Explicit", + + "|Continue|Do|Until|Loop|Next|With|Exit|Function|Property|Type|Enum|Sub|IIf|Class", + "storage.type.asp": "Dim|Call|Const|Redim|Set|Let|Get|New|Randomize|Option|Explicit|Preserve|Erase|Execute|ExecuteGlobal", "storage.modifier.asp": "Private|Public|Default", - "keyword.operator.asp": "Mod|And|Not|Or|Xor|as", + "keyword.operator.asp": "Mod|And|Not|Or|Xor|As|Eqv|Imp|Is", "constant.language.asp": "Empty|False|Nothing|Null|True", + "variable.language.vb.asp": "Me", + "support.class.vb.asp": "RegExp", "support.class.asp": "Application|ObjectContext|Request|Response|Server|Session", "support.class.collection.asp": "Contents|StaticObjects|ClientCertificate|Cookies|Form|QueryString|ServerVariables", "support.constant.asp": "TotalBytes|Buffer|CacheControl|Charset|ContentType|Expires|ExpiresAbsolute" @@ -30,13 +32,17 @@ var VBScriptHighlightRules = function() { + "|Trim|Maths|Mid|Minute|Month|MonthName|MsgBox|Now|Oct|Remove|RemoveAll|Replace" + "|RGB|Right|Rnd|Round|ScriptEngine|ScriptEngineBuildVersion|ScriptEngineMajorVersion" + "|ScriptEngineMinorVersion|Second|SetLocale|Sgn|Sin|Space|Split|Sqr|StrComp|String|StrReverse" - + "|Tan|Time|Timer|TimeSerial|TimeValue|TypeName|UBound|UCase|Unescape|VarType|Weekday|WeekdayName|Year", - "support.type.vb.asp": "vbtrue|vbfalse|vbcr|vbcrlf|vbformfeed|vblf|vbnewline|vbnullchar|vbnullstring|" - + "int32|vbtab|vbverticaltab|vbbinarycompare|vbtextcomparevbsunday|vbmonday|vbtuesday|vbwednesday" - + "|vbthursday|vbfriday|vbsaturday|vbusesystemdayofweek|vbfirstjan1|vbfirstfourdays|vbfirstfullweek" - + "|vbgeneraldate|vblongdate|vbshortdate|vblongtime|vbshorttime|vbobjecterror|vbEmpty|vbNull|vbInteger" + + "|Tan|Time|Timer|TimeSerial|TimeValue|TypeName|UBound|UCase|Unescape|VarType|Weekday|WeekdayName|Year" + + "|AscB|AscW|ChrB|ChrW|InStrB|LeftB|LenB|MidB|RightB|Abs|GetUILanguage", + "support.type.vb.asp": "vbTrue|vbFalse|vbCr|vbCrLf|vbFormFeed|vbLf|vbNewLine|vbNullChar|vbNullString" + + "|vbTab|vbVerticalTab|vbBinaryCompare|vbTextCompare|vbSunday|vbMonday|vbTuesday|vbWednesday" + + "|vbThursday|vbFriday|vbSaturday|vbUseSystemDayOfWeek|vbFirstJan1|vbFirstFourDays|vbFirstFullWeek" + + "|vbGeneralDate|vbLongDate|vbShortDate|vbLongTime|vbShortTime|vbObjectError|vbEmpty|vbNull|vbInteger" + "|vbLong|vbSingle|vbDouble|vbCurrency|vbDate|vbString|vbObject|vbError|vbBoolean|vbVariant" - + "|vbDataObject|vbDecimal|vbByte|vbArray" + + "|vbDataObject|vbDecimal|vbByte|vbArray|vbOKOnly|vbOKCancel|vbAbortRetryIgnore|vbYesNoCancel|vbYesNo" + + "|vbRetryCancel|vbCritical|vbQuestion|vbExclamation|vbInformation|vbDefaultButton1|vbDefaultButton2" + + "|vbDefaultButton3|vbDefaultButton4|vbApplicationModal|vbSystemModal|vbOK|vbCancel|vbAbort|vbRetry|vbIgnore|vbYes|vbNo" + + "|vbUseDefault" }, "identifier", true); this.$rules = { @@ -78,7 +84,7 @@ var VBScriptHighlightRules = function() { }, { token: "storage.type.asp", - regex: "On Error Resume Next|On Error GoTo", + regex: "On\\s+Error\\s+(?:Resume\\s+Next|GoTo)\\b", caseInsensitive: true }, { @@ -106,7 +112,7 @@ var VBScriptHighlightRules = function() { }, { token: ["keyword.operator.asp"], - regex: "\\-|\\+|\\*\\/|\\>|\\<|\\=|\\&" + regex: "\\-|\\+|\\*|\\/|\\>|\\<|\\=|\\&|\\\\|\\^" } ], "state_3": [ @@ -145,7 +151,7 @@ var VBScriptHighlightRules = function() { "comment": [ { token: "comment.line.apostrophe.asp", - regex: "$|(?=(?:%>))", + regex: "$", next: "start" }, { @@ -175,23 +181,446 @@ oop.inherits(VBScriptHighlightRules, TextHighlightRules); exports.VBScriptHighlightRules = VBScriptHighlightRules; }); -define("ace/mode/vbscript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/vbscript_highlight_rules"], function(require, exports, module) { +define("ace/mode/folding/vbscript",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var BaseFoldMode = require("./fold_mode").FoldMode; +var Range = require("../../range").Range; +var TokenIterator = require("../../token_iterator").TokenIterator; + + +var FoldMode = exports.FoldMode = function() {}; + +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + this.indentKeywords = { + "class": 1, + "function": 1, + "sub": 1, + "if": 1, + "select": 1, + "do": 1, + "for": 1, + "while": 1, + "with": 1, + "property": 1, + "else": 1, + "elseif": 1, + "end": -1, + "loop": -1, + "next": -1, + "wend": -1 + }; + + this.foldingStartMarker = /(?:\s|^)(class|function|sub|if|select|do|for|while|with|property|else|elseif)\b/i; + this.foldingStopMarker = /\b(end|loop|next|wend)\b/i; + + this.getFoldWidgetRange = function (session, foldStyle, row) { + var line = session.getLine(row); + var isStart = this.foldingStartMarker.test(line); + var isEnd = this.foldingStopMarker.test(line); + if (isStart || isEnd) { + var match = (isEnd) ? this.foldingStopMarker.exec(line) : this.foldingStartMarker.exec(line); + var keyword = match && match[1].toLowerCase(); + if (keyword) { + var type = session.getTokenAt(row, match.index + 2).type; + if (type === "keyword.control.asp" || type === "storage.type.function.asp") + return this.vbsBlock(session, row, match.index + 2); + } + } + }; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + var isStart = this.foldingStartMarker.test(line); + var isEnd = this.foldingStopMarker.test(line); + if (isStart && !isEnd) { + var match = this.foldingStartMarker.exec(line); + var keyword = match && match[1].toLowerCase(); + if (keyword) { + var type = session.getTokenAt(row, match.index + 2).type; + if (type == "keyword.control.asp" || type == "storage.type.function.asp") { + if (keyword == "if" && !/then\s*('|$)/i.test(line)) + return ""; + return "start"; + } + } + } + return ""; + }; + + this.vbsBlock = function(session, row, column, tokenRange) { + var stream = new TokenIterator(session, row, column); + + var endOpenings = { + "class": 1, + "function": 1, + "sub": 1, + "if": 1, + "select": 1, + "with": 1, + "property": 1, + "else": 1, + "elseif": 1 + }; + + var token = stream.getCurrentToken(); + if (!token || (token.type != "keyword.control.asp" && token.type != "storage.type.function.asp")) + return; + + var startTokenValue = token.value.toLowerCase(); + var val = token.value.toLowerCase(); + + var stack = [val]; + var dir = this.indentKeywords[val]; + + if (!dir) + return; + + var firstRange = stream.getCurrentTokenRange(); + switch (val) { + case "property": + case "sub": + case "function": + case "if": + case "select": + case "do": + case "for": + case "class": + case "while": + case "with": + var line = session.getLine(row); + var singleLineCondition = /^\s*If\s+.*\s+Then(?!')\s+(?!')\S/i.test(line); + if (singleLineCondition) + return; + var checkToken = new RegExp("(?:^|\\s)" + val, "i"); + var endTest = /^\s*End\s(If|Sub|Select|Function|Class|With|Property)\s*/i.test(line); + if (!checkToken.test(line) && !endTest) { + return; + } + if (endTest) { + var tokenRange = stream.getCurrentTokenRange(); + stream.step = stream.stepBackward; + stream.step(); + stream.step(); + token = stream.getCurrentToken(); + if (token) { + val = token.value.toLowerCase(); + if (val == "end") { + firstRange = stream.getCurrentTokenRange(); + firstRange = new Range(firstRange.start.row, firstRange.start.column, tokenRange.start.row, tokenRange.end.column); + } + } + dir = -1; + } + break; + case "end": + var tokenPos = stream.getCurrentTokenPosition(); + firstRange = stream.getCurrentTokenRange(); + stream.step = stream.stepForward; + stream.step(); + stream.step(); + token = stream.getCurrentToken(); + if (token) { + val = token.value.toLowerCase(); + if (val in endOpenings) { + startTokenValue = val; + var nextTokenPos = stream.getCurrentTokenPosition(); + var endColumn = nextTokenPos.column + val.length; + firstRange = new Range(tokenPos.row, tokenPos.column, nextTokenPos.row, endColumn); + } + } + stream.step = stream.stepBackward; + stream.step(); + stream.step(); + break; + } + var startColumn = dir === -1 ? session.getLine(row - 1).length : session.getLine(row).length; + var startRow = row; + var ranges = []; + ranges.push(firstRange); + + stream.step = dir === -1 ? stream.stepBackward : stream.stepForward; + while(token = stream.step()) { + var outputRange = null; + var ignore = false; + if (token.type != "keyword.control.asp" && token.type != "storage.type.function.asp") + continue; + val = token.value.toLowerCase(); + var level = dir * this.indentKeywords[val]; + + switch (val) { + case "property": + case "sub": + case "function": + case "if": + case "select": + case "do": + case "for": + case "class": + case "while": + case "with": + var line = session.getLine(stream.getCurrentTokenRow()); + var singleLineCondition = /^\s*If\s+.*\s+Then(?!')\s+(?!')\S/i.test(line); + if (singleLineCondition) { + level = 0; + ignore = true; + } + var checkToken = new RegExp("^\\s* end\\s+" + val, "i"); + if (checkToken.test(line)) { + level = 0; + ignore = true; + } + break; + case "elseif": + case "else": + level = 0; + if (startTokenValue != "elseif") { + ignore = true; + } + break; + } + + if (level > 0) { + stack.unshift(val); + } else if (level <= 0 && ignore === false) { + stack.shift(); + if (!stack.length) { + switch (val) { + case "end": + var tokenPos = stream.getCurrentTokenPosition(); + outputRange = stream.getCurrentTokenRange(); + stream.step(); + stream.step(); + token = stream.getCurrentToken(); + if (token) { + val = token.value.toLowerCase(); + if (val in endOpenings) { + if ((startTokenValue == "else" || startTokenValue == "elseif")) { + if (val !== "if") { + ranges.shift(); + } + } else { + if (val != startTokenValue) + ranges.shift(); + } + var nextTokenPos = stream.getCurrentTokenPosition(); + var endColumn = nextTokenPos.column + val.length; + outputRange = new Range(tokenPos.row, tokenPos.column, nextTokenPos.row, endColumn); + } else { + ranges.shift(); + } + } else { + ranges.shift(); + } + stream.step = stream.stepBackward; + stream.step(); + stream.step(); + token = stream.getCurrentToken(); + val = token.value.toLowerCase(); + break; + case "select": + case "sub": + case "if": + case "function": + case "class": + case "with": + case "property": + if (val != startTokenValue) + ranges.shift(); + break; + case "do": + if (startTokenValue != "loop") + ranges.shift(); + break; + case "loop": + if (startTokenValue != "do") + ranges.shift(); + break; + case "for": + if (startTokenValue != "next") + ranges.shift(); + break; + case "next": + if (startTokenValue != "for") + ranges.shift(); + break; + case "while": + if (startTokenValue != "wend") + ranges.shift(); + break; + case "wend": + if (startTokenValue != "while") + ranges.shift(); + break; + } + break; + } + + if (level === 0){ + stack.unshift(val); + } + } + } + + if (!token) + return null; + + if (tokenRange) { + if (!outputRange) { + ranges.push(stream.getCurrentTokenRange()); + } else { + ranges.push(outputRange); + } + return ranges; + } + + var row = stream.getCurrentTokenRow(); + if (dir === -1) { + var endColumn = session.getLine(row).length; + return new Range(row, endColumn, startRow - 1, startColumn); + } else + return new Range(startRow, startColumn, row - 1, session.getLine(row - 1).length); + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/vbscript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/vbscript_highlight_rules","ace/mode/folding/vbscript","ace/range"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var VBScriptHighlightRules = require("./vbscript_highlight_rules").VBScriptHighlightRules; +var FoldMode = require("./folding/vbscript").FoldMode; +var Range = require("../range").Range; var Mode = function() { this.HighlightRules = VBScriptHighlightRules; + this.foldingRules = new FoldMode(); this.$behaviour = this.$defaultBehaviour; + this.indentKeywords = this.foldingRules.indentKeywords; }; oop.inherits(Mode, TextMode); (function() { - + this.lineCommentStart = ["'", "REM"]; - + + var outdentKeywords = [ + "else", + "elseif", + "end", + "loop", + "next", + "wend" + ]; + + function getNetIndentLevel(tokens, line, indentKeywords) { + var level = 0; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + if (token.type == "keyword.control.asp" || token.type == "storage.type.function.asp") { + var val = token.value.toLowerCase(); + if (val in indentKeywords) { + switch (val) { + case "property": + case "sub": + case "function": + case "select": + case "do": + case "for": + case "class": + case "while": + case "with": + case "if": + var checkToken = new RegExp("^\\s* end\\s+" + val, "i"); + var singleLineCondition = /^\s*If\s+.*\s+Then(?!')\s+(?!')\S/i.test(line); + if (!singleLineCondition && !checkToken.test(line)) + level += indentKeywords[val]; + break; + default: + level += indentKeywords[val]; + break; + } + } + } + } + if (level < 0) { + return -1; + } else if (level > 0) { + return 1; + } else { + return 0; + } + } + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + var level = 0; + + var tokenizedLine = this.getTokenizer().getLineTokens(line, state); + var tokens = tokenizedLine.tokens; + + if (state == "start") { + level = getNetIndentLevel(tokens, line, this.indentKeywords); + } + if (level > 0) { + return indent + tab; + } else if (level < 0 && indent.substr(indent.length - tab.length) == tab) { + if (!this.checkOutdent(state, line, "\n")) { + return indent.substr(0, indent.length - tab.length); + } + } + return indent; + }; + + this.checkOutdent = function(state, line, input) { + if (input != "\n" && input != "\r" && input != "\r\n") + return false; + + var tokens = this.getTokenizer().getLineTokens(line.trim(), state).tokens; + + if (!tokens || !tokens.length) + return false; + var val = tokens[0].value.toLowerCase(); + return ((tokens[0].type == "keyword.control.asp" || tokens[0].type == "storage.type.function.asp") && outdentKeywords.indexOf(val) != -1); + }; + + this.getMatching = function(session, row, column, tokenRange) { + if (row == undefined) { + var pos = session.selection.lead; + column = pos.column; + row = pos.row; + } + if (tokenRange == undefined) + tokenRange = true; + + var startToken = session.getTokenAt(row, column); + if (startToken) { + var val = startToken.value.toLowerCase(); + if (val in this.indentKeywords) + return this.foldingRules.vbsBlock(session, row, column, tokenRange); + } + }; + + this.autoOutdent = function(state, session, row) { + var line = session.getLine(row); + var column = line.match(/^\s*/)[0].length; + if (!column || !row) return; + + var startRange = this.getMatching(session, row, column + 1, false); + if (!startRange || startRange.start.row == row) + return; + var indent = this.$getIndent(session.getLine(startRange.start.row)); + if (indent.length != column) { + session.replace(new Range(row, 0, row, column), indent); + session.outdentRows(new Range(row + 1, 0, row + 1, 0)); + } + }; + this.$id = "ace/mode/vbscript"; }).call(Mode.prototype); diff --git a/htdocs/includes/ace/src/mode-velocity.js b/htdocs/includes/ace/src/mode-velocity.js index ea94a8fd9ad..98458db2d49 100644 --- a/htdocs/includes/ace/src/mode-velocity.js +++ b/htdocs/includes/ace/src/mode-velocity.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2775,6 +2778,7 @@ oop.inherits(Mode, HtmlMode); this.lineCommentStart = "##"; this.blockComment = {start: "#*", end: "*#"}; this.$id = "ace/mode/velocity"; + this.snippetFileId = "ace/snippets/velocity"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-vhdl.js b/htdocs/includes/ace/src/mode-vhdl.js index 75f22a1f512..d3e4ba6fd59 100644 --- a/htdocs/includes/ace/src/mode-vhdl.js +++ b/htdocs/includes/ace/src/mode-vhdl.js @@ -8,18 +8,21 @@ var VHDLHighlightRules = function() { - var keywords = "access|after|ailas|all|architecture|assert|attribute|"+ - "begin|block|buffer|bus|case|component|configuration|"+ - "disconnect|downto|else|elsif|end|entity|file|for|function|"+ - "generate|generic|guarded|if|impure|in|inertial|inout|is|"+ - "label|linkage|literal|loop|mapnew|next|of|on|open|others|"+ - "out|port|process|pure|range|record|reject|report|return|"+ - "select|severity|shared|signal|subtype|then|to|transport|"+ - "type|unaffected|united|until|wait|when|while|with"; + var keywords = "access|after|alias|all|architecture|assert|attribute|"+ + "begin|block|body|buffer|bus|case|component|configuration|"+ + "context|disconnect|downto|else|elsif|end|entity|exit|"+ + "file|for|force|function|generate|generic|group|guarded|"+ + "if|impure|in|inertial|inout|is|label|library|linkage|"+ + "literal|loop|map|new|next|of|on|or|open|others|out|"+ + "package|parameter|port|postponed|procedure|process|"+ + "protected|pure|range|record|register|reject|release|"+ + "report|return|select|severity|shared|signal|subtype|then|"+ + "to|transport|type|unaffected|units|until|use|variable|"+ + "wait|when|while|with"; var storageType = "bit|bit_vector|boolean|character|integer|line|natural|"+ "positive|real|register|signed|std_logic|"+ - "std_logic_vector|string||text|time|unsigned|variable"; + "std_logic_vector|string||text|time|unsigned"; var storageModifiers = "array|constant"; diff --git a/htdocs/includes/ace/src/mode-visualforce.js b/htdocs/includes/ace/src/mode-visualforce.js index ad9ab780b74..30c2cd90d18 100644 --- a/htdocs/includes/ace/src/mode-visualforce.js +++ b/htdocs/includes/ace/src/mode-visualforce.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -1316,6 +1317,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/css"; + this.snippetFileId = "ace/snippets/css"; }).call(Mode.prototype); exports.Mode = Mode; @@ -2493,6 +2495,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/html"; + this.snippetFileId = "ace/snippets/html"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-wollok.js b/htdocs/includes/ace/src/mode-wollok.js index a4dba0f9ce4..e62e249a84d 100644 --- a/htdocs/includes/ace/src/mode-wollok.js +++ b/htdocs/includes/ace/src/mode-wollok.js @@ -784,6 +784,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/javascript"; + this.snippetFileId = "ace/snippets/javascript"; }).call(Mode.prototype); exports.Mode = Mode; @@ -899,6 +900,7 @@ oop.inherits(Mode, JavaScriptMode); }; this.$id = "ace/mode/wollok"; + this.snippetFileId = "ace/snippets/wollok"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/mode-xquery.js b/htdocs/includes/ace/src/mode-xquery.js index 0a87a75fa2b..4512ba9d91e 100644 --- a/htdocs/includes/ace/src/mode-xquery.js +++ b/htdocs/includes/ace/src/mode-xquery.js @@ -2630,6 +2630,7 @@ oop.inherits(Mode, TextMode); }; this.$id = "ace/mode/xquery"; + this.snippetFileId = "ace/snippets/xquery"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/htdocs/includes/ace/src/snippets/abap.js b/htdocs/includes/ace/src/snippets/abap.js index 39342f476a4..8a6b11f7d6f 100644 --- a/htdocs/includes/ace/src/snippets/abap.js +++ b/htdocs/includes/ace/src/snippets/abap.js @@ -1,10 +1,5 @@ -define("ace/snippets/abap",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "abap"; - -}); (function() { +; (function() { window.require(["ace/snippets/abap"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/ada.js b/htdocs/includes/ace/src/snippets/ada.js index 94be2e5962e..8eb30a101bd 100644 --- a/htdocs/includes/ace/src/snippets/ada.js +++ b/htdocs/includes/ace/src/snippets/ada.js @@ -1,10 +1,5 @@ -define("ace/snippets/ada",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "ada"; - -}); (function() { +; (function() { window.require(["ace/snippets/ada"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/alda.js b/htdocs/includes/ace/src/snippets/alda.js new file mode 100644 index 00000000000..a7827995831 --- /dev/null +++ b/htdocs/includes/ace/src/snippets/alda.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/alda"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/apache_conf.js b/htdocs/includes/ace/src/snippets/apache_conf.js index c4e29459270..21986504c25 100644 --- a/htdocs/includes/ace/src/snippets/apache_conf.js +++ b/htdocs/includes/ace/src/snippets/apache_conf.js @@ -1,10 +1,5 @@ -define("ace/snippets/apache_conf",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "apache_conf"; - -}); (function() { +; (function() { window.require(["ace/snippets/apache_conf"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/apex.js b/htdocs/includes/ace/src/snippets/apex.js index 0c1f767377d..2dbcd0fce11 100644 --- a/htdocs/includes/ace/src/snippets/apex.js +++ b/htdocs/includes/ace/src/snippets/apex.js @@ -1,10 +1,5 @@ -define("ace/snippets/apex",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "apex"; - -}); (function() { +; (function() { window.require(["ace/snippets/apex"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/applescript.js b/htdocs/includes/ace/src/snippets/applescript.js index 2412c72c9af..ea322dbde2b 100644 --- a/htdocs/includes/ace/src/snippets/applescript.js +++ b/htdocs/includes/ace/src/snippets/applescript.js @@ -1,10 +1,5 @@ -define("ace/snippets/applescript",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "applescript"; - -}); (function() { +; (function() { window.require(["ace/snippets/applescript"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/aql.js b/htdocs/includes/ace/src/snippets/aql.js index f9ef46d179d..5568f6a1084 100644 --- a/htdocs/includes/ace/src/snippets/aql.js +++ b/htdocs/includes/ace/src/snippets/aql.js @@ -1,10 +1,5 @@ -define("ace/snippets/aql",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "aql"; - -}); (function() { +; (function() { window.require(["ace/snippets/aql"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/asciidoc.js b/htdocs/includes/ace/src/snippets/asciidoc.js index 7c68e42e3f0..e5b47cfa570 100644 --- a/htdocs/includes/ace/src/snippets/asciidoc.js +++ b/htdocs/includes/ace/src/snippets/asciidoc.js @@ -1,10 +1,5 @@ -define("ace/snippets/asciidoc",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "asciidoc"; - -}); (function() { +; (function() { window.require(["ace/snippets/asciidoc"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/asl.js b/htdocs/includes/ace/src/snippets/asl.js index e077ac0e4ab..0166b95535e 100644 --- a/htdocs/includes/ace/src/snippets/asl.js +++ b/htdocs/includes/ace/src/snippets/asl.js @@ -1,9 +1,5 @@ -define("ace/snippets/asl",["require","exports","module"], function (require, exports, module) { - "use strict"; - exports.snippetText =undefined; - exports.scope = "asl"; -}); (function() { +; (function() { window.require(["ace/snippets/asl"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/assembly_x86.js b/htdocs/includes/ace/src/snippets/assembly_x86.js index 7b16369e1be..ffbf5971f61 100644 --- a/htdocs/includes/ace/src/snippets/assembly_x86.js +++ b/htdocs/includes/ace/src/snippets/assembly_x86.js @@ -1,10 +1,5 @@ -define("ace/snippets/assembly_x86",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "assembly_x86"; - -}); (function() { +; (function() { window.require(["ace/snippets/assembly_x86"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/autohotkey.js b/htdocs/includes/ace/src/snippets/autohotkey.js index 601d201ce16..e0674d4eac6 100644 --- a/htdocs/includes/ace/src/snippets/autohotkey.js +++ b/htdocs/includes/ace/src/snippets/autohotkey.js @@ -1,10 +1,5 @@ -define("ace/snippets/autohotkey",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "autohotkey"; - -}); (function() { +; (function() { window.require(["ace/snippets/autohotkey"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/batchfile.js b/htdocs/includes/ace/src/snippets/batchfile.js index dfae8ab00bc..0404a41ee28 100644 --- a/htdocs/includes/ace/src/snippets/batchfile.js +++ b/htdocs/includes/ace/src/snippets/batchfile.js @@ -1,10 +1,5 @@ -define("ace/snippets/batchfile",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "batchfile"; - -}); (function() { +; (function() { window.require(["ace/snippets/batchfile"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/bro.js b/htdocs/includes/ace/src/snippets/bro.js deleted file mode 100644 index 9412c6003e3..00000000000 --- a/htdocs/includes/ace/src/snippets/bro.js +++ /dev/null @@ -1,14 +0,0 @@ -define("ace/snippets/bro",["require","exports","module"], function(require, exports, module) { -"use strict"; - -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { - window.require(["ace/snippets/bro"], function(m) { - if (typeof module == "object" && typeof exports == "object" && module) { - module.exports = m; - } - }); - })(); - \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/c9search.js b/htdocs/includes/ace/src/snippets/c9search.js index b5c7058137b..d83a158fc79 100644 --- a/htdocs/includes/ace/src/snippets/c9search.js +++ b/htdocs/includes/ace/src/snippets/c9search.js @@ -1,10 +1,5 @@ -define("ace/snippets/c9search",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "c9search"; - -}); (function() { +; (function() { window.require(["ace/snippets/c9search"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/cirru.js b/htdocs/includes/ace/src/snippets/cirru.js index 882b0c9741f..8bd664ed3f9 100644 --- a/htdocs/includes/ace/src/snippets/cirru.js +++ b/htdocs/includes/ace/src/snippets/cirru.js @@ -1,10 +1,5 @@ -define("ace/snippets/cirru",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "cirru"; - -}); (function() { +; (function() { window.require(["ace/snippets/cirru"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/cobol.js b/htdocs/includes/ace/src/snippets/cobol.js index 303dea71778..1fece5b6445 100644 --- a/htdocs/includes/ace/src/snippets/cobol.js +++ b/htdocs/includes/ace/src/snippets/cobol.js @@ -1,10 +1,5 @@ -define("ace/snippets/cobol",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "cobol"; - -}); (function() { +; (function() { window.require(["ace/snippets/cobol"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/coldfusion.js b/htdocs/includes/ace/src/snippets/coldfusion.js index db72fad9320..0f1ff4d2b8a 100644 --- a/htdocs/includes/ace/src/snippets/coldfusion.js +++ b/htdocs/includes/ace/src/snippets/coldfusion.js @@ -1,10 +1,5 @@ -define("ace/snippets/coldfusion",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "coldfusion"; - -}); (function() { +; (function() { window.require(["ace/snippets/coldfusion"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/crystal.js b/htdocs/includes/ace/src/snippets/crystal.js index ef64a9fdce1..39614eb1fe5 100644 --- a/htdocs/includes/ace/src/snippets/crystal.js +++ b/htdocs/includes/ace/src/snippets/crystal.js @@ -1,10 +1,5 @@ -define("ace/snippets/crystal",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "crystal"; - -}); (function() { +; (function() { window.require(["ace/snippets/crystal"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/csharp.js b/htdocs/includes/ace/src/snippets/csharp.js index f36041cbcd7..22c8f86c0a7 100644 --- a/htdocs/includes/ace/src/snippets/csharp.js +++ b/htdocs/includes/ace/src/snippets/csharp.js @@ -1,10 +1,5 @@ -define("ace/snippets/csharp",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "csharp"; - -}); (function() { +; (function() { window.require(["ace/snippets/csharp"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/csound_score.js b/htdocs/includes/ace/src/snippets/csound_score.js index 82ee2c17d35..3d7ae0e6720 100644 --- a/htdocs/includes/ace/src/snippets/csound_score.js +++ b/htdocs/includes/ace/src/snippets/csound_score.js @@ -1,10 +1,5 @@ -define("ace/snippets/csound_score",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "csound_score"; - -}); (function() { +; (function() { window.require(["ace/snippets/csound_score"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/csp.js b/htdocs/includes/ace/src/snippets/csp.js index 8225367a49b..685814919fa 100644 --- a/htdocs/includes/ace/src/snippets/csp.js +++ b/htdocs/includes/ace/src/snippets/csp.js @@ -1,10 +1,5 @@ -define("ace/snippets/csp",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/csp"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/curly.js b/htdocs/includes/ace/src/snippets/curly.js index 1d7b8f7b290..d0c5487d9f0 100644 --- a/htdocs/includes/ace/src/snippets/curly.js +++ b/htdocs/includes/ace/src/snippets/curly.js @@ -1,10 +1,5 @@ -define("ace/snippets/curly",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "curly"; - -}); (function() { +; (function() { window.require(["ace/snippets/curly"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/d.js b/htdocs/includes/ace/src/snippets/d.js index 117da84d0eb..18257d4f6c6 100644 --- a/htdocs/includes/ace/src/snippets/d.js +++ b/htdocs/includes/ace/src/snippets/d.js @@ -1,10 +1,5 @@ -define("ace/snippets/d",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "d"; - -}); (function() { +; (function() { window.require(["ace/snippets/d"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/dockerfile.js b/htdocs/includes/ace/src/snippets/dockerfile.js index 6ebfb397359..cd5d4182f1a 100644 --- a/htdocs/includes/ace/src/snippets/dockerfile.js +++ b/htdocs/includes/ace/src/snippets/dockerfile.js @@ -1,10 +1,5 @@ -define("ace/snippets/dockerfile",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "dockerfile"; - -}); (function() { +; (function() { window.require(["ace/snippets/dockerfile"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/dot.js b/htdocs/includes/ace/src/snippets/dot.js index 0af0a491752..aec363b01d6 100644 --- a/htdocs/includes/ace/src/snippets/dot.js +++ b/htdocs/includes/ace/src/snippets/dot.js @@ -1,10 +1,5 @@ -define("ace/snippets/dot",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "dot"; - -}); (function() { +; (function() { window.require(["ace/snippets/dot"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/eiffel.js b/htdocs/includes/ace/src/snippets/eiffel.js index bc6a66a93b3..60a36440f0d 100644 --- a/htdocs/includes/ace/src/snippets/eiffel.js +++ b/htdocs/includes/ace/src/snippets/eiffel.js @@ -1,10 +1,5 @@ -define("ace/snippets/eiffel",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "eiffel"; - -}); (function() { +; (function() { window.require(["ace/snippets/eiffel"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/ejs.js b/htdocs/includes/ace/src/snippets/ejs.js index 83368d91ee0..3e0f355e747 100644 --- a/htdocs/includes/ace/src/snippets/ejs.js +++ b/htdocs/includes/ace/src/snippets/ejs.js @@ -1,10 +1,5 @@ -define("ace/snippets/ejs",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "ejs"; - -}); (function() { +; (function() { window.require(["ace/snippets/ejs"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/elixir.js b/htdocs/includes/ace/src/snippets/elixir.js index 8ddaf1c4495..f408337980b 100644 --- a/htdocs/includes/ace/src/snippets/elixir.js +++ b/htdocs/includes/ace/src/snippets/elixir.js @@ -1,10 +1,5 @@ -define("ace/snippets/elixir",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/elixir"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/elm.js b/htdocs/includes/ace/src/snippets/elm.js index 71d7a7e15b0..c1122649f1b 100644 --- a/htdocs/includes/ace/src/snippets/elm.js +++ b/htdocs/includes/ace/src/snippets/elm.js @@ -1,10 +1,5 @@ -define("ace/snippets/elm",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "elm"; - -}); (function() { +; (function() { window.require(["ace/snippets/elm"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/forth.js b/htdocs/includes/ace/src/snippets/forth.js index 0861c05f3e9..a7a0c053f63 100644 --- a/htdocs/includes/ace/src/snippets/forth.js +++ b/htdocs/includes/ace/src/snippets/forth.js @@ -1,10 +1,5 @@ -define("ace/snippets/forth",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "forth"; - -}); (function() { +; (function() { window.require(["ace/snippets/forth"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/fortran.js b/htdocs/includes/ace/src/snippets/fortran.js index 69bffe8f2aa..ec3ae4e6457 100644 --- a/htdocs/includes/ace/src/snippets/fortran.js +++ b/htdocs/includes/ace/src/snippets/fortran.js @@ -1,10 +1,5 @@ -define("ace/snippets/fortran",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "fortran"; - -}); (function() { +; (function() { window.require(["ace/snippets/fortran"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/fsharp.js b/htdocs/includes/ace/src/snippets/fsharp.js index bbc8eb65b5e..dfe6a1391e1 100644 --- a/htdocs/includes/ace/src/snippets/fsharp.js +++ b/htdocs/includes/ace/src/snippets/fsharp.js @@ -1,10 +1,5 @@ -define("ace/snippets/fsharp",["require","exports","module"], function(require, exports, module) { - "use strict"; - exports.snippetText =undefined; - exports.scope = "fsharp"; - -}); (function() { +; (function() { window.require(["ace/snippets/fsharp"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/ftl.js b/htdocs/includes/ace/src/snippets/ftl.js index 7b7cb67948e..aa9f0e0bbfc 100644 --- a/htdocs/includes/ace/src/snippets/ftl.js +++ b/htdocs/includes/ace/src/snippets/ftl.js @@ -1,10 +1,5 @@ -define("ace/snippets/ftl",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "ftl"; - -}); (function() { +; (function() { window.require(["ace/snippets/ftl"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/gcode.js b/htdocs/includes/ace/src/snippets/gcode.js index b44f1656ce3..d85b1b4838b 100644 --- a/htdocs/includes/ace/src/snippets/gcode.js +++ b/htdocs/includes/ace/src/snippets/gcode.js @@ -1,10 +1,5 @@ -define("ace/snippets/gcode",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "gcode"; - -}); (function() { +; (function() { window.require(["ace/snippets/gcode"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/gherkin.js b/htdocs/includes/ace/src/snippets/gherkin.js index 8986e377a7d..11c54661bdc 100644 --- a/htdocs/includes/ace/src/snippets/gherkin.js +++ b/htdocs/includes/ace/src/snippets/gherkin.js @@ -1,10 +1,5 @@ -define("ace/snippets/gherkin",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "gherkin"; - -}); (function() { +; (function() { window.require(["ace/snippets/gherkin"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/gitignore.js b/htdocs/includes/ace/src/snippets/gitignore.js index aea0fb0df9a..a6af8361d76 100644 --- a/htdocs/includes/ace/src/snippets/gitignore.js +++ b/htdocs/includes/ace/src/snippets/gitignore.js @@ -1,10 +1,5 @@ -define("ace/snippets/gitignore",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "gitignore"; - -}); (function() { +; (function() { window.require(["ace/snippets/gitignore"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/glsl.js b/htdocs/includes/ace/src/snippets/glsl.js index f638fbc6eac..bdea4bfaa64 100644 --- a/htdocs/includes/ace/src/snippets/glsl.js +++ b/htdocs/includes/ace/src/snippets/glsl.js @@ -1,10 +1,5 @@ -define("ace/snippets/glsl",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "glsl"; - -}); (function() { +; (function() { window.require(["ace/snippets/glsl"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/golang.js b/htdocs/includes/ace/src/snippets/golang.js index b16e805474f..18a9f97b64c 100644 --- a/htdocs/includes/ace/src/snippets/golang.js +++ b/htdocs/includes/ace/src/snippets/golang.js @@ -1,10 +1,5 @@ -define("ace/snippets/golang",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "golang"; - -}); (function() { +; (function() { window.require(["ace/snippets/golang"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/groovy.js b/htdocs/includes/ace/src/snippets/groovy.js index 56091acbccd..72f2f32ecb1 100644 --- a/htdocs/includes/ace/src/snippets/groovy.js +++ b/htdocs/includes/ace/src/snippets/groovy.js @@ -1,10 +1,5 @@ -define("ace/snippets/groovy",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "groovy"; - -}); (function() { +; (function() { window.require(["ace/snippets/groovy"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/handlebars.js b/htdocs/includes/ace/src/snippets/handlebars.js index ca8b6354867..2eaf61de444 100644 --- a/htdocs/includes/ace/src/snippets/handlebars.js +++ b/htdocs/includes/ace/src/snippets/handlebars.js @@ -1,10 +1,5 @@ -define("ace/snippets/handlebars",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "handlebars"; - -}); (function() { +; (function() { window.require(["ace/snippets/handlebars"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/haskell_cabal.js b/htdocs/includes/ace/src/snippets/haskell_cabal.js index 471feb12baa..1a90a9cbf97 100644 --- a/htdocs/includes/ace/src/snippets/haskell_cabal.js +++ b/htdocs/includes/ace/src/snippets/haskell_cabal.js @@ -1,10 +1,5 @@ -define("ace/snippets/haskell_cabal",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "haskell_cabal"; - -}); (function() { +; (function() { window.require(["ace/snippets/haskell_cabal"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/haxe.js b/htdocs/includes/ace/src/snippets/haxe.js index 8feed8d150c..b1f2dbe6c37 100644 --- a/htdocs/includes/ace/src/snippets/haxe.js +++ b/htdocs/includes/ace/src/snippets/haxe.js @@ -1,10 +1,5 @@ -define("ace/snippets/haxe",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "haxe"; - -}); (function() { +; (function() { window.require(["ace/snippets/haxe"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/hjson.js b/htdocs/includes/ace/src/snippets/hjson.js index 79be57d0cf3..96938d67d7a 100644 --- a/htdocs/includes/ace/src/snippets/hjson.js +++ b/htdocs/includes/ace/src/snippets/hjson.js @@ -1,10 +1,5 @@ -define("ace/snippets/hjson",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/hjson"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/html.js b/htdocs/includes/ace/src/snippets/html.js index 975496c1b49..885d2a2d64f 100644 --- a/htdocs/includes/ace/src/snippets/html.js +++ b/htdocs/includes/ace/src/snippets/html.js @@ -237,9 +237,7 @@ snippet button:s\n\ snippet button:r\n\ \n\ snippet canvas\n\ - \n\ - ${1}\n\ - \n\ + \n\ snippet caption\n\ ${1}\n\ snippet cite\n\ @@ -853,7 +851,7 @@ snippet ul+\n\ snippet var\n\ ${1}\n\ snippet video\n\ - ${8}\n\ + ${8}\n\ snippet wbr\n\ ${1}\n\ "; diff --git a/htdocs/includes/ace/src/snippets/html_elixir.js b/htdocs/includes/ace/src/snippets/html_elixir.js index c8521b55ca8..0db3e076f71 100644 --- a/htdocs/includes/ace/src/snippets/html_elixir.js +++ b/htdocs/includes/ace/src/snippets/html_elixir.js @@ -1,10 +1,5 @@ -define("ace/snippets/html_elixir",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "html_elixir"; - -}); (function() { +; (function() { window.require(["ace/snippets/html_elixir"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/html_ruby.js b/htdocs/includes/ace/src/snippets/html_ruby.js index ba20e65e72d..5d4499743c0 100644 --- a/htdocs/includes/ace/src/snippets/html_ruby.js +++ b/htdocs/includes/ace/src/snippets/html_ruby.js @@ -1,10 +1,5 @@ -define("ace/snippets/html_ruby",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "html_ruby"; - -}); (function() { +; (function() { window.require(["ace/snippets/html_ruby"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/ini.js b/htdocs/includes/ace/src/snippets/ini.js index 07200fda5b7..f31743c5b0d 100644 --- a/htdocs/includes/ace/src/snippets/ini.js +++ b/htdocs/includes/ace/src/snippets/ini.js @@ -1,10 +1,5 @@ -define("ace/snippets/ini",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "ini"; - -}); (function() { +; (function() { window.require(["ace/snippets/ini"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/jack.js b/htdocs/includes/ace/src/snippets/jack.js index 2688a3a1011..fc242d3c2a6 100644 --- a/htdocs/includes/ace/src/snippets/jack.js +++ b/htdocs/includes/ace/src/snippets/jack.js @@ -1,10 +1,5 @@ -define("ace/snippets/jack",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "jack"; - -}); (function() { +; (function() { window.require(["ace/snippets/jack"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/jade.js b/htdocs/includes/ace/src/snippets/jade.js index 6a4676b883d..1a1c1c25e37 100644 --- a/htdocs/includes/ace/src/snippets/jade.js +++ b/htdocs/includes/ace/src/snippets/jade.js @@ -1,10 +1,5 @@ -define("ace/snippets/jade",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "jade"; - -}); (function() { +; (function() { window.require(["ace/snippets/jade"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/json.js b/htdocs/includes/ace/src/snippets/json.js index 7c9c2eaf295..f1c015c4264 100644 --- a/htdocs/includes/ace/src/snippets/json.js +++ b/htdocs/includes/ace/src/snippets/json.js @@ -1,10 +1,5 @@ -define("ace/snippets/json",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "json"; - -}); (function() { +; (function() { window.require(["ace/snippets/json"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/json5.js b/htdocs/includes/ace/src/snippets/json5.js index 8afbead737d..4ae9f4b7b1f 100644 --- a/htdocs/includes/ace/src/snippets/json5.js +++ b/htdocs/includes/ace/src/snippets/json5.js @@ -1,10 +1,5 @@ -define("ace/snippets/json5",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "json5"; - -}); (function() { +; (function() { window.require(["ace/snippets/json5"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/jssm.js b/htdocs/includes/ace/src/snippets/jssm.js index fceb11ddfe9..2fcea71ccf0 100644 --- a/htdocs/includes/ace/src/snippets/jssm.js +++ b/htdocs/includes/ace/src/snippets/jssm.js @@ -1,10 +1,5 @@ -define("ace/snippets/jssm",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/jssm"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/jsx.js b/htdocs/includes/ace/src/snippets/jsx.js index 38f276f80a2..b26a3586bbb 100644 --- a/htdocs/includes/ace/src/snippets/jsx.js +++ b/htdocs/includes/ace/src/snippets/jsx.js @@ -1,10 +1,5 @@ -define("ace/snippets/jsx",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "jsx"; - -}); (function() { +; (function() { window.require(["ace/snippets/jsx"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/julia.js b/htdocs/includes/ace/src/snippets/julia.js index 360f7c3d200..30a74650766 100644 --- a/htdocs/includes/ace/src/snippets/julia.js +++ b/htdocs/includes/ace/src/snippets/julia.js @@ -1,10 +1,5 @@ -define("ace/snippets/julia",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "julia"; - -}); (function() { +; (function() { window.require(["ace/snippets/julia"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/kotlin.js b/htdocs/includes/ace/src/snippets/kotlin.js index b2e3d3cbb52..c9e543c7d58 100644 --- a/htdocs/includes/ace/src/snippets/kotlin.js +++ b/htdocs/includes/ace/src/snippets/kotlin.js @@ -1,10 +1,5 @@ -define("ace/snippets/kotlin",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/kotlin"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/latex.js b/htdocs/includes/ace/src/snippets/latex.js index 6afc3775b98..711a30b780f 100644 --- a/htdocs/includes/ace/src/snippets/latex.js +++ b/htdocs/includes/ace/src/snippets/latex.js @@ -1,10 +1,5 @@ -define("ace/snippets/latex",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "latex"; - -}); (function() { +; (function() { window.require(["ace/snippets/latex"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/latte.js b/htdocs/includes/ace/src/snippets/latte.js new file mode 100644 index 00000000000..d5c341ce881 --- /dev/null +++ b/htdocs/includes/ace/src/snippets/latte.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/latte"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/less.js b/htdocs/includes/ace/src/snippets/less.js index a87b47b185c..2b4c6b3b469 100644 --- a/htdocs/includes/ace/src/snippets/less.js +++ b/htdocs/includes/ace/src/snippets/less.js @@ -1,10 +1,5 @@ -define("ace/snippets/less",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "less"; - -}); (function() { +; (function() { window.require(["ace/snippets/less"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/lisp.js b/htdocs/includes/ace/src/snippets/lisp.js index f6c13860ec9..a971e2131e5 100644 --- a/htdocs/includes/ace/src/snippets/lisp.js +++ b/htdocs/includes/ace/src/snippets/lisp.js @@ -1,10 +1,5 @@ -define("ace/snippets/lisp",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "lisp"; - -}); (function() { +; (function() { window.require(["ace/snippets/lisp"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/livescript.js b/htdocs/includes/ace/src/snippets/livescript.js index 08b6cb107d6..ed4b397ac34 100644 --- a/htdocs/includes/ace/src/snippets/livescript.js +++ b/htdocs/includes/ace/src/snippets/livescript.js @@ -1,10 +1,5 @@ -define("ace/snippets/livescript",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "livescript"; - -}); (function() { +; (function() { window.require(["ace/snippets/livescript"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/logiql.js b/htdocs/includes/ace/src/snippets/logiql.js index 073da94b692..d0fea2bdae5 100644 --- a/htdocs/includes/ace/src/snippets/logiql.js +++ b/htdocs/includes/ace/src/snippets/logiql.js @@ -1,10 +1,5 @@ -define("ace/snippets/logiql",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "logiql"; - -}); (function() { +; (function() { window.require(["ace/snippets/logiql"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/logtalk.js b/htdocs/includes/ace/src/snippets/logtalk.js index 4ab4f1f9e8c..4ae82ed92b1 100644 --- a/htdocs/includes/ace/src/snippets/logtalk.js +++ b/htdocs/includes/ace/src/snippets/logtalk.js @@ -1,10 +1,5 @@ -define("ace/snippets/logtalk",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "logtalk"; - -}); (function() { +; (function() { window.require(["ace/snippets/logtalk"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/luapage.js b/htdocs/includes/ace/src/snippets/luapage.js index 8f52b58fc01..db7de782348 100644 --- a/htdocs/includes/ace/src/snippets/luapage.js +++ b/htdocs/includes/ace/src/snippets/luapage.js @@ -1,10 +1,5 @@ -define("ace/snippets/luapage",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "luapage"; - -}); (function() { +; (function() { window.require(["ace/snippets/luapage"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/lucene.js b/htdocs/includes/ace/src/snippets/lucene.js index c61509bea79..bb248e9c4b2 100644 --- a/htdocs/includes/ace/src/snippets/lucene.js +++ b/htdocs/includes/ace/src/snippets/lucene.js @@ -1,10 +1,5 @@ -define("ace/snippets/lucene",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "lucene"; - -}); (function() { +; (function() { window.require(["ace/snippets/lucene"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/mask.js b/htdocs/includes/ace/src/snippets/mask.js index 1b9c0c56dc2..f63c0a61b6d 100644 --- a/htdocs/includes/ace/src/snippets/mask.js +++ b/htdocs/includes/ace/src/snippets/mask.js @@ -1,10 +1,5 @@ -define("ace/snippets/mask",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "mask"; - -}); (function() { +; (function() { window.require(["ace/snippets/mask"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/matlab.js b/htdocs/includes/ace/src/snippets/matlab.js index d8fcd2bd071..cc5fb70e7a5 100644 --- a/htdocs/includes/ace/src/snippets/matlab.js +++ b/htdocs/includes/ace/src/snippets/matlab.js @@ -1,10 +1,5 @@ -define("ace/snippets/matlab",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "matlab"; - -}); (function() { +; (function() { window.require(["ace/snippets/matlab"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/mediawiki.js b/htdocs/includes/ace/src/snippets/mediawiki.js new file mode 100644 index 00000000000..bd73d00064b --- /dev/null +++ b/htdocs/includes/ace/src/snippets/mediawiki.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/mediawiki"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/mel.js b/htdocs/includes/ace/src/snippets/mel.js index 4e43ab1be3f..fa5ecbc8985 100644 --- a/htdocs/includes/ace/src/snippets/mel.js +++ b/htdocs/includes/ace/src/snippets/mel.js @@ -1,10 +1,5 @@ -define("ace/snippets/mel",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "mel"; - -}); (function() { +; (function() { window.require(["ace/snippets/mel"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/mips.js b/htdocs/includes/ace/src/snippets/mips.js new file mode 100644 index 00000000000..9badca8efcf --- /dev/null +++ b/htdocs/includes/ace/src/snippets/mips.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/mips"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/mixal.js b/htdocs/includes/ace/src/snippets/mixal.js index 60b08ea8f52..8246ef784c3 100644 --- a/htdocs/includes/ace/src/snippets/mixal.js +++ b/htdocs/includes/ace/src/snippets/mixal.js @@ -1,10 +1,5 @@ -define("ace/snippets/mixal",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "mixal"; - -}); (function() { +; (function() { window.require(["ace/snippets/mixal"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/mushcode.js b/htdocs/includes/ace/src/snippets/mushcode.js index 1ff99c4abae..8eddd370b3d 100644 --- a/htdocs/includes/ace/src/snippets/mushcode.js +++ b/htdocs/includes/ace/src/snippets/mushcode.js @@ -1,10 +1,5 @@ -define("ace/snippets/mushcode",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "mushcode"; - -}); (function() { +; (function() { window.require(["ace/snippets/mushcode"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/mysql.js b/htdocs/includes/ace/src/snippets/mysql.js index 2791c37f87a..d8544a1b7a8 100644 --- a/htdocs/includes/ace/src/snippets/mysql.js +++ b/htdocs/includes/ace/src/snippets/mysql.js @@ -1,10 +1,5 @@ -define("ace/snippets/mysql",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "mysql"; - -}); (function() { +; (function() { window.require(["ace/snippets/mysql"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/nginx.js b/htdocs/includes/ace/src/snippets/nginx.js index 4305b2cae3e..565e3b8a6ce 100644 --- a/htdocs/includes/ace/src/snippets/nginx.js +++ b/htdocs/includes/ace/src/snippets/nginx.js @@ -1,10 +1,5 @@ -define("ace/snippets/nginx",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "nginx"; - -}); (function() { +; (function() { window.require(["ace/snippets/nginx"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/nim.js b/htdocs/includes/ace/src/snippets/nim.js index f73018ce124..b3b4dfc0489 100644 --- a/htdocs/includes/ace/src/snippets/nim.js +++ b/htdocs/includes/ace/src/snippets/nim.js @@ -1,10 +1,5 @@ -define("ace/snippets/nim",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "nim"; - -}); (function() { +; (function() { window.require(["ace/snippets/nim"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/nix.js b/htdocs/includes/ace/src/snippets/nix.js index c7d9035a6d3..bc63bd3d5ce 100644 --- a/htdocs/includes/ace/src/snippets/nix.js +++ b/htdocs/includes/ace/src/snippets/nix.js @@ -1,10 +1,5 @@ -define("ace/snippets/nix",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "nix"; - -}); (function() { +; (function() { window.require(["ace/snippets/nix"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/nsis.js b/htdocs/includes/ace/src/snippets/nsis.js index 423a1a8b336..caf0839d1af 100644 --- a/htdocs/includes/ace/src/snippets/nsis.js +++ b/htdocs/includes/ace/src/snippets/nsis.js @@ -1,10 +1,5 @@ -define("ace/snippets/nsis",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/nsis"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/nunjucks.js b/htdocs/includes/ace/src/snippets/nunjucks.js index 961adec5778..748d2d9ffc4 100644 --- a/htdocs/includes/ace/src/snippets/nunjucks.js +++ b/htdocs/includes/ace/src/snippets/nunjucks.js @@ -1,10 +1,5 @@ -define("ace/snippets/nunjucks",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "nunjucks"; - -}); (function() { +; (function() { window.require(["ace/snippets/nunjucks"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/objectivec.js b/htdocs/includes/ace/src/snippets/objectivec.js index 32816f0b2a1..77bad68f2c2 100644 --- a/htdocs/includes/ace/src/snippets/objectivec.js +++ b/htdocs/includes/ace/src/snippets/objectivec.js @@ -1,10 +1,5 @@ -define("ace/snippets/objectivec",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "objectivec"; - -}); (function() { +; (function() { window.require(["ace/snippets/objectivec"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/ocaml.js b/htdocs/includes/ace/src/snippets/ocaml.js index 2d1f07a0043..23789d1ec6f 100644 --- a/htdocs/includes/ace/src/snippets/ocaml.js +++ b/htdocs/includes/ace/src/snippets/ocaml.js @@ -1,10 +1,5 @@ -define("ace/snippets/ocaml",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "ocaml"; - -}); (function() { +; (function() { window.require(["ace/snippets/ocaml"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/pascal.js b/htdocs/includes/ace/src/snippets/pascal.js index 296a7565525..f6d60d88ec4 100644 --- a/htdocs/includes/ace/src/snippets/pascal.js +++ b/htdocs/includes/ace/src/snippets/pascal.js @@ -1,10 +1,5 @@ -define("ace/snippets/pascal",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "pascal"; - -}); (function() { +; (function() { window.require(["ace/snippets/pascal"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/perl6.js b/htdocs/includes/ace/src/snippets/perl6.js deleted file mode 100644 index 90ecfbe0c82..00000000000 --- a/htdocs/includes/ace/src/snippets/perl6.js +++ /dev/null @@ -1,14 +0,0 @@ -define("ace/snippets/perl6",["require","exports","module"], function(require, exports, module) { -"use strict"; - -exports.snippetText =undefined; -exports.scope = "perl6"; - -}); (function() { - window.require(["ace/snippets/perl6"], function(m) { - if (typeof module == "object" && typeof exports == "object" && module) { - module.exports = m; - } - }); - })(); - \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/pgsql.js b/htdocs/includes/ace/src/snippets/pgsql.js index b8b45fb8acb..c15cb260ae6 100644 --- a/htdocs/includes/ace/src/snippets/pgsql.js +++ b/htdocs/includes/ace/src/snippets/pgsql.js @@ -1,10 +1,5 @@ -define("ace/snippets/pgsql",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "pgsql"; - -}); (function() { +; (function() { window.require(["ace/snippets/pgsql"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/php_laravel_blade.js b/htdocs/includes/ace/src/snippets/php_laravel_blade.js index 9a722c9b371..d4790ba2852 100644 --- a/htdocs/includes/ace/src/snippets/php_laravel_blade.js +++ b/htdocs/includes/ace/src/snippets/php_laravel_blade.js @@ -1,10 +1,5 @@ -define("ace/snippets/php_laravel_blade",["require","exports","module"], function(require, exports, module) { - "use strict"; - exports.snippetText =undefined; - exports.scope = "php"; - -}); (function() { +; (function() { window.require(["ace/snippets/php_laravel_blade"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/pig.js b/htdocs/includes/ace/src/snippets/pig.js index 94d46c7cc7f..157d1921126 100644 --- a/htdocs/includes/ace/src/snippets/pig.js +++ b/htdocs/includes/ace/src/snippets/pig.js @@ -1,10 +1,5 @@ -define("ace/snippets/pig",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "pig"; - -}); (function() { +; (function() { window.require(["ace/snippets/pig"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/plain_text.js b/htdocs/includes/ace/src/snippets/plain_text.js index 988880c9c97..92dfce5cd7b 100644 --- a/htdocs/includes/ace/src/snippets/plain_text.js +++ b/htdocs/includes/ace/src/snippets/plain_text.js @@ -1,10 +1,5 @@ -define("ace/snippets/plain_text",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "plain_text"; - -}); (function() { +; (function() { window.require(["ace/snippets/plain_text"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/powershell.js b/htdocs/includes/ace/src/snippets/powershell.js index 4d8388a81ea..0f36eededab 100644 --- a/htdocs/includes/ace/src/snippets/powershell.js +++ b/htdocs/includes/ace/src/snippets/powershell.js @@ -1,10 +1,5 @@ -define("ace/snippets/powershell",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "powershell"; - -}); (function() { +; (function() { window.require(["ace/snippets/powershell"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/praat.js b/htdocs/includes/ace/src/snippets/praat.js index 75fa2e423e5..e4e734fc77b 100644 --- a/htdocs/includes/ace/src/snippets/praat.js +++ b/htdocs/includes/ace/src/snippets/praat.js @@ -1,10 +1,5 @@ -define("ace/snippets/praat",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "praat"; - -}); (function() { +; (function() { window.require(["ace/snippets/praat"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/prisma.js b/htdocs/includes/ace/src/snippets/prisma.js new file mode 100644 index 00000000000..4a9e2b3e3e6 --- /dev/null +++ b/htdocs/includes/ace/src/snippets/prisma.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/prisma"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/prolog.js b/htdocs/includes/ace/src/snippets/prolog.js index 9147ec6dfaf..4c23dac3852 100644 --- a/htdocs/includes/ace/src/snippets/prolog.js +++ b/htdocs/includes/ace/src/snippets/prolog.js @@ -1,10 +1,5 @@ -define("ace/snippets/prolog",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "prolog"; - -}); (function() { +; (function() { window.require(["ace/snippets/prolog"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/properties.js b/htdocs/includes/ace/src/snippets/properties.js index 1ef5ff3e732..36c01dcb83e 100644 --- a/htdocs/includes/ace/src/snippets/properties.js +++ b/htdocs/includes/ace/src/snippets/properties.js @@ -1,10 +1,5 @@ -define("ace/snippets/properties",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "properties"; - -}); (function() { +; (function() { window.require(["ace/snippets/properties"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/protobuf.js b/htdocs/includes/ace/src/snippets/protobuf.js index 98f00415c7e..b169bbfc539 100644 --- a/htdocs/includes/ace/src/snippets/protobuf.js +++ b/htdocs/includes/ace/src/snippets/protobuf.js @@ -1,10 +1,5 @@ -define("ace/snippets/protobuf",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText = ""; -exports.scope = "protobuf"; - -}); (function() { +; (function() { window.require(["ace/snippets/protobuf"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/puppet.js b/htdocs/includes/ace/src/snippets/puppet.js index 5c7b31650a3..52021e3a5a5 100644 --- a/htdocs/includes/ace/src/snippets/puppet.js +++ b/htdocs/includes/ace/src/snippets/puppet.js @@ -1,10 +1,5 @@ -define("ace/snippets/puppet",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "puppet"; - -}); (function() { +; (function() { window.require(["ace/snippets/puppet"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/qml.js b/htdocs/includes/ace/src/snippets/qml.js new file mode 100644 index 00000000000..cb4f66ede73 --- /dev/null +++ b/htdocs/includes/ace/src/snippets/qml.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/qml"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/raku.js b/htdocs/includes/ace/src/snippets/raku.js new file mode 100644 index 00000000000..8beaf95dc05 --- /dev/null +++ b/htdocs/includes/ace/src/snippets/raku.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/raku"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/rdoc.js b/htdocs/includes/ace/src/snippets/rdoc.js index f4dc8927f84..e4845db4c67 100644 --- a/htdocs/includes/ace/src/snippets/rdoc.js +++ b/htdocs/includes/ace/src/snippets/rdoc.js @@ -1,10 +1,5 @@ -define("ace/snippets/rdoc",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "rdoc"; - -}); (function() { +; (function() { window.require(["ace/snippets/rdoc"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/red.js b/htdocs/includes/ace/src/snippets/red.js index 900634e691e..80cbd1b55af 100644 --- a/htdocs/includes/ace/src/snippets/red.js +++ b/htdocs/includes/ace/src/snippets/red.js @@ -1,10 +1,5 @@ -define("ace/snippets/red",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText = " "; -exports.scope = "red"; - -}); (function() { +; (function() { window.require(["ace/snippets/red"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/redshift.js b/htdocs/includes/ace/src/snippets/redshift.js index 088f0febf03..bedd1473317 100644 --- a/htdocs/includes/ace/src/snippets/redshift.js +++ b/htdocs/includes/ace/src/snippets/redshift.js @@ -1,10 +1,5 @@ -define("ace/snippets/redshift",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "redshift"; - -}); (function() { +; (function() { window.require(["ace/snippets/redshift"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/rhtml.js b/htdocs/includes/ace/src/snippets/rhtml.js index e31ed6f8e92..7eb8a5eba86 100644 --- a/htdocs/includes/ace/src/snippets/rhtml.js +++ b/htdocs/includes/ace/src/snippets/rhtml.js @@ -1,10 +1,5 @@ -define("ace/snippets/rhtml",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "rhtml"; - -}); (function() { +; (function() { window.require(["ace/snippets/rhtml"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/rust.js b/htdocs/includes/ace/src/snippets/rust.js index 9ee8633e254..63d42815a5d 100644 --- a/htdocs/includes/ace/src/snippets/rust.js +++ b/htdocs/includes/ace/src/snippets/rust.js @@ -1,10 +1,5 @@ -define("ace/snippets/rust",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "rust"; - -}); (function() { +; (function() { window.require(["ace/snippets/rust"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/sass.js b/htdocs/includes/ace/src/snippets/sass.js index 684485dd0ee..0a4de9b4442 100644 --- a/htdocs/includes/ace/src/snippets/sass.js +++ b/htdocs/includes/ace/src/snippets/sass.js @@ -1,10 +1,5 @@ -define("ace/snippets/sass",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "sass"; - -}); (function() { +; (function() { window.require(["ace/snippets/sass"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/scad.js b/htdocs/includes/ace/src/snippets/scad.js index 4d7eec20085..2fb0826416f 100644 --- a/htdocs/includes/ace/src/snippets/scad.js +++ b/htdocs/includes/ace/src/snippets/scad.js @@ -1,10 +1,5 @@ -define("ace/snippets/scad",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "scad"; - -}); (function() { +; (function() { window.require(["ace/snippets/scad"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/scala.js b/htdocs/includes/ace/src/snippets/scala.js index 03eb329e7a4..adc0abbd496 100644 --- a/htdocs/includes/ace/src/snippets/scala.js +++ b/htdocs/includes/ace/src/snippets/scala.js @@ -1,10 +1,5 @@ -define("ace/snippets/scala",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "scala"; - -}); (function() { +; (function() { window.require(["ace/snippets/scala"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/scheme.js b/htdocs/includes/ace/src/snippets/scheme.js index 0f0906f147f..29c3d357914 100644 --- a/htdocs/includes/ace/src/snippets/scheme.js +++ b/htdocs/includes/ace/src/snippets/scheme.js @@ -1,10 +1,5 @@ -define("ace/snippets/scheme",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "scheme"; - -}); (function() { +; (function() { window.require(["ace/snippets/scheme"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/scrypt.js b/htdocs/includes/ace/src/snippets/scrypt.js new file mode 100644 index 00000000000..2d0601a1046 --- /dev/null +++ b/htdocs/includes/ace/src/snippets/scrypt.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/scrypt"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/scss.js b/htdocs/includes/ace/src/snippets/scss.js index 8e636cea79c..6e808dea9f3 100644 --- a/htdocs/includes/ace/src/snippets/scss.js +++ b/htdocs/includes/ace/src/snippets/scss.js @@ -1,10 +1,5 @@ -define("ace/snippets/scss",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "scss"; - -}); (function() { +; (function() { window.require(["ace/snippets/scss"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/sjs.js b/htdocs/includes/ace/src/snippets/sjs.js index a0756ae154d..bc8c1872023 100644 --- a/htdocs/includes/ace/src/snippets/sjs.js +++ b/htdocs/includes/ace/src/snippets/sjs.js @@ -1,10 +1,5 @@ -define("ace/snippets/sjs",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "sjs"; - -}); (function() { +; (function() { window.require(["ace/snippets/sjs"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/slim.js b/htdocs/includes/ace/src/snippets/slim.js index 7b159a94d6a..2fcd039ac1c 100644 --- a/htdocs/includes/ace/src/snippets/slim.js +++ b/htdocs/includes/ace/src/snippets/slim.js @@ -1,10 +1,5 @@ -define("ace/snippets/slim",["require","exports","module"], function(require, exports, module) { - "use strict"; - exports.snippetText =undefined; - exports.scope = "slim"; - -}); (function() { +; (function() { window.require(["ace/snippets/slim"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/smarty.js b/htdocs/includes/ace/src/snippets/smarty.js index 84c3d8eee1c..3affd2eac6e 100644 --- a/htdocs/includes/ace/src/snippets/smarty.js +++ b/htdocs/includes/ace/src/snippets/smarty.js @@ -1,10 +1,5 @@ -define("ace/snippets/smarty",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "smarty"; - -}); (function() { +; (function() { window.require(["ace/snippets/smarty"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/smithy.js b/htdocs/includes/ace/src/snippets/smithy.js new file mode 100644 index 00000000000..4077f9eeeaa --- /dev/null +++ b/htdocs/includes/ace/src/snippets/smithy.js @@ -0,0 +1,9 @@ + +; (function() { + window.require(["ace/snippets/smithy"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/snippets/soy_template.js b/htdocs/includes/ace/src/snippets/soy_template.js index d087ef1d21a..c7409658633 100644 --- a/htdocs/includes/ace/src/snippets/soy_template.js +++ b/htdocs/includes/ace/src/snippets/soy_template.js @@ -1,10 +1,5 @@ -define("ace/snippets/soy_template",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "soy_template"; - -}); (function() { +; (function() { window.require(["ace/snippets/soy_template"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/space.js b/htdocs/includes/ace/src/snippets/space.js index ae87ec48d82..8f485977088 100644 --- a/htdocs/includes/ace/src/snippets/space.js +++ b/htdocs/includes/ace/src/snippets/space.js @@ -1,10 +1,5 @@ -define("ace/snippets/space",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "space"; - -}); (function() { +; (function() { window.require(["ace/snippets/space"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/sparql.js b/htdocs/includes/ace/src/snippets/sparql.js index e021a74fb94..fe60397edb4 100644 --- a/htdocs/includes/ace/src/snippets/sparql.js +++ b/htdocs/includes/ace/src/snippets/sparql.js @@ -1,10 +1,5 @@ -define("ace/snippets/sparql",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/sparql"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/stylus.js b/htdocs/includes/ace/src/snippets/stylus.js index 0172b391622..34f1d714119 100644 --- a/htdocs/includes/ace/src/snippets/stylus.js +++ b/htdocs/includes/ace/src/snippets/stylus.js @@ -1,10 +1,5 @@ -define("ace/snippets/stylus",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "stylus"; - -}); (function() { +; (function() { window.require(["ace/snippets/stylus"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/svg.js b/htdocs/includes/ace/src/snippets/svg.js index 9f63d38fa3b..1aa4a8502e7 100644 --- a/htdocs/includes/ace/src/snippets/svg.js +++ b/htdocs/includes/ace/src/snippets/svg.js @@ -1,10 +1,5 @@ -define("ace/snippets/svg",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "svg"; - -}); (function() { +; (function() { window.require(["ace/snippets/svg"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/swift.js b/htdocs/includes/ace/src/snippets/swift.js index 8b510938dd3..143e32b7acd 100644 --- a/htdocs/includes/ace/src/snippets/swift.js +++ b/htdocs/includes/ace/src/snippets/swift.js @@ -1,10 +1,5 @@ -define("ace/snippets/swift",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "swift"; - -}); (function() { +; (function() { window.require(["ace/snippets/swift"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/terraform.js b/htdocs/includes/ace/src/snippets/terraform.js index 7e0593733b5..c9d8d31d601 100644 --- a/htdocs/includes/ace/src/snippets/terraform.js +++ b/htdocs/includes/ace/src/snippets/terraform.js @@ -1,10 +1,5 @@ -define("ace/snippets/terraform",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "terraform"; - -}); (function() { +; (function() { window.require(["ace/snippets/terraform"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/text.js b/htdocs/includes/ace/src/snippets/text.js index 949bb2a72dd..85b4d10e5f7 100644 --- a/htdocs/includes/ace/src/snippets/text.js +++ b/htdocs/includes/ace/src/snippets/text.js @@ -1,10 +1,5 @@ -define("ace/snippets/text",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "text"; - -}); (function() { +; (function() { window.require(["ace/snippets/text"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/toml.js b/htdocs/includes/ace/src/snippets/toml.js index 4f0c1fa463f..e585672c285 100644 --- a/htdocs/includes/ace/src/snippets/toml.js +++ b/htdocs/includes/ace/src/snippets/toml.js @@ -1,10 +1,5 @@ -define("ace/snippets/toml",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "toml"; - -}); (function() { +; (function() { window.require(["ace/snippets/toml"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/tsx.js b/htdocs/includes/ace/src/snippets/tsx.js index fd1bba27203..f0456fdd9a1 100644 --- a/htdocs/includes/ace/src/snippets/tsx.js +++ b/htdocs/includes/ace/src/snippets/tsx.js @@ -1,10 +1,5 @@ -define("ace/snippets/tsx",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "tsx"; - -}); (function() { +; (function() { window.require(["ace/snippets/tsx"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/turtle.js b/htdocs/includes/ace/src/snippets/turtle.js index c6bc21bfa50..7e0a30cec5b 100644 --- a/htdocs/includes/ace/src/snippets/turtle.js +++ b/htdocs/includes/ace/src/snippets/turtle.js @@ -1,10 +1,5 @@ -define("ace/snippets/turtle",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/turtle"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/twig.js b/htdocs/includes/ace/src/snippets/twig.js index fe757895eb6..2cec7aaa7ff 100644 --- a/htdocs/includes/ace/src/snippets/twig.js +++ b/htdocs/includes/ace/src/snippets/twig.js @@ -1,10 +1,5 @@ -define("ace/snippets/twig",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "twig"; - -}); (function() { +; (function() { window.require(["ace/snippets/twig"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/typescript.js b/htdocs/includes/ace/src/snippets/typescript.js index 2da2fb807fa..27dc42bf129 100644 --- a/htdocs/includes/ace/src/snippets/typescript.js +++ b/htdocs/includes/ace/src/snippets/typescript.js @@ -1,10 +1,5 @@ -define("ace/snippets/typescript",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "typescript"; - -}); (function() { +; (function() { window.require(["ace/snippets/typescript"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/vbscript.js b/htdocs/includes/ace/src/snippets/vbscript.js index 0989a0810c9..637e51913ff 100644 --- a/htdocs/includes/ace/src/snippets/vbscript.js +++ b/htdocs/includes/ace/src/snippets/vbscript.js @@ -1,10 +1,5 @@ -define("ace/snippets/vbscript",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "vbscript"; - -}); (function() { +; (function() { window.require(["ace/snippets/vbscript"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/verilog.js b/htdocs/includes/ace/src/snippets/verilog.js index 2ed2eef0e45..d824e8463ef 100644 --- a/htdocs/includes/ace/src/snippets/verilog.js +++ b/htdocs/includes/ace/src/snippets/verilog.js @@ -1,10 +1,5 @@ -define("ace/snippets/verilog",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "verilog"; - -}); (function() { +; (function() { window.require(["ace/snippets/verilog"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/vhdl.js b/htdocs/includes/ace/src/snippets/vhdl.js index d9b716461be..015c2fbf371 100644 --- a/htdocs/includes/ace/src/snippets/vhdl.js +++ b/htdocs/includes/ace/src/snippets/vhdl.js @@ -1,10 +1,5 @@ -define("ace/snippets/vhdl",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "vhdl"; - -}); (function() { +; (function() { window.require(["ace/snippets/vhdl"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/visualforce.js b/htdocs/includes/ace/src/snippets/visualforce.js index 11c0781cef2..135cf6bdea8 100644 --- a/htdocs/includes/ace/src/snippets/visualforce.js +++ b/htdocs/includes/ace/src/snippets/visualforce.js @@ -1,10 +1,5 @@ -define("ace/snippets/visualforce",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "visualforce"; - -}); (function() { +; (function() { window.require(["ace/snippets/visualforce"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/xml.js b/htdocs/includes/ace/src/snippets/xml.js index 9bbe62ad7b6..927c6659786 100644 --- a/htdocs/includes/ace/src/snippets/xml.js +++ b/htdocs/includes/ace/src/snippets/xml.js @@ -1,10 +1,5 @@ -define("ace/snippets/xml",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "xml"; - -}); (function() { +; (function() { window.require(["ace/snippets/xml"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/yaml.js b/htdocs/includes/ace/src/snippets/yaml.js index bbfecbc21da..13a274dc84c 100644 --- a/htdocs/includes/ace/src/snippets/yaml.js +++ b/htdocs/includes/ace/src/snippets/yaml.js @@ -1,10 +1,5 @@ -define("ace/snippets/yaml",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = "yaml"; - -}); (function() { +; (function() { window.require(["ace/snippets/yaml"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/snippets/zeek.js b/htdocs/includes/ace/src/snippets/zeek.js index e432c22e116..a1fc7cdff3c 100644 --- a/htdocs/includes/ace/src/snippets/zeek.js +++ b/htdocs/includes/ace/src/snippets/zeek.js @@ -1,10 +1,5 @@ -define("ace/snippets/zeek",["require","exports","module"], function(require, exports, module) { -"use strict"; -exports.snippetText =undefined; -exports.scope = ""; - -}); (function() { +; (function() { window.require(["ace/snippets/zeek"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { module.exports = m; diff --git a/htdocs/includes/ace/src/theme-ambiance.js b/htdocs/includes/ace/src/theme-ambiance.js index bac9b4d6339..0830aed50b4 100644 --- a/htdocs/includes/ace/src/theme-ambiance.js +++ b/htdocs/includes/ace/src/theme-ambiance.js @@ -25,7 +25,7 @@ color: #777;\ .ace-ambiance .ace_fold-widget.ace_start,\ .ace-ambiance .ace_fold-widget.ace_end,\ .ace-ambiance .ace_fold-widget.ace_closed{\ -background: none;\ +background: none !important;\ border: none;\ box-shadow: none;\ }\ @@ -169,10 +169,11 @@ background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICA }\ .ace-ambiance .ace_indent-guide {\ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQUFD4z6Crq/sfAAuYAuYl+7lfAAAAAElFTkSuQmCC\") right repeat-y;\ -}"; +}\ +"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/ambiance"], function(m) { diff --git a/htdocs/includes/ace/src/theme-chaos.js b/htdocs/includes/ace/src/theme-chaos.js index 1a46b5b1d02..630a72f72ce 100644 --- a/htdocs/includes/ace/src/theme-chaos.js +++ b/htdocs/includes/ace/src/theme-chaos.js @@ -121,7 +121,7 @@ color: #777;\ .ace-chaos .ace_fold-widget.ace_start,\ .ace-chaos .ace_fold-widget.ace_end,\ .ace-chaos .ace_fold-widget.ace_closed{\ -background: none;\ +background: none !important;\ border: none;\ box-shadow: none;\ }\ @@ -151,7 +151,7 @@ color: #000;\ "; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/chaos"], function(m) { diff --git a/htdocs/includes/ace/src/theme-chrome.js b/htdocs/includes/ace/src/theme-chrome.js index e55118cb13d..9fa527e4a3f 100644 --- a/htdocs/includes/ace/src/theme-chrome.js +++ b/htdocs/includes/ace/src/theme-chrome.js @@ -124,7 +124,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ "; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/chrome"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-clouds.js b/htdocs/includes/ace/src/theme-clouds.js index 01e6cc0b172..2673f62f815 100644 --- a/htdocs/includes/ace/src/theme-clouds.js +++ b/htdocs/includes/ace/src/theme-clouds.js @@ -91,7 +91,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/clouds"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-clouds_midnight.js b/htdocs/includes/ace/src/theme-clouds_midnight.js index 60f0f654365..d88ece21d43 100644 --- a/htdocs/includes/ace/src/theme-clouds_midnight.js +++ b/htdocs/includes/ace/src/theme-clouds_midnight.js @@ -92,7 +92,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/clouds_midnight"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-cobalt.js b/htdocs/includes/ace/src/theme-cobalt.js index 74f20385609..5459c756153 100644 --- a/htdocs/includes/ace/src/theme-cobalt.js +++ b/htdocs/includes/ace/src/theme-cobalt.js @@ -109,7 +109,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb "; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/cobalt"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-crimson_editor.js b/htdocs/includes/ace/src/theme-crimson_editor.js index 88d70538c49..b162e5be5a3 100644 --- a/htdocs/includes/ace/src/theme-crimson_editor.js +++ b/htdocs/includes/ace/src/theme-crimson_editor.js @@ -114,7 +114,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ exports.cssClass = "ace-crimson-editor"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/crimson_editor"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-dawn.js b/htdocs/includes/ace/src/theme-dawn.js index 8a635b3ddff..923dad68d5f 100644 --- a/htdocs/includes/ace/src/theme-dawn.js +++ b/htdocs/includes/ace/src/theme-dawn.js @@ -104,7 +104,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/dawn"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-dracula.js b/htdocs/includes/ace/src/theme-dracula.js index 78942e2867b..3085b9d9693 100644 --- a/htdocs/includes/ace/src/theme-dracula.js +++ b/htdocs/includes/ace/src/theme-dracula.js @@ -124,7 +124,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb exports.$selectionColorConflict = true; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/dracula"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-dreamweaver.js b/htdocs/includes/ace/src/theme-dreamweaver.js index 26abc55bf93..fa9771e9233 100644 --- a/htdocs/includes/ace/src/theme-dreamweaver.js +++ b/htdocs/includes/ace/src/theme-dreamweaver.js @@ -137,7 +137,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/dreamweaver"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-eclipse.js b/htdocs/includes/ace/src/theme-eclipse.js index 31057e66f0f..5deddde3f19 100644 --- a/htdocs/includes/ace/src/theme-eclipse.js +++ b/htdocs/includes/ace/src/theme-eclipse.js @@ -94,7 +94,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ exports.cssClass = "ace-eclipse"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/eclipse"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-github.js b/htdocs/includes/ace/src/theme-github.js index 7f6baf4acd2..12d70bc7746 100644 --- a/htdocs/includes/ace/src/theme-github.js +++ b/htdocs/includes/ace/src/theme-github.js @@ -99,7 +99,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ }"; var dom = require("../lib/dom"); - dom.importCssString(exports.cssText, exports.cssClass); + dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/github"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-gob.js b/htdocs/includes/ace/src/theme-gob.js index 9c03e7bd055..7326db1ec07 100644 --- a/htdocs/includes/ace/src/theme-gob.js +++ b/htdocs/includes/ace/src/theme-gob.js @@ -108,7 +108,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb "; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/gob"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-gruvbox.js b/htdocs/includes/ace/src/theme-gruvbox.js index d2e6ded6b27..c52e8f0fca8 100644 --- a/htdocs/includes/ace/src/theme-gruvbox.js +++ b/htdocs/includes/ace/src/theme-gruvbox.js @@ -77,7 +77,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/gruvbox"], function(m) { diff --git a/htdocs/includes/ace/src/theme-idle_fingers.js b/htdocs/includes/ace/src/theme-idle_fingers.js index 877b884dc3c..1af5e27a28b 100644 --- a/htdocs/includes/ace/src/theme-idle_fingers.js +++ b/htdocs/includes/ace/src/theme-idle_fingers.js @@ -92,7 +92,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/idle_fingers"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-iplastic.js b/htdocs/includes/ace/src/theme-iplastic.js index d09b09f2b42..6eaf7abe3c7 100644 --- a/htdocs/includes/ace/src/theme-iplastic.js +++ b/htdocs/includes/ace/src/theme-iplastic.js @@ -117,7 +117,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/iplastic"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-katzenmilch.js b/htdocs/includes/ace/src/theme-katzenmilch.js index 45dd629a12b..596d9702050 100644 --- a/htdocs/includes/ace/src/theme-katzenmilch.js +++ b/htdocs/includes/ace/src/theme-katzenmilch.js @@ -117,7 +117,7 @@ rbackground-color: rgba(73, 166, 210, 0.039)\ }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/katzenmilch"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-kr_theme.js b/htdocs/includes/ace/src/theme-kr_theme.js index bb32770a2a4..1509c0b1ead 100644 --- a/htdocs/includes/ace/src/theme-kr_theme.js +++ b/htdocs/includes/ace/src/theme-kr_theme.js @@ -100,7 +100,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/kr_theme"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-kuroir.js b/htdocs/includes/ace/src/theme-kuroir.js index 6d12d2c71c0..85af8e85ba9 100644 --- a/htdocs/includes/ace/src/theme-kuroir.js +++ b/htdocs/includes/ace/src/theme-kuroir.js @@ -57,7 +57,7 @@ background-color:rgba(191, 97, 51, 0.051);}.ace-kuroir .ace_markup.ace_list{colo "; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/kuroir"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-merbivore.js b/htdocs/includes/ace/src/theme-merbivore.js index 636fbe44d43..e638fb1c6e7 100644 --- a/htdocs/includes/ace/src/theme-merbivore.js +++ b/htdocs/includes/ace/src/theme-merbivore.js @@ -91,7 +91,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/merbivore"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-merbivore_soft.js b/htdocs/includes/ace/src/theme-merbivore_soft.js index 4ce881ae5a7..d79865b0f66 100644 --- a/htdocs/includes/ace/src/theme-merbivore_soft.js +++ b/htdocs/includes/ace/src/theme-merbivore_soft.js @@ -92,7 +92,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/merbivore_soft"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-mono_industrial.js b/htdocs/includes/ace/src/theme-mono_industrial.js index 6a00097b0d2..0bd57662e85 100644 --- a/htdocs/includes/ace/src/theme-mono_industrial.js +++ b/htdocs/includes/ace/src/theme-mono_industrial.js @@ -103,7 +103,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/mono_industrial"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-monokai.js b/htdocs/includes/ace/src/theme-monokai.js index ce64226bda5..7eed6b445d9 100644 --- a/htdocs/includes/ace/src/theme-monokai.js +++ b/htdocs/includes/ace/src/theme-monokai.js @@ -101,7 +101,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/monokai"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-nord_dark.js b/htdocs/includes/ace/src/theme-nord_dark.js new file mode 100644 index 00000000000..c97f58317ad --- /dev/null +++ b/htdocs/includes/ace/src/theme-nord_dark.js @@ -0,0 +1,102 @@ +define("ace/theme/nord_dark",["require","exports","module","ace/lib/dom"], function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-nord-dark"; +exports.cssText = ".ace-nord-dark .ace_gutter {\ +color: #616e88;\ +}\ +.ace-nord-dark .ace_print-margin {\ +width: 1px;\ +background: #4c566a;\ +}\ +.ace-nord-dark {\ +background-color: #2e3440;\ +color: #d8dee9;\ +}\ +.ace-nord-dark .ace_entity.ace_other.ace_attribute-name,\ +.ace-nord-dark .ace_storage {\ +color: #d8dee9;\ +}\ +.ace-nord-dark .ace_cursor {\ +color: #d8dee9;\ +},\ +.ace-nord-dark .ace_string.ace_regexp {\ +color: #bf616a;\ +}\ +.ace-nord-dark .ace_marker-layer .ace_active-line {\ +background: #434c5ecc;\ +}\ +.ace-nord-dark .ace_marker-layer .ace_selection {\ +background: #434c5ecc;\ +}\ +.ace-nord-dark.ace_multiselect .ace_selection.ace_start {\ +box-shadow: 0 0 3px 0px #2e3440;\ +}\ +.ace-nord-dark .ace_marker-layer .ace_step {\ +background: #ebcb8b;\ +}\ +.ace-nord-dark .ace_marker-layer .ace_bracket {\ +margin: -1px 0 0 -1px;\ +border: 1px solid #88c0d066;\ +}\ +.ace-nord-dark .ace_gutter-active-line {\ +background-color: #434c5ecc;\ +}\ +.ace-nord-dark .ace_marker-layer .ace_selected-word {\ +border: 1px solid #88c0d066;\ +}\ +.ace-nord-dark .ace_invisible {\ +color: #4c566a;\ +}\ +.ace-nord-dark .ace_keyword,\ +.ace-nord-dark .ace_meta,\ +.ace-nord-dark .ace_support.ace_class,\ +.ace-nord-dark .ace_support.ace_type {\ +color: #81a1c1;\ +}\ +.ace-nord-dark .ace_constant.ace_character,\ +.ace-nord-dark .ace_constant.ace_other {\ +color: #d8dee9;\ +}\ +.ace-nord-dark .ace_constant.ace_language {\ +color: #5e81ac;\ +}\ +.ace-nord-dark .ace_constant.ace_escape {\ +color: #ebcB8b;\ +}\ +.ace-nord-dark .ace_constant.ace_numeric {\ +color: #b48ead;\ +}\ +.ace-nord-dark .ace_fold {\ +background-color: #4c566a;\ +border-color: #d8dee9;\ +}\ +.ace-nord-dark .ace_entity.ace_name.ace_function,\ +.ace-nord-dark .ace_entity.ace_name.ace_tag,\ +.ace-nord-dark .ace_support.ace_function,\ +.ace-nord-dark .ace_variable,\ +.ace-nord-dark .ace_variable.ace_language {\ +color: #8fbcbb;\ +}\ +.ace-nord-dark .ace_string {\ +color: #a3be8c;\ +}\ +.ace-nord-dark .ace_comment {\ +color: #616e88;\ +}\ +.ace-nord-dark .ace_indent-guide {\ +box-shadow: inset -1px 0 0 0 #434c5eb3;\ +}\ +"; +exports.$selectionColorConflict = true; + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass, false); +}); (function() { + window.require(["ace/theme/nord_dark"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/theme-one_dark.js b/htdocs/includes/ace/src/theme-one_dark.js new file mode 100644 index 00000000000..b99f2287b92 --- /dev/null +++ b/htdocs/includes/ace/src/theme-one_dark.js @@ -0,0 +1,139 @@ +define("ace/theme/one_dark",["require","exports","module","ace/lib/dom"], function(require, exports, module) { + + exports.isDark = true; + exports.cssClass = "ace-one-dark"; + exports.cssText = ".ace-one-dark .ace_gutter {\ +background: #282c34;\ +color: #6a6f7a\ +}\ +.ace-one-dark .ace_print-margin {\ +width: 1px;\ +background: #e8e8e8\ +}\ +.ace-one-dark {\ +background-color: #282c34;\ +color: #abb2bf\ +}\ +.ace-one-dark .ace_cursor {\ +color: #528bff\ +}\ +.ace-one-dark .ace_marker-layer .ace_selection {\ +background: #3d4350\ +}\ +.ace-one-dark.ace_multiselect .ace_selection.ace_start {\ +box-shadow: 0 0 3px 0 #282c34;\ +border-radius: 2px\ +}\ +.ace-one-dark .ace_marker-layer .ace_step {\ +background: #c6dbae\ +}\ +.ace-one-dark .ace_marker-layer .ace_bracket {\ +margin: -1px 0 0 -1px;\ +border: 1px solid #747369\ +}\ +.ace-one-dark .ace_marker-layer .ace_active-line {\ +background: rgba(76, 87, 103, .19)\ +}\ +.ace-one-dark .ace_gutter-active-line {\ +background-color: rgba(76, 87, 103, .19)\ +}\ +.ace-one-dark .ace_marker-layer .ace_selected-word {\ +border: 1px solid #3d4350\ +}\ +.ace-one-dark .ace_fold {\ +background-color: #61afef;\ +border-color: #abb2bf\ +}\ +.ace-one-dark .ace_keyword {\ +color: #c678dd\ +}\ +.ace-one-dark .ace_keyword.ace_operator {\ +color: #c678dd\ +}\ +.ace-one-dark .ace_keyword.ace_other.ace_unit {\ +color: #d19a66\ +}\ +.ace-one-dark .ace_constant.ace_language {\ +color: #d19a66\ +}\ +.ace-one-dark .ace_constant.ace_numeric {\ +color: #d19a66\ +}\ +.ace-one-dark .ace_constant.ace_character {\ +color: #56b6c2\ +}\ +.ace-one-dark .ace_constant.ace_other {\ +color: #56b6c2\ +}\ +.ace-one-dark .ace_support.ace_function {\ +color: #61afef\ +}\ +.ace-one-dark .ace_support.ace_constant {\ +color: #d19a66\ +}\ +.ace-one-dark .ace_support.ace_class {\ +color: #e5c07b\ +}\ +.ace-one-dark .ace_support.ace_type {\ +color: #e5c07b\ +}\ +.ace-one-dark .ace_storage {\ +color: #c678dd\ +}\ +.ace-one-dark .ace_storage.ace_type {\ +color: #c678dd\ +}\ +.ace-one-dark .ace_invalid {\ +color: #fff;\ +background-color: #f2777a\ +}\ +.ace-one-dark .ace_invalid.ace_deprecated {\ +color: #272b33;\ +background-color: #d27b53\ +}\ +.ace-one-dark .ace_string {\ +color: #98c379\ +}\ +.ace-one-dark .ace_string.ace_regexp {\ +color: #e06c75\ +}\ +.ace-one-dark .ace_comment {\ +font-style: italic;\ +color: #5c6370\ +}\ +.ace-one-dark .ace_variable {\ +color: #e06c75\ +}\ +.ace-one-dark .ace_variable.ace_parameter {\ +color: #d19a66\ +}\ +.ace-one-dark .ace_meta.ace_tag {\ +color: #e06c75\ +}\ +.ace-one-dark .ace_entity.ace_other.ace_attribute-name {\ +color: #e06c75\ +}\ +.ace-one-dark .ace_entity.ace_name.ace_function {\ +color: #61afef\ +}\ +.ace-one-dark .ace_entity.ace_name.ace_tag {\ +color: #e06c75\ +}\ +.ace-one-dark .ace_markup.ace_heading {\ +color: #98c379\ +}\ +.ace-one-dark .ace_indent-guide {\ +background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ09NrYAgMjP4PAAtGAwchHMyAAAAAAElFTkSuQmCC) right repeat-y\ +}\ +"; + + var dom = require("../lib/dom"); + dom.importCssString(exports.cssText, exports.cssClass, false); + }); (function() { + window.require(["ace/theme/one_dark"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/theme-pastel_on_dark.js b/htdocs/includes/ace/src/theme-pastel_on_dark.js index e02957c99b8..cc51053dc43 100644 --- a/htdocs/includes/ace/src/theme-pastel_on_dark.js +++ b/htdocs/includes/ace/src/theme-pastel_on_dark.js @@ -104,7 +104,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/pastel_on_dark"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-solarized_dark.js b/htdocs/includes/ace/src/theme-solarized_dark.js index dad8d3896b9..e9a2664d166 100644 --- a/htdocs/includes/ace/src/theme-solarized_dark.js +++ b/htdocs/includes/ace/src/theme-solarized_dark.js @@ -84,7 +84,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/solarized_dark"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-solarized_light.js b/htdocs/includes/ace/src/theme-solarized_light.js index 70f9383041c..2746ea63c78 100644 --- a/htdocs/includes/ace/src/theme-solarized_light.js +++ b/htdocs/includes/ace/src/theme-solarized_light.js @@ -87,7 +87,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/solarized_light"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-sqlserver.js b/htdocs/includes/ace/src/theme-sqlserver.js index 91724014b01..1b626a28fcf 100644 --- a/htdocs/includes/ace/src/theme-sqlserver.js +++ b/htdocs/includes/ace/src/theme-sqlserver.js @@ -134,7 +134,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ "; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/sqlserver"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-terminal.js b/htdocs/includes/ace/src/theme-terminal.js index 8f87077cae7..b10de0bd323 100644 --- a/htdocs/includes/ace/src/theme-terminal.js +++ b/htdocs/includes/ace/src/theme-terminal.js @@ -110,7 +110,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb "; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/terminal"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-textmate.js b/htdocs/includes/ace/src/theme-textmate.js index 6ad09556895..dc651d74b73 100644 --- a/htdocs/includes/ace/src/theme-textmate.js +++ b/htdocs/includes/ace/src/theme-textmate.js @@ -126,7 +126,7 @@ background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZ exports.$id = "ace/theme/textmate"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/textmate"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-tomorrow.js b/htdocs/includes/ace/src/theme-tomorrow.js index 5a2e3b5a4f2..b1f73da83b6 100644 --- a/htdocs/includes/ace/src/theme-tomorrow.js +++ b/htdocs/includes/ace/src/theme-tomorrow.js @@ -104,7 +104,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/tomorrow"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-tomorrow_night.js b/htdocs/includes/ace/src/theme-tomorrow_night.js index 9cdeedce37b..36c748fd64b 100644 --- a/htdocs/includes/ace/src/theme-tomorrow_night.js +++ b/htdocs/includes/ace/src/theme-tomorrow_night.js @@ -104,7 +104,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/tomorrow_night"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-tomorrow_night_blue.js b/htdocs/includes/ace/src/theme-tomorrow_night_blue.js index 52afc918d78..7bf7fc64680 100644 --- a/htdocs/includes/ace/src/theme-tomorrow_night_blue.js +++ b/htdocs/includes/ace/src/theme-tomorrow_night_blue.js @@ -102,7 +102,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/tomorrow_night_blue"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-tomorrow_night_bright.js b/htdocs/includes/ace/src/theme-tomorrow_night_bright.js index b90c17921a4..3bf12ddd420 100644 --- a/htdocs/includes/ace/src/theme-tomorrow_night_bright.js +++ b/htdocs/includes/ace/src/theme-tomorrow_night_bright.js @@ -117,7 +117,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/tomorrow_night_bright"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-tomorrow_night_eighties.js b/htdocs/includes/ace/src/theme-tomorrow_night_eighties.js index 5759eadbc3d..e5c48fcaedf 100644 --- a/htdocs/includes/ace/src/theme-tomorrow_night_eighties.js +++ b/htdocs/includes/ace/src/theme-tomorrow_night_eighties.js @@ -104,7 +104,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/tomorrow_night_eighties"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-twilight.js b/htdocs/includes/ace/src/theme-twilight.js index 34857c311a4..03e9d07da2a 100644 --- a/htdocs/includes/ace/src/theme-twilight.js +++ b/htdocs/includes/ace/src/theme-twilight.js @@ -80,8 +80,7 @@ color: #DAD085\ color: #F9EE98\ }\ .ace-twilight .ace_entity.ace_name.ace_function,\ -.ace-twilight .ace_meta.ace_tag,\ -.ace-twilight .ace_variable {\ +.ace-twilight .ace_meta.ace_tag {\ color: #AC885B\ }\ .ace-twilight .ace_string {\ @@ -102,10 +101,11 @@ color: #494949\ }\ .ace-twilight .ace_indent-guide {\ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y\ -}"; +}\ +"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/twilight"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-vibrant_ink.js b/htdocs/includes/ace/src/theme-vibrant_ink.js index 6fbc5094c93..26f7de9043a 100644 --- a/htdocs/includes/ace/src/theme-vibrant_ink.js +++ b/htdocs/includes/ace/src/theme-vibrant_ink.js @@ -90,7 +90,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/vibrant_ink"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/theme-xcode.js b/htdocs/includes/ace/src/theme-xcode.js index 99a5b75ef9a..daded3a15eb 100644 --- a/htdocs/includes/ace/src/theme-xcode.js +++ b/htdocs/includes/ace/src/theme-xcode.js @@ -84,7 +84,7 @@ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgb }"; var dom = require("../lib/dom"); -dom.importCssString(exports.cssText, exports.cssClass); +dom.importCssString(exports.cssText, exports.cssClass, false); }); (function() { window.require(["ace/theme/xcode"], function(m) { if (typeof module == "object" && typeof exports == "object" && module) { diff --git a/htdocs/includes/ace/src/worker-base.js b/htdocs/includes/ace/src/worker-base.js new file mode 100644 index 00000000000..ca582ac58ec --- /dev/null +++ b/htdocs/includes/ace/src/worker-base.js @@ -0,0 +1,1421 @@ +"no use strict"; +!(function(window) { +if (typeof window.window != "undefined" && window.document) + return; +if (window.require && window.define) + return; + +if (!window.console) { + window.console = function() { + var msgs = Array.prototype.slice.call(arguments, 0); + postMessage({type: "log", data: msgs}); + }; + window.console.error = + window.console.warn = + window.console.log = + window.console.trace = window.console; +} +window.window = window; +window.ace = window; + +window.onerror = function(message, file, line, col, err) { + postMessage({type: "error", data: { + message: message, + data: err.data, + file: file, + line: line, + col: col, + stack: err.stack + }}); +}; + +window.normalizeModule = function(parentId, moduleName) { + // normalize plugin requires + if (moduleName.indexOf("!") !== -1) { + var chunks = moduleName.split("!"); + return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]); + } + // normalize relative requires + if (moduleName.charAt(0) == ".") { + var base = parentId.split("/").slice(0, -1).join("/"); + moduleName = (base ? base + "/" : "") + moduleName; + + while (moduleName.indexOf(".") !== -1 && previous != moduleName) { + var previous = moduleName; + moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); + } + } + + return moduleName; +}; + +window.require = function require(parentId, id) { + if (!id) { + id = parentId; + parentId = null; + } + if (!id.charAt) + throw new Error("worker.js require() accepts only (parentId, id) as arguments"); + + id = window.normalizeModule(parentId, id); + + var module = window.require.modules[id]; + if (module) { + if (!module.initialized) { + module.initialized = true; + module.exports = module.factory().exports; + } + return module.exports; + } + + if (!window.require.tlns) + return console.log("unable to load " + id); + + var path = resolveModuleId(id, window.require.tlns); + if (path.slice(-3) != ".js") path += ".js"; + + window.require.id = id; + window.require.modules[id] = {}; // prevent infinite loop on broken modules + importScripts(path); + return window.require(parentId, id); +}; +function resolveModuleId(id, paths) { + var testPath = id, tail = ""; + while (testPath) { + var alias = paths[testPath]; + if (typeof alias == "string") { + return alias + tail; + } else if (alias) { + return alias.location.replace(/\/*$/, "/") + (tail || alias.main || alias.name); + } else if (alias === false) { + return ""; + } + var i = testPath.lastIndexOf("/"); + if (i === -1) break; + tail = testPath.substr(i) + tail; + testPath = testPath.slice(0, i); + } + return id; +} +window.require.modules = {}; +window.require.tlns = {}; + +window.define = function(id, deps, factory) { + if (arguments.length == 2) { + factory = deps; + if (typeof id != "string") { + deps = id; + id = window.require.id; + } + } else if (arguments.length == 1) { + factory = id; + deps = []; + id = window.require.id; + } + + if (typeof factory != "function") { + window.require.modules[id] = { + exports: factory, + initialized: true + }; + return; + } + + if (!deps.length) + // If there is no dependencies, we inject "require", "exports" and + // "module" as dependencies, to provide CommonJS compatibility. + deps = ["require", "exports", "module"]; + + var req = function(childId) { + return window.require(id, childId); + }; + + window.require.modules[id] = { + exports: {}, + factory: function() { + var module = this; + var returnExports = factory.apply(this, deps.slice(0, factory.length).map(function(dep) { + switch (dep) { + // Because "require", "exports" and "module" aren't actual + // dependencies, we must handle them seperately. + case "require": return req; + case "exports": return module.exports; + case "module": return module; + // But for all other dependencies, we can just go ahead and + // require them. + default: return req(dep); + } + })); + if (returnExports) + module.exports = returnExports; + return module; + } + }; +}; +window.define.amd = {}; +require.tlns = {}; +window.initBaseUrls = function initBaseUrls(topLevelNamespaces) { + for (var i in topLevelNamespaces) + require.tlns[i] = topLevelNamespaces[i]; +}; + +window.initSender = function initSender() { + + var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter; + var oop = window.require("ace/lib/oop"); + + var Sender = function() {}; + + (function() { + + oop.implement(this, EventEmitter); + + this.callback = function(data, callbackId) { + postMessage({ + type: "call", + id: callbackId, + data: data + }); + }; + + this.emit = function(name, data) { + postMessage({ + type: "event", + name: name, + data: data + }); + }; + + }).call(Sender.prototype); + + return new Sender(); +}; + +var main = window.main = null; +var sender = window.sender = null; + +window.onmessage = function(e) { + var msg = e.data; + if (msg.event && sender) { + sender._signal(msg.event, msg.data); + } + else if (msg.command) { + if (main[msg.command]) + main[msg.command].apply(main, msg.args); + else if (window[msg.command]) + window[msg.command].apply(window, msg.args); + else + throw new Error("Unknown command:" + msg.command); + } + else if (msg.init) { + window.initBaseUrls(msg.tlns); + sender = window.sender = window.initSender(); + var clazz = require(msg.module)[msg.classname]; + main = window.main = new clazz(sender); + } +}; +})(this); + +define("ace/range",[], function(require, exports, module) { +"use strict"; +var comparePoints = function(p1, p2) { + return p1.row - p2.row || p1.column - p2.column; +}; +var Range = function(startRow, startColumn, endRow, endColumn) { + this.start = { + row: startRow, + column: startColumn + }; + + this.end = { + row: endRow, + column: endColumn + }; +}; + +(function() { + this.isEqual = function(range) { + return this.start.row === range.start.row && + this.end.row === range.end.row && + this.start.column === range.start.column && + this.end.column === range.end.column; + }; + this.toString = function() { + return ("Range: [" + this.start.row + "/" + this.start.column + + "] -> [" + this.end.row + "/" + this.end.column + "]"); + }; + + this.contains = function(row, column) { + return this.compare(row, column) == 0; + }; + this.compareRange = function(range) { + var cmp, + end = range.end, + start = range.start; + + cmp = this.compare(end.row, end.column); + if (cmp == 1) { + cmp = this.compare(start.row, start.column); + if (cmp == 1) { + return 2; + } else if (cmp == 0) { + return 1; + } else { + return 0; + } + } else if (cmp == -1) { + return -2; + } else { + cmp = this.compare(start.row, start.column); + if (cmp == -1) { + return -1; + } else if (cmp == 1) { + return 42; + } else { + return 0; + } + } + }; + this.comparePoint = function(p) { + return this.compare(p.row, p.column); + }; + this.containsRange = function(range) { + return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0; + }; + this.intersects = function(range) { + var cmp = this.compareRange(range); + return (cmp == -1 || cmp == 0 || cmp == 1); + }; + this.isEnd = function(row, column) { + return this.end.row == row && this.end.column == column; + }; + this.isStart = function(row, column) { + return this.start.row == row && this.start.column == column; + }; + this.setStart = function(row, column) { + if (typeof row == "object") { + this.start.column = row.column; + this.start.row = row.row; + } else { + this.start.row = row; + this.start.column = column; + } + }; + this.setEnd = function(row, column) { + if (typeof row == "object") { + this.end.column = row.column; + this.end.row = row.row; + } else { + this.end.row = row; + this.end.column = column; + } + }; + this.inside = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isEnd(row, column) || this.isStart(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.insideStart = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isEnd(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.insideEnd = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isStart(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.compare = function(row, column) { + if (!this.isMultiLine()) { + if (row === this.start.row) { + return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0); + } + } + + if (row < this.start.row) + return -1; + + if (row > this.end.row) + return 1; + + if (this.start.row === row) + return column >= this.start.column ? 0 : -1; + + if (this.end.row === row) + return column <= this.end.column ? 0 : 1; + + return 0; + }; + this.compareStart = function(row, column) { + if (this.start.row == row && this.start.column == column) { + return -1; + } else { + return this.compare(row, column); + } + }; + this.compareEnd = function(row, column) { + if (this.end.row == row && this.end.column == column) { + return 1; + } else { + return this.compare(row, column); + } + }; + this.compareInside = function(row, column) { + if (this.end.row == row && this.end.column == column) { + return 1; + } else if (this.start.row == row && this.start.column == column) { + return -1; + } else { + return this.compare(row, column); + } + }; + this.clipRows = function(firstRow, lastRow) { + if (this.end.row > lastRow) + var end = {row: lastRow + 1, column: 0}; + else if (this.end.row < firstRow) + var end = {row: firstRow, column: 0}; + + if (this.start.row > lastRow) + var start = {row: lastRow + 1, column: 0}; + else if (this.start.row < firstRow) + var start = {row: firstRow, column: 0}; + + return Range.fromPoints(start || this.start, end || this.end); + }; + this.extend = function(row, column) { + var cmp = this.compare(row, column); + + if (cmp == 0) + return this; + else if (cmp == -1) + var start = {row: row, column: column}; + else + var end = {row: row, column: column}; + + return Range.fromPoints(start || this.start, end || this.end); + }; + + this.isEmpty = function() { + return (this.start.row === this.end.row && this.start.column === this.end.column); + }; + this.isMultiLine = function() { + return (this.start.row !== this.end.row); + }; + this.clone = function() { + return Range.fromPoints(this.start, this.end); + }; + this.collapseRows = function() { + if (this.end.column == 0) + return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0); + else + return new Range(this.start.row, 0, this.end.row, 0); + }; + this.toScreenRange = function(session) { + var screenPosStart = session.documentToScreenPosition(this.start); + var screenPosEnd = session.documentToScreenPosition(this.end); + + return new Range( + screenPosStart.row, screenPosStart.column, + screenPosEnd.row, screenPosEnd.column + ); + }; + this.moveBy = function(row, column) { + this.start.row += row; + this.start.column += column; + this.end.row += row; + this.end.column += column; + }; + +}).call(Range.prototype); +Range.fromPoints = function(start, end) { + return new Range(start.row, start.column, end.row, end.column); +}; +Range.comparePoints = comparePoints; + +Range.comparePoints = function(p1, p2) { + return p1.row - p2.row || p1.column - p2.column; +}; + + +exports.Range = Range; +}); + +define("ace/lib/oop",[], function(require, exports, module) { +"use strict"; + +exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); +}; + +exports.mixin = function(obj, mixin) { + for (var key in mixin) { + obj[key] = mixin[key]; + } + return obj; +}; + +exports.implement = function(proto, mixin) { + exports.mixin(proto, mixin); +}; + +}); + +define("ace/apply_delta",[], function(require, exports, module) { +"use strict"; + +function throwDeltaError(delta, errorText){ + console.log("Invalid Delta:", delta); + throw "Invalid Delta: " + errorText; +} + +function positionInDocument(docLines, position) { + return position.row >= 0 && position.row < docLines.length && + position.column >= 0 && position.column <= docLines[position.row].length; +} + +function validateDelta(docLines, delta) { + if (delta.action != "insert" && delta.action != "remove") + throwDeltaError(delta, "delta.action must be 'insert' or 'remove'"); + if (!(delta.lines instanceof Array)) + throwDeltaError(delta, "delta.lines must be an Array"); + if (!delta.start || !delta.end) + throwDeltaError(delta, "delta.start/end must be an present"); + var start = delta.start; + if (!positionInDocument(docLines, delta.start)) + throwDeltaError(delta, "delta.start must be contained in document"); + var end = delta.end; + if (delta.action == "remove" && !positionInDocument(docLines, end)) + throwDeltaError(delta, "delta.end must contained in document for 'remove' actions"); + var numRangeRows = end.row - start.row; + var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0)); + if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars) + throwDeltaError(delta, "delta.range must match delta lines"); +} + +exports.applyDelta = function(docLines, delta, doNotValidate) { + + var row = delta.start.row; + var startColumn = delta.start.column; + var line = docLines[row] || ""; + switch (delta.action) { + case "insert": + var lines = delta.lines; + if (lines.length === 1) { + docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn); + } else { + var args = [row, 1].concat(delta.lines); + docLines.splice.apply(docLines, args); + docLines[row] = line.substring(0, startColumn) + docLines[row]; + docLines[row + delta.lines.length - 1] += line.substring(startColumn); + } + break; + case "remove": + var endColumn = delta.end.column; + var endRow = delta.end.row; + if (row === endRow) { + docLines[row] = line.substring(0, startColumn) + line.substring(endColumn); + } else { + docLines.splice( + row, endRow - row + 1, + line.substring(0, startColumn) + docLines[endRow].substring(endColumn) + ); + } + break; + } +}; +}); + +define("ace/lib/event_emitter",[], function(require, exports, module) { +"use strict"; + +var EventEmitter = {}; +var stopPropagation = function() { this.propagationStopped = true; }; +var preventDefault = function() { this.defaultPrevented = true; }; + +EventEmitter._emit = +EventEmitter._dispatchEvent = function(eventName, e) { + this._eventRegistry || (this._eventRegistry = {}); + this._defaultHandlers || (this._defaultHandlers = {}); + + var listeners = this._eventRegistry[eventName] || []; + var defaultHandler = this._defaultHandlers[eventName]; + if (!listeners.length && !defaultHandler) + return; + + if (typeof e != "object" || !e) + e = {}; + + if (!e.type) + e.type = eventName; + if (!e.stopPropagation) + e.stopPropagation = stopPropagation; + if (!e.preventDefault) + e.preventDefault = preventDefault; + + listeners = listeners.slice(); + for (var i=0; i this.row) + return; + + var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight); + this.setPosition(point.row, point.column, true); + }; + + function $pointsInOrder(point1, point2, equalPointsInOrder) { + var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column; + return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter); + } + + function $getTransformedPoint(delta, point, moveIfEqual) { + var deltaIsInsert = delta.action == "insert"; + var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row); + var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column); + var deltaStart = delta.start; + var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range. + if ($pointsInOrder(point, deltaStart, moveIfEqual)) { + return { + row: point.row, + column: point.column + }; + } + if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) { + return { + row: point.row + deltaRowShift, + column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0) + }; + } + + return { + row: deltaStart.row, + column: deltaStart.column + }; + } + this.setPosition = function(row, column, noClip) { + var pos; + if (noClip) { + pos = { + row: row, + column: column + }; + } else { + pos = this.$clipPositionToDocument(row, column); + } + + if (this.row == pos.row && this.column == pos.column) + return; + + var old = { + row: this.row, + column: this.column + }; + + this.row = pos.row; + this.column = pos.column; + this._signal("change", { + old: old, + value: pos + }); + }; + this.detach = function() { + this.document.off("change", this.$onChange); + }; + this.attach = function(doc) { + this.document = doc || this.document; + this.document.on("change", this.$onChange); + }; + this.$clipPositionToDocument = function(row, column) { + var pos = {}; + + if (row >= this.document.getLength()) { + pos.row = Math.max(0, this.document.getLength() - 1); + pos.column = this.document.getLine(pos.row).length; + } + else if (row < 0) { + pos.row = 0; + pos.column = 0; + } + else { + pos.row = row; + pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); + } + + if (column < 0) + pos.column = 0; + + return pos; + }; + +}).call(Anchor.prototype); + +}); + +define("ace/document",[], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var applyDelta = require("./apply_delta").applyDelta; +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var Range = require("./range").Range; +var Anchor = require("./anchor").Anchor; + +var Document = function(textOrLines) { + this.$lines = [""]; + if (textOrLines.length === 0) { + this.$lines = [""]; + } else if (Array.isArray(textOrLines)) { + this.insertMergedLines({row: 0, column: 0}, textOrLines); + } else { + this.insert({row: 0, column:0}, textOrLines); + } +}; + +(function() { + + oop.implement(this, EventEmitter); + this.setValue = function(text) { + var len = this.getLength() - 1; + this.remove(new Range(0, 0, len, this.getLine(len).length)); + this.insert({row: 0, column: 0}, text); + }; + this.getValue = function() { + return this.getAllLines().join(this.getNewLineCharacter()); + }; + this.createAnchor = function(row, column) { + return new Anchor(this, row, column); + }; + if ("aaa".split(/a/).length === 0) { + this.$split = function(text) { + return text.replace(/\r\n|\r/g, "\n").split("\n"); + }; + } else { + this.$split = function(text) { + return text.split(/\r\n|\r|\n/); + }; + } + + + this.$detectNewLine = function(text) { + var match = text.match(/^.*?(\r\n|\r|\n)/m); + this.$autoNewLine = match ? match[1] : "\n"; + this._signal("changeNewLineMode"); + }; + this.getNewLineCharacter = function() { + switch (this.$newLineMode) { + case "windows": + return "\r\n"; + case "unix": + return "\n"; + default: + return this.$autoNewLine || "\n"; + } + }; + + this.$autoNewLine = ""; + this.$newLineMode = "auto"; + this.setNewLineMode = function(newLineMode) { + if (this.$newLineMode === newLineMode) + return; + + this.$newLineMode = newLineMode; + this._signal("changeNewLineMode"); + }; + this.getNewLineMode = function() { + return this.$newLineMode; + }; + this.isNewLine = function(text) { + return (text == "\r\n" || text == "\r" || text == "\n"); + }; + this.getLine = function(row) { + return this.$lines[row] || ""; + }; + this.getLines = function(firstRow, lastRow) { + return this.$lines.slice(firstRow, lastRow + 1); + }; + this.getAllLines = function() { + return this.getLines(0, this.getLength()); + }; + this.getLength = function() { + return this.$lines.length; + }; + this.getTextRange = function(range) { + return this.getLinesForRange(range).join(this.getNewLineCharacter()); + }; + this.getLinesForRange = function(range) { + var lines; + if (range.start.row === range.end.row) { + lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)]; + } else { + lines = this.getLines(range.start.row, range.end.row); + lines[0] = (lines[0] || "").substring(range.start.column); + var l = lines.length - 1; + if (range.end.row - range.start.row == l) + lines[l] = lines[l].substring(0, range.end.column); + } + return lines; + }; + this.insertLines = function(row, lines) { + console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."); + return this.insertFullLines(row, lines); + }; + this.removeLines = function(firstRow, lastRow) { + console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."); + return this.removeFullLines(firstRow, lastRow); + }; + this.insertNewLine = function(position) { + console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."); + return this.insertMergedLines(position, ["", ""]); + }; + this.insert = function(position, text) { + if (this.getLength() <= 1) + this.$detectNewLine(text); + + return this.insertMergedLines(position, this.$split(text)); + }; + this.insertInLine = function(position, text) { + var start = this.clippedPos(position.row, position.column); + var end = this.pos(position.row, position.column + text.length); + + this.applyDelta({ + start: start, + end: end, + action: "insert", + lines: [text] + }, true); + + return this.clonePos(end); + }; + + this.clippedPos = function(row, column) { + var length = this.getLength(); + if (row === undefined) { + row = length; + } else if (row < 0) { + row = 0; + } else if (row >= length) { + row = length - 1; + column = undefined; + } + var line = this.getLine(row); + if (column == undefined) + column = line.length; + column = Math.min(Math.max(column, 0), line.length); + return {row: row, column: column}; + }; + + this.clonePos = function(pos) { + return {row: pos.row, column: pos.column}; + }; + + this.pos = function(row, column) { + return {row: row, column: column}; + }; + + this.$clipPosition = function(position) { + var length = this.getLength(); + if (position.row >= length) { + position.row = Math.max(0, length - 1); + position.column = this.getLine(length - 1).length; + } else { + position.row = Math.max(0, position.row); + position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length); + } + return position; + }; + this.insertFullLines = function(row, lines) { + row = Math.min(Math.max(row, 0), this.getLength()); + var column = 0; + if (row < this.getLength()) { + lines = lines.concat([""]); + column = 0; + } else { + lines = [""].concat(lines); + row--; + column = this.$lines[row].length; + } + this.insertMergedLines({row: row, column: column}, lines); + }; + this.insertMergedLines = function(position, lines) { + var start = this.clippedPos(position.row, position.column); + var end = { + row: start.row + lines.length - 1, + column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length + }; + + this.applyDelta({ + start: start, + end: end, + action: "insert", + lines: lines + }); + + return this.clonePos(end); + }; + this.remove = function(range) { + var start = this.clippedPos(range.start.row, range.start.column); + var end = this.clippedPos(range.end.row, range.end.column); + this.applyDelta({ + start: start, + end: end, + action: "remove", + lines: this.getLinesForRange({start: start, end: end}) + }); + return this.clonePos(start); + }; + this.removeInLine = function(row, startColumn, endColumn) { + var start = this.clippedPos(row, startColumn); + var end = this.clippedPos(row, endColumn); + + this.applyDelta({ + start: start, + end: end, + action: "remove", + lines: this.getLinesForRange({start: start, end: end}) + }, true); + + return this.clonePos(start); + }; + this.removeFullLines = function(firstRow, lastRow) { + firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1); + lastRow = Math.min(Math.max(0, lastRow ), this.getLength() - 1); + var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0; + var deleteLastNewLine = lastRow < this.getLength() - 1; + var startRow = ( deleteFirstNewLine ? firstRow - 1 : firstRow ); + var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0 ); + var endRow = ( deleteLastNewLine ? lastRow + 1 : lastRow ); + var endCol = ( deleteLastNewLine ? 0 : this.getLine(endRow).length ); + var range = new Range(startRow, startCol, endRow, endCol); + var deletedLines = this.$lines.slice(firstRow, lastRow + 1); + + this.applyDelta({ + start: range.start, + end: range.end, + action: "remove", + lines: this.getLinesForRange(range) + }); + return deletedLines; + }; + this.removeNewLine = function(row) { + if (row < this.getLength() - 1 && row >= 0) { + this.applyDelta({ + start: this.pos(row, this.getLine(row).length), + end: this.pos(row + 1, 0), + action: "remove", + lines: ["", ""] + }); + } + }; + this.replace = function(range, text) { + if (!(range instanceof Range)) + range = Range.fromPoints(range.start, range.end); + if (text.length === 0 && range.isEmpty()) + return range.start; + if (text == this.getTextRange(range)) + return range.end; + + this.remove(range); + var end; + if (text) { + end = this.insert(range.start, text); + } + else { + end = range.start; + } + + return end; + }; + this.applyDeltas = function(deltas) { + for (var i=0; i=0; i--) { + this.revertDelta(deltas[i]); + } + }; + this.applyDelta = function(delta, doNotValidate) { + var isInsert = delta.action == "insert"; + if (isInsert ? delta.lines.length <= 1 && !delta.lines[0] + : !Range.comparePoints(delta.start, delta.end)) { + return; + } + + if (isInsert && delta.lines.length > 20000) { + this.$splitAndapplyLargeDelta(delta, 20000); + } + else { + applyDelta(this.$lines, delta, doNotValidate); + this._signal("change", delta); + } + }; + + this.$safeApplyDelta = function(delta) { + var docLength = this.$lines.length; + if ( + delta.action == "remove" && delta.start.row < docLength && delta.end.row < docLength + || delta.action == "insert" && delta.start.row <= docLength + ) { + this.applyDelta(delta); + } + }; + + this.$splitAndapplyLargeDelta = function(delta, MAX) { + var lines = delta.lines; + var l = lines.length - MAX + 1; + var row = delta.start.row; + var column = delta.start.column; + for (var from = 0, to = 0; from < l; from = to) { + to += MAX - 1; + var chunk = lines.slice(from, to); + chunk.push(""); + this.applyDelta({ + start: this.pos(row + from, column), + end: this.pos(row + to, column = 0), + action: delta.action, + lines: chunk + }, true); + } + delta.lines = lines.slice(from); + delta.start.row = row + from; + delta.start.column = column; + this.applyDelta(delta, true); + }; + this.revertDelta = function(delta) { + this.$safeApplyDelta({ + start: this.clonePos(delta.start), + end: this.clonePos(delta.end), + action: (delta.action == "insert" ? "remove" : "insert"), + lines: delta.lines.slice() + }); + }; + this.indexToPosition = function(index, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + for (var i = startRow || 0, l = lines.length; i < l; i++) { + index -= lines[i].length + newlineLength; + if (index < 0) + return {row: i, column: index + lines[i].length + newlineLength}; + } + return {row: l-1, column: index + lines[l-1].length + newlineLength}; + }; + this.positionToIndex = function(pos, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + var index = 0; + var row = Math.min(pos.row, lines.length); + for (var i = startRow || 0; i < row; ++i) + index += lines[i].length + newlineLength; + + return index + pos.column; + }; + +}).call(Document.prototype); + +exports.Document = Document; +}); + +define("ace/lib/lang",[], function(require, exports, module) { +"use strict"; + +exports.last = function(a) { + return a[a.length - 1]; +}; + +exports.stringReverse = function(string) { + return string.split("").reverse().join(""); +}; + +exports.stringRepeat = function (string, count) { + var result = ''; + while (count > 0) { + if (count & 1) + result += string; + + if (count >>= 1) + string += string; + } + return result; +}; + +var trimBeginRegexp = /^\s\s*/; +var trimEndRegexp = /\s\s*$/; + +exports.stringTrimLeft = function (string) { + return string.replace(trimBeginRegexp, ''); +}; + +exports.stringTrimRight = function (string) { + return string.replace(trimEndRegexp, ''); +}; + +exports.copyObject = function(obj) { + var copy = {}; + for (var key in obj) { + copy[key] = obj[key]; + } + return copy; +}; + +exports.copyArray = function(array){ + var copy = []; + for (var i=0, l=array.length; i 0) { - if (pos > length) - pos = length; - } else if (pos == void 0) { - pos = 0; - } else if (pos < 0) { - pos = Math.max(length + pos, 0); - } - - if (!(pos+removeCount < length)) - removeCount = length - pos; - - var removed = this.slice(pos, pos+removeCount); - var insert = slice.call(arguments, 2); - var add = insert.length; - if (pos === length) { - if (add) { - this.push.apply(this, insert); - } - } else { - var remove = Math.min(removeCount, length - pos); - var tailOldPos = pos + remove; - var tailNewPos = tailOldPos + add - remove; - var tailCount = length - tailOldPos; - var lengthAfterRemove = length - remove; - - if (tailNewPos < tailOldPos) { // case A - for (var i = 0; i < tailCount; ++i) { - this[tailNewPos+i] = this[tailOldPos+i]; - } - } else if (tailNewPos > tailOldPos) { // case B - for (i = tailCount; i--; ) { - this[tailNewPos+i] = this[tailOldPos+i]; - } - } // else, add == remove (nothing to do) - - if (add && pos === lengthAfterRemove) { - this.length = lengthAfterRemove; // truncate array - this.push.apply(this, insert); - } else { - this.length = lengthAfterRemove + add; // reserves space - for (i = 0; i < add; ++i) { - this[pos+i] = insert[i]; - } - } - } - return removed; - }; - } -} -if (!Array.isArray) { - Array.isArray = function isArray(obj) { - return _toString(obj) == "[object Array]"; - }; -} -var boxedString = Object("a"), - splitString = boxedString[0] != "a" || !(0 in boxedString); - -if (!Array.prototype.forEach) { - Array.prototype.forEach = function forEach(fun /*, thisp*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - thisp = arguments[1], - i = -1, - length = self.length >>> 0; - if (_toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message - } - - while (++i < length) { - if (i in self) { - fun.call(thisp, self[i], i, object); - } - } - }; -} -if (!Array.prototype.map) { - Array.prototype.map = function map(fun /*, thisp*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - result = Array(length), - thisp = arguments[1]; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self) - result[i] = fun.call(thisp, self[i], i, object); - } - return result; - }; -} -if (!Array.prototype.filter) { - Array.prototype.filter = function filter(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - result = [], - value, - thisp = arguments[1]; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self) { - value = self[i]; - if (fun.call(thisp, value, i, object)) { - result.push(value); - } - } - } - return result; - }; -} -if (!Array.prototype.every) { - Array.prototype.every = function every(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - thisp = arguments[1]; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self && !fun.call(thisp, self[i], i, object)) { - return false; - } - } - return true; - }; -} -if (!Array.prototype.some) { - Array.prototype.some = function some(fun /*, thisp */) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0, - thisp = arguments[1]; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - - for (var i = 0; i < length; i++) { - if (i in self && fun.call(thisp, self[i], i, object)) { - return true; - } - } - return false; - }; -} -if (!Array.prototype.reduce) { - Array.prototype.reduce = function reduce(fun /*, initial*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - if (!length && arguments.length == 1) { - throw new TypeError("reduce of empty array with no initial value"); - } - - var i = 0; - var result; - if (arguments.length >= 2) { - result = arguments[1]; - } else { - do { - if (i in self) { - result = self[i++]; - break; - } - if (++i >= length) { - throw new TypeError("reduce of empty array with no initial value"); - } - } while (true); - } - - for (; i < length; i++) { - if (i in self) { - result = fun.call(void 0, result, self[i], i, object); - } - } - - return result; - }; -} -if (!Array.prototype.reduceRight) { - Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { - var object = toObject(this), - self = splitString && _toString(this) == "[object String]" ? - this.split("") : - object, - length = self.length >>> 0; - if (_toString(fun) != "[object Function]") { - throw new TypeError(fun + " is not a function"); - } - if (!length && arguments.length == 1) { - throw new TypeError("reduceRight of empty array with no initial value"); - } - - var result, i = length - 1; - if (arguments.length >= 2) { - result = arguments[1]; - } else { - do { - if (i in self) { - result = self[i--]; - break; - } - if (--i < 0) { - throw new TypeError("reduceRight of empty array with no initial value"); - } - } while (true); - } - - do { - if (i in this) { - result = fun.call(void 0, result, self[i], i, object); - } - } while (i--); - - return result; - }; -} -if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { - Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { - var self = splitString && _toString(this) == "[object String]" ? - this.split("") : - toObject(this), - length = self.length >>> 0; - - if (!length) { - return -1; - } - - var i = 0; - if (arguments.length > 1) { - i = toInteger(arguments[1]); - } - i = i >= 0 ? i : Math.max(0, length + i); - for (; i < length; i++) { - if (i in self && self[i] === sought) { - return i; - } - } - return -1; - }; -} -if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { - Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { - var self = splitString && _toString(this) == "[object String]" ? - this.split("") : - toObject(this), - length = self.length >>> 0; - - if (!length) { - return -1; - } - var i = length - 1; - if (arguments.length > 1) { - i = Math.min(i, toInteger(arguments[1])); - } - i = i >= 0 ? i : length - Math.abs(i); - for (; i >= 0; i--) { - if (i in self && sought === self[i]) { - return i; - } - } - return -1; - }; -} -if (!Object.getPrototypeOf) { - Object.getPrototypeOf = function getPrototypeOf(object) { - return object.__proto__ || ( - object.constructor ? - object.constructor.prototype : - prototypeOfObject - ); - }; -} -if (!Object.getOwnPropertyDescriptor) { - var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " + - "non-object: "; - Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { - if ((typeof object != "object" && typeof object != "function") || object === null) - throw new TypeError(ERR_NON_OBJECT + object); - if (!owns(object, property)) - return; - - var descriptor, getter, setter; - descriptor = { enumerable: true, configurable: true }; - if (supportsAccessors) { - var prototype = object.__proto__; - object.__proto__ = prototypeOfObject; - - var getter = lookupGetter(object, property); - var setter = lookupSetter(object, property); - object.__proto__ = prototype; - - if (getter || setter) { - if (getter) descriptor.get = getter; - if (setter) descriptor.set = setter; - return descriptor; - } - } - descriptor.value = object[property]; - return descriptor; - }; -} -if (!Object.getOwnPropertyNames) { - Object.getOwnPropertyNames = function getOwnPropertyNames(object) { - return Object.keys(object); - }; -} -if (!Object.create) { - var createEmpty; - if (Object.prototype.__proto__ === null) { - createEmpty = function () { - return { "__proto__": null }; - }; - } else { - createEmpty = function () { - var empty = {}; - for (var i in empty) - empty[i] = null; - empty.constructor = - empty.hasOwnProperty = - empty.propertyIsEnumerable = - empty.isPrototypeOf = - empty.toLocaleString = - empty.toString = - empty.valueOf = - empty.__proto__ = null; - return empty; - } - } - - Object.create = function create(prototype, properties) { - var object; - if (prototype === null) { - object = createEmpty(); - } else { - if (typeof prototype != "object") - throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); - var Type = function () {}; - Type.prototype = prototype; - object = new Type(); - object.__proto__ = prototype; - } - if (properties !== void 0) - Object.defineProperties(object, properties); - return object; - }; -} - -function doesDefinePropertyWork(object) { - try { - Object.defineProperty(object, "sentinel", {}); - return "sentinel" in object; - } catch (exception) { - } -} -if (Object.defineProperty) { - var definePropertyWorksOnObject = doesDefinePropertyWork({}); - var definePropertyWorksOnDom = typeof document == "undefined" || - doesDefinePropertyWork(document.createElement("div")); - if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { - var definePropertyFallback = Object.defineProperty; - } -} - -if (!Object.defineProperty || definePropertyFallback) { - var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; - var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " - var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + - "on this javascript engine"; - - Object.defineProperty = function defineProperty(object, property, descriptor) { - if ((typeof object != "object" && typeof object != "function") || object === null) - throw new TypeError(ERR_NON_OBJECT_TARGET + object); - if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) - throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); - if (definePropertyFallback) { - try { - return definePropertyFallback.call(Object, object, property, descriptor); - } catch (exception) { - } - } - if (owns(descriptor, "value")) { - - if (supportsAccessors && (lookupGetter(object, property) || - lookupSetter(object, property))) - { - var prototype = object.__proto__; - object.__proto__ = prototypeOfObject; - delete object[property]; - object[property] = descriptor.value; - object.__proto__ = prototype; - } else { - object[property] = descriptor.value; - } - } else { - if (!supportsAccessors) - throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); - if (owns(descriptor, "get")) - defineGetter(object, property, descriptor.get); - if (owns(descriptor, "set")) - defineSetter(object, property, descriptor.set); - } - - return object; - }; -} -if (!Object.defineProperties) { - Object.defineProperties = function defineProperties(object, properties) { - for (var property in properties) { - if (owns(properties, property)) - Object.defineProperty(object, property, properties[property]); - } - return object; - }; -} -if (!Object.seal) { - Object.seal = function seal(object) { - return object; - }; -} -if (!Object.freeze) { - Object.freeze = function freeze(object) { - return object; - }; -} -try { - Object.freeze(function () {}); -} catch (exception) { - Object.freeze = (function freeze(freezeObject) { - return function freeze(object) { - if (typeof object == "function") { - return object; - } else { - return freezeObject(object); - } - }; - })(Object.freeze); -} -if (!Object.preventExtensions) { - Object.preventExtensions = function preventExtensions(object) { - return object; - }; -} -if (!Object.isSealed) { - Object.isSealed = function isSealed(object) { - return false; - }; -} -if (!Object.isFrozen) { - Object.isFrozen = function isFrozen(object) { - return false; - }; -} -if (!Object.isExtensible) { - Object.isExtensible = function isExtensible(object) { - if (Object(object) === object) { - throw new TypeError(); // TODO message - } - var name = ''; - while (owns(object, name)) { - name += '?'; - } - object[name] = true; - var returnValue = owns(object, name); - delete object[name]; - return returnValue; - }; -} -if (!Object.keys) { - var hasDontEnumBug = true, - dontEnums = [ - "toString", - "toLocaleString", - "valueOf", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "constructor" - ], - dontEnumsLength = dontEnums.length; - - for (var key in {"toString": null}) { - hasDontEnumBug = false; - } - - Object.keys = function keys(object) { - - if ( - (typeof object != "object" && typeof object != "function") || - object === null - ) { - throw new TypeError("Object.keys called on a non-object"); - } - - var keys = []; - for (var name in object) { - if (owns(object, name)) { - keys.push(name); - } - } - - if (hasDontEnumBug) { - for (var i = 0, ii = dontEnumsLength; i < ii; i++) { - var dontEnum = dontEnums[i]; - if (owns(object, dontEnum)) { - keys.push(dontEnum); - } - } - } - return keys; - }; - -} -if (!Date.now) { - Date.now = function now() { - return new Date().getTime(); - }; -} -var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" + - "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + - "\u2029\uFEFF"; -if (!String.prototype.trim) { - ws = "[" + ws + "]"; - var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), - trimEndRegexp = new RegExp(ws + ws + "*$"); - String.prototype.trim = function trim() { - return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); - }; -} - -function toInteger(n) { - n = +n; - if (n !== n) { // isNaN - n = 0; - } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - return n; -} - -function isPrimitive(input) { - var type = typeof input; - return ( - input === null || - type === "undefined" || - type === "boolean" || - type === "number" || - type === "string" - ); -} - -function toPrimitive(input) { - var val, valueOf, toString; - if (isPrimitive(input)) { - return input; - } - valueOf = input.valueOf; - if (typeof valueOf === "function") { - val = valueOf.call(input); - if (isPrimitive(val)) { - return val; - } - } - toString = input.toString; - if (typeof toString === "function") { - val = toString.call(input); - if (isPrimitive(val)) { - return val; - } - } - throw new TypeError(); -} -var toObject = function (o) { - if (o == null) { // this matches both null and undefined - throw new TypeError("can't convert "+o+" to object"); - } - return Object(o); -}; - -}); diff --git a/htdocs/includes/ace/src/worker-css.js b/htdocs/includes/ace/src/worker-css.js index a7d914e3397..8cccc059adb 100644 --- a/htdocs/includes/ace/src/worker-css.js +++ b/htdocs/includes/ace/src/worker-css.js @@ -209,7 +209,6 @@ window.onmessage = function(e) { } else if (msg.init) { window.initBaseUrls(msg.tlns); - require("ace/lib/es5-shim"); sender = window.sender = window.initSender(); var clazz = require(msg.module)[msg.classname]; main = window.main = new clazz(sender); @@ -787,8 +786,8 @@ EventEmitter._signal = function(eventName, e) { EventEmitter.once = function(eventName, callback) { var _self = this; - this.addEventListener(eventName, function newCallback() { - _self.removeEventListener(eventName, newCallback); + this.on(eventName, function newCallback() { + _self.off(eventName, newCallback); callback.apply(null, arguments); }); if (!callback) { @@ -860,7 +859,9 @@ EventEmitter.removeEventListener = function(eventName, callback) { }; EventEmitter.removeAllListeners = function(eventName) { - if (this._eventRegistry) this._eventRegistry[eventName] = []; + if (!eventName) this._eventRegistry = this._defaultHandlers = undefined; + if (this._eventRegistry) this._eventRegistry[eventName] = undefined; + if (this._defaultHandlers) this._defaultHandlers[eventName] = undefined; }; exports.EventEmitter = EventEmitter; @@ -960,7 +961,7 @@ var Anchor = exports.Anchor = function(doc, row, column) { }); }; this.detach = function() { - this.document.removeEventListener("change", this.$onChange); + this.document.off("change", this.$onChange); }; this.attach = function(doc) { this.document = doc || this.document; @@ -1292,6 +1293,16 @@ var Document = function(textOrLines) { } }; + this.$safeApplyDelta = function(delta) { + var docLength = this.$lines.length; + if ( + delta.action == "remove" && delta.start.row < docLength && delta.end.row < docLength + || delta.action == "insert" && delta.start.row <= docLength + ) { + this.applyDelta(delta); + } + }; + this.$splitAndapplyLargeDelta = function(delta, MAX) { var lines = delta.lines; var l = lines.length - MAX + 1; @@ -1314,7 +1325,7 @@ var Document = function(textOrLines) { this.applyDelta(delta, true); }; this.revertDelta = function(delta) { - this.applyDelta({ + this.$safeApplyDelta({ start: this.clonePos(delta.start), end: this.clonePos(delta.end), action: (delta.action == "insert" ? "remove" : "insert"), @@ -1410,589 +1421,217 @@ var Mirror = exports.Mirror = function(sender) { }); define("ace/mode/css/csslint",[], function(require, exports, module) { -var parserlib = {}; -(function(){ -function EventTarget(){ - this._listeners = {}; -} -EventTarget.prototype = { - constructor: EventTarget, - addListener: function(type, listener){ - if (!this._listeners[type]){ - this._listeners[type] = []; - } +var CSSLint = (function(){ + var module = module || {}, + exports = exports || {}; +var parserlib = (function () { +var require; +require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i= 0 && this._ltIndex < this._lt.length){ - - i++; - this._token = this._lt[this._ltIndex++]; - info = tokenInfo[this._token.type]; - while((info.channel !== undefined && channel !== info.channel) && - this._ltIndex < this._lt.length){ - this._token = this._lt[this._ltIndex++]; - info = tokenInfo[this._token.type]; - i++; - } - if ((info.channel === undefined || channel === info.channel) && - this._ltIndex <= this._lt.length){ - this._ltIndexCache.push(i); - return this._token.type; - } - } - token = this._getToken(); - if (token.type > -1 && !tokenInfo[token.type].hide){ - token.channel = tokenInfo[token.type].channel; - this._token = token; - this._lt.push(token); - this._ltIndexCache.push(this._lt.length - this._ltIndex + i); - if (this._lt.length > 5){ - this._lt.shift(); - } - if (this._ltIndexCache.length > 5){ - this._ltIndexCache.shift(); - } - this._ltIndex = this._lt.length; - } - info = tokenInfo[token.type]; - if (info && - (info.hide || - (info.channel !== undefined && channel !== info.channel))){ - return this.get(channel); - } else { - return token.type; - } - }, - LA: function(index){ - var total = index, - tt; - if (index > 0){ - if (index > 5){ - throw new Error("Too much lookahead."); - } - while(total){ - tt = this.get(); - total--; - } - while(total < index){ - this.unget(); - total++; - } - } else if (index < 0){ - - if(this._lt[this._ltIndex+index]){ - tt = this._lt[this._ltIndex+index].type; - } else { - throw new Error("Too much lookbehind."); - } - - } else { - tt = this._token.type; - } - - return tt; - - }, - LT: function(index){ - this.LA(index); - return this._lt[this._ltIndex+index-1]; - }, - peek: function(){ - return this.LA(1); - }, - token: function(){ - return this._token; - }, - tokenName: function(tokenType){ - if (tokenType < 0 || tokenType > this._tokenData.length){ - return "UNKNOWN_TOKEN"; - } else { - return this._tokenData[tokenType].name; - } - }, - tokenType: function(tokenName){ - return this._tokenData[tokenName] || -1; - }, - unget: function(){ - if (this._ltIndexCache.length){ - this._ltIndex -= this._ltIndexCache.pop();//--; - this._token = this._lt[this._ltIndex - 1]; - } else { - throw new Error("Too much lookahead."); - } - } - -}; - - -parserlib.util = { -StringReader: StringReader, -SyntaxError : SyntaxError, -SyntaxUnit : SyntaxUnit, -EventTarget : EventTarget, -TokenStreamBase : TokenStreamBase -}; -})(); -(function(){ -var EventTarget = parserlib.util.EventTarget, -TokenStreamBase = parserlib.util.TokenStreamBase, -StringReader = parserlib.util.StringReader, -SyntaxError = parserlib.util.SyntaxError, -SyntaxUnit = parserlib.util.SyntaxUnit; - -var Colors = { - aliceblue :"#f0f8ff", - antiquewhite :"#faebd7", - aqua :"#00ffff", - aquamarine :"#7fffd4", - azure :"#f0ffff", - beige :"#f5f5dc", - bisque :"#ffe4c4", - black :"#000000", - blanchedalmond :"#ffebcd", - blue :"#0000ff", - blueviolet :"#8a2be2", - brown :"#a52a2a", - burlywood :"#deb887", - cadetblue :"#5f9ea0", - chartreuse :"#7fff00", - chocolate :"#d2691e", - coral :"#ff7f50", - cornflowerblue :"#6495ed", - cornsilk :"#fff8dc", - crimson :"#dc143c", - cyan :"#00ffff", - darkblue :"#00008b", - darkcyan :"#008b8b", - darkgoldenrod :"#b8860b", - darkgray :"#a9a9a9", - darkgrey :"#a9a9a9", - darkgreen :"#006400", - darkkhaki :"#bdb76b", - darkmagenta :"#8b008b", - darkolivegreen :"#556b2f", - darkorange :"#ff8c00", - darkorchid :"#9932cc", - darkred :"#8b0000", - darksalmon :"#e9967a", - darkseagreen :"#8fbc8f", - darkslateblue :"#483d8b", - darkslategray :"#2f4f4f", - darkslategrey :"#2f4f4f", - darkturquoise :"#00ced1", - darkviolet :"#9400d3", - deeppink :"#ff1493", - deepskyblue :"#00bfff", - dimgray :"#696969", - dimgrey :"#696969", - dodgerblue :"#1e90ff", - firebrick :"#b22222", - floralwhite :"#fffaf0", - forestgreen :"#228b22", - fuchsia :"#ff00ff", - gainsboro :"#dcdcdc", - ghostwhite :"#f8f8ff", - gold :"#ffd700", - goldenrod :"#daa520", - gray :"#808080", - grey :"#808080", - green :"#008000", - greenyellow :"#adff2f", - honeydew :"#f0fff0", - hotpink :"#ff69b4", - indianred :"#cd5c5c", - indigo :"#4b0082", - ivory :"#fffff0", - khaki :"#f0e68c", - lavender :"#e6e6fa", - lavenderblush :"#fff0f5", - lawngreen :"#7cfc00", - lemonchiffon :"#fffacd", - lightblue :"#add8e6", - lightcoral :"#f08080", - lightcyan :"#e0ffff", - lightgoldenrodyellow :"#fafad2", - lightgray :"#d3d3d3", - lightgrey :"#d3d3d3", - lightgreen :"#90ee90", - lightpink :"#ffb6c1", - lightsalmon :"#ffa07a", - lightseagreen :"#20b2aa", - lightskyblue :"#87cefa", - lightslategray :"#778899", - lightslategrey :"#778899", - lightsteelblue :"#b0c4de", - lightyellow :"#ffffe0", - lime :"#00ff00", - limegreen :"#32cd32", - linen :"#faf0e6", - magenta :"#ff00ff", - maroon :"#800000", - mediumaquamarine:"#66cdaa", - mediumblue :"#0000cd", - mediumorchid :"#ba55d3", - mediumpurple :"#9370d8", - mediumseagreen :"#3cb371", - mediumslateblue :"#7b68ee", - mediumspringgreen :"#00fa9a", - mediumturquoise :"#48d1cc", - mediumvioletred :"#c71585", - midnightblue :"#191970", - mintcream :"#f5fffa", - mistyrose :"#ffe4e1", - moccasin :"#ffe4b5", - navajowhite :"#ffdead", - navy :"#000080", - oldlace :"#fdf5e6", - olive :"#808000", - olivedrab :"#6b8e23", - orange :"#ffa500", - orangered :"#ff4500", - orchid :"#da70d6", - palegoldenrod :"#eee8aa", - palegreen :"#98fb98", - paleturquoise :"#afeeee", - palevioletred :"#d87093", - papayawhip :"#ffefd5", - peachpuff :"#ffdab9", - peru :"#cd853f", - pink :"#ffc0cb", - plum :"#dda0dd", - powderblue :"#b0e0e6", - purple :"#800080", - red :"#ff0000", - rosybrown :"#bc8f8f", - royalblue :"#4169e1", - saddlebrown :"#8b4513", - salmon :"#fa8072", - sandybrown :"#f4a460", - seagreen :"#2e8b57", - seashell :"#fff5ee", - sienna :"#a0522d", - silver :"#c0c0c0", - skyblue :"#87ceeb", - slateblue :"#6a5acd", - slategray :"#708090", - slategrey :"#708090", - snow :"#fffafa", - springgreen :"#00ff7f", - steelblue :"#4682b4", - tan :"#d2b48c", - teal :"#008080", - thistle :"#d8bfd8", - tomato :"#ff6347", - turquoise :"#40e0d0", - violet :"#ee82ee", - wheat :"#f5deb3", - white :"#ffffff", - whitesmoke :"#f5f5f5", - yellow :"#ffff00", - yellowgreen :"#9acd32", - activeBorder :"Active window border.", - activecaption :"Active window caption.", - appworkspace :"Background color of multiple document interface.", - background :"Desktop background.", - buttonface :"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.", - buttonhighlight :"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.", - buttonshadow :"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.", - buttontext :"Text on push buttons.", - captiontext :"Text in caption, size box, and scrollbar arrow box.", - graytext :"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.", - greytext :"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.", - highlight :"Item(s) selected in a control.", - highlighttext :"Text of item(s) selected in a control.", - inactiveborder :"Inactive window border.", - inactivecaption :"Inactive window caption.", - inactivecaptiontext :"Color of text in an inactive caption.", - infobackground :"Background color for tooltip controls.", - infotext :"Text color for tooltip controls.", - menu :"Menu background.", - menutext :"Text in menus.", - scrollbar :"Scroll bar gray area.", - threeddarkshadow :"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - threedface :"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - threedhighlight :"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - threedlightshadow :"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - threedshadow :"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", - window :"Window background.", - windowframe :"Window frame.", - windowtext :"Text in windows." -}; -function Combinator(text, line, col){ +var Parser = require("./Parser"); +function Combinator(text, line, col) { SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE); this.type = "unknown"; - if (/^\s+$/.test(text)){ + if (/^\s+$/.test(text)) { this.type = "descendant"; - } else if (text == ">"){ + } else if (text === ">") { this.type = "child"; - } else if (text == "+"){ + } else if (text === "+") { this.type = "adjacent-sibling"; - } else if (text == "~"){ + } else if (text === "~") { this.type = "sibling"; } @@ -2000,7 +1639,322 @@ function Combinator(text, line, col){ Combinator.prototype = new SyntaxUnit(); Combinator.prototype.constructor = Combinator; -function MediaFeature(name, value){ + + +},{"../util/SyntaxUnit":26,"./Parser":6}],3:[function(require,module,exports){ +"use strict"; + +module.exports = Matcher; + +var StringReader = require("../util/StringReader"); +var SyntaxError = require("../util/SyntaxError"); +function Matcher(matchFunc, toString) { + this.match = function(expression) { + var result; + expression.mark(); + result = matchFunc(expression); + if (result) { + expression.drop(); + } else { + expression.restore(); + } + return result; + }; + this.toString = typeof toString === "function" ? toString : function() { + return toString; + }; +} +Matcher.prec = { + MOD: 5, + SEQ: 4, + ANDAND: 3, + OROR: 2, + ALT: 1 +}; +Matcher.parse = function(str) { + var reader, eat, expr, oror, andand, seq, mod, term, result; + reader = new StringReader(str); + eat = function(matcher) { + var result = reader.readMatch(matcher); + if (result === null) { + throw new SyntaxError( + "Expected " + matcher, reader.getLine(), reader.getCol()); + } + return result; + }; + expr = function() { + var m = [ oror() ]; + while (reader.readMatch(" | ") !== null) { + m.push(oror()); + } + return m.length === 1 ? m[0] : Matcher.alt.apply(Matcher, m); + }; + oror = function() { + var m = [ andand() ]; + while (reader.readMatch(" || ") !== null) { + m.push(andand()); + } + return m.length === 1 ? m[0] : Matcher.oror.apply(Matcher, m); + }; + andand = function() { + var m = [ seq() ]; + while (reader.readMatch(" && ") !== null) { + m.push(seq()); + } + return m.length === 1 ? m[0] : Matcher.andand.apply(Matcher, m); + }; + seq = function() { + var m = [ mod() ]; + while (reader.readMatch(/^ (?![&|\]])/) !== null) { + m.push(mod()); + } + return m.length === 1 ? m[0] : Matcher.seq.apply(Matcher, m); + }; + mod = function() { + var m = term(); + if (reader.readMatch("?") !== null) { + return m.question(); + } else if (reader.readMatch("*") !== null) { + return m.star(); + } else if (reader.readMatch("+") !== null) { + return m.plus(); + } else if (reader.readMatch("#") !== null) { + return m.hash(); + } else if (reader.readMatch(/^\{\s*/) !== null) { + var min = eat(/^\d+/); + eat(/^\s*,\s*/); + var max = eat(/^\d+/); + eat(/^\s*\}/); + return m.braces(Number(min), Number(max)); + } + return m; + }; + term = function() { + if (reader.readMatch("[ ") !== null) { + var m = expr(); + eat(" ]"); + return m; + } + return Matcher.fromType(eat(/^[^ ?*+#{]+/)); + }; + result = expr(); + if (!reader.eof()) { + throw new SyntaxError( + "Expected end of string", reader.getLine(), reader.getCol()); + } + return result; +}; +Matcher.cast = function(m) { + if (m instanceof Matcher) { + return m; + } + return Matcher.parse(m); +}; +Matcher.fromType = function(type) { + var ValidationTypes = require("./ValidationTypes"); + return new Matcher(function(expression) { + return expression.hasNext() && ValidationTypes.isType(expression, type); + }, type); +}; +Matcher.seq = function() { + var ms = Array.prototype.slice.call(arguments).map(Matcher.cast); + if (ms.length === 1) { + return ms[0]; + } + return new Matcher(function(expression) { + var i, result = true; + for (i = 0; result && i < ms.length; i++) { + result = ms[i].match(expression); + } + return result; + }, function(prec) { + var p = Matcher.prec.SEQ; + var s = ms.map(function(m) { + return m.toString(p); + }).join(" "); + if (prec > p) { + s = "[ " + s + " ]"; + } + return s; + }); +}; +Matcher.alt = function() { + var ms = Array.prototype.slice.call(arguments).map(Matcher.cast); + if (ms.length === 1) { + return ms[0]; + } + return new Matcher(function(expression) { + var i, result = false; + for (i = 0; !result && i < ms.length; i++) { + result = ms[i].match(expression); + } + return result; + }, function(prec) { + var p = Matcher.prec.ALT; + var s = ms.map(function(m) { + return m.toString(p); + }).join(" | "); + if (prec > p) { + s = "[ " + s + " ]"; + } + return s; + }); +}; +Matcher.many = function(required) { + var ms = Array.prototype.slice.call(arguments, 1).reduce(function(acc, v) { + if (v.expand) { + var ValidationTypes = require("./ValidationTypes"); + acc.push.apply(acc, ValidationTypes.complex[v.expand].options); + } else { + acc.push(Matcher.cast(v)); + } + return acc; + }, []); + + if (required === true) { + required = ms.map(function() { + return true; + }); + } + + var result = new Matcher(function(expression) { + var seen = [], max = 0, pass = 0; + var success = function(matchCount) { + if (pass === 0) { + max = Math.max(matchCount, max); + return matchCount === ms.length; + } else { + return matchCount === max; + } + }; + var tryMatch = function(matchCount) { + for (var i = 0; i < ms.length; i++) { + if (seen[i]) { + continue; + } + expression.mark(); + if (ms[i].match(expression)) { + seen[i] = true; + if (tryMatch(matchCount + (required === false || required[i] ? 1 : 0))) { + expression.drop(); + return true; + } + expression.restore(); + seen[i] = false; + } else { + expression.drop(); + } + } + return success(matchCount); + }; + if (!tryMatch(0)) { + pass++; + tryMatch(0); + } + + if (required === false) { + return max > 0; + } + for (var i = 0; i < ms.length; i++) { + if (required[i] && !seen[i]) { + return false; + } + } + return true; + }, function(prec) { + var p = required === false ? Matcher.prec.OROR : Matcher.prec.ANDAND; + var s = ms.map(function(m, i) { + if (required !== false && !required[i]) { + return m.toString(Matcher.prec.MOD) + "?"; + } + return m.toString(p); + }).join(required === false ? " || " : " && "); + if (prec > p) { + s = "[ " + s + " ]"; + } + return s; + }); + result.options = ms; + return result; +}; +Matcher.andand = function() { + var args = Array.prototype.slice.call(arguments); + args.unshift(true); + return Matcher.many.apply(Matcher, args); +}; +Matcher.oror = function() { + var args = Array.prototype.slice.call(arguments); + args.unshift(false); + return Matcher.many.apply(Matcher, args); +}; +Matcher.prototype = { + constructor: Matcher, + match: function() { + throw new Error("unimplemented"); + }, + toString: function() { + throw new Error("unimplemented"); + }, + func: function() { + return this.match.bind(this); + }, + then: function(m) { + return Matcher.seq(this, m); + }, + or: function(m) { + return Matcher.alt(this, m); + }, + andand: function(m) { + return Matcher.many(true, this, m); + }, + oror: function(m) { + return Matcher.many(false, this, m); + }, + star: function() { + return this.braces(0, Infinity, "*"); + }, + plus: function() { + return this.braces(1, Infinity, "+"); + }, + question: function() { + return this.braces(0, 1, "?"); + }, + hash: function() { + return this.braces(1, Infinity, "#", Matcher.cast(",")); + }, + braces: function(min, max, marker, optSep) { + var m1 = this, m2 = optSep ? optSep.then(this) : this; + if (!marker) { + marker = "{" + min + "," + max + "}"; + } + return new Matcher(function(expression) { + var result = true, i; + for (i = 0; i < max; i++) { + if (i > 0 && optSep) { + result = m2.match(expression); + } else { + result = m1.match(expression); + } + if (!result) { + break; + } + } + return i >= min; + }, function() { + return m1.toString(Matcher.prec.MOD) + marker; + }); + } +}; + +},{"../util/StringReader":24,"../util/SyntaxError":25,"./ValidationTypes":21}],4:[function(require,module,exports){ +"use strict"; + +module.exports = MediaFeature; + +var SyntaxUnit = require("../util/SyntaxUnit"); + +var Parser = require("./Parser"); +function MediaFeature(name, value) { SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE); this.name = name; @@ -2009,9 +1963,19 @@ function MediaFeature(name, value){ MediaFeature.prototype = new SyntaxUnit(); MediaFeature.prototype.constructor = MediaFeature; -function MediaQuery(modifier, mediaType, features, line, col){ - SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); + +},{"../util/SyntaxUnit":26,"./Parser":6}],5:[function(require,module,exports){ +"use strict"; + +module.exports = MediaQuery; + +var SyntaxUnit = require("../util/SyntaxUnit"); + +var Parser = require("./Parser"); +function MediaQuery(modifier, mediaType, features, line, col) { + + SyntaxUnit.call(this, (modifier ? modifier + " " : "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); this.modifier = modifier; this.mediaType = mediaType; this.features = features; @@ -2020,7 +1984,30 @@ function MediaQuery(modifier, mediaType, features, line, col){ MediaQuery.prototype = new SyntaxUnit(); MediaQuery.prototype.constructor = MediaQuery; -function Parser(options){ + + +},{"../util/SyntaxUnit":26,"./Parser":6}],6:[function(require,module,exports){ +"use strict"; + +module.exports = Parser; + +var EventTarget = require("../util/EventTarget"); +var SyntaxError = require("../util/SyntaxError"); +var SyntaxUnit = require("../util/SyntaxUnit"); + +var Combinator = require("./Combinator"); +var MediaFeature = require("./MediaFeature"); +var MediaQuery = require("./MediaQuery"); +var PropertyName = require("./PropertyName"); +var PropertyValue = require("./PropertyValue"); +var PropertyValuePart = require("./PropertyValuePart"); +var Selector = require("./Selector"); +var SelectorPart = require("./SelectorPart"); +var SelectorSubPart = require("./SelectorSubPart"); +var TokenStream = require("./TokenStream"); +var Tokens = require("./Tokens"); +var Validation = require("./Validation"); +function Parser(options) { EventTarget.call(this); @@ -2039,11 +2026,12 @@ Parser.SELECTOR_TYPE = 7; Parser.SELECTOR_PART_TYPE = 8; Parser.SELECTOR_SUB_PART_TYPE = 9; -Parser.prototype = function(){ +Parser.prototype = function() { - var proto = new EventTarget(), //new prototype + var proto = new EventTarget(), // new prototype prop, additions = { + __proto__: null, constructor: Parser, DEFAULT_TYPE : 0, COMBINATOR_TYPE : 1, @@ -2056,10 +2044,9 @@ Parser.prototype = function(){ SELECTOR_PART_TYPE : 8, SELECTOR_SUB_PART_TYPE : 9, - _stylesheet: function(){ + _stylesheet: function() { var tokenStream = this._tokenStream, - charset = null, count, token, tt; @@ -2068,20 +2055,20 @@ Parser.prototype = function(){ this._charset(); this._skipCruft(); - while (tokenStream.peek() == Tokens.IMPORT_SYM){ + while (tokenStream.peek() === Tokens.IMPORT_SYM) { this._import(); this._skipCruft(); } - while (tokenStream.peek() == Tokens.NAMESPACE_SYM){ + while (tokenStream.peek() === Tokens.NAMESPACE_SYM) { this._namespace(); this._skipCruft(); } tt = tokenStream.peek(); - while(tt > Tokens.EOF){ + while (tt > Tokens.EOF) { try { - switch(tt){ + switch (tt) { case Tokens.MEDIA_SYM: this._media(); this._skipCruft(); @@ -2102,9 +2089,17 @@ Parser.prototype = function(){ this._viewport(); this._skipCruft(); break; - case Tokens.UNKNOWN_SYM: //unknown @ rule + case Tokens.DOCUMENT_SYM: + this._document(); + this._skipCruft(); + break; + case Tokens.SUPPORTS_SYM: + this._supports(); + this._skipCruft(); + break; + case Tokens.UNKNOWN_SYM: // unknown @ rule tokenStream.get(); - if (!this.options.strict){ + if (!this.options.strict) { this.fire({ type: "error", error: null, @@ -2112,12 +2107,12 @@ Parser.prototype = function(){ line: tokenStream.LT(0).startLine, col: tokenStream.LT(0).startCol }); - count=0; - while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){ - count++; //keep track of nesting depth + count = 0; + while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) === Tokens.LBRACE) { + count++; // keep track of nesting depth } - while(count){ + while (count) { tokenStream.advance([Tokens.RBRACE]); count--; } @@ -2130,8 +2125,8 @@ Parser.prototype = function(){ this._readWhitespace(); break; default: - if(!this._ruleset()){ - switch(tt){ + if (!this._ruleset()) { + switch (tt) { case Tokens.CHARSET_SYM: token = tokenStream.LT(1); this._charset(false); @@ -2145,14 +2140,14 @@ Parser.prototype = function(){ this._namespace(false); throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol); default: - tokenStream.get(); //get the last token + tokenStream.get(); // get the last token this._unexpectedToken(tokenStream.token()); } } } - } catch(ex) { - if (ex instanceof SyntaxError && !this.options.strict){ + } catch (ex) { + if (ex instanceof SyntaxError && !this.options.strict) { this.fire({ type: "error", error: ex, @@ -2168,21 +2163,21 @@ Parser.prototype = function(){ tt = tokenStream.peek(); } - if (tt != Tokens.EOF){ + if (tt !== Tokens.EOF) { this._unexpectedToken(tokenStream.token()); } this.fire("endstylesheet"); }, - _charset: function(emit){ + _charset: function(emit) { var tokenStream = this._tokenStream, charset, token, line, col; - if (tokenStream.match(Tokens.CHARSET_SYM)){ + if (tokenStream.match(Tokens.CHARSET_SYM)) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; @@ -2195,7 +2190,7 @@ Parser.prototype = function(){ this._readWhitespace(); tokenStream.mustMatch(Tokens.SEMICOLON); - if (emit !== false){ + if (emit !== false) { this.fire({ type: "charset", charset:charset, @@ -2206,10 +2201,9 @@ Parser.prototype = function(){ } }, - _import: function(emit){ + _import: function(emit) { var tokenStream = this._tokenStream, - tt, uri, importToken, mediaList = []; @@ -2226,7 +2220,7 @@ Parser.prototype = function(){ tokenStream.mustMatch(Tokens.SEMICOLON); this._readWhitespace(); - if (emit !== false){ + if (emit !== false) { this.fire({ type: "import", uri: uri, @@ -2238,7 +2232,7 @@ Parser.prototype = function(){ }, - _namespace: function(emit){ + _namespace: function(emit) { var tokenStream = this._tokenStream, line, @@ -2249,7 +2243,7 @@ Parser.prototype = function(){ line = tokenStream.token().startLine; col = tokenStream.token().startCol; this._readWhitespace(); - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { prefix = tokenStream.token().value; this._readWhitespace(); } @@ -2261,7 +2255,7 @@ Parser.prototype = function(){ tokenStream.mustMatch(Tokens.SEMICOLON); this._readWhitespace(); - if (emit !== false){ + if (emit !== false) { this.fire({ type: "namespace", prefix: prefix, @@ -2273,11 +2267,119 @@ Parser.prototype = function(){ }, - _media: function(){ + _supports: function(emit) { + var tokenStream = this._tokenStream, + line, + col; + + if (tokenStream.match(Tokens.SUPPORTS_SYM)) { + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + + this._readWhitespace(); + this._supports_condition(); + this._readWhitespace(); + + tokenStream.mustMatch(Tokens.LBRACE); + this._readWhitespace(); + + if (emit !== false) { + this.fire({ + type: "startsupports", + line: line, + col: col + }); + } + + while (true) { + if (!this._ruleset()) { + break; + } + } + + tokenStream.mustMatch(Tokens.RBRACE); + this._readWhitespace(); + + this.fire({ + type: "endsupports", + line: line, + col: col + }); + } + }, + + _supports_condition: function() { + var tokenStream = this._tokenStream, + ident; + + if (tokenStream.match(Tokens.IDENT)) { + ident = tokenStream.token().value.toLowerCase(); + + if (ident === "not") { + tokenStream.mustMatch(Tokens.S); + this._supports_condition_in_parens(); + } else { + tokenStream.unget(); + } + } else { + this._supports_condition_in_parens(); + this._readWhitespace(); + + while (tokenStream.peek() === Tokens.IDENT) { + ident = tokenStream.LT(1).value.toLowerCase(); + if (ident === "and" || ident === "or") { + tokenStream.mustMatch(Tokens.IDENT); + this._readWhitespace(); + this._supports_condition_in_parens(); + this._readWhitespace(); + } + } + } + }, + + _supports_condition_in_parens: function() { + var tokenStream = this._tokenStream, + ident; + + if (tokenStream.match(Tokens.LPAREN)) { + this._readWhitespace(); + if (tokenStream.match(Tokens.IDENT)) { + ident = tokenStream.token().value.toLowerCase(); + if (ident === "not") { + this._readWhitespace(); + this._supports_condition(); + this._readWhitespace(); + tokenStream.mustMatch(Tokens.RPAREN); + } else { + tokenStream.unget(); + this._supports_declaration_condition(false); + } + } else { + this._supports_condition(); + this._readWhitespace(); + tokenStream.mustMatch(Tokens.RPAREN); + } + } else { + this._supports_declaration_condition(); + } + }, + + _supports_declaration_condition: function(requireStartParen) { + var tokenStream = this._tokenStream; + + if (requireStartParen !== false) { + tokenStream.mustMatch(Tokens.LPAREN); + } + this._readWhitespace(); + this._declaration(); + tokenStream.mustMatch(Tokens.RPAREN); + }, + + _media: function() { var tokenStream = this._tokenStream, line, col, - mediaList;// = []; + mediaList; // = []; tokenStream.mustMatch(Tokens.MEDIA_SYM); line = tokenStream.token().startLine; col = tokenStream.token().startCol; @@ -2296,14 +2398,20 @@ Parser.prototype = function(){ col: col }); - while(true) { - if (tokenStream.peek() == Tokens.PAGE_SYM){ + while (true) { + if (tokenStream.peek() === Tokens.PAGE_SYM) { this._page(); - } else if (tokenStream.peek() == Tokens.FONT_FACE_SYM){ + } else if (tokenStream.peek() === Tokens.FONT_FACE_SYM) { this._font_face(); - } else if (tokenStream.peek() == Tokens.VIEWPORT_SYM){ + } else if (tokenStream.peek() === Tokens.VIEWPORT_SYM) { this._viewport(); - } else if (!this._ruleset()){ + } else if (tokenStream.peek() === Tokens.DOCUMENT_SYM) { + this._document(); + } else if (tokenStream.peek() === Tokens.SUPPORTS_SYM) { + this._supports(); + } else if (tokenStream.peek() === Tokens.MEDIA_SYM) { + this._media(); + } else if (!this._ruleset()) { break; } } @@ -2318,34 +2426,34 @@ Parser.prototype = function(){ col: col }); }, - _media_query_list: function(){ + _media_query_list: function() { var tokenStream = this._tokenStream, mediaList = []; this._readWhitespace(); - if (tokenStream.peek() == Tokens.IDENT || tokenStream.peek() == Tokens.LPAREN){ + if (tokenStream.peek() === Tokens.IDENT || tokenStream.peek() === Tokens.LPAREN) { mediaList.push(this._media_query()); } - while(tokenStream.match(Tokens.COMMA)){ + while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); mediaList.push(this._media_query()); } return mediaList; }, - _media_query: function(){ + _media_query: function() { var tokenStream = this._tokenStream, type = null, ident = null, token = null, expressions = []; - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { ident = tokenStream.token().value.toLowerCase(); - if (ident != "only" && ident != "not"){ + if (ident !== "only" && ident !== "not") { tokenStream.unget(); ident = null; } else { @@ -2355,24 +2463,24 @@ Parser.prototype = function(){ this._readWhitespace(); - if (tokenStream.peek() == Tokens.IDENT){ + if (tokenStream.peek() === Tokens.IDENT) { type = this._media_type(); - if (token === null){ + if (token === null) { token = tokenStream.token(); } - } else if (tokenStream.peek() == Tokens.LPAREN){ - if (token === null){ + } else if (tokenStream.peek() === Tokens.LPAREN) { + if (token === null) { token = tokenStream.LT(1); } expressions.push(this._media_expression()); } - if (type === null && expressions.length === 0){ + if (type === null && expressions.length === 0) { return null; } else { this._readWhitespace(); - while (tokenStream.match(Tokens.IDENT)){ - if (tokenStream.token().value.toLowerCase() != "and"){ + while (tokenStream.match(Tokens.IDENT)) { + if (tokenStream.token().value.toLowerCase() !== "and") { this._unexpectedToken(tokenStream.token()); } @@ -2383,10 +2491,10 @@ Parser.prototype = function(){ return new MediaQuery(ident, type, expressions, token.startLine, token.startCol); }, - _media_type: function(){ + _media_type: function() { return this._media_feature(); }, - _media_expression: function(){ + _media_expression: function() { var tokenStream = this._tokenStream, feature = null, token, @@ -2398,7 +2506,7 @@ Parser.prototype = function(){ feature = this._media_feature(); this._readWhitespace(); - if (tokenStream.match(Tokens.COLON)){ + if (tokenStream.match(Tokens.COLON)) { this._readWhitespace(); token = tokenStream.LT(1); expression = this._expression(); @@ -2407,16 +2515,18 @@ Parser.prototype = function(){ tokenStream.mustMatch(Tokens.RPAREN); this._readWhitespace(); - return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null)); + return new MediaFeature(feature, expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null); }, - _media_feature: function(){ + _media_feature: function() { var tokenStream = this._tokenStream; + this._readWhitespace(); + tokenStream.mustMatch(Tokens.IDENT); return SyntaxUnit.fromToken(tokenStream.token()); }, - _page: function(){ + _page: function() { var tokenStream = this._tokenStream, line, col, @@ -2428,13 +2538,13 @@ Parser.prototype = function(){ this._readWhitespace(); - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { identifier = tokenStream.token().value; - if (identifier.toLowerCase() === "auto"){ + if (identifier.toLowerCase() === "auto") { this._unexpectedToken(tokenStream.token()); } } - if (tokenStream.peek() == Tokens.COLON){ + if (tokenStream.peek() === Tokens.COLON) { pseudoPage = this._pseudo_page(); } @@ -2459,13 +2569,13 @@ Parser.prototype = function(){ }); }, - _margin: function(){ + _margin: function() { var tokenStream = this._tokenStream, line, col, marginSym = this._margin_sym(); - if (marginSym){ + if (marginSym) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; @@ -2489,18 +2599,17 @@ Parser.prototype = function(){ return false; } }, - _margin_sym: function(){ + _margin_sym: function() { var tokenStream = this._tokenStream; - if(tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM, - Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM, - Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM, - Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM, - Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM, - Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM, - Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) - { + if (tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM, + Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM, + Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM, + Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM, + Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM, + Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM, + Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) { return SyntaxUnit.fromToken(tokenStream.token()); } else { return null; @@ -2508,7 +2617,7 @@ Parser.prototype = function(){ }, - _pseudo_page: function(){ + _pseudo_page: function() { var tokenStream = this._tokenStream; @@ -2518,7 +2627,7 @@ Parser.prototype = function(){ return tokenStream.token().value; }, - _font_face: function(){ + _font_face: function() { var tokenStream = this._tokenStream, line, col; @@ -2543,40 +2652,126 @@ Parser.prototype = function(){ }); }, - _viewport: function(){ - var tokenStream = this._tokenStream, + _viewport: function() { + var tokenStream = this._tokenStream, line, col; - tokenStream.mustMatch(Tokens.VIEWPORT_SYM); - line = tokenStream.token().startLine; - col = tokenStream.token().startCol; + tokenStream.mustMatch(Tokens.VIEWPORT_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; - this._readWhitespace(); + this._readWhitespace(); - this.fire({ - type: "startviewport", - line: line, - col: col - }); + this.fire({ + type: "startviewport", + line: line, + col: col + }); - this._readDeclarations(true); + this._readDeclarations(true); - this.fire({ - type: "endviewport", - line: line, - col: col - }); + this.fire({ + type: "endviewport", + line: line, + col: col + }); }, - _operator: function(inFunction){ + _document: function() { + + var tokenStream = this._tokenStream, + token, + functions = [], + prefix = ""; + + tokenStream.mustMatch(Tokens.DOCUMENT_SYM); + token = tokenStream.token(); + if (/^@-([^-]+)-/.test(token.value)) { + prefix = RegExp.$1; + } + + this._readWhitespace(); + functions.push(this._document_function()); + + while (tokenStream.match(Tokens.COMMA)) { + this._readWhitespace(); + functions.push(this._document_function()); + } + + tokenStream.mustMatch(Tokens.LBRACE); + this._readWhitespace(); + + this.fire({ + type: "startdocument", + functions: functions, + prefix: prefix, + line: token.startLine, + col: token.startCol + }); + + var ok = true; + while (ok) { + switch (tokenStream.peek()) { + case Tokens.PAGE_SYM: + this._page(); + break; + case Tokens.FONT_FACE_SYM: + this._font_face(); + break; + case Tokens.VIEWPORT_SYM: + this._viewport(); + break; + case Tokens.MEDIA_SYM: + this._media(); + break; + case Tokens.KEYFRAMES_SYM: + this._keyframes(); + break; + case Tokens.DOCUMENT_SYM: + this._document(); + break; + default: + ok = Boolean(this._ruleset()); + } + } + + tokenStream.mustMatch(Tokens.RBRACE); + token = tokenStream.token(); + this._readWhitespace(); + + this.fire({ + type: "enddocument", + functions: functions, + prefix: prefix, + line: token.startLine, + col: token.startCol + }); + }, + + _document_function: function() { + + var tokenStream = this._tokenStream, + value; + + if (tokenStream.match(Tokens.URI)) { + value = tokenStream.token().value; + this._readWhitespace(); + } else { + value = this._function(); + } + + return value; + }, + + _operator: function(inFunction) { var tokenStream = this._tokenStream, token = null; if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) || - (inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))){ + inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS])) { token = tokenStream.token(); this._readWhitespace(); } @@ -2584,13 +2779,13 @@ Parser.prototype = function(){ }, - _combinator: function(){ + _combinator: function() { var tokenStream = this._tokenStream, value = null, token; - if(tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])){ + if (tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])) { token = tokenStream.token(); value = new Combinator(token.value, token.startLine, token.startCol); this._readWhitespace(); @@ -2599,57 +2794,67 @@ Parser.prototype = function(){ return value; }, - _unary_operator: function(){ + _unary_operator: function() { var tokenStream = this._tokenStream; - if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){ + if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])) { return tokenStream.token().value; } else { return null; } }, - _property: function(){ + _property: function() { - var tokenStream = this._tokenStream, - value = null, - hack = null, - tokenValue, + var tokenStream = this._tokenStream, + value = null, + hack = null, + propertyName = "", token, line, col; - if (tokenStream.peek() == Tokens.STAR && this.options.starHack){ + if (tokenStream.peek() === Tokens.STAR && this.options.starHack) { tokenStream.get(); token = tokenStream.token(); hack = token.value; line = token.startLine; col = token.startCol; } - - if(tokenStream.match(Tokens.IDENT)){ + if (tokenStream.peek() === Tokens.MINUS) { + tokenStream.get(); token = tokenStream.token(); - tokenValue = token.value; - if (tokenValue.charAt(0) == "_" && this.options.underscoreHack){ + propertyName = token.value; + line = token.startLine; + col = token.startCol; + } + + if (tokenStream.match(Tokens.IDENT)) { + token = tokenStream.token(); + propertyName += token.value; + if (propertyName.charAt(0) === "_" && this.options.underscoreHack) { hack = "_"; - tokenValue = tokenValue.substring(1); + propertyName = propertyName.substring(1); } - value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol)); + value = new PropertyName(propertyName, hack, line || token.startLine, col || token.startCol); this._readWhitespace(); + } else if (tokenStream.peek() === Tokens.RBRACE) { + } else { + this._unexpectedToken(tokenStream.LT(1)); } return value; }, - _ruleset: function(){ + _ruleset: function() { var tokenStream = this._tokenStream, tt, selectors; try { selectors = this._selectors_group(); - } catch (ex){ - if (ex instanceof SyntaxError && !this.options.strict){ + } catch (ex) { + if (ex instanceof SyntaxError && !this.options.strict) { this.fire({ type: "error", error: ex, @@ -2658,7 +2863,7 @@ Parser.prototype = function(){ col: ex.col }); tt = tokenStream.advance([Tokens.RBRACE]); - if (tt == Tokens.RBRACE){ + if (tt === Tokens.RBRACE) { } else { throw ex; } @@ -2668,7 +2873,7 @@ Parser.prototype = function(){ } return true; } - if (selectors){ + if (selectors) { this.fire({ type: "startrule", @@ -2691,19 +2896,19 @@ Parser.prototype = function(){ return selectors; }, - _selectors_group: function(){ + _selectors_group: function() { var tokenStream = this._tokenStream, selectors = [], selector; selector = this._selector(); - if (selector !== null){ + if (selector !== null) { selectors.push(selector); - while(tokenStream.match(Tokens.COMMA)){ + while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); selector = this._selector(); - if (selector !== null){ + if (selector !== null) { selectors.push(selector); } else { this._unexpectedToken(tokenStream.LT(1)); @@ -2713,7 +2918,7 @@ Parser.prototype = function(){ return selectors.length ? selectors : null; }, - _selector: function(){ + _selector: function() { var tokenStream = this._tokenStream, selector = [], @@ -2721,7 +2926,7 @@ Parser.prototype = function(){ combinator = null, ws = null; nextSelector = this._simple_selector_sequence(); - if (nextSelector === null){ + if (nextSelector === null) { return null; } @@ -2730,26 +2935,26 @@ Parser.prototype = function(){ do { combinator = this._combinator(); - if (combinator !== null){ + if (combinator !== null) { selector.push(combinator); nextSelector = this._simple_selector_sequence(); - if (nextSelector === null){ + if (nextSelector === null) { this._unexpectedToken(tokenStream.LT(1)); } else { selector.push(nextSelector); } } else { - if (this._readWhitespace()){ + if (this._readWhitespace()) { ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol); combinator = this._combinator(); nextSelector = this._simple_selector_sequence(); - if (nextSelector === null){ - if (combinator !== null){ + if (nextSelector === null) { + if (combinator !== null) { this._unexpectedToken(tokenStream.LT(1)); } } else { - if (combinator !== null){ + if (combinator !== null) { selector.push(combinator); } else { selector.push(ws); @@ -2762,18 +2967,18 @@ Parser.prototype = function(){ } } - } while(true); + } while (true); return new Selector(selector, selector[0].line, selector[0].col); }, - _simple_selector_sequence: function(){ + _simple_selector_sequence: function() { var tokenStream = this._tokenStream, elementName = null, modifiers = [], - selectorText= "", + selectorText = "", components = [ - function(){ + function() { return tokenStream.match(Tokens.HASH) ? new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : null; @@ -2786,31 +2991,30 @@ Parser.prototype = function(){ i = 0, len = components.length, component = null, - found = false, line, col; line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; elementName = this._type_selector(); - if (!elementName){ + if (!elementName) { elementName = this._universal(); } - if (elementName !== null){ + if (elementName !== null) { selectorText += elementName; } - while(true){ - if (tokenStream.peek() === Tokens.S){ + while (true) { + if (tokenStream.peek() === Tokens.S) { break; } - while(i < len && component === null){ + while (i < len && component === null) { component = components[i++].call(this); } - if (component === null){ - if (selectorText === ""){ + if (component === null) { + if (selectorText === "") { return null; } else { break; @@ -2828,35 +3032,35 @@ Parser.prototype = function(){ new SelectorPart(elementName, modifiers, selectorText, line, col) : null; }, - _type_selector: function(){ + _type_selector: function() { var tokenStream = this._tokenStream, ns = this._namespace_prefix(), elementName = this._element_name(); - if (!elementName){ - if (ns){ + if (!elementName) { + if (ns) { tokenStream.unget(); - if (ns.length > 1){ + if (ns.length > 1) { tokenStream.unget(); } } return null; } else { - if (ns){ + if (ns) { elementName.text = ns + elementName.text; elementName.col -= ns.length; } return elementName; } }, - _class: function(){ + _class: function() { var tokenStream = this._tokenStream, token; - if (tokenStream.match(Tokens.DOT)){ + if (tokenStream.match(Tokens.DOT)) { tokenStream.mustMatch(Tokens.IDENT); token = tokenStream.token(); return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1); @@ -2865,12 +3069,12 @@ Parser.prototype = function(){ } }, - _element_name: function(){ + _element_name: function() { var tokenStream = this._tokenStream, token; - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { token = tokenStream.token(); return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol); @@ -2878,12 +3082,12 @@ Parser.prototype = function(){ return null; } }, - _namespace_prefix: function(){ + _namespace_prefix: function() { var tokenStream = this._tokenStream, value = ""; - if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){ + if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE) { - if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){ + if (tokenStream.match([Tokens.IDENT, Tokens.STAR])) { value += tokenStream.token().value; } @@ -2894,38 +3098,38 @@ Parser.prototype = function(){ return value.length ? value : null; }, - _universal: function(){ + _universal: function() { var tokenStream = this._tokenStream, value = "", ns; ns = this._namespace_prefix(); - if(ns){ + if (ns) { value += ns; } - if(tokenStream.match(Tokens.STAR)){ + if (tokenStream.match(Tokens.STAR)) { value += "*"; } return value.length ? value : null; - }, - _attrib: function(){ + }, + _attrib: function() { var tokenStream = this._tokenStream, value = null, ns, token; - if (tokenStream.match(Tokens.LBRACKET)){ + if (tokenStream.match(Tokens.LBRACKET)) { token = tokenStream.token(); value = token.value; value += this._readWhitespace(); ns = this._namespace_prefix(); - if (ns){ + if (ns) { value += ns; } @@ -2933,8 +3137,8 @@ Parser.prototype = function(){ value += tokenStream.token().value; value += this._readWhitespace(); - if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH, - Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){ + if (tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH, + Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])) { value += tokenStream.token().value; value += this._readWhitespace(); @@ -2951,7 +3155,7 @@ Parser.prototype = function(){ return null; } }, - _pseudo: function(){ + _pseudo: function() { var tokenStream = this._tokenStream, pseudo = null, @@ -2959,35 +3163,39 @@ Parser.prototype = function(){ line, col; - if (tokenStream.match(Tokens.COLON)){ + if (tokenStream.match(Tokens.COLON)) { - if (tokenStream.match(Tokens.COLON)){ + if (tokenStream.match(Tokens.COLON)) { colons += ":"; } - if (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.match(Tokens.IDENT)) { pseudo = tokenStream.token().value; line = tokenStream.token().startLine; col = tokenStream.token().startCol - colons.length; - } else if (tokenStream.peek() == Tokens.FUNCTION){ + } else if (tokenStream.peek() === Tokens.FUNCTION) { line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol - colons.length; pseudo = this._functional_pseudo(); } - if (pseudo){ + if (pseudo) { pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col); + } else { + var startLine = tokenStream.LT(1).startLine, + startCol = tokenStream.LT(0).startCol; + throw new SyntaxError("Expected a `FUNCTION` or `IDENT` after colon at line " + startLine + ", col " + startCol + ".", startLine, startCol); } } return pseudo; }, - _functional_pseudo: function(){ + _functional_pseudo: function() { var tokenStream = this._tokenStream, value = null; - if(tokenStream.match(Tokens.FUNCTION)){ + if (tokenStream.match(Tokens.FUNCTION)) { value = tokenStream.token().value; value += this._readWhitespace(); value += this._expression(); @@ -2997,15 +3205,15 @@ Parser.prototype = function(){ return value; }, - _expression: function(){ + _expression: function() { var tokenStream = this._tokenStream, value = ""; - while(tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION, - Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH, - Tokens.FREQ, Tokens.ANGLE, Tokens.TIME, - Tokens.RESOLUTION, Tokens.SLASH])){ + while (tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION, + Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH, + Tokens.FREQ, Tokens.ANGLE, Tokens.TIME, + Tokens.RESOLUTION, Tokens.SLASH])) { value += tokenStream.token().value; value += this._readWhitespace(); @@ -3014,7 +3222,7 @@ Parser.prototype = function(){ return value.length ? value : null; }, - _negation: function(){ + _negation: function() { var tokenStream = this._tokenStream, line, @@ -3023,7 +3231,7 @@ Parser.prototype = function(){ arg, subpart = null; - if (tokenStream.match(Tokens.NOT)){ + if (tokenStream.match(Tokens.NOT)) { value = tokenStream.token().value; line = tokenStream.token().startLine; col = tokenStream.token().startCol; @@ -3040,13 +3248,13 @@ Parser.prototype = function(){ return subpart; }, - _negation_arg: function(){ + _negation_arg: function() { var tokenStream = this._tokenStream, args = [ this._type_selector, this._universal, - function(){ + function() { return tokenStream.match(Tokens.HASH) ? new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : null; @@ -3058,7 +3266,6 @@ Parser.prototype = function(){ arg = null, i = 0, len = args.length, - elementName, line, col, part; @@ -3066,15 +3273,15 @@ Parser.prototype = function(){ line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; - while(i < len && arg === null){ + while (i < len && arg === null) { arg = args[i].call(this); i++; } - if (arg === null){ + if (arg === null) { this._unexpectedToken(tokenStream.LT(1)); } - if (arg.type == "elementName"){ + if (arg.type === "elementName") { part = new SelectorPart(arg, [], arg.toString(), line, col); } else { part = new SelectorPart(null, [arg], arg.toString(), line, col); @@ -3083,31 +3290,30 @@ Parser.prototype = function(){ return part; }, - _declaration: function(){ + _declaration: function() { - var tokenStream = this._tokenStream, - property = null, - expr = null, - prio = null, - error = null, - invalid = null, - propertyName= ""; + var tokenStream = this._tokenStream, + property = null, + expr = null, + prio = null, + invalid = null, + propertyName = ""; property = this._property(); - if (property !== null){ + if (property !== null) { tokenStream.mustMatch(Tokens.COLON); this._readWhitespace(); expr = this._expr(); - if (!expr || expr.length === 0){ + if (!expr || expr.length === 0) { this._unexpectedToken(tokenStream.LT(1)); } prio = this._prio(); propertyName = property.toString(); - if (this.options.starHack && property.hack == "*" || - this.options.underscoreHack && property.hack == "_") { + if (this.options.starHack && property.hack === "*" || + this.options.underscoreHack && property.hack === "_") { propertyName = property.text; } @@ -3134,7 +3340,7 @@ Parser.prototype = function(){ } }, - _prio: function(){ + _prio: function() { var tokenStream = this._tokenStream, result = tokenStream.match(Tokens.IMPORTANT_SYM); @@ -3143,21 +3349,20 @@ Parser.prototype = function(){ return result; }, - _expr: function(inFunction){ + _expr: function(inFunction) { - var tokenStream = this._tokenStream, - values = [], + var values = [], value = null, operator = null; value = this._term(inFunction); - if (value !== null){ + if (value !== null) { values.push(value); do { operator = this._operator(inFunction); - if (operator){ + if (operator) { values.push(operator); } /*else { values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); @@ -3166,44 +3371,45 @@ Parser.prototype = function(){ value = this._term(inFunction); - if (value === null){ + if (value === null) { break; } else { values.push(value); } - } while(true); + } while (true); } return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null; }, - _term: function(inFunction){ + _term: function(inFunction) { var tokenStream = this._tokenStream, unary = null, value = null, endChar = null, + part = null, token, line, col; unary = this._unary_operator(); - if (unary !== null){ + if (unary !== null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } - if (tokenStream.peek() == Tokens.IE_FUNCTION && this.options.ieFilters){ + if (tokenStream.peek() === Tokens.IE_FUNCTION && this.options.ieFilters) { value = this._ie_function(); - if (unary === null){ + if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } - } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])){ + } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])) { token = tokenStream.token(); endChar = token.endChar; value = token.value + this._expr(inFunction).text; - if (unary === null){ + if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; } @@ -3211,24 +3417,25 @@ Parser.prototype = function(){ value += endChar; this._readWhitespace(); } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH, - Tokens.ANGLE, Tokens.TIME, - Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])){ + Tokens.ANGLE, Tokens.TIME, + Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])) { value = tokenStream.token().value; - if (unary === null){ + if (unary === null) { line = tokenStream.token().startLine; col = tokenStream.token().startCol; + part = PropertyValuePart.fromToken(tokenStream.token()); } this._readWhitespace(); } else { token = this._hexcolor(); - if (token === null){ - if (unary === null){ + if (token === null) { + if (unary === null) { line = tokenStream.LT(1).startLine; col = tokenStream.LT(1).startCol; } - if (value === null){ - if (tokenStream.LA(3) == Tokens.EQUALS && this.options.ieFilters){ + if (value === null) { + if (tokenStream.LA(3) === Tokens.EQUALS && this.options.ieFilters) { value = this._ie_function(); } else { value = this._function(); @@ -3237,7 +3444,7 @@ Parser.prototype = function(){ } else { value = token.value; - if (unary === null){ + if (unary === null) { line = token.startLine; col = token.startCol; } @@ -3245,31 +3452,31 @@ Parser.prototype = function(){ } - return value !== null ? + return part !== null ? part : value !== null ? new PropertyValuePart(unary !== null ? unary + value : value, line, col) : null; }, - _function: function(){ + _function: function() { var tokenStream = this._tokenStream, functionText = null, expr = null, lt; - if (tokenStream.match(Tokens.FUNCTION)){ + if (tokenStream.match(Tokens.FUNCTION)) { functionText = tokenStream.token().value; this._readWhitespace(); expr = this._expr(true); functionText += expr; - if (this.options.ieFilters && tokenStream.peek() == Tokens.EQUALS){ + if (this.options.ieFilters && tokenStream.peek() === Tokens.EQUALS) { do { - if (this._readWhitespace()){ + if (this._readWhitespace()) { functionText += tokenStream.token().value; } - if (tokenStream.LA(0) == Tokens.COMMA){ + if (tokenStream.LA(0) === Tokens.COMMA) { functionText += tokenStream.token().value; } @@ -3279,12 +3486,12 @@ Parser.prototype = function(){ tokenStream.match(Tokens.EQUALS); functionText += tokenStream.token().value; lt = tokenStream.peek(); - while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){ + while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) { tokenStream.get(); functionText += tokenStream.token().value; lt = tokenStream.peek(); } - } while(tokenStream.match([Tokens.COMMA, Tokens.S])); + } while (tokenStream.match([Tokens.COMMA, Tokens.S])); } tokenStream.match(Tokens.RPAREN); @@ -3295,21 +3502,20 @@ Parser.prototype = function(){ return functionText; }, - _ie_function: function(){ + _ie_function: function() { var tokenStream = this._tokenStream, functionText = null, - expr = null, lt; - if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])){ + if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])) { functionText = tokenStream.token().value; do { - if (this._readWhitespace()){ + if (this._readWhitespace()) { functionText += tokenStream.token().value; } - if (tokenStream.LA(0) == Tokens.COMMA){ + if (tokenStream.LA(0) === Tokens.COMMA) { functionText += tokenStream.token().value; } @@ -3319,12 +3525,12 @@ Parser.prototype = function(){ tokenStream.match(Tokens.EQUALS); functionText += tokenStream.token().value; lt = tokenStream.peek(); - while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){ + while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) { tokenStream.get(); functionText += tokenStream.token().value; lt = tokenStream.peek(); } - } while(tokenStream.match([Tokens.COMMA, Tokens.S])); + } while (tokenStream.match([Tokens.COMMA, Tokens.S])); tokenStream.match(Tokens.RPAREN); functionText += ")"; @@ -3334,17 +3540,17 @@ Parser.prototype = function(){ return functionText; }, - _hexcolor: function(){ + _hexcolor: function() { var tokenStream = this._tokenStream, token = null, color; - if(tokenStream.match(Tokens.HASH)){ + if (tokenStream.match(Tokens.HASH)) { token = tokenStream.token(); color = token.value; - if (!/#[a-f0-9]{3,6}/i.test(color)){ + if (!/#[a-f0-9]{3,6}/i.test(color)) { throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); } this._readWhitespace(); @@ -3353,7 +3559,7 @@ Parser.prototype = function(){ return token; }, - _keyframes: function(){ + _keyframes: function() { var tokenStream = this._tokenStream, token, tt, @@ -3362,7 +3568,7 @@ Parser.prototype = function(){ tokenStream.mustMatch(Tokens.KEYFRAMES_SYM); token = tokenStream.token(); - if (/^@\-([^\-]+)\-/.test(token.value)) { + if (/^@-([^-]+)-/.test(token.value)) { prefix = RegExp.$1; } @@ -3382,7 +3588,7 @@ Parser.prototype = function(){ this._readWhitespace(); tt = tokenStream.peek(); - while(tt == Tokens.IDENT || tt == Tokens.PERCENTAGE) { + while (tt === Tokens.IDENT || tt === Tokens.PERCENTAGE) { this._keyframe_rule(); this._readWhitespace(); tt = tokenStream.peek(); @@ -3398,21 +3604,19 @@ Parser.prototype = function(){ this._readWhitespace(); tokenStream.mustMatch(Tokens.RBRACE); + this._readWhitespace(); }, - _keyframe_name: function(){ - var tokenStream = this._tokenStream, - token; + _keyframe_name: function() { + var tokenStream = this._tokenStream; tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); return SyntaxUnit.fromToken(tokenStream.token()); }, - _keyframe_rule: function(){ - var tokenStream = this._tokenStream, - token, - keyList = this._key_list(); + _keyframe_rule: function() { + var keyList = this._key_list(); this.fire({ type: "startkeyframerule", @@ -3432,16 +3636,14 @@ Parser.prototype = function(){ }, - _key_list: function(){ + _key_list: function() { var tokenStream = this._tokenStream, - token, - key, keyList = []; keyList.push(this._key()); this._readWhitespace(); - while(tokenStream.match(Tokens.COMMA)){ + while (tokenStream.match(Tokens.COMMA)) { this._readWhitespace(); keyList.push(this._key()); this._readWhitespace(); @@ -3450,17 +3652,17 @@ Parser.prototype = function(){ return keyList; }, - _key: function(){ + _key: function() { var tokenStream = this._tokenStream, token; - if (tokenStream.match(Tokens.PERCENTAGE)){ + if (tokenStream.match(Tokens.PERCENTAGE)) { return SyntaxUnit.fromToken(tokenStream.token()); - } else if (tokenStream.match(Tokens.IDENT)){ + } else if (tokenStream.match(Tokens.IDENT)) { token = tokenStream.token(); - if (/from|to/i.test(token.value)){ + if (/from|to/i.test(token.value)) { return SyntaxUnit.fromToken(token); } @@ -3468,18 +3670,18 @@ Parser.prototype = function(){ } this._unexpectedToken(tokenStream.LT(1)); }, - _skipCruft: function(){ - while(this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])){ + _skipCruft: function() { + while (this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])) { } }, - _readDeclarations: function(checkStart, readMargins){ + _readDeclarations: function(checkStart, readMargins) { var tokenStream = this._tokenStream, tt; this._readWhitespace(); - if (checkStart){ + if (checkStart) { tokenStream.mustMatch(Tokens.LBRACE); } @@ -3487,11 +3689,11 @@ Parser.prototype = function(){ try { - while(true){ + while (true) { - if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())){ - } else if (this._declaration()){ - if (!tokenStream.match(Tokens.SEMICOLON)){ + if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())) { + } else if (this._declaration()) { + if (!tokenStream.match(Tokens.SEMICOLON)) { break; } } else { @@ -3504,7 +3706,7 @@ Parser.prototype = function(){ this._readWhitespace(); } catch (ex) { - if (ex instanceof SyntaxError && !this.options.strict){ + if (ex instanceof SyntaxError && !this.options.strict) { this.fire({ type: "error", error: ex, @@ -3513,9 +3715,9 @@ Parser.prototype = function(){ col: ex.col }); tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]); - if (tt == Tokens.SEMICOLON){ + if (tt === Tokens.SEMICOLON) { this._readDeclarations(false, readMargins); - } else if (tt != Tokens.RBRACE){ + } else if (tt !== Tokens.RBRACE) { throw ex; } @@ -3525,45 +3727,45 @@ Parser.prototype = function(){ } }, - _readWhitespace: function(){ + _readWhitespace: function() { var tokenStream = this._tokenStream, ws = ""; - while(tokenStream.match(Tokens.S)){ + while (tokenStream.match(Tokens.S)) { ws += tokenStream.token().value; } return ws; }, - _unexpectedToken: function(token){ + _unexpectedToken: function(token) { throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); }, - _verifyEnd: function(){ - if (this._tokenStream.LA(1) != Tokens.EOF){ + _verifyEnd: function() { + if (this._tokenStream.LA(1) !== Tokens.EOF) { this._unexpectedToken(this._tokenStream.LT(1)); } }, - _validateProperty: function(property, value){ + _validateProperty: function(property, value) { Validation.validate(property, value); }, - parse: function(input){ + parse: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._stylesheet(); }, - parseStyleSheet: function(input){ + parseStyleSheet: function(input) { return this.parse(input); }, - parseMediaQuery: function(input){ + parseMediaQuery: function(input) { this._tokenStream = new TokenStream(input, Tokens); var result = this._media_query(); this._verifyEnd(); return result; }, - parsePropertyValue: function(input){ + parsePropertyValue: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._readWhitespace(); @@ -3573,7 +3775,7 @@ Parser.prototype = function(){ this._verifyEnd(); return result; }, - parseRule: function(input){ + parseRule: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._readWhitespace(); @@ -3582,7 +3784,7 @@ Parser.prototype = function(){ this._verifyEnd(); return result; }, - parseSelector: function(input){ + parseSelector: function(input) { this._tokenStream = new TokenStream(input, Tokens); this._readWhitespace(); @@ -3592,510 +3794,482 @@ Parser.prototype = function(){ this._verifyEnd(); return result; }, - parseStyleAttribute: function(input){ - input += "}"; // for error recovery in _readDeclarations() + parseStyleAttribute: function(input) { + input += "}"; // for error recovery in _readDeclarations() this._tokenStream = new TokenStream(input, Tokens); this._readDeclarations(); } }; - for (prop in additions){ - if (additions.hasOwnProperty(prop)){ + for (prop in additions) { + if (Object.prototype.hasOwnProperty.call(additions, prop)) { proto[prop] = additions[prop]; } } return proto; }(); -var Properties = { - "align-items" : "flex-start | flex-end | center | baseline | stretch", - "align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", - "align-self" : "auto | flex-start | flex-end | center | baseline | stretch", - "-webkit-align-items" : "flex-start | flex-end | center | baseline | stretch", - "-webkit-align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", - "-webkit-align-self" : "auto | flex-start | flex-end | center | baseline | stretch", - "alignment-adjust" : "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | ", - "alignment-baseline" : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical", - "animation" : 1, - "animation-delay" : { multi: "