diff --git a/.gitignore b/.gitignore index 4b4d7a126..897e7292d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,7 @@ vendor tests/config.yml .history/ + +composer.json +composer.lock +.gitignore \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 9dc6b4df6..000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Listen for Xdebug", - "type": "php", - "request": "launch", - "port": 9003 - }, - { - "name": "Launch currently open script", - "type": "php", - "request": "launch", - "program": "${file}", - "cwd": "${fileDirname}", - "port": 0, - "runtimeArgs": [ - "-dxdebug.start_with_request=yes" - ], - "env": { - "XDEBUG_MODE": "debug,develop", - "XDEBUG_CONFIG": "client_port=${port}" - } - }, - { - "name": "Launch Built-in web server", - "type": "php", - "request": "launch", - "runtimeArgs": [ - "-dxdebug.mode=debug", - "-dxdebug.start_with_request=yes", - "-S", - "localhost:0" - ], - "program": "", - "cwd": "${workspaceRoot}", - "port": 9003, - "serverReadyAction": { - "pattern": "Development Server \\(http://localhost:([0-9]+)\\) started", - "uriFormat": "http://localhost:%s", - "action": "openExternally" - } - } - ] -} \ No newline at end of file diff --git a/check.php b/check.php index 1826f0683..7514950b4 100644 --- a/check.php +++ b/check.php @@ -96,7 +96,7 @@ // ********************* SYSTEM *********************** $system_tests = array(); $php_version = phpversion(); -$desired_version = '5.4'; +$desired_version = '8.0.0'; $php_version_ok = version_compare($php_version, $desired_version, '>='); $status = $php_version_ok ? $php_version : $php_version . ' - EPESI requires at least ' . $desired_version; $system_tests[] = array('label' => 'PHP version', 'status' => $status, 'severity' => $php_version_ok ? 0 : 2); @@ -105,11 +105,11 @@ // ********************* ERRORS *********************** $err = error_reporting(); -$strict = (($err | E_STRICT) == $err); +$strict = (($err | E_DEPRECATED) == $err); $display = ini_get('display_errors'); $error_tests = array(); -$error_tests[] = array('label'=>'Strict errors reporting', 'status'=>!$strict?'Disabled':'Enabled', 'severity'=>!$strict?0:2); +$error_tests[] = array('label'=>'Deprecated errors reporting', 'status'=>!$strict?'Disabled':'Enabled', 'severity'=>!$strict?0:2); $error_tests[] = array('label'=>'Error display', 'status'=>$display?'On':'Off', 'severity'=>$display?0:1); $checks[] = array('label'=>'Error reporting', 'tests'=>$error_tests, 'solution'=>'http://forum.epesibim.com'); diff --git a/composer.json b/composer.json index b63d770e5..e9fcef8c5 100644 --- a/composer.json +++ b/composer.json @@ -2,14 +2,13 @@ "require" : { "pimple/pimple" : "^3.0", "twig/twig" : "^1.24", - "symfony/console" : "^2.7", - "symfony/http-foundation" : "^2.7", + "symfony/console" : "^3", + "symfony/http-foundation" : "^3", "phpdocumentor/reflection-docblock" : "~5", - "fzaninotto/faker" : "^1.6", "phpfastcache/phpfastcache" : "^5.0", "ifsnop/mysqldump-php" : "dev-master", - "memio/memio" : "^2.0", - "psy/psysh" : "@stable", + "memio/memio" : "^3.0", + "psy/psysh" : "^0.12", "enyo/dropzone" : "@stable", "ezyang/htmlpurifier" : "^4.10", "moneyphp/money" : "^3.0", @@ -18,10 +17,11 @@ }, "scripts" : { "post-install-cmd" : [ - "@composer -d=\"modules/CRM/Mail\" install", - "@composer -d=\"modules/Libs/PHPExcel\" install", - "@composer -d=\"modules/Libs/TCPDF\" install", - "@composer -d=\"modules/Libs/QuickForm\" install" + "@composer -d \"modules/CRM/Mail\" update", + "@composer -d \"modules/Libs/PHPExcel\" update", + "@composer -d \"modules/Libs/TCPDF\" update", + "@composer -d \"modules/Libs/QuickForm\" update", + "@composer -d modules/Base/Theme update" ] }, "autoload" : { @@ -32,9 +32,5 @@ "psr-0" : { "" : "modules/" } - }, - "require-dev" : { - "codeception/codeception" : "*", - "codeception/aspect-mock" : "*" } } diff --git a/composer.lock b/composer.lock index d4218ae35..1688ba6d6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "50c7e5f11e89cb0a9ade8d997f68734d", + "content-hash": "a0a95e66cbef5722d296aa796fdb0526", "packages": [ { "name": "adodb/adodb-php", - "version": "v5.22.7", + "version": "v5.22.10", "source": { "type": "git", "url": "https://github.com/ADOdb/ADOdb.git", - "reference": "e7150539d5707ae556172532e2b25ac4e88cb2a6" + "reference": "38ce257600e67b1e854f2e9054166569cff4bf6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ADOdb/ADOdb/zipball/e7150539d5707ae556172532e2b25ac4e88cb2a6", - "reference": "e7150539d5707ae556172532e2b25ac4e88cb2a6", + "url": "https://api.github.com/repos/ADOdb/ADOdb/zipball/38ce257600e67b1e854f2e9054166569cff4bf6b", + "reference": "38ce257600e67b1e854f2e9054166569cff4bf6b", "shasum": "" }, "require": { @@ -65,28 +65,28 @@ "issues": "https://github.com/ADOdb/ADOdb/issues", "source": "https://github.com/ADOdb/ADOdb" }, - "time": "2023-11-04T22:25:49+00:00" + "time": "2025-08-03T16:20:39+00:00" }, { "name": "cron/cron", - "version": "1.8.1", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/Cron/Cron.git", - "reference": "ce28a372a67fab87d3782ca81b71c05e22befc15" + "reference": "1cce4e131d93b24bdbb89e18ca212462b47752f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Cron/Cron/zipball/ce28a372a67fab87d3782ca81b71c05e22befc15", - "reference": "ce28a372a67fab87d3782ca81b71c05e22befc15", + "url": "https://api.github.com/repos/Cron/Cron/zipball/1cce4e131d93b24bdbb89e18ca212462b47752f1", + "reference": "1cce4e131d93b24bdbb89e18ca212462b47752f1", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "symfony/process": "^4.0|^5.0|^6.0" + "php": "^8.0", + "symfony/process": "^4.0|^5.0|^6.0|^7.0" }, "require-dev": { - "phpunit/phpunit": "^8.0 || ^9.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { @@ -112,35 +112,36 @@ "description": "Cronjobs", "support": { "issues": "https://github.com/Cron/Cron/issues", - "source": "https://github.com/Cron/Cron/tree/1.8.1" + "source": "https://github.com/Cron/Cron/tree/1.9.1" }, - "time": "2023-02-14T20:40:25+00:00" + "time": "2024-11-13T21:04:33+00:00" }, { "name": "doctrine/deprecations", - "version": "1.1.3", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=13" + }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" + "doctrine/coding-standard": "^9 || ^12 || ^13", + "phpstan/phpstan": "1.4.10 || 2.1.11", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "psr/log": "^1 || ^2 || ^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -148,7 +149,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -159,9 +160,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + "source": "https://github.com/doctrine/deprecations/tree/1.1.5" }, - "time": "2024-01-30T19:34:25+00:00" + "time": "2025-04-07T20:06:18+00:00" }, { "name": "enyo/dropzone", @@ -205,20 +206,20 @@ }, { "name": "ezyang/htmlpurifier", - "version": "v4.17.0", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c" + "reference": "cb56001e54359df7ae76dc522d08845dc741621b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/bbc513d79acf6691fa9cf10f192c90dd2957f18c", - "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/cb56001e54359df7ae76dc522d08845dc741621b", + "reference": "cb56001e54359df7ae76dc522d08845dc741621b", "shasum": "" }, "require": { - "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "require-dev": { "cerdic/css-tidy": "^1.7 || ^2.0", @@ -260,64 +261,9 @@ ], "support": { "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/v4.17.0" - }, - "time": "2023-11-17T15:01:25+00:00" - }, - { - "name": "fzaninotto/faker", - "version": "v1.9.2", - "source": { - "type": "git", - "url": "https://github.com/fzaninotto/Faker.git", - "reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/848d8125239d7dbf8ab25cb7f054f1a630e68c2e", - "reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "ext-intl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7", - "squizlabs/php_codesniffer": "^2.9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "Faker\\": "src/Faker/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "François Zaninotto" - } - ], - "description": "Faker is a PHP library that generates fake data for you.", - "keywords": [ - "data", - "faker", - "fixtures" - ], - "support": { - "issues": "https://github.com/fzaninotto/Faker/issues", - "source": "https://github.com/fzaninotto/Faker/tree/v1.9.2" + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.18.0" }, - "abandoned": true, - "time": "2020-12-11T09:56:16+00:00" + "time": "2024-11-01T03:51:45+00:00" }, { "name": "ifsnop/mysqldump-php", @@ -325,12 +271,12 @@ "source": { "type": "git", "url": "https://github.com/ifsnop/mysqldump-php.git", - "reference": "2d3a43fc0c49f23bf7dee392b0dd1f8c799f89d3" + "reference": "91408c95b54ac2ce10ae6f34f18fa52934cf1410" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ifsnop/mysqldump-php/zipball/2d3a43fc0c49f23bf7dee392b0dd1f8c799f89d3", - "reference": "2d3a43fc0c49f23bf7dee392b0dd1f8c799f89d3", + "url": "https://api.github.com/repos/ifsnop/mysqldump-php/zipball/91408c95b54ac2ce10ae6f34f18fa52934cf1410", + "reference": "91408c95b54ac2ce10ae6f34f18fa52934cf1410", "shasum": "" }, "require": { @@ -375,32 +321,32 @@ ], "support": { "issues": "https://github.com/ifsnop/mysqldump-php/issues", - "source": "https://github.com/ifsnop/mysqldump-php/tree/v2.12" + "source": "https://github.com/ifsnop/mysqldump-php/tree/master" }, - "time": "2023-04-12T07:43:14+00:00" + "time": "2024-09-20T01:53:49+00:00" }, { "name": "memio/linter", - "version": "v2.0.3", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/memio/linter.git", - "reference": "6f282955869cdf72332a096f80ebc2897835a8b9" + "reference": "7df9893e1bba5c98d80518bca409d86cf8250eb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/memio/linter/zipball/6f282955869cdf72332a096f80ebc2897835a8b9", - "reference": "6f282955869cdf72332a096f80ebc2897835a8b9", + "url": "https://api.github.com/repos/memio/linter/zipball/7df9893e1bba5c98d80518bca409d86cf8250eb7", + "reference": "7df9893e1bba5c98d80518bca409d86cf8250eb7", "shasum": "" }, "require": { - "memio/model": "^2.0", - "memio/validator": "^2.0", - "php": "^7.0" + "memio/model": "^3.0", + "memio/validator": "^3.0", + "php": "^7.2 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.10", - "phpspec/phpspec": "^4.3" + "phpspec/phpspec": "^6.1 || ^7.0" }, "type": "library", "autoload": { @@ -429,35 +375,35 @@ ], "support": { "issues": "https://github.com/memio/linter/issues", - "source": "https://github.com/memio/linter/tree/v2.0.3" + "source": "https://github.com/memio/linter/tree/v3.0.0" }, - "time": "2018-03-02T14:52:00+00:00" + "time": "2024-08-14T19:40:10+00:00" }, { "name": "memio/memio", - "version": "v2.0.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/memio/memio.git", - "reference": "47708e9f39e1cd70d832ab60fe1006290246d09b" + "reference": "23e789ce8d121cb4a949cac8b9d04190f2b6fc8f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/memio/memio/zipball/47708e9f39e1cd70d832ab60fe1006290246d09b", - "reference": "47708e9f39e1cd70d832ab60fe1006290246d09b", + "url": "https://api.github.com/repos/memio/memio/zipball/23e789ce8d121cb4a949cac8b9d04190f2b6fc8f", + "reference": "23e789ce8d121cb4a949cac8b9d04190f2b6fc8f", "shasum": "" }, "require": { - "memio/linter": "^2.0@alpha", - "memio/model": "^2.0@alpha", - "memio/pretty-printer": "^2.0@alpha", - "memio/twig-template-engine": "^2.0@alpha", - "memio/validator": "^2.0@alpha", - "php": "^7.0" + "memio/linter": "^3.0", + "memio/model": "^3.0.1", + "memio/pretty-printer": "^3.0", + "memio/twig-template-engine": "^3.0", + "memio/validator": "^3.0.1", + "php": "^7.2 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^1.6", - "phpunit/phpunit": "^5.4" + "friendsofphp/php-cs-fixer": "^3.0", + "phpunit/phpunit": "^8.5" }, "type": "library", "autoload": { @@ -487,37 +433,32 @@ ], "support": { "issues": "https://github.com/memio/memio/issues", - "source": "https://github.com/memio/memio/tree/version-2" + "source": "https://github.com/memio/memio/tree/v3.0.0" }, - "time": "2016-10-03T18:20:18+00:00" + "time": "2024-08-14T21:19:56+00:00" }, { "name": "memio/model", - "version": "2.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/memio/model.git", - "reference": "1e4609e0df347e1b9ed0f12eb4db82f378a6c049" + "reference": "ca3575ffe181a135bd90cfb451a49418e9e64c90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/memio/model/zipball/1e4609e0df347e1b9ed0f12eb4db82f378a6c049", - "reference": "1e4609e0df347e1b9ed0f12eb4db82f378a6c049", + "url": "https://api.github.com/repos/memio/model/zipball/ca3575ffe181a135bd90cfb451a49418e9e64c90", + "reference": "ca3575ffe181a135bd90cfb451a49418e9e64c90", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.10", - "phpspec/phpspec": "^4.3" + "friendsofphp/php-cs-fixer": "^2.16", + "phpspec/phpspec": "^6.1 || ^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, "autoload": { "psr-4": { "Memio\\Model\\": "src/Memio/Model" @@ -544,31 +485,31 @@ ], "support": { "issues": "https://github.com/memio/model/issues", - "source": "https://github.com/memio/model/tree/2.0.4" + "source": "https://github.com/memio/model/tree/3.0.1" }, - "time": "2018-06-13T10:27:07+00:00" + "time": "2024-08-13T05:52:25+00:00" }, { "name": "memio/pretty-printer", - "version": "2.0.3", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/memio/pretty-printer.git", - "reference": "8181fbc211135f12ec78a7c4adb3445342454e7d" + "reference": "9748026f53123b2abccc980f34beeeaacfc05f52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/memio/pretty-printer/zipball/8181fbc211135f12ec78a7c4adb3445342454e7d", - "reference": "8181fbc211135f12ec78a7c4adb3445342454e7d", + "url": "https://api.github.com/repos/memio/pretty-printer/zipball/9748026f53123b2abccc980f34beeeaacfc05f52", + "reference": "9748026f53123b2abccc980f34beeeaacfc05f52", "shasum": "" }, "require": { - "memio/model": "^2.0", - "php": "^7.0" + "memio/model": "^3.0", + "php": "^7.2 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.10", - "phpspec/phpspec": "^4.3" + "phpspec/phpspec": "^6.1 || ^7.0" }, "type": "library", "autoload": { @@ -597,40 +538,35 @@ ], "support": { "issues": "https://github.com/memio/pretty-printer/issues", - "source": "https://github.com/memio/pretty-printer/tree/2.0.3" + "source": "https://github.com/memio/pretty-printer/tree/v3.0.0" }, - "time": "2018-03-02T15:10:58+00:00" + "time": "2024-08-13T06:26:43+00:00" }, { "name": "memio/twig-template-engine", - "version": "v2.0.3", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/memio/twig-template-engine.git", - "reference": "746f944440cb7c3bcfffefc80753ecc2e9604778" + "reference": "475ff90f611722f9a01bac953118db131cc6c997" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/memio/twig-template-engine/zipball/746f944440cb7c3bcfffefc80753ecc2e9604778", - "reference": "746f944440cb7c3bcfffefc80753ecc2e9604778", + "url": "https://api.github.com/repos/memio/twig-template-engine/zipball/475ff90f611722f9a01bac953118db131cc6c997", + "reference": "475ff90f611722f9a01bac953118db131cc6c997", "shasum": "" }, "require": { - "memio/model": "^2.0", - "memio/pretty-printer": "^2.0", - "php": "^7.0", - "twig/twig": "^1.18 || ^2.0" + "memio/model": "^3.0", + "memio/pretty-printer": "^3.0", + "php": "^7.2 || ^8.0", + "twig/twig": "^1.18 || ^2.0 || ^3.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.10", - "phpspec/phpspec": "^4.3" + "phpspec/phpspec": "^6.1 || ^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, "autoload": { "psr-4": { "Memio\\TwigTemplateEngine\\": "src/Memio/TwigTemplateEngine", @@ -660,31 +596,31 @@ ], "support": { "issues": "https://github.com/memio/twig-template-engine/issues", - "source": "https://github.com/memio/twig-template-engine/tree/master" + "source": "https://github.com/memio/twig-template-engine/tree/v3.0.1" }, - "time": "2018-03-02T15:17:41+00:00" + "time": "2024-08-14T21:22:48+00:00" }, { "name": "memio/validator", - "version": "v2.0.3", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/memio/validator.git", - "reference": "ff524bd973e186c72fec654cce3c057997e4cfc9" + "reference": "b01a936f59c645d5cfc58c604fcc97bf44b9250f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/memio/validator/zipball/ff524bd973e186c72fec654cce3c057997e4cfc9", - "reference": "ff524bd973e186c72fec654cce3c057997e4cfc9", + "url": "https://api.github.com/repos/memio/validator/zipball/b01a936f59c645d5cfc58c604fcc97bf44b9250f", + "reference": "b01a936f59c645d5cfc58c604fcc97bf44b9250f", "shasum": "" }, "require": { - "memio/model": "^2.0", - "php": "^7.0" + "memio/model": "^3.0", + "php": "^7.2 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.10", - "phpspec/phpspec": "^4.3" + "friendsofphp/php-cs-fixer": "^2.16", + "phpspec/phpspec": "^6.1 || ^7.0" }, "type": "library", "autoload": { @@ -713,9 +649,9 @@ ], "support": { "issues": "https://github.com/memio/validator/issues", - "source": "https://github.com/memio/validator/tree/v2.0.3" + "source": "https://github.com/memio/validator/tree/v3.0.1" }, - "time": "2018-03-02T15:26:34+00:00" + "time": "2024-08-13T06:06:08+00:00" }, { "name": "moneyphp/money", @@ -805,25 +741,27 @@ }, { "name": "nikic/php-parser", - "version": "v4.19.1", + "version": "v5.6.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b" + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b", - "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.1" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -831,7 +769,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -855,9 +793,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" }, - "time": "2024-03-17T08:10:35+00:00" + "time": "2025-08-13T20:13:15+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -914,16 +852,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.4.1", + "version": "5.6.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c" + "reference": "92dde6a5919e34835c506ac8c523ef095a95ed62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/92dde6a5919e34835c506ac8c523ef095a95ed62", + "reference": "92dde6a5919e34835c506ac8c523ef095a95ed62", "shasum": "" }, "require": { @@ -932,17 +870,17 @@ "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.5", + "mockery/mockery": "~1.3.5 || ~1.6.0", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.8", "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^5.13" + "psalm/phar": "^5.26" }, "type": "library", "extra": { @@ -972,29 +910,29 @@ "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/5.4.1" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.2" }, - "time": "2024-05-21T05:55:05+00:00" + "time": "2025-04-13T19:20:35+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.8.2", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "153ae662783729388a584b4361f2545e4d841e3c" + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", - "reference": "153ae662783729388a584b4361f2545e4d841e3c", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", "php": "^7.3 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.13" + "phpstan/phpdoc-parser": "^1.18|^2.0" }, "require-dev": { "ext-tokenizer": "*", @@ -1030,9 +968,9 @@ "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.8.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" }, - "time": "2024-02-23T11:10:43+00:00" + "time": "2024-11-09T15:12:26+00:00" }, { "name": "phpfastcache/phpfastcache", @@ -1180,30 +1118,30 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/b9e61a61e39e02dd90944e9115241c7f7e76bfd8", + "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "doctrine/annotations": "^2.0", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^5.3.0", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", "symfony/process": "^5.2" }, "type": "library", @@ -1221,9 +1159,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.2.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2025-07-13T07:04:09+00:00" }, { "name": "pimple/pimple", @@ -1448,30 +1386,30 @@ }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1492,50 +1430,54 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "psy/psysh", - "version": "v0.10.12", + "version": "v0.12.10", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "a0d9981aa07ecfcbea28e4bfa868031cca121e7d" + "reference": "6e80abe6f2257121f1eb9a4c55bf29d921025b22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/a0d9981aa07ecfcbea28e4bfa868031cca121e7d", - "reference": "a0d9981aa07ecfcbea28e4bfa868031cca121e7d", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/6e80abe6f2257121f1eb9a4c55bf29d921025b22", + "reference": "6e80abe6f2257121f1eb9a4c55bf29d921025b22", "shasum": "" }, "require": { "ext-json": "*", "ext-tokenizer": "*", - "nikic/php-parser": "~4.0|~3.0|~2.0|~1.3", - "php": "^8.0 || ^7.0 || ^5.5.9", - "symfony/console": "~5.0|~4.0|~3.0|^2.4.2|~2.3.10", - "symfony/var-dumper": "~5.0|~4.0|~3.0|~2.7" + "nikic/php-parser": "^5.0 || ^4.0", + "php": "^8.0 || ^7.4", + "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.2", - "hoa/console": "3.17.*" + "bamarni/composer-bin-plugin": "^1.2" }, "suggest": { "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", "ext-pdo-sqlite": "The doc command requires SQLite to work.", - "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", - "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", - "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." }, "bin": [ "bin/psysh" ], "type": "library", "extra": { + "bamarni-bin": { + "bin-links": false, + "forward-command": false + }, "branch-alias": { - "dev-main": "0.10.x-dev" + "dev-main": "0.12.x-dev" } }, "autoload": { @@ -1553,12 +1495,11 @@ "authors": [ { "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" + "email": "justin@justinhileman.info" } ], "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", + "homepage": "https://psysh.org", "keywords": [ "REPL", "console", @@ -1567,45 +1508,51 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.10.12" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.10" }, - "time": "2021-11-30T14:05:36+00:00" + "time": "2025-08-04T12:39:37+00:00" }, { "name": "symfony/console", - "version": "v2.8.52", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12" + "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12", - "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12", + "url": "https://api.github.com/repos/symfony/console/zipball/a10b1da6fc93080c180bba7219b5ff5b7518fe81", + "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/debug": "^2.7.2|~3.0.0", + "php": "^5.5.9|>=7.0.8", + "symfony/debug": "~2.8|~3.0|~4.0", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0" + "symfony/config": "~3.3|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.3|~4.0" }, "suggest": { - "psr/log-implementation": "For using the console logger", + "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/lock": "", "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" @@ -1631,41 +1578,49 @@ "description": "Symfony Console Component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/console/tree/v2.8.52" + "source": "https://github.com/symfony/console/tree/v3.4.47" }, - "time": "2018-11-20T15:55:20+00:00" + "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": "symfony/debug", - "version": "v3.0.9", + "version": "v4.4.44", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" + "reference": "1a692492190773c5310bc7877cb590c04c2f05be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", - "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", + "url": "https://api.github.com/repos/symfony/debug/zipball/1a692492190773c5310bc7877cb590c04c2f05be", + "reference": "1a692492190773c5310bc7877cb590c04c2f05be", "shasum": "" }, "require": { - "php": ">=5.5.9", - "psr/log": "~1.0" + "php": ">=7.1.3", + "psr/log": "^1|^2|^3" }, "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + "symfony/http-kernel": "<3.4" }, "require-dev": { - "symfony/class-loader": "~2.8|~3.0", - "symfony/http-kernel": "~2.8|~3.0" + "symfony/http-kernel": "^3.4|^4.0|^5.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Debug\\": "" @@ -1688,43 +1643,51 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Debug Component", + "description": "Provides tools to ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug/tree/3.0" + "source": "https://github.com/symfony/debug/tree/v4.4.44" }, + "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" + } + ], "abandoned": "symfony/error-handler", - "time": "2016-07-30T07:22:48+00:00" + "time": "2022-07-28T16:29:46+00:00" }, { "name": "symfony/http-foundation", - "version": "v2.8.52", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "3929d9fe8148d17819ad0178c748b8d339420709" + "reference": "b9885fcce6fe494201da4f70a9309770e9d13dc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3929d9fe8148d17819ad0178c748b8d339420709", - "reference": "3929d9fe8148d17819ad0178c748b8d339420709", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b9885fcce6fe494201da4f70a9309770e9d13dc8", + "reference": "b9885fcce6fe494201da4f70a9309770e9d13dc8", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php54": "~1.0", - "symfony/polyfill-php55": "~1.0" + "symfony/polyfill-php70": "~1.6" }, "require-dev": { - "symfony/expression-language": "~2.4|~3.0.0" + "symfony/expression-language": "~2.8|~3.0|~4.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" @@ -1750,26 +1713,40 @@ "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/2.8" + "source": "https://github.com/symfony/http-foundation/tree/v3.4.47" }, - "time": "2019-11-12T12:34:41+00:00" + "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": "symfony/polyfill-ctype", - "version": "v1.30.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "0424dff1c58f028c451efff2045f5d92410bd540" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", - "reference": "0424dff1c58f028c451efff2045f5d92410bd540", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -1780,8 +1757,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -1815,7 +1792,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" }, "funding": [ { @@ -1831,24 +1808,25 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.30.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -1859,8 +1837,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -1895,7 +1873,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" }, "funding": [ { @@ -1911,20 +1889,20 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { - "name": "symfony/polyfill-php54", + "name": "symfony/polyfill-php70", "version": "v1.20.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "37285b1d5d13f37c8bee546d8d2ad0353460c4c7" + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/37285b1d5d13f37c8bee546d8d2ad0353460c4c7", - "reference": "37285b1d5d13f37c8bee546d8d2ad0353460c4c7", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", "shasum": "" }, "require": { @@ -1932,80 +1910,12 @@ }, "type": "metapackage", "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "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 backporting some PHP 5.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php54/tree/v1.20.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/polyfill-php55", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "c17452124a883900e1d73961f9075a638399c1a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/c17452124a883900e1d73961f9075a638399c1a0", - "reference": "c17452124a883900e1d73961f9075a638399c1a0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "metapackage", - "extra": { "branch-alias": { "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" } }, "notification-url": "https://packagist.org/downloads/", @@ -2022,7 +1932,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -2031,7 +1941,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php55/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-php70/tree/v1.20.0" }, "funding": [ { @@ -2051,34 +1961,26 @@ }, { "name": "symfony/polyfill-php72", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "10112722600777e02d2745716b70c5db4ca70442" + "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/10112722600777e02d2745716b70c5db4ca70442", - "reference": "10112722600777e02d2745716b70c5db4ca70442", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce", + "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "type": "library", + "type": "metapackage", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "notification-url": "https://packagist.org/downloads/", @@ -2104,7 +2006,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.31.0" }, "funding": [ { @@ -2120,30 +2022,30 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.30.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2184,7 +2086,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" }, "funding": [ { @@ -2200,25 +2102,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2025-01-02T08:10:11+00:00" }, { "name": "symfony/process", - "version": "v5.4.40", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "deedcb3bb4669cae2148bc920eafd2b16dc7c046" + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/deedcb3bb4669cae2148bc920eafd2b16dc7c046", - "reference": "deedcb3bb4669cae2148bc920eafd2b16dc7c046", + "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -2246,7 +2147,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.40" + "source": "https://github.com/symfony/process/tree/v7.3.0" }, "funding": [ { @@ -2262,44 +2163,47 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:33:22+00:00" + "time": "2025-04-17T09:11:12+00:00" }, { "name": "symfony/var-dumper", - "version": "v4.0.15", + "version": "v4.4.47", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "3af63f44ddb45b03af4d172a4ce3e5c58b25fc5b" + "reference": "1069c7a3fca74578022fab6f81643248d02f8e63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3af63f44ddb45b03af4d172a4ce3e5c58b25fc5b", - "reference": "3af63f44ddb45b03af4d172a4ce3e5c58b25fc5b", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1069c7a3fca74578022fab6f81643248d02f8e63", + "reference": "1069c7a3fca74578022fab6f81643248d02f8e63", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5" + "symfony/polyfill-php72": "~1.5", + "symfony/polyfill-php80": "^1.16" }, "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/console": "<3.4" }, "require-dev": { "ext-iconv": "*", - "twig/twig": "~1.34|~2.4" + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^1.43|^2.13|^3.0.4" }, "suggest": { "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump" + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" }, + "bin": [ + "Resources/bin/var-dump-server" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { "files": [ "Resources/functions/dump.php" @@ -2325,29 +2229,43 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony mechanism for exploring and dumping PHP variables", + "description": "Provides mechanisms for walking through any arbitrary PHP variable", "homepage": "https://symfony.com", "keywords": [ "debug", "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/4.0" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.47" }, - "time": "2018-07-26T11:22:46+00:00" + "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": "2022-10-03T15:15:11+00:00" }, { "name": "twig/twig", - "version": "v1.44.7", + "version": "v1.44.8", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "0887422319889e442458e48e2f3d9add1a172ad5" + "reference": "b1f009c449e435a0384814e67205d9190a4d050e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/0887422319889e442458e48e2f3d9add1a172ad5", - "reference": "0887422319889e442458e48e2f3d9add1a172ad5", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/b1f009c449e435a0384814e67205d9190a4d050e", + "reference": "b1f009c449e435a0384814e67205d9190a4d050e", "shasum": "" }, "require": { @@ -2400,7 +2318,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v1.44.7" + "source": "https://github.com/twigphp/Twig/tree/v1.44.8" }, "funding": [ { @@ -2412,7 +2330,7 @@ "type": "tidelift" } ], - "time": "2022-09-28T08:38:36+00:00" + "time": "2024-09-09T17:17:16+00:00" }, { "name": "webmozart/assert", @@ -2473,3302 +2391,16 @@ "time": "2022-06-03T18:03:27+00:00" } ], - "packages-dev": [ - { - "name": "behat/gherkin", - "version": "v4.9.0", - "source": { - "type": "git", - "url": "https://github.com/Behat/Gherkin.git", - "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/0bc8d1e30e96183e4f36db9dc79caead300beff4", - "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4", - "shasum": "" - }, - "require": { - "php": "~7.2|~8.0" - }, - "require-dev": { - "cucumber/cucumber": "dev-gherkin-22.0.0", - "phpunit/phpunit": "~8|~9", - "symfony/yaml": "~3|~4|~5" - }, - "suggest": { - "symfony/yaml": "If you want to parse features, represented in YAML files" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Gherkin": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Gherkin DSL parser for PHP", - "homepage": "http://behat.org/", - "keywords": [ - "BDD", - "Behat", - "Cucumber", - "DSL", - "gherkin", - "parser" - ], - "support": { - "issues": "https://github.com/Behat/Gherkin/issues", - "source": "https://github.com/Behat/Gherkin/tree/v4.9.0" - }, - "time": "2021-10-12T13:05:09+00:00" - }, - { - "name": "codeception/aspect-mock", - "version": "4.1.1", - "source": { - "type": "git", - "url": "https://github.com/Codeception/AspectMock.git", - "reference": "b15254b7d2a9641bbb2ae7794220e72fa2e2b37d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/AspectMock/zipball/b15254b7d2a9641bbb2ae7794220e72fa2e2b37d", - "reference": "b15254b7d2a9641bbb2ae7794220e72fa2e2b37d", - "shasum": "" - }, - "require": { - "goaop/framework": "^3.0", - "php": "^7.4", - "phpunit/phpunit": "^9.5", - "symfony/finder": "^4.4 | ^5.4 | ^6.0" - }, - "require-dev": { - "codeception/codeception": "^4.1", - "codeception/specify": "^2.0", - "codeception/verify": "^2.2", - "consolidation/robo": "^3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "AspectMock": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert@codeception.com" - } - ], - "description": "Experimental Mocking Framework powered by Aspects", - "support": { - "issues": "https://github.com/Codeception/AspectMock/issues", - "source": "https://github.com/Codeception/AspectMock/tree/4.1.1" - }, - "abandoned": true, - "time": "2021-12-18T14:10:58+00:00" - }, - { - "name": "codeception/codeception", - "version": "4.2.2", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Codeception.git", - "reference": "b88014f3348c93f3df99dc6d0967b0dbfa804474" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/b88014f3348c93f3df99dc6d0967b0dbfa804474", - "reference": "b88014f3348c93f3df99dc6d0967b0dbfa804474", - "shasum": "" - }, - "require": { - "behat/gherkin": "^4.4.0", - "codeception/lib-asserts": "^1.0 | 2.0.*@dev", - "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.1.1 | ^9.0", - "codeception/stub": "^2.0 | ^3.0 | ^4.0", - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "guzzlehttp/psr7": "^1.4 | ^2.0", - "php": ">=5.6.0 <9.0", - "symfony/console": ">=2.7 <6.0", - "symfony/css-selector": ">=2.7 <6.0", - "symfony/event-dispatcher": ">=2.7 <6.0", - "symfony/finder": ">=2.7 <6.0", - "symfony/yaml": ">=2.7 <6.0" - }, - "require-dev": { - "codeception/module-asserts": "^1.0 | 2.0.*@dev", - "codeception/module-cli": "^1.0 | 2.0.*@dev", - "codeception/module-db": "^1.0 | 2.0.*@dev", - "codeception/module-filesystem": "^1.0 | 2.0.*@dev", - "codeception/module-phpbrowser": "^1.0 | 2.0.*@dev", - "codeception/specify": "~0.3", - "codeception/util-universalframework": "*@dev", - "monolog/monolog": "~1.8", - "squizlabs/php_codesniffer": "~2.0", - "symfony/process": ">=2.7 <6.0", - "vlucas/phpdotenv": "^2.0 | ^3.0 | ^4.0 | ^5.0" - }, - "suggest": { - "codeception/specify": "BDD-style code blocks", - "codeception/verify": "BDD-style assertions", - "hoa/console": "For interactive console functionality", - "stecman/symfony-console-completion": "For BASH autocompletion", - "symfony/phpunit-bridge": "For phpunit-bridge support" - }, - "bin": [ - "codecept" - ], - "type": "library", - "extra": { - "branch-alias": [] - }, - "autoload": { - "files": [ - "functions.php" - ], - "psr-4": { - "Codeception\\": "src/Codeception", - "Codeception\\Extension\\": "ext" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "https://codegyre.com" - } - ], - "description": "BDD-style testing framework", - "homepage": "https://codeception.com/", - "keywords": [ - "BDD", - "TDD", - "acceptance testing", - "functional testing", - "unit testing" - ], - "support": { - "issues": "https://github.com/Codeception/Codeception/issues", - "source": "https://github.com/Codeception/Codeception/tree/4.2.2" - }, - "funding": [ - { - "url": "https://opencollective.com/codeception", - "type": "open_collective" - } - ], - "time": "2022-08-13T13:28:25+00:00" - }, - { - "name": "codeception/lib-asserts", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/Codeception/lib-asserts.git", - "reference": "78c55044611437988b54e1daecf13f247a742bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/lib-asserts/zipball/78c55044611437988b54e1daecf13f247a742bf8", - "reference": "78c55044611437988b54e1daecf13f247a742bf8", - "shasum": "" - }, - "require": { - "codeception/phpunit-wrapper": "^7.7.1 | ^8.0.3 | ^9.0", - "ext-dom": "*", - "php": "^7.4 | ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" - }, - { - "name": "Gintautas Miselis" - }, - { - "name": "Gustavo Nieves", - "homepage": "https://medium.com/@ganieves" - } - ], - "description": "Assertion methods used by Codeception core and Asserts module", - "homepage": "https://codeception.com/", - "keywords": [ - "codeception" - ], - "support": { - "issues": "https://github.com/Codeception/lib-asserts/issues", - "source": "https://github.com/Codeception/lib-asserts/tree/2.0.1" - }, - "time": "2022-09-27T06:17:39+00:00" - }, - { - "name": "codeception/phpunit-wrapper", - "version": "9.0.9", - "source": { - "type": "git", - "url": "https://github.com/Codeception/phpunit-wrapper.git", - "reference": "7439a53ae367986e9c22b2ac00f9d7376bb2f8cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/7439a53ae367986e9c22b2ac00f9d7376bb2f8cf", - "reference": "7439a53ae367986e9c22b2ac00f9d7376bb2f8cf", - "shasum": "" - }, - "require": { - "php": ">=7.2", - "phpunit/phpunit": "^9.0" - }, - "require-dev": { - "codeception/specify": "*", - "consolidation/robo": "^3.0.0-alpha3", - "vlucas/phpdotenv": "^3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Codeception\\PHPUnit\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Davert", - "email": "davert.php@resend.cc" - }, - { - "name": "Naktibalda" - } - ], - "description": "PHPUnit classes used by Codeception", - "support": { - "issues": "https://github.com/Codeception/phpunit-wrapper/issues", - "source": "https://github.com/Codeception/phpunit-wrapper/tree/9.0.9" - }, - "time": "2022-05-23T06:24:11+00:00" - }, - { - "name": "codeception/stub", - "version": "4.0.2", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Stub.git", - "reference": "18a148dacd293fc7b044042f5aa63a82b08bff5d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Stub/zipball/18a148dacd293fc7b044042f5aa63a82b08bff5d", - "reference": "18a148dacd293fc7b044042f5aa63a82b08bff5d", - "shasum": "" - }, - "require": { - "php": "^7.4 | ^8.0", - "phpunit/phpunit": "^8.4 | ^9.0 | ^10.0 | 10.0.x-dev" - }, - "require-dev": { - "consolidation/robo": "^3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Codeception\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", - "support": { - "issues": "https://github.com/Codeception/Stub/issues", - "source": "https://github.com/Codeception/Stub/tree/4.0.2" - }, - "time": "2022-01-31T19:25:15+00:00" - }, - { - "name": "doctrine/annotations", - "version": "1.14.3", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", - "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^1 || ^2", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "~1.4.10 || ^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "vimeo/psalm": "^4.10" - }, - "suggest": { - "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.14.3" - }, - "time": "2023-02-01T09:20:38+00:00" - }, - { - "name": "doctrine/cache", - "version": "1.13.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "56cd022adb5514472cb144c087393c1821911d09" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/56cd022adb5514472cb144c087393c1821911d09", - "reference": "56cd022adb5514472cb144c087393c1821911d09", - "shasum": "" - }, - "require": { - "php": "~7.1 || ^8.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "require-dev": { - "alcaeus/mongo-php-adapter": "^1.1", - "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^9", - "mongodb/mongodb": "^1.1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "predis/predis": "~1.0", - "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6" - }, - "suggest": { - "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", - "homepage": "https://www.doctrine-project.org/projects/cache.html", - "keywords": [ - "abstraction", - "apcu", - "cache", - "caching", - "couchdb", - "memcached", - "php", - "redis", - "xcache" - ], - "support": { - "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/1.13.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%2Fcache", - "type": "tidelift" - } - ], - "time": "2022-05-20T20:06:54+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^11", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.30 || ^5.4" - }, - "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.5.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": "2022-12-30T00:15:36+00:00" - }, - { - "name": "doctrine/lexer", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6", - "reference": "861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^12", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^4.11 || ^5.21" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/2.1.1" - }, - "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%2Flexer", - "type": "tidelift" - } - ], - "time": "2024-02-05T11:35:39+00:00" - }, - { - "name": "goaop/framework", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/goaop/framework.git", - "reference": "596fcaefc18dfc4e3982b3ee552b0a3ceca9a8b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/goaop/framework/zipball/596fcaefc18dfc4e3982b3ee552b0a3ceca9a8b1", - "reference": "596fcaefc18dfc4e3982b3ee552b0a3ceca9a8b1", - "shasum": "" - }, - "require": { - "doctrine/annotations": "^1.11.1", - "doctrine/cache": "^1.10", - "goaop/parser-reflection": "^3.0.1", - "jakubledl/dissect": "~1.0", - "laminas/laminas-code": "^4.0", - "php": "^7.4.0", - "symfony/finder": "^4.4|^5.1" - }, - "require-dev": { - "adlawson/vfs": "^0.12.1", - "doctrine/orm": "^2.5", - "phpstan/phpstan": "^0.12.64", - "phpunit/phpunit": "^9.5", - "symfony/console": "^4.4|^5.1", - "symfony/filesystem": "^4.4|^5.1", - "symfony/process": "^4.4|^5.1", - "webmozart/glob": "^4.1" - }, - "suggest": { - "symfony/console": "Enables the usage of the command-line tool." - }, - "bin": [ - "bin/aspect" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Go\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Lisachenko Alexander", - "homepage": "https://github.com/lisachenko" - } - ], - "description": "Framework for aspect-oriented programming in PHP.", - "homepage": "http://go.aopphp.com/", - "keywords": [ - "aop", - "aspect", - "library", - "php" - ], - "support": { - "issues": "https://github.com/goaop/framework/issues", - "source": "https://github.com/goaop/framework/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/lisachenko", - "type": "github" - } - ], - "time": "2021-01-08T13:54:33+00:00" - }, - { - "name": "goaop/parser-reflection", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/goaop/parser-reflection.git", - "reference": "c06ae32c4f5664dbd5829ab417485929eded0657" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/goaop/parser-reflection/zipball/c06ae32c4f5664dbd5829ab417485929eded0657", - "reference": "c06ae32c4f5664dbd5829ab417485929eded0657", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.0", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "files": [ - "src/bootstrap.php" - ], - "psr-4": { - "Go\\ParserReflection\\": "src" - }, - "exclude-from-classmap": [ - "/tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alexander Lisachenko", - "email": "lisachenko.it@gmail.com" - } - ], - "description": "Provides reflection information, based on raw source", - "support": { - "issues": "https://github.com/goaop/parser-reflection/issues", - "source": "https://github.com/goaop/parser-reflection/tree/3.0.1" - }, - "time": "2021-01-03T18:16:54+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.7.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", - "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" - }, - "provide": { - "psr/http-factory-implementation": "1.0", - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "0.9.0", - "phpunit/phpunit": "^8.5.39 || ^9.6.20" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.7.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", - "type": "tidelift" - } - ], - "time": "2024-07-18T11:15:46+00:00" - }, - { - "name": "jakubledl/dissect", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/jakubledl/dissect.git", - "reference": "d3a391de31e45a247e95cef6cf58a91c05af67c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jakubledl/dissect/zipball/d3a391de31e45a247e95cef6cf58a91c05af67c4", - "reference": "d3a391de31e45a247e95cef6cf58a91c05af67c4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/console": "~2.1" - }, - "suggest": { - "symfony/console": "for the command-line tool" - }, - "bin": [ - "bin/dissect.php", - "bin/dissect" - ], - "type": "library", - "autoload": { - "psr-0": { - "Dissect": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "unlicense" - ], - "authors": [ - { - "name": "Jakub Lédl", - "email": "jakubledl@gmail.com" - } - ], - "description": "Lexing and parsing in pure PHP", - "homepage": "https://github.com/jakubledl/dissect", - "keywords": [ - "ast", - "lexing", - "parser", - "parsing" - ], - "support": { - "issues": "https://github.com/jakubledl/dissect/issues", - "source": "https://github.com/jakubledl/dissect/tree/v1.0.1" - }, - "time": "2013-01-29T21:29:14+00:00" - }, - { - "name": "laminas/laminas-code", - "version": "4.7.1", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-code.git", - "reference": "91aabc066d5620428120800c0eafc0411e441a62" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/91aabc066d5620428120800c0eafc0411e441a62", - "reference": "91aabc066d5620428120800c0eafc0411e441a62", - "shasum": "" - }, - "require": { - "php": ">=7.4, <8.2" - }, - "require-dev": { - "doctrine/annotations": "^1.13.2", - "ext-phar": "*", - "laminas/laminas-coding-standard": "^2.3.0", - "laminas/laminas-stdlib": "^3.6.1", - "phpunit/phpunit": "^9.5.10", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.13.1" - }, - "suggest": { - "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", - "laminas/laminas-stdlib": "Laminas\\Stdlib component" - }, - "type": "library", - "autoload": { - "files": [ - "polyfill/ReflectionEnumPolyfill.php" - ], - "psr-4": { - "Laminas\\Code\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", - "homepage": "https://laminas.dev", - "keywords": [ - "code", - "laminas", - "laminasframework" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-code/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-code/issues", - "rss": "https://github.com/laminas/laminas-code/releases.atom", - "source": "https://github.com/laminas/laminas-code" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-11-21T01:32:31+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.12.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2024-06-12T14:39:25+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2024-03-03T12:33:53+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.31", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.2-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": "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": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T06:37:42+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-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": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-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": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-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": "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/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-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": "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/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.6.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "49d7820565836236411f5dc002d16dd689cde42f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/49d7820565836236411f5dc002d16dd689cde42f", - "reference": "49d7820565836236411f5dc002d16dd689cde42f", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.5.0 || ^2", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.31", - "phpunit/php-file-iterator": "^3.0.6", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.4", - "phpunit/php-timer": "^5.0.3", - "sebastian/cli-parser": "^1.0.2", - "sebastian/code-unit": "^1.0.8", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.6", - "sebastian/environment": "^5.1.5", - "sebastian/exporter": "^4.0.6", - "sebastian/global-state": "^5.0.7", - "sebastian/object-enumerator": "^4.0.4", - "sebastian/resource-operations": "^3.0.4", - "sebastian/type": "^3.2.1", - "sebastian/version": "^3.0.2" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.6-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "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", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.20" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2024-07-10T11:45:39+00:00" - }, - { - "name": "psr/event-dispatcher", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" - }, - "time": "2019-01-08T18:20:26+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", - "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "psr/http-message": "^1.0 || ^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory" - }, - "time": "2024-04-15T12:06:14+00:00" - }, - { - "name": "psr/http-message", - "version": "2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" - }, - "time": "2023-04-04T09:54:51+00:00" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "type": "library", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders.", - "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" - }, - "time": "2019-03-08T08:55:37+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "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", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T06:27:43+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "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", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-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": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-22T06:19:30+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T06:30:58+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-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/5.1.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:03:51+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T06:33:00+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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/5.0.7" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T06:35:11+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "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", - "role": "lead" - } - ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-22T06:20:34+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:07:39+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-14T16:00:52+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-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": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:13:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-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": "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/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v5.4.40", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "ea43887e9afd2029509662d4f95e8b5ef6fc9bbb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/ea43887e9afd2029509662d4f95e8b5ef6fc9bbb", - "reference": "ea43887e9afd2029509662d4f95e8b5ef6fc9bbb", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Converts CSS selectors to XPath expressions", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.4.40" - }, - "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": "2024-05-31T14:33:22+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.5.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "80d075412b557d41002320b96a096ca65aa2c98d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/80d075412b557d41002320b96a096ca65aa2c98d", - "reference": "80d075412b557d41002320b96a096ca65aa2c98d", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.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": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.3" - }, - "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": "2023-01-24T14:02:46+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v5.4.40", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a54e2a8a114065f31020d6a89ede83e34c3b27a4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a54e2a8a114065f31020d6a89ede83e34c3b27a4", - "reference": "a54e2a8a114065f31020d6a89ede83e34c3b27a4", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/event-dispatcher-contracts": "^2|^3", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "symfony/dependency-injection": "<4.4" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.0|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/stopwatch": "^4.4|^5.0|^6.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "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": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.40" - }, - "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": "2024-05-31T14:33:22+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "540f4c73e87fd0c71ca44a6aa305d024ac68cb73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/540f4c73e87fd0c71ca44a6aa305d024ac68cb73", - "reference": "540f4c73e87fd0c71ca44a6aa305d024ac68cb73", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/event-dispatcher": "^1" - }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } - }, - "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": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.3" - }, - "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": "2024-01-23T13:51:25+00:00" - }, - { - "name": "symfony/finder", - "version": "v5.4.42", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "0724c51fa067b198e36506d2864e09a52180998a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/0724c51fa067b198e36506d2864e09a52180998a", - "reference": "0724c51fa067b198e36506d2864e09a52180998a", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "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": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.42" - }, - "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": "2024-07-22T08:53:29+00:00" - }, - { - "name": "symfony/yaml", - "version": "v3.3.18", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "af615970e265543a26ee712c958404eb9b7ac93d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/af615970e265543a26ee712c958404eb9b7ac93d", - "reference": "af615970e265543a26ee712c958404eb9b7ac93d", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "require-dev": { - "symfony/console": "~2.8|~3.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.3-dev" - } - }, - "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/3.3" - }, - "time": "2018-01-20T15:04:53+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "support": { - "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.3" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2024-03-03T12:36:25+00:00" - } - ], + "packages-dev": [], "aliases": [], "minimum-stability": "stable", "stability-flags": { "ifsnop/mysqldump-php": 20, - "psy/psysh": 0, "enyo/dropzone": 0 }, "prefer-stable": false, "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.2.0" } diff --git a/include/error.php b/include/error.php index d98374a9a..3073a0997 100644 --- a/include/error.php +++ b/include/error.php @@ -251,7 +251,7 @@ function epesi_log($message,$file) { if (version_compare(phpversion(), '5.4.0')==-1) $error_reporting_level = E_ALL; //all without notices else - $error_reporting_level = E_ALL & ~E_STRICT & ~E_DEPRECATED; // E_STRICT cause 5.4 unusable, E_DEPRECATED + $error_reporting_level = E_ALL & ~E_DEPRECATED; } else $error_reporting_level = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR; diff --git a/include/version.php b/include/version.php index a185b16b7..0b6933af5 100644 --- a/include/version.php +++ b/include/version.php @@ -1,6 +1,6 @@ label without translation + * $a['label'] => label with translation + * */ public function compare($a, $b) { $icons = Base_ActionBarCommon::$available_icons; - if (!isset($a['position'])) { + if (!isset($a['position']) || $a['position'] == 0) { $a['position'] = $icons[$a['icon']]?? (max($icons) + 1); } - if (!isset($b['position'])) { + if (!isset($b['position']) || $b['position'] == 0) { $b['position'] = $icons[$b['icon']]?? (max($icons) + 1); - } - - return $a['position'] - $b['position']?: strcmp(strip_tags($a['label']),strip_tags($b['label'])); + } + $ret = ($a['position'] - $b['position'])?: strcmp(strip_tags($a['label']),strip_tags($b['label'])); + return $ret; } public function compare_launcher($a, $b) { diff --git a/modules/Base/ActionBar/theme/default.css b/modules/Base/ActionBar/theme/default.css index fbc772640..2918bb07e 100644 --- a/modules/Base/ActionBar/theme/default.css +++ b/modules/Base/ActionBar/theme/default.css @@ -23,7 +23,7 @@ #Base_ActionBar .epesi_big_button { padding: 0px; - margin: 0px 0px 4px; + margin: 0px 0px 0px; height: 74px; width: auto; min-width: 64px; diff --git a/modules/Base/Theme/composer.lock b/modules/Base/Theme/composer.lock index 20e09b963..e687aaad3 100644 --- a/modules/Base/Theme/composer.lock +++ b/modules/Base/Theme/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "smarty/smarty", - "version": "v4.2.1", + "version": "v4.5.5", "source": { "type": "git", "url": "https://github.com/smarty-php/smarty.git", - "reference": "ffa2b81a8e354a49fd8a2f24742dc9dc399e8007" + "reference": "c4851c12e34ff80073ddeb7d98b059d57dea9de2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/smarty-php/smarty/zipball/ffa2b81a8e354a49fd8a2f24742dc9dc399e8007", - "reference": "ffa2b81a8e354a49fd8a2f24742dc9dc399e8007", + "url": "https://api.github.com/repos/smarty-php/smarty/zipball/c4851c12e34ff80073ddeb7d98b059d57dea9de2", + "reference": "c4851c12e34ff80073ddeb7d98b059d57dea9de2", "shasum": "" }, "require": { @@ -68,18 +68,18 @@ "support": { "forum": "https://github.com/smarty-php/smarty/discussions", "issues": "https://github.com/smarty-php/smarty/issues", - "source": "https://github.com/smarty-php/smarty/tree/v4.2.1" + "source": "https://github.com/smarty-php/smarty/tree/v4.5.5" }, - "time": "2022-09-14T10:59:01+00:00" + "time": "2024-11-21T22:06:22+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.0.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/modules/Base/Theme/smarty/plugins/modifier.strpos.php b/modules/Base/Theme/smarty/plugins/modifier.strpos.php new file mode 100644 index 000000000..53530b38e --- /dev/null +++ b/modules/Base/Theme/smarty/plugins/modifier.strpos.php @@ -0,0 +1,35 @@ +$emp,'customers'=>$cus,'status'=>0, 'priority'=>1, 'permission'=>0)).'>'; - if (CRM_TasksInstall::is_installed() && Utils_RecordBrowserCommon::get_access('task','add')) $ret['new']['task'] = '$emp,'customers'=>$cus,'status'=>0, 'priority'=>1, 'permission'=>0)).'>'; - if (CRM_PhoneCallInstall::is_installed() && Utils_RecordBrowserCommon::get_access('phonecall','add')) $ret['new']['phonecall'] = 'date('Y-m-d H:i:s'),'customer'=>'company/'.$values['id'],'employees'=>$me['id'],'status'=>0, 'permission'=>0, 'priority'=>1),'none',array('date_and_time')).'>'; - $ret['new']['note'] = Utils_RecordBrowser::$rb_obj->add_note_button('company/'.$values['id']); + $ret = array(); + $me = CRM_ContactsCommon::get_my_record(); + $emp = array($me['id']); + if (isset($values['id'])){ + $cus = array('company/'.$values['id']); + if (CRM_MeetingInstall::is_installed() && Utils_RecordBrowserCommon::get_access('crm_meeting','add')) $ret['new']['event'] = '$emp,'customers'=>$cus,'status'=>0, 'priority'=>1, 'permission'=>0)).'>'; + if (CRM_TasksInstall::is_installed() && Utils_RecordBrowserCommon::get_access('task','add')) $ret['new']['task'] = '$emp,'customers'=>$cus,'status'=>0, 'priority'=>1, 'permission'=>0)).'>'; + if (CRM_PhoneCallInstall::is_installed() && Utils_RecordBrowserCommon::get_access('phonecall','add')) $ret['new']['phonecall'] = 'date('Y-m-d H:i:s'),'customer'=>'company/'.$values['id'],'employees'=>$me['id'],'status'=>0, 'permission'=>0, 'priority'=>1),'none',array('date_and_time')).'>'; + $ret['new']['note'] = Utils_RecordBrowser::$rb_obj->add_note_button('company/'.$values['id']); + } return $ret; case 'adding': $values['permission'] = Base_User_SettingsCommon::get('CRM_Common','default_record_permission'); @@ -1003,8 +1005,10 @@ public static function submit_contact($values, $mode) { $me = CRM_ContactsCommon::get_my_record(); $emp = array($me['id']); $cus = array(); - if ($is_employee) $emp[] = $values['id']; - else $cus[] = 'contact/'.$values['id']; + if (isset($values['id'])){ + if ($is_employee) $emp[] = $values['id']; + else $cus[] = 'contact/'.$values['id']; + } $ret = array(); $ret['new'] = array(); $ret['new']['crm_filter'] = '1)).'>F'; @@ -1012,15 +1016,17 @@ public static function submit_contact($values, $mode) { CRM_FiltersCommon::set_profile('c'.$values['id']); if (CRM_MeetingInstall::is_installed() && Utils_RecordBrowserCommon::get_access('crm_meeting','add')) $ret['new']['event'] = '$emp,'customers'=>$cus,'status'=>0, 'priority'=>1, 'permission'=>0)).'>'; if (CRM_TasksInstall::is_installed() && Utils_RecordBrowserCommon::get_access('task','add')) $ret['new']['task'] = '$emp,'customers'=>$cus,'status'=>0, 'priority'=>1, 'permission'=>0)).'>'; - if (CRM_PhoneCallInstall::is_installed() && Utils_RecordBrowserCommon::get_access('phonecall','add')) $ret['new']['phonecall'] = 'date('Y-m-d H:i:s'),'customer'=>'contact/'.$values['id'],'employees'=>$me['id'],'status'=>0, 'permission'=>0, 'priority'=>1),'none',false).'>'; - $ret['new']['note'] = Utils_RecordBrowser::$rb_obj->add_note_button('contact/'.$values['id']); + if (isset($values['id'])){ + if (CRM_PhoneCallInstall::is_installed() && Utils_RecordBrowserCommon::get_access('phonecall','add')) $ret['new']['phonecall'] = 'date('Y-m-d H:i:s'),'customer'=>'contact/'.$values['id'],'employees'=>$me['id'],'status'=>0, 'permission'=>0, 'priority'=>1),'none',false).'>'; + $ret['new']['note'] = Utils_RecordBrowser::$rb_obj->add_note_button('contact/'.$values['id']); + } return $ret; case 'adding': $values['permission'] = Base_User_SettingsCommon::get('CRM_Common','default_record_permission'); break; case 'add': - if (isset($values['email']) && $values['email']=='' && $values['login']!=0 && $mode=='add') - $values['email'] = DB::GetOne('SELECT mail FROM user_password WHERE user_login_id=%d', array($values['login'])); + if (isset($values['email']) && $values['email']=='' && (int) $values['login']!=0 && $mode=='add') + $values['email'] = DB::GetOne('SELECT mail FROM user_password WHERE user_login_id=%d', array((int) $values['login'])); case 'edit': if (isset($values['create_company'])) { $comp_id = Utils_RecordBrowserCommon::new_record('company', diff --git a/modules/CRM/Contacts/theme/Contact.tpl b/modules/CRM/Contacts/theme/Contact.tpl index 9320da8d1..17c3b9992 100644 --- a/modules/CRM/Contacts/theme/Contact.tpl +++ b/modules/CRM/Contacts/theme/Contact.tpl @@ -49,9 +49,8 @@ -
+ - {* create new company *} {if isset($form_data.create_company)} @@ -69,22 +68,20 @@ {/if} {assign var=x value=1} - {if $action=='view'} - {assign var=y value=1} - {else} - {assign var=y value=2} - {/if} + {assign var=y value=1} {foreach key=k item=f from=$fields name=fields} {if $f.type!="multiselect"} {if !isset($focus) && $f.type=="text"} {assign var=focus value=$f.element} {/if} - {if $y == 1 && $x >= 2} - {else} {assign var=y value=$y+1} {/if} @@ -131,11 +130,11 @@ {/if} diff --git a/modules/CRM/Mail/composer.lock b/modules/CRM/Mail/composer.lock index 325145b27..d3eab0fcc 100644 --- a/modules/CRM/Mail/composer.lock +++ b/modules/CRM/Mail/composer.lock @@ -1,24 +1,23 @@ { "_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#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "hash": "b85c6e4defdefc3ae4499e07481a8ecb", "content-hash": "4838a2fe6ca8867c2ee90f2ce53a21e2", "packages": [ { "name": "tedivm/fetch", - "version": "v0.7.1", + "version": "v0.7.2", "source": { "type": "git", "url": "https://github.com/tedious/Fetch.git", - "reference": "ea3f1bbde6bd6388488105240640642dc82c06a6" + "reference": "9a1b0eb87d343eb0c8c57acb33973c594b8aca8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tedious/Fetch/zipball/ea3f1bbde6bd6388488105240640642dc82c06a6", - "reference": "ea3f1bbde6bd6388488105240640642dc82c06a6", + "url": "https://api.github.com/repos/tedious/Fetch/zipball/9a1b0eb87d343eb0c8c57acb33973c594b8aca8d", + "reference": "9a1b0eb87d343eb0c8c57acb33973c594b8aca8d", "shasum": "" }, "require": { @@ -54,15 +53,26 @@ "imap", "pop3" ], - "time": "2015-08-02 03:38:12" + "support": { + "issues": "https://github.com/tedious/Fetch/issues", + "source": "https://github.com/tedious/Fetch/tree/v0.7.2" + }, + "funding": [ + { + "url": "https://github.com/tedivm", + "type": "github" + } + ], + "time": "2016-11-26T08:28:12+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [] + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/modules/CRM/Meeting/MeetingCommon_0.php b/modules/CRM/Meeting/MeetingCommon_0.php index c6357adee..fd63cfa5c 100644 --- a/modules/CRM/Meeting/MeetingCommon_0.php +++ b/modules/CRM/Meeting/MeetingCommon_0.php @@ -413,7 +413,7 @@ public static function submit_meeting($values, $mode) { break; case 'display': $pdf = Utils_RecordBrowser::$rb_obj->pack_module(Libs_TCPDF::module_name(), 'L'); - if ($pdf->prepare()) { + if ($pdf->prepare() && isset($values['id'])) { $pdf->set_title($values['title']); $pdf->set_subject(''); $pdf->prepare_header(); @@ -456,7 +456,9 @@ public static function submit_meeting($values, $mode) { if (CRM_MeetingInstall::is_installed()) $ret['new']['event'] = '$values['title'],'permission'=>$values['permission'],'priority'=>$values['priority'],'description'=>$values['description'],'date'=>date('Y-m-d'),'time'=>date('H:i:s'),'duration'=>3600,'employees'=>$values['employees'], 'customers'=>$values['customers'],'status'=>0), 'none', false).'>'; if (CRM_TasksInstall::is_installed()) $ret['new']['task'] = '$values['title'],'permission'=>$values['permission'],'priority'=>$values['priority'],'description'=>$values['description'],'employees'=>$values['employees'], 'customers'=>$values['customers'],'status'=>0,'deadline'=>date('Y-m-d', strtotime('+1 day')))).'>'; if (CRM_PhoneCallInstall::is_installed()) $ret['new']['phonecall'] = '$values['title'],'permission'=>$values['permission'],'priority'=>$values['priority'],'description'=>$values['description'],'date_and_time'=>date('Y-m-d H:i:s'),'employees'=>$values['employees'], 'customer'=>$cus,'status'=>0), 'none', false).'>'; - $ret['new']['note'] = Utils_RecordBrowser::$rb_obj->add_note_button('crm_meeting/'.$values['id']); + if (isset($values['id'])){ + $ret['new']['note'] = Utils_RecordBrowser::$rb_obj->add_note_button('crm_meeting/'.$values['id']); + } $ret['fdow'] = Utils_PopupCalendarCommon::get_first_day_of_week() - 1; diff --git a/modules/CRM/Roundcube/RC/config/config.inc.php b/modules/CRM/Roundcube/RC/config/config.inc.php index 8c2fde5cc..3477e33b5 100644 --- a/modules/CRM/Roundcube/RC/config/config.inc.php +++ b/modules/CRM/Roundcube/RC/config/config.inc.php @@ -6,7 +6,7 @@ $CID = isset($_GET['ECID']) ? $_GET['ECID'] : false; define('CID', $CID); define('READ_ONLY_SESSION',isset($_GET['_action']) && $_GET['_action']=='plugin.epesi_archive'?false:true); -error_reporting(E_ALL & ~(E_STRICT | E_NOTICE | E_DEPRECATED)); +error_reporting(E_ALL & ~(E_NOTICE | E_DEPRECATED)); require_once('vendor/autoload.php'); require_once('include/data_dir.php'); diff --git a/modules/CRM/Roundcube/RC/program/lib/Roundcube/bootstrap.php b/modules/CRM/Roundcube/RC/program/lib/Roundcube/bootstrap.php index 2718997a2..e24d953ab 100644 --- a/modules/CRM/Roundcube/RC/program/lib/Roundcube/bootstrap.php +++ b/modules/CRM/Roundcube/RC/program/lib/Roundcube/bootstrap.php @@ -25,7 +25,7 @@ */ $config = array( - 'error_reporting' => E_ALL & ~E_NOTICE & ~E_STRICT, + 'error_reporting' => E_ALL & ~E_NOTICE & ~E_DEPRECATED, // Some users are not using Installer, so we'll check some // critical PHP settings here. Only these, which doesn't provide // an error/warning in the logs later. See (#1486307). diff --git a/modules/CRM/Roundcube/RC/skins/larry/svggradient.php b/modules/CRM/Roundcube/RC/skins/larry/svggradient.php index 8db2c5f63..46902e53c 100644 --- a/modules/CRM/Roundcube/RC/skins/larry/svggradient.php +++ b/modules/CRM/Roundcube/RC/skins/larry/svggradient.php @@ -11,7 +11,7 @@ * See http://creativecommons.org/licenses/by-sa/3.0/ for details. */ -ini_set('error_reporting', E_ALL &~ (E_NOTICE | E_STRICT)); +ini_set('error_reporting', E_ALL &~ (E_NOTICE | E_DEPRECATED)); header('Content-Type: image/svg+xml'); header("Expires: ".gmdate("D, d M Y H:i:s", time()+864000)." GMT"); diff --git a/modules/CRM/Tasks/TasksCommon_0.php b/modules/CRM/Tasks/TasksCommon_0.php index 0899b6514..0df10eaeb 100644 --- a/modules/CRM/Tasks/TasksCommon_0.php +++ b/modules/CRM/Tasks/TasksCommon_0.php @@ -226,7 +226,9 @@ public static function submit_task($values, $mode) { if (CRM_MeetingInstall::is_installed()) $ret['new']['event'] = '$values['title'],'permission'=>$values['permission'],'priority'=>$values['priority'],'description'=>$values['description'],'date'=>date('Y-m-d'),'time'=>date('H:i:s'),'duration'=>3600,'employees'=>$values['employees'], 'customers'=>$values['customers'],'status'=>0), 'none', false).'>'; $ret['new']['task'] = ''; if (CRM_PhoneCallInstall::is_installed()) $ret['new']['phonecall'] = '$values['title'],'permission'=>$values['permission'],'priority'=>$values['priority'],'description'=>$values['description'],'date_and_time'=>date('Y-m-d H:i:s'),'employees'=>$values['employees'], 'customer'=>$cus,'status'=>0), 'none', false).'>'; - $ret['new']['note'] = Utils_RecordBrowser::$rb_obj->add_note_button('task/'.$values['id']); + if (isset($values['id'])){ + $ret['new']['note'] = Utils_RecordBrowser::$rb_obj->add_note_button('task/'.$values['id']); + } return $ret; case 'adding': if (!isset($values['deadline'])) { diff --git a/modules/Libs/OpenFlashChart/.hidden b/modules/Libs/OpenFlashChart/.hidden deleted file mode 100644 index 5c23a06b1..000000000 --- a/modules/Libs/OpenFlashChart/.hidden +++ /dev/null @@ -1 +0,0 @@ -2-lug \ No newline at end of file diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Area/OFC_Charts_Area_Hollow.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Area/OFC_Charts_Area_Hollow.php deleted file mode 100644 index 324c61c6e..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Area/OFC_Charts_Area_Hollow.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Area.php'); - -class OFC_Charts_Area_Hollow extends OFC_Charts_Area -{ - function OFC_Charts_Area_Hollow() - { - parent::OFC_Charts_Area(); - - $this->type = 'area_hollow'; - - $this->{'fill-alpha'} = 0.35; - - $this->values = array(); - } - - function set_width( $w ) - { - $this->width = $w; - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_values( $v ) { - $this->values = $v; - } - - function set_dot_size( $size ) - { - $this->{'dot-size'} = $size; - } - - function set_key( $text, $font_size ) - { - $this->text = $text; - $this->{'font-size'} = $font_size; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_3d.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_3d.php deleted file mode 100644 index a4cb29afa..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_3d.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Bar.php'); - -class bar_3d_value -{ - function bar_3d_value( $top ) - { - $this->top = $top; -// $this->bottom = $bottom; - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_tooltip( $tip ) - { - $this->tip = $tip; - } -} - -class OFC_Charts_Bar_3d extends OFC_Charts_Bar -{ - function OFC_Charts_Bar_3d() - { - parent::OFC_Charts_Bar(); - - $this->type = 'bar_3d'; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Filled.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Filled.php deleted file mode 100644 index fe1e9903a..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Filled.php +++ /dev/null @@ -1,60 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Bar.php'); - -class OFC_Charts_Bar_Filled_Value extends OFC_Charts_Bar_Value -{ - function OFC_Charts_Bar_Filled_Value( $val, $colour ) - { - parent::OFC_Charts_Bar_Value( $val, $colour ); - } - - function set_outline_colour( $outline_colour ) - { - $this->{'outline-colour'} = $outline_colour; - } -} - -class OFC_Charts_Bar_Filled extends OFC_Charts_Bar -{ - function OFC_Charts_Bar_Filled( $colour=null, $outline_colour=null ) - { - parent::OFC_Charts_Bar(); - - $this->type = 'bar_filled'; - - if( isset( $colour ) ) - { - $this->set_colour( $colour ); - } - - if( isset( $outline_colour ) ) - { - $this->set_outline_colour( $outline_colour ); - } - } - - function set_outline_colour( $outline_colour ) - { - $this->{'outline-colour'} = $outline_colour; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Glass.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Glass.php deleted file mode 100644 index 7dc255306..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Glass.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Bar.php'); - -class bar_glass_value -{ - function bar_glass_value( $top ) - { - $this->top = $top; -// $this->bottom = $bottom; - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_tooltip( $tip ) - { - $this->tip = $tip; - } -} - -class OFC_Charts_Bar_Glass extends OFC_Charts_Bar -{ - - function OFC_Charts_Bar_Glass() - { - parent::OFC_Charts_Bar(); - - $this->type = 'bar_glass'; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Horizontal.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Horizontal.php deleted file mode 100644 index f6dab7482..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Horizontal.php +++ /dev/null @@ -1,49 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Bar.php'); - -class OFC_Charts_Bar_Horizontal_Value -{ - function OFC_Charts_Bar_Horizontal_Value( $left, $right ) - { - $this->left = $left; - $this->right = $right; - } -} - -class OFC_Charts_Bar_Horizontal -{ - - function OFC_Charts_Bar_Horizontal() - { - $this->type = "hbar"; - $this->colour = "#9933CC"; - $this->text = "Page views";; - $this->{'font-size'} = 10; - $this->values = array(); - } - - function append_value( $v ) - { - $this->values[] = $v; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Sketch.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Sketch.php deleted file mode 100644 index cdc2e4b10..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Sketch.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Bar.php'); - -class OFC_Charts_Bar_Sketch extends OFC_Charts_Bar -{ - function OFC_Charts_Bar_Sketch( $colour, $outline_colour, $fun_factor ) - { - parent::OFC_Charts_Bar(); - - $this->type = 'bar_sketch'; - - $this->set_colour( $colour ); - $this->set_outline_colour( $outline_colour ); - $this->offset = $fun_factor; - } - - function set_outline_colour( $outline_colour ) - { - $this->{'outline-colour'} = $outline_colour; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Stack.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Stack.php deleted file mode 100644 index ad2875226..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Stack.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Bar.php'); - -class OFC_Charts_Bar_Stack_Value -{ - function OFC_Charts_Bar_Stack_Value( $val, $colour ) - { - $this->val = $val; - $this->colour = $colour; - } -} - -class OFC_Charts_Bar_Stack extends OFC_Charts_Bar -{ - function OFC_Charts_Bar_Stack() - { - parent::OFC_Charts_Bar(); - - $this->type = 'bar_stack'; - } - - function append_stack( $v ) - { - $this->append_value( $v ); - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Value.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Value.php deleted file mode 100644 index 27fe49cc5..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Bar/OFC_Charts_Bar_Value.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Bar.php'); - -class OFC_Charts_Bar_Value -{ - function OFC_Charts_Bar_Value( $top, $bottom=null ) - { - $this->top = $top; - - if( isset( $bottom ) ) - { - $this->bottom = $bottom; - } - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_tooltip( $tip ) - { - $this->tip = $tip; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Line/OFC_Charts_Line_Dot.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Line/OFC_Charts_Line_Dot.php deleted file mode 100644 index 2e3363f4a..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Line/OFC_Charts_Line_Dot.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Line.php'); - -class OFC_Charts_Line_Dot extends OFC_Charts_Line -{ - function OFC_Charts_Line_Dot() - { - parent::OFC_Charts_Line(); - - $this->type = 'line_dot'; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Line/OFC_Charts_Line_Hollow.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Line/OFC_Charts_Line_Hollow.php deleted file mode 100644 index 40afd858f..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Line/OFC_Charts_Line_Hollow.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Line.php'); - -class OFC_Charts_Line_Hollow extends OFC_Charts_Line -{ - function OFC_Charts_Line_Hollow() - { - parent::OFC_Charts_Line(); - - $this->type = 'line_hollow'; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Area.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Area.php deleted file mode 100644 index 91c4ad572..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Area.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Base.php'); - -class OFC_Charts_Area extends OFC_Charts_Base -{ - - function OFC_Charts_Area() - { - parent::OFC_Charts_Base(); - - $this->type = 'area'; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Bar.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Bar.php deleted file mode 100644 index 983536f57..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Bar.php +++ /dev/null @@ -1,86 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Base.php'); - -class OFC_Charts_Bar_Value -{ - function OFC_Charts_Bar_Value( $top, $bottom=null ) - { - $this->top = $top; - - if( isset( $bottom ) ) - { - $this->bottom = $bottom; - } - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_tooltip( $tip ) - { - $this->tip = $tip; - } -} - -class OFC_Charts_Bar extends OFC_Charts_Base -{ - function OFC_Charts_Bar() - { - parent::OFC_Charts_Base(); - - $this->type = 'bar'; - } - - function set_key( $text, $size ) - { - $this->text = $text; - $this->{'font-size'} = $size; - } - - function set_values( $v ) - { - $this->values = $v; - } - - function append_value( $v ) - { - $this->values[] = $v; - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_alpha( $alpha ) - { - $this->alpha = $alpha; - } - - function set_tooltip( $tip ) - { - $this->tip = $tip; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Base.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Base.php deleted file mode 100644 index 6559b14c9..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Base.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class OFC_Charts_Base -{ - function OFC_Charts_Base() - { - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Line.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Line.php deleted file mode 100644 index 4e6fba1ae..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Line.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Base.php'); - -class OFC_Charts_Line extends OFC_Charts_Base -{ - function OFC_Charts_Line() - { - parent::OFC_Charts_Base(); - - $this->type = 'line'; - } - - function set_values( $v ) - { - $this->values = $v; - } - - function set_width( $width ) - { - $this->width = $width; - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_dot_size( $size ) - { - $this->{'dot-size'} = $size; - } - - function set_halo_size( $size ) - { - $this->{'halo-size'} = $size; - } - - function set_key( $text, $font_size ) - { - $this->text = $text; - $this->{'font-size'} = $font_size; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Pie.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Pie.php deleted file mode 100644 index 55674149c..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Pie.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Base.php'); - -class OFC_Charts_Pie_Value -{ - function OFC_Charts_Pie_Value( $value, $text ) - { - $this->value = $value; - $this->text = $text; - } -} - -class OFC_Charts_Pie extends OFC_Charts_Base -{ - function OFC_Charts_Pie() - { - parent::OFC_Charts_Base(); - - $this->type = 'pie'; - $this->colours = array("#d01f3c","#356aa0","#C79810"); - $this->alpha = 0.6; - $this->border = 2; - $this->values = array(2,3,new OFC_Charts_Pie_Value(6.5, 'hello (6.5)')); - } - - // boolean - function set_animate( $v ) - { - $this->animate = $v; - } - - // real - function set_start_angle( $angle ) - { - $this->{'start-angle'} = $angle; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Scatter.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Scatter.php deleted file mode 100644 index b68d1500c..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/OFC_Charts_Scatter.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Charts/OFC_Charts_Base.php'); - -class OFC_Charts_Scatter_Value -{ - function OFC_Charts_Scatter_Value( $x, $y, $dot_size=-1 ) - { - $this->x = $x; - $this->y = $y; - - if( $dot_size > 0 ) - { - $this->{'dot-size'} = $dot_size; - } - } -} - -class OFC_Charts_Scatter extends OFC_Charts_Base -{ - function OFC_Charts_Scatter( $colour, $dot_size ) - { - parent::OFC_Charts_Base(); - - $this->type = 'scatter'; - $this->set_colour( $colour ); - $this->set_dot_size( $dot_size ); - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_dot_size( $dot_size ) - { - $this->{'dot-size'} = $dot_size; - } - - function set_values( $values ) - { - $this->values = $values; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Scatter/OFC_Scatter_Line.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Scatter/OFC_Scatter_Line.php deleted file mode 100644 index 48ebae9b4..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Charts/Scatter/OFC_Scatter_Line.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - require_once('OFC/Charts/OFC_Charts_Scatter.php'); - - class OFC_Charts_Scatter_Line extends OFC_Charts_Scatter - { - function OFC_Charts_Scatter_Line( $colour, $dot_size ) - { - parent::OFC_Charts_Scatter( $colour, $dot_size ); - - $this->type = 'scatter_line'; - } - } \ No newline at end of file diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X.php deleted file mode 100644 index 00839a23e..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X.php +++ /dev/null @@ -1,81 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Elements/OFC_Elements_Axis.php'); -require_once('OFC/Elements/Axis/OFC_Elements_Axis_X_Label_Set.php'); - -class OFC_Elements_Axis_X extends OFC_Elements_Axis -{ - function OFC_Elements_Axis_X() - { - parent::OFC_Elements_Axis(); - } - - function set_stroke( $stroke ) - { - $this->stroke = $stroke; - } - - function set_tick_height( $height ) - { - $this->{'tick-height'} = $height; - } - - // $o is a boolean - function set_offset( $o ) - { - $this->offset = ($o) ? true : false; - } - - function set_3d( $val ) - { - $this->{'3d'} = $val; - } - - function set_labels( $x_axis_labels ) - { - $this->labels = $x_axis_labels; - } - - function set_range( $min, $max, $steps=1 ) - { - $this->min = $min; - $this->max = $max; - $this->set_steps( $steps ); - } - - /** - * helper function to make the examples - * simpler. - */ - function set_labels_from_array( $a ) - { - $x_axis_labels = new OFC_Elements_Axis_X_Label_Set(); - $x_axis_labels->set_labels( $a ); - - $this->labels = $x_axis_labels; - - if( isset( $this->steps ) ) - { - $x_axis_labels->set_steps( $this->steps ); - } - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X_Label.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X_Label.php deleted file mode 100644 index 2ee291ef3..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X_Label.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class OFC_Elements_Axis_X_Label extends OFC_Elements_Base -{ - function OFC_Elements_Axis_X_Label( $text, $colour, $size, $rotate ) - { - parent::OFC_Elements_Base(); - - $this->set_text( $text ); - $this->set_colour( $colour ); - $this->set_size( $size ); - $this->set_rotate( $rotate ); - } - - function set_text( $text ) - { - $this->text = $text; - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_size( $size ) - { - $this->size = $size; - } - - function set_rotate( $rotate ) - { - $this->rotate = $rotate; - } - - function set_vertical() - { - $this->rotate = 'vertical'; - } - - function set_visible() - { - $this->visible = true; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X_Label_Set.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X_Label_Set.php deleted file mode 100644 index 8086775bc..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_X_Label_Set.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class OFC_Elements_Axis_X_Label_Set -{ - function OFC_Elements_Axis_X_Label_Set() - { - } - - function set_steps( $steps ) - { - $this->steps = $steps; - } - - /** - * An array of [x_axis_label or string] - */ - function set_labels( $labels ) - { - $this->labels = $labels; - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_size( $size ) - { - $this->size = $size; - } - - function set_vertical() - { - $this->rotate = 'vertical'; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_Y.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_Y.php deleted file mode 100644 index 8976c9d1d..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_Y.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Elements/OFC_Elements_Axis.php'); - -class OFC_Elements_Axis_Y extends OFC_Elements_Axis -{ - function OFC_Elements_Axis_Y() - { - parent::OFC_Elements_Axis(); - } - - function set_grid_colour( $colour ) - { - $this->{'grid-colour'} = $colour; - } - - function set_stroke( $s ) - { - $this->stroke = $s; - } - - function set_tick_length( $val ) - { - $this->{'tick-length'} = $val; - } - - function set_range( $min, $max, $steps=1 ) - { - $this->min = $min; - $this->max = $max; - $this->set_steps( $steps ); - } - - function set_offset( $off ) - { - $this->offset = ($off) ? 1 : 0; - } - - function set_labels( $labels ) - { - $this->labels = $labels; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_Y_Right.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_Y_Right.php deleted file mode 100644 index c93cc949d..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Axis/OFC_Elements_Axis_Y_Right.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class OFC_Elements_Axis_Y_Right extends OFC_Elements_Axis_Y -{ - function OFC_Elements_Axis_Y_Right() - { - parent::OFC_Elements_Axis_Y(); - } - - /** - * y axis right does NOT control - * grid colour, the left axis does - */ - function set_grid_colour( $colour ) - { - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Legend/OFC_Elements_Legend_X.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Legend/OFC_Elements_Legend_X.php deleted file mode 100644 index 4b6634a0e..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Legend/OFC_Elements_Legend_X.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Elements/OFC_Elements_Base.php'); - -class OFC_Elements_Legend_X extends OFC_Elements_Base -{ - function OFC_Elements_Legend_X( $text='' ) - { - parent::OFC_Elements_Base(); - - $this->text = $text; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Legend/OFC_Elements_Legend_Y.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Legend/OFC_Elements_Legend_Y.php deleted file mode 100644 index 4a6371bda..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/Legend/OFC_Elements_Legend_Y.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Elements/OFC_Elements_Base.php'); - -class OFC_Elements_Legend_Y extends OFC_Elements_Base -{ - function OFC_Elements_Legend_Y( $text='' ) - { - parent::OFC_Elements_Base(); - - $this->text = $text; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Axis.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Axis.php deleted file mode 100644 index 2cd0e6eb3..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Axis.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Elements/OFC_Elements_Base.php'); - -class OFC_Elements_Axis extends OFC_Elements_Base -{ - function OFC_Elements_Axis() - { - parent::OFC_Elements_Base(); - } - - function set_colours( $colour, $grid_colour ) - { - $this->set_colour( $colour ); - $this->set_grid_colour( $grid_colour ); - } - - function set_colour( $colour ) - { - $this->colour = $colour; - } - - function set_grid_colour( $colour ) - { - $this->{'grid-colour'} = $colour; - } - - function set_steps( $steps=1 ) - { - $this->steps = $steps; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Base.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Base.php deleted file mode 100644 index dee2eff66..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Base.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -class OFC_Elements_Base { - - function OFC_Elements_Base() { - } - - function set_style($css) { - $this->style = $css; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Title.php b/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Title.php deleted file mode 100644 index 9a30045c7..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/Elements/OFC_Elements_Title.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Elements/OFC_Elements_Base.php'); - -class OFC_Elements_Title extends OFC_Elements_Base -{ - function OFC_Elements_Title( $text='' ) - { - parent::OFC_Elements_Base(); - - $this->text = $text; - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/JSON.php b/modules/Libs/OpenFlashChart/2-lug/OFC/JSON.php deleted file mode 100644 index daac9df8f..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/JSON.php +++ /dev/null @@ -1,805 +0,0 @@ - - * @author Matt Knapp - * @author Brett Stimmerman - * @copyright 2005 Michal Migurski - * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ - * @license http://www.opensource.org/licenses/bsd-license.php - * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 - */ - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_SLICE', 1); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_STR', 2); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_ARR', 3); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_OBJ', 4); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_CMT', 5); - -/** - * Behavior switch for Services_JSON::decode() - */ -define('SERVICES_JSON_LOOSE_TYPE', 16); - -/** - * Behavior switch for Services_JSON::decode() - */ -define('SERVICES_JSON_SUPPRESS_ERRORS', 32); - -/** - * Converts to and from JSON format. - * - * Brief example of use: - * - * - * // create a new instance of Services_JSON - * $json = new Services_JSON(); - * - * // convert a complexe value to JSON notation, and send it to the browser - * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); - * $output = $json->encode($value); - * - * print($output); - * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] - * - * // accept incoming POST data, assumed to be in JSON notation - * $input = file_get_contents('php://input', 1000000); - * $value = $json->decode($input); - * - */ -class Services_JSON -{ - /** - * constructs a new JSON instance - * - * @param int $use object behavior flags; combine with boolean-OR - * - * possible values: - * - SERVICES_JSON_LOOSE_TYPE: loose typing. - * "{...}" syntax creates associative arrays - * instead of objects in decode(). - * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. - * Values which can't be encoded (e.g. resources) - * appear as NULL instead of throwing errors. - * By default, a deeply-nested resource will - * bubble up with an error, so all return values - * from encode() should be checked with isError() - */ - function Services_JSON($use = 0) - { - $this->use = $use; - } - - /** - * convert a string from one UTF-16 char to one UTF-8 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf16 UTF-16 character - * @return string UTF-8 character - * @access private - */ - function utf162utf8($utf16) - { - // oh please oh please oh please oh please oh please - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); - } - - $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); - - switch(true) { - case ((0x7F & $bytes) == $bytes): - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x7F & $bytes); - - case (0x07FF & $bytes) == $bytes: - // return a 2-byte UTF-8 character - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0xC0 | (($bytes >> 6) & 0x1F)) - . chr(0x80 | ($bytes & 0x3F)); - - case (0xFFFF & $bytes) == $bytes: - // return a 3-byte UTF-8 character - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0xE0 | (($bytes >> 12) & 0x0F)) - . chr(0x80 | (($bytes >> 6) & 0x3F)) - . chr(0x80 | ($bytes & 0x3F)); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * convert a string from one UTF-8 char to one UTF-16 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf8 UTF-8 character - * @return string UTF-16 character - * @access private - */ - function utf82utf16($utf8) - { - // oh please oh please oh please oh please oh please - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); - } - - switch(strlen($utf8)) { - case 1: - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return $utf8; - - case 2: - // return a UTF-16 character from a 2-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x07 & (ord($utf8{0}) >> 2)) - . chr((0xC0 & (ord($utf8{0}) << 6)) - | (0x3F & ord($utf8{1}))); - - case 3: - // return a UTF-16 character from a 3-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr((0xF0 & (ord($utf8{0}) << 4)) - | (0x0F & (ord($utf8{1}) >> 2))) - . chr((0xC0 & (ord($utf8{1}) << 6)) - | (0x7F & ord($utf8{2}))); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * encodes an arbitrary variable into JSON format - * - * @param mixed $var any number, boolean, string, array, or object to be encoded. - * see argument 1 to Services_JSON() above for array-parsing behavior. - * if var is a strng, note that encode() always expects it - * to be in ASCII or UTF-8 format! - * - * @return mixed JSON string representation of input var or an error if a problem occurs - * @access public - */ - function encode($var) - { - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - - case 'NULL': - return 'null'; - - case 'integer': - return (int) $var; - - case 'double': - case 'float': - return (float) $var; - - case 'string': - // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT - $ascii = ''; - $strlen_var = strlen($var); - - /* - * Iterate over every character in the string, - * escaping with a slash or encoding to UTF-8 where necessary - */ - for ($c = 0; $c < $strlen_var; ++$c) { - - $ord_var_c = ord($var{$c}); - - switch (true) { - case $ord_var_c == 0x08: - $ascii .= '\b'; - break; - case $ord_var_c == 0x09: - $ascii .= '\t'; - break; - case $ord_var_c == 0x0A: - $ascii .= '\n'; - break; - case $ord_var_c == 0x0C: - $ascii .= '\f'; - break; - case $ord_var_c == 0x0D: - $ascii .= '\r'; - break; - - case $ord_var_c == 0x22: - case $ord_var_c == 0x2F: - case $ord_var_c == 0x5C: - // double quote, slash, slosh - $ascii .= '\\'.$var{$c}; - break; - - case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): - // characters U-00000000 - U-0000007F (same as ASCII) - $ascii .= $var{$c}; - break; - - case (($ord_var_c & 0xE0) == 0xC0): - // characters U-00000080 - U-000007FF, mask 110XXXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, ord($var{$c + 1})); - $c += 1; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF0) == 0xE0): - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2})); - $c += 2; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF8) == 0xF0): - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3})); - $c += 3; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFC) == 0xF8): - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4})); - $c += 4; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFE) == 0xFC): - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4}), - ord($var{$c + 5})); - $c += 5; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - } - } - - return '"'.$ascii.'"'; - - case 'array': - /* - * As per JSON spec if any array key is not an integer - * we must treat the the whole array as an object. We - * also try to catch a sparsely populated associative - * array with numeric keys here because some JS engines - * will create an array with empty indexes up to - * max_index which can cause memory issues and because - * the keys, which may be relevant, will be remapped - * otherwise. - * - * As per the ECMA and JSON specification an object may - * have any string as a property. Unfortunately due to - * a hole in the ECMA specification if the key is a - * ECMA reserved word or starts with a digit the - * parameter is only accessible using ECMAScript's - * bracket notation. - */ - - // treat as a JSON object - if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - $properties = array_map(array($this, 'name_value'), - array_keys($var), - array_values($var)); - - foreach($properties as $property) { - if(Services_JSON::isError($property)) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - } - - // treat it like a regular array - $elements = array_map(array($this, 'encode'), $var); - - foreach($elements as $element) { - if(Services_JSON::isError($element)) { - return $element; - } - } - - return '[' . join(',', $elements) . ']'; - - case 'object': - $vars = get_object_vars($var); - - $properties = array_map(array($this, 'name_value'), - array_keys($vars), - array_values($vars)); - - foreach($properties as $property) { - if(Services_JSON::isError($property)) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - - default: - return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) - ? 'null' - : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); - } - } - - /** - * array-walking function for use in generating JSON-formatted name-value pairs - * - * @param string $name name of key to use - * @param mixed $value reference to an array element to be encoded - * - * @return string JSON-formatted name-value pair, like '"name":value' - * @access private - */ - function name_value($name, $value) - { - $encoded_value = $this->encode($value); - - if(Services_JSON::isError($encoded_value)) { - return $encoded_value; - } - - return $this->encode(strval($name)) . ':' . $encoded_value; - } - - /** - * reduce a string by removing leading and trailing comments and whitespace - * - * @param $str string string value to strip of comments and whitespace - * - * @return string string value stripped of comments and whitespace - * @access private - */ - function reduce_string($str) - { - $str = preg_replace(array( - - // eliminate single line comments in '// ...' form - '#^\s*//(.+)$#m', - - // eliminate multi-line comments in '/* ... */' form, at start of string - '#^\s*/\*(.+)\*/#Us', - - // eliminate multi-line comments in '/* ... */' form, at end of string - '#/\*(.+)\*/\s*$#Us' - - ), '', $str); - - // eliminate extraneous space - return trim($str); - } - - /** - * decodes a JSON string into appropriate variable - * - * @param string $str JSON-formatted string - * - * @return mixed number, boolean, string, array, or object - * corresponding to given JSON input string. - * See argument 1 to Services_JSON() above for object-output behavior. - * Note that decode() always returns strings - * in ASCII or UTF-8 format! - * @access public - */ - function decode($str) - { - $str = $this->reduce_string($str); - - switch (strtolower($str)) { - case 'true': - return true; - - case 'false': - return false; - - case 'null': - return null; - - default: - $m = array(); - - if (is_numeric($str)) { - // Lookie-loo, it's a number - - // This would work on its own, but I'm trying to be - // good about returning integers where appropriate: - // return (float)$str; - - // Return float or int, as appropriate - return ((float)$str == (integer)$str) - ? (integer)$str - : (float)$str; - - } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { - // STRINGS RETURNED IN UTF-8 FORMAT - $delim = substr($str, 0, 1); - $chrs = substr($str, 1, -1); - $utf8 = ''; - $strlen_chrs = strlen($chrs); - - for ($c = 0; $c < $strlen_chrs; ++$c) { - - $substr_chrs_c_2 = substr($chrs, $c, 2); - $ord_chrs_c = ord($chrs{$c}); - - switch (true) { - case $substr_chrs_c_2 == '\b': - $utf8 .= chr(0x08); - ++$c; - break; - case $substr_chrs_c_2 == '\t': - $utf8 .= chr(0x09); - ++$c; - break; - case $substr_chrs_c_2 == '\n': - $utf8 .= chr(0x0A); - ++$c; - break; - case $substr_chrs_c_2 == '\f': - $utf8 .= chr(0x0C); - ++$c; - break; - case $substr_chrs_c_2 == '\r': - $utf8 .= chr(0x0D); - ++$c; - break; - - case $substr_chrs_c_2 == '\\"': - case $substr_chrs_c_2 == '\\\'': - case $substr_chrs_c_2 == '\\\\': - case $substr_chrs_c_2 == '\\/': - if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || - ($delim == "'" && $substr_chrs_c_2 != '\\"')) { - $utf8 .= $chrs{++$c}; - } - break; - - case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): - // single, escaped unicode character - $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) - . chr(hexdec(substr($chrs, ($c + 4), 2))); - $utf8 .= $this->utf162utf8($utf16); - $c += 5; - break; - - case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): - $utf8 .= $chrs{$c}; - break; - - case ($ord_chrs_c & 0xE0) == 0xC0: - // characters U-00000080 - U-000007FF, mask 110XXXXX - //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 2); - ++$c; - break; - - case ($ord_chrs_c & 0xF0) == 0xE0: - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 3); - $c += 2; - break; - - case ($ord_chrs_c & 0xF8) == 0xF0: - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 4); - $c += 3; - break; - - case ($ord_chrs_c & 0xFC) == 0xF8: - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 5); - $c += 4; - break; - - case ($ord_chrs_c & 0xFE) == 0xFC: - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 6); - $c += 5; - break; - - } - - } - - return $utf8; - - } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { - // array, or object notation - - if ($str{0} == '[') { - $stk = array(SERVICES_JSON_IN_ARR); - $arr = array(); - } else { - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $stk = array(SERVICES_JSON_IN_OBJ); - $obj = array(); - } else { - $stk = array(SERVICES_JSON_IN_OBJ); - $obj = new stdClass(); - } - } - - array_push($stk, array('what' => SERVICES_JSON_SLICE, - 'where' => 0, - 'delim' => false)); - - $chrs = substr($str, 1, -1); - $chrs = $this->reduce_string($chrs); - - if ($chrs == '') { - if (reset($stk) == SERVICES_JSON_IN_ARR) { - return $arr; - - } else { - return $obj; - - } - } - - //print("\nparsing {$chrs}\n"); - - $strlen_chrs = strlen($chrs); - - for ($c = 0; $c <= $strlen_chrs; ++$c) { - - $top = end($stk); - $substr_chrs_c_2 = substr($chrs, $c, 2); - - if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { - // found a comma that is not inside a string, array, etc., - // OR we've reached the end of the character list - $slice = substr($chrs, $top['where'], ($c - $top['where'])); - array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); - //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - if (reset($stk) == SERVICES_JSON_IN_ARR) { - // we are in an array, so just push an element onto the stack - array_push($arr, $this->decode($slice)); - - } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { - // we are in an object, so figure - // out the property name and set an - // element in an associative array, - // for now - $parts = array(); - - if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - // "name":value pair - $key = $this->decode($parts[1]); - $val = $this->decode($parts[2]); - - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $obj[$key] = $val; - } else { - $obj->$key = $val; - } - } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - // name:value pair, where name is unquoted - $key = $parts[1]; - $val = $this->decode($parts[2]); - - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $obj[$key] = $val; - } else { - $obj->$key = $val; - } - } - - } - - } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { - // found a quote, and we are not inside a string - array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); - //print("Found start of string at {$c}\n"); - - } elseif (($chrs{$c} == $top['delim']) && - ($top['what'] == SERVICES_JSON_IN_STR) && - ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { - // found a quote, we're in a string, and it's not escaped - // we know that it's not escaped becase there is _not_ an - // odd number of backslashes at the end of the string so far - array_pop($stk); - //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); - - } elseif (($chrs{$c} == '[') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a left-bracket, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); - //print("Found start of array at {$c}\n"); - - } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { - // found a right-bracket, and we're in an array - array_pop($stk); - //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } elseif (($chrs{$c} == '{') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a left-brace, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); - //print("Found start of object at {$c}\n"); - - } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { - // found a right-brace, and we're in an object - array_pop($stk); - //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } elseif (($substr_chrs_c_2 == '/*') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a comment start, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); - $c++; - //print("Found start of comment at {$c}\n"); - - } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { - // found a comment end, and we're in one now - array_pop($stk); - $c++; - - for ($i = $top['where']; $i <= $c; ++$i) - $chrs = substr_replace($chrs, ' ', $i, 1); - - //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } - - } - - if (reset($stk) == SERVICES_JSON_IN_ARR) { - return $arr; - - } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { - return $obj; - - } - - } - } - } - - /** - * @todo Ultimately, this should just call PEAR::isError() - */ - function isError($data, $code = null) - { - if (class_exists('pear')) { - return PEAR::isError($data, $code); - } elseif (is_object($data) && (get_class($data) == 'services_json_error' || - is_subclass_of($data, 'services_json_error'))) { - return true; - } - - return false; - } -} - -if (class_exists('PEAR_Error')) { - - class Services_JSON_Error extends PEAR_Error - { - function Services_JSON_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) - { - parent::PEAR_Error($message, $code, $mode, $options, $userinfo); - } - } - -} else { - - /** - * @todo Ultimately, this class shall be descended from PEAR_Error - */ - class Services_JSON_Error - { - function Services_JSON_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) - { - - } - } - -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/JSON_Format.php b/modules/Libs/OpenFlashChart/2-lug/OFC/JSON_Format.php deleted file mode 100644 index 5573b07a2..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/JSON_Format.php +++ /dev/null @@ -1,105 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// Pretty print some JSON -function json_format($json) -{ - $tab = " "; - $new_json = ""; - $indent_level = 0; - $in_string = false; - -/* - commented out by monk.e.boy 22nd May '08 - because my web server is PHP4, and - json_* are PHP5 functions... - - $json_obj = json_decode($json); - - if($json_obj === false) - return false; - - $json = json_encode($json_obj); -*/ - $len = strlen($json); - - for($c = 0; $c < $len; $c++) - { - $char = $json[$c]; - switch($char) - { - case '{': - case '[': - if(!$in_string) - { - $new_json .= $char . "\n" . str_repeat($tab, $indent_level+1); - $indent_level++; - } - else - { - $new_json .= $char; - } - break; - case '}': - case ']': - if(!$in_string) - { - $indent_level--; - $new_json .= "\n" . str_repeat($tab, $indent_level) . $char; - } - else - { - $new_json .= $char; - } - break; - case ',': - if(!$in_string) - { - $new_json .= ",\n" . str_repeat($tab, $indent_level); - } - else - { - $new_json .= $char; - } - break; - case ':': - if(!$in_string) - { - $new_json .= ": "; - } - else - { - $new_json .= $char; - } - break; - case '"': - if($c > 0 && $json[$c-1] != '\\') - { - $in_string = !$in_string; - } - default: - $new_json .= $char; - break; - } - } - - return $new_json; -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/OFC_Chart.php b/modules/Libs/OpenFlashChart/2-lug/OFC/OFC_Chart.php deleted file mode 100644 index a3371a9da..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/OFC_Chart.php +++ /dev/null @@ -1,116 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -if (! function_exists('json_encode')) -{ - require_once('OFC/JSON.php'); -} - -require_once('OFC/JSON_Format.php'); - -require_once('OFC/OFC_Elements.php'); - -require_once('OFC/Charts/OFC_Charts_Area.php'); -require_once('OFC/Charts/OFC_Charts_Bar.php'); -require_once('OFC/Charts/OFC_Charts_Line.php'); -require_once('OFC/Charts/OFC_Charts_Pie.php'); -require_once('OFC/Charts/OFC_Charts_Scatter.php'); -require_once('OFC/Charts/Area/OFC_Charts_Area_Hollow.php'); -require_once('OFC/Charts/Bar/OFC_Charts_Bar_Filled.php'); -require_once('OFC/Charts/Bar/OFC_Charts_Bar_3d.php'); -require_once('OFC/Charts/Bar/OFC_Charts_Bar_Glass.php'); -require_once('OFC/Charts/Bar/OFC_Charts_Bar_Horizontal.php'); -require_once('OFC/Charts/Bar/OFC_Charts_Bar_Sketch.php'); -require_once('OFC/Charts/Bar/OFC_Charts_Bar_Stack.php'); -require_once('OFC/Charts/Line/OFC_Charts_Line_Dot.php'); -require_once('OFC/Charts/Line/OFC_Charts_Line_Hollow.php'); - -class OFC_Chart -{ - function OFC_Chart() - { - $this->title = new OFC_Elements_Title( "Many data lines" ); - $this->elements = array(); - } - - function set_title( $t ) - { - $this->title = $t; - } - - function set_x_axis( $x ) - { - $this->x_axis = $x; - } - - function set_y_axis( $y ) - { - $this->y_axis = $y; - } - - function add_y_axis( $y ) - { - $this->y_axis = $y; - } - - function set_y_axis_right( $y ) - { - $this->y_axis_right = $y; - } - - function add_element( $e ) - { - $this->elements[] = $e; - } - - function set_x_legend( $x ) - { - $this->x_legend = $x; - } - - function set_y_legend( $y ) - { - $this->y_legend = $y; - } - - function set_bg_colour( $colour ) - { - $this->bg_colour = $colour; - } - - function toString() - { - if (function_exists('json_encode')) - { - return json_encode($this); - } - else - { - $json = new Services_JSON(); - return $json->encode( $this ); - } - } - - function toPrettyString() - { - return json_format( $this->toString() ); - } -} - diff --git a/modules/Libs/OpenFlashChart/2-lug/OFC/OFC_Elements.php b/modules/Libs/OpenFlashChart/2-lug/OFC/OFC_Elements.php deleted file mode 100644 index 32fa7c078..000000000 --- a/modules/Libs/OpenFlashChart/2-lug/OFC/OFC_Elements.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -require_once('OFC/Elements/OFC_Elements_Base.php'); -require_once('OFC/Elements/OFC_Elements_Axis.php'); -require_once('OFC/Elements/Axis/OFC_Elements_Axis_X.php'); -require_once('OFC/Elements/Axis/OFC_Elements_Axis_X_Label.php'); -require_once('OFC/Elements/Axis/OFC_Elements_Axis_X_Label_Set.php'); -require_once('OFC/Elements/Axis/OFC_Elements_Axis_Y.php'); -require_once('OFC/Elements/Axis/OFC_Elements_Axis_Y_Right.php'); -require_once('OFC/Elements/Legend/OFC_Elements_Legend_X.php'); -require_once('OFC/Elements/Legend/OFC_Elements_Legend_Y.php'); -require_once('OFC/Elements/OFC_Elements_Title.php'); - diff --git a/modules/Libs/OpenFlashChart/2-lug/open-flash-chart.swf b/modules/Libs/OpenFlashChart/2-lug/open-flash-chart.swf deleted file mode 100644 index 3a01e52ae..000000000 Binary files a/modules/Libs/OpenFlashChart/2-lug/open-flash-chart.swf and /dev/null differ diff --git a/modules/Libs/OpenFlashChart/OpenFlashChartInstall.php b/modules/Libs/OpenFlashChart/OpenFlashChartInstall.php deleted file mode 100644 index 43f057a57..000000000 --- a/modules/Libs/OpenFlashChart/OpenFlashChartInstall.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Copyright © 2006, Janusz Tylek - * @version 1.0 - * @license MIT - * @package epesi-libs - * @subpackage openflashchart - */ -defined("_VALID_ACCESS") || die('Direct access forbidden'); - -class Libs_OpenFlashChartInstall extends ModuleInstall { - - public function install() { - return true; - } - - public function uninstall() { - return true; - } - - public function version() { - return array("1.0"); - } - - public function requires($v) { - return array(); - } - - public static function info() { - return array( - 'Description'=>'Flash Charts', - 'Author'=>'pbukowski@telaxus.com', - 'License'=>'MIT'); - } - - public static function simple_setup() { - return false; - } - -} - -?> \ No newline at end of file diff --git a/modules/Libs/OpenFlashChart/OpenFlashChart_0.php b/modules/Libs/OpenFlashChart/OpenFlashChart_0.php deleted file mode 100644 index e4bb73c69..000000000 --- a/modules/Libs/OpenFlashChart/OpenFlashChart_0.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Copyright © 2006, Janusz Tylek - * @version 1.0 - * @license MIT - * @package epesi-libs - * @subpackage openflashchart - */ -defined("_VALID_ACCESS") || die('Direct access forbidden'); - -class Libs_OpenFlashChart extends Module { - private $ofc; - private $width="500px"; - private $height="300px"; - private static $included = false; - - public function construct() { - if(!self::$included) { - $dir = $this->get_module_dir(); - ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.$dir.'/2-lug'); - require_once('OFC/OFC_Chart.php'); - self::$included = true; - } - - $this->ofc = new OFC_Chart(); - } - - public function & __call($func_name, $args) { - if (is_object($this->ofc)) - $return = call_user_func_array(array(&$this->ofc, $func_name), $args); - else - trigger_error("OpenFlashChart object doesn't exists", E_USER_ERROR); - return $return; - } - - public function set_width($w) { - if(is_numeric($w)) $w .= 'px'; - $this->width = $w; - } - - public function set_height($h) { - if(is_numeric($h)) $h .= 'px'; - $this->height = $h; - } - - public function body() { - $md = md5($this->get_path()); - $data = $this->ofc->toString(); - $this->set_module_variable('data',$data); -// eval_js('var open_flash_chart_data=function() {'. -// 'return "'.Epesi::escapeJS($data).'";'. -// '}'); - $url=urlencode($this->get_module_dir().'data.php?id='.CID.'&chart='.$this->get_path()); - print(''.md5($data).''); - print(''. - ''. - ''. - ''. - ''. - ''. - ''. - ''); - } - -} - -?> \ No newline at end of file diff --git a/modules/Libs/OpenFlashChart/data.php b/modules/Libs/OpenFlashChart/data.php deleted file mode 100644 index 521faf666..000000000 --- a/modules/Libs/OpenFlashChart/data.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright Copyright © 2006, Janusz Tylek - * @version 1.0 - * @license MIT - * @package epesi-libs - * @subpackage openflashchart - */ -if(!isset($_REQUEST['id']) || !isset($_REQUEST['chart'])) die('Invalid usage'); -$id = $_REQUEST['id']; -$chart_id = $_REQUEST['chart']; - -define('CID', $id); -define('READ_ONLY_SESSION',true); -require_once('../../../include.php'); - -$fn = Module::static_get_module_variable($chart_id,'data',null); - -echo $fn; -?> diff --git a/modules/Libs/PHPExcel/composer.json b/modules/Libs/PHPExcel/composer.json index 4ccdc0681..f65821792 100644 --- a/modules/Libs/PHPExcel/composer.json +++ b/modules/Libs/PHPExcel/composer.json @@ -1,5 +1,5 @@ { "require": { - "phpoffice/phpexcel": "^1.8" + "phpoffice/phpspreadsheet": "^1.29" } } diff --git a/modules/Libs/PHPExcel/composer.lock b/modules/Libs/PHPExcel/composer.lock index 109be1ec5..3033953d9 100644 --- a/modules/Libs/PHPExcel/composer.lock +++ b/modules/Libs/PHPExcel/composer.lock @@ -1,75 +1,661 @@ { "_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#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "50489714dc35b8c5a19828e5fdb18e98", + "content-hash": "f01ca2e7ccfd85272670bf19ebc4f1fb", "packages": [ { - "name": "phpoffice/phpexcel", - "version": "1.8.1", + "name": "composer/pcre", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/PHPOffice/PHPExcel.git", - "reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32" + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/372c7cbb695a6f6f1e62649381aeaa37e7e70b32", - "reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.18.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "cb56001e54359df7ae76dc522d08845dc741621b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/cb56001e54359df7ae76dc522d08845dc741621b", + "reference": "cb56001e54359df7ae76dc522d08845dc741621b", + "shasum": "" + }, + "require": { + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" + }, + "type": "library", + "autoload": { + "files": [ + "library/HTMLPurifier.composer.php" + ], + "psr-0": { + "HTMLPurifier": "library/" + }, + "exclude-from-classmap": [ + "/library/HTMLPurifier/Language/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.18.0" + }, + "time": "2024-11-01T03:51:45+00:00" + }, + { + "name": "maennchen/zipstream-php", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/aeadcf5c412332eb426c0f9b4485f6accba2a99f", + "reference": "aeadcf5c412332eb426c0f9b4485f6accba2a99f", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-zlib": "*", + "php-64bit": "^8.2" + }, + "require-dev": { + "brianium/paratest": "^7.7", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.16", + "guzzlehttp/guzzle": "^7.5", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.5", + "phpunit/phpunit": "^11.0", + "vimeo/psalm": "^6.0" + }, + "suggest": { + "guzzlehttp/psr7": "^2.4", + "psr/http-message": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Duncan", + "email": "pabs@pablotron.org" + }, + { + "name": "Jonatan Männchen", + "email": "jonatan@maennchen.ch" + }, + { + "name": "Jesse Donat", + "email": "donatj@gmail.com" + }, + { + "name": "András Kolesár", + "email": "kolesar@kolesar.hu" + } + ], + "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", + "keywords": [ + "stream", + "zip" + ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.2" + }, + "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + } + ], + "time": "2025-01-27T12:07:53+00:00" + }, + { + "name": "markbaker/complex", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2" + }, + "time": "2022-12-06T16:21:08+00:00" + }, + { + "name": "markbaker/matrix", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "^4.0", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "sebastian/phpcpd": "^4.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@demon-angel.eu" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1" + }, + "time": "2022-12-02T22:17:43+00:00" + }, + { + "name": "phpoffice/phpspreadsheet", + "version": "1.30.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "2f39286e0136673778b7a142b3f0d141e43d1714" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/2f39286e0136673778b7a142b3f0d141e43d1714", + "reference": "2f39286e0136673778b7a142b3f0d141e43d1714", + "shasum": "" + }, + "require": { + "composer/pcre": "^1||^2||^3", + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", "ext-xml": "*", + "ext-xmlreader": "*", "ext-xmlwriter": "*", - "php": ">=5.2.0" + "ext-zip": "*", + "ext-zlib": "*", + "ezyang/htmlpurifier": "^4.15", + "maennchen/zipstream-php": "^2.1 || ^3.0", + "markbaker/complex": "^3.0", + "markbaker/matrix": "^3.0", + "php": "^7.4 || ^8.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-main", + "dompdf/dompdf": "^1.0 || ^2.0 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.2", + "mitoteam/jpgraph": "^10.3", + "mpdf/mpdf": "^8.1.1", + "phpcompatibility/php-compatibility": "^9.3", + "phpstan/phpstan": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^8.5 || ^9.0", + "squizlabs/php_codesniffer": "^3.7", + "tecnickcom/tcpdf": "^6.5" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-intl": "PHP Internationalization Functions", + "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" }, "type": "library", "autoload": { - "psr-0": { - "PHPExcel": "Classes/" + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL" + "MIT" ], "authors": [ { "name": "Maarten Balliauw", - "homepage": "http://blog.maartenballiauw.be" + "homepage": "https://blog.maartenballiauw.be" }, { - "name": "Mark Baker" + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" }, { "name": "Franck Lefevre", - "homepage": "http://blog.rootslabs.net" + "homepage": "https://rootslabs.net" }, { "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" } ], - "description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", - "homepage": "http://phpexcel.codeplex.com", + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", "keywords": [ "OpenXML", "excel", + "gnumeric", + "ods", "php", "spreadsheet", "xls", "xlsx" ], - "time": "2015-05-01T07:00:55+00:00" + "support": { + "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.30.0" + }, + "time": "2025-08-10T06:28:02+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [] + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/modules/Libs/QuickForm/FieldTypes/multiselect/multiselect.js b/modules/Libs/QuickForm/FieldTypes/multiselect/multiselect.js index 67a409340..7e537ae51 100644 --- a/modules/Libs/QuickForm/FieldTypes/multiselect/multiselect.js +++ b/modules/Libs/QuickForm/FieldTypes/multiselect/multiselect.js @@ -1,4 +1,4 @@ -ms_remove_selected = function(myName, list_sep){ +ms_remove_selected = function(myName, mod, list_sep){ var tolist = document.getElementsByName(myName+"to[]")[0]; var fromlist = document.getElementsByName(myName+"from[]")[0]; var list_result = ""; @@ -29,7 +29,7 @@ ms_remove_selected = function(myName, list_sep){ document.getElementsByName(myName)[0].value=list_result; }; -ms_add_selected = function(myName, list_sep){ +ms_add_selected = function(myName, mod, list_sep){ var tolist = document.getElementsByName(myName+"to[]")[0]; var fromlist = document.getElementsByName(myName+"from[]")[0]; var list_result = ""; @@ -63,7 +63,7 @@ ms_add_selected = function(myName, list_sep){ document.getElementsByName(myName)[0].value=list_result; }; -ms_remove_all = function(myName, list_sep){ +ms_remove_all = function(myName, mod, list_sep){ var tolist = document.getElementsByName(myName+"to[]")[0]; var fromlist = document.getElementsByName(myName+"from[]")[0]; var list_result = ""; @@ -92,7 +92,7 @@ ms_remove_all = function(myName, list_sep){ document.getElementsByName(myName)[0].value=list_result; }; -ms_add_all = function(myName, list_sep){ +ms_add_all = function(myName, mod, list_sep){ var tolist = document.getElementsByName(myName+"to[]")[0]; var fromlist = document.getElementsByName(myName+"from[]")[0]; var k = 0; diff --git a/modules/Libs/QuickForm/QuickForm_0.php b/modules/Libs/QuickForm/QuickForm_0.php index 501663c8a..92d29eb5a 100644 --- a/modules/Libs/QuickForm/QuickForm_0.php +++ b/modules/Libs/QuickForm/QuickForm_0.php @@ -73,7 +73,7 @@ public function display($args = array()) trigger_error("QuickFrom object doesn't exists", E_USER_ERROR); } - public function & __call($func_name, array $args=array()) { + public function &__call($func_name, array $args=array()) { if ($func_name=='addElement' && isset($args[0])) { if(is_string($args[0])) $type = $args[0]; @@ -94,7 +94,8 @@ public function & __call($func_name, array $args=array()) { $qb = $qbi->get_builder_module($this, $default_crits); $qb->add_to_form($this, $args[1], $args[2]); } - return; + $return = null; + return $return; } } if (is_object($this->qf)) { diff --git a/modules/Libs/QuickForm/composer.lock b/modules/Libs/QuickForm/composer.lock index 19b1319a0..8612d225a 100644 --- a/modules/Libs/QuickForm/composer.lock +++ b/modules/Libs/QuickForm/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "openpsa/quickform", - "version": "v3.4", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/openpsa/quickform.git", - "reference": "4a979f322aed0dacfb9716d1a768afd9ea9bb5eb" + "reference": "5e31c1c9b45b8101a8ff370b8f5abbbf71d9daf1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/openpsa/quickform/zipball/4a979f322aed0dacfb9716d1a768afd9ea9bb5eb", - "reference": "4a979f322aed0dacfb9716d1a768afd9ea9bb5eb", + "url": "https://api.github.com/repos/openpsa/quickform/zipball/5e31c1c9b45b8101a8ff370b8f5abbbf71d9daf1", + "reference": "5e31c1c9b45b8101a8ff370b8f5abbbf71d9daf1", "shasum": "" }, "require": { @@ -52,18 +52,18 @@ ], "support": { "issues": "https://github.com/openpsa/quickform/issues", - "source": "https://github.com/openpsa/quickform/tree/v3.4" + "source": "https://github.com/openpsa/quickform/tree/v3.4.1" }, - "time": "2022-09-20T08:47:45+00:00" + "time": "2023-04-20T08:24:29+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.0.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/modules/Libs/QuickForm/theme/column.tpl b/modules/Libs/QuickForm/theme/column.tpl index e6ba9c119..614fa12de 100644 --- a/modules/Libs/QuickForm/theme/column.tpl +++ b/modules/Libs/QuickForm/theme/column.tpl @@ -1,10 +1,12 @@ {$form_open} -{foreach from=$form_data.header item=h} -
- {$h} -
-{/foreach} +{if isset($form_data.header)} + {foreach from=$form_data.header item=h} +
+ {$h} +
+ {/foreach} +{/if}
- + {if $y == 1 && $x > 1} + + +
+ {/if} + {$f.full_field} + {if $y==$rows or ($y==$rows-1 and $x>$no_empty)} {if $x>$no_empty} @@ -92,10 +89,12 @@ {/if} + {assign var=y value=1} {assign var=x value=$x+1} -
 
-
+
- - {foreach key=k item=f from=$longfields name=fields} - {$f.full_field} - {/foreach} -
+ + {foreach key=k item=f from=$longfields name=fields} + {$f.full_field} + {/foreach} +
{foreach from=$form_data item=f} {if is_array($f) && isset($f.type) && isset($f.html) && isset($f.label) && $f.type!='hidden' && $f.type!='button' && $f.type!='submit'} diff --git a/modules/Libs/QuickForm/theme/row.tpl b/modules/Libs/QuickForm/theme/row.tpl index f956b1aa8..af5149265 100644 --- a/modules/Libs/QuickForm/theme/row.tpl +++ b/modules/Libs/QuickForm/theme/row.tpl @@ -1,7 +1,13 @@
{$form_open} - +{if isset($form_data.header)} + {foreach from=$form_data.header item=h} +
+ {$h} +
+ {/foreach} +{/if}
{foreach from=$form_data item=f} {if is_array($f) && isset($f.type) && isset($f.html) && isset($f.label) && $f.type!='hidden' && $f.type!='button' && $f.type!='submit'} diff --git a/modules/Libs/TCPDF/composer.lock b/modules/Libs/TCPDF/composer.lock index b59c57d45..1814d8efc 100644 --- a/modules/Libs/TCPDF/composer.lock +++ b/modules/Libs/TCPDF/composer.lock @@ -4,24 +4,25 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ff887fa70b38934eeb1c3e344a583056", + "content-hash": "007a56ce5d77eeb623b8cae82ac92f7f", "packages": [ { "name": "tecnickcom/tcpdf", - "version": "6.6.2", + "version": "6.10.0", "source": { "type": "git", "url": "https://github.com/tecnickcom/TCPDF.git", - "reference": "e3cffc9bcbc76e89e167e9eb0bbda0cab7518459" + "reference": "ca5b6de294512145db96bcbc94e61696599c391d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/e3cffc9bcbc76e89e167e9eb0bbda0cab7518459", - "reference": "e3cffc9bcbc76e89e167e9eb0bbda0cab7518459", + "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/ca5b6de294512145db96bcbc94e61696599c391d", + "reference": "ca5b6de294512145db96bcbc94e61696599c391d", "shasum": "" }, "require": { - "php": ">=5.3.0" + "ext-curl": "*", + "php": ">=7.1.0" }, "type": "library", "autoload": { @@ -29,8 +30,6 @@ "config", "include", "tcpdf.php", - "tcpdf_parser.php", - "tcpdf_import.php", "tcpdf_barcodes_1d.php", "tcpdf_barcodes_2d.php", "include/tcpdf_colors.php", @@ -46,7 +45,7 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-only" + "LGPL-3.0-or-later" ], "authors": [ { @@ -68,24 +67,24 @@ ], "support": { "issues": "https://github.com/tecnickcom/TCPDF/issues", - "source": "https://github.com/tecnickcom/TCPDF/tree/6.6.2" + "source": "https://github.com/tecnickcom/TCPDF/tree/6.10.0" }, "funding": [ { - "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_donations¤cy_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20tcpdf%20project", + "url": "https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ", "type": "custom" } ], - "time": "2022-12-17T10:28:59+00:00" + "time": "2025-05-27T18:02:28+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.0.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/modules/Utils/Attachment/AttachmentCommon_0.php b/modules/Utils/Attachment/AttachmentCommon_0.php index f74d9f54e..838811f23 100644 --- a/modules/Utils/Attachment/AttachmentCommon_0.php +++ b/modules/Utils/Attachment/AttachmentCommon_0.php @@ -518,7 +518,7 @@ public static function submit_attachment($values, $mode) { if(!$ret) print(__('Access denied')); return $ret; case 'display': - if(self::get_all_files($values['id'])) { + if(isset ($values['id']) && self::get_all_files($values['id'])) { $ret = array(); $ret['new'] = array(); $ret['new']['crm_filter'] = '1)).'>F'; diff --git a/modules/Utils/CurrencyField/CurrencyFieldCommon_0.php b/modules/Utils/CurrencyField/CurrencyFieldCommon_0.php index cdcea75f2..262d8f5ac 100644 --- a/modules/Utils/CurrencyField/CurrencyFieldCommon_0.php +++ b/modules/Utils/CurrencyField/CurrencyFieldCommon_0.php @@ -46,7 +46,7 @@ public static function get_values($p) { if (!is_array($p)) $p = explode('__', $p); if(!is_numeric($p[0]) && $p[0]!='') return false; if (!isset($p[1])) $p[1] = Base_User_SettingsCommon::get('Utils_CurrencyField', 'default_currency'); - $p[0] = str_replace(array(',', self::get_decimal_point($p[1])), '.', $p[0]); + $p[0] = (float) str_replace(array(',', self::get_decimal_point($p[1])), '.', $p[0]); return $p; } diff --git a/modules/Utils/FileUpload/FileUpload_0.php b/modules/Utils/FileUpload/FileUpload_0.php index a2d4ea25b..7075fe531 100644 --- a/modules/Utils/FileUpload/FileUpload_0.php +++ b/modules/Utils/FileUpload/FileUpload_0.php @@ -17,6 +17,7 @@ class Utils_FileUpload extends Module { private $form = null; private $upload_button_caption; private $submit_button = true; + private $added_upload_elem = false; /** * Module constructor. diff --git a/modules/Utils/LeightboxPrompt/theme/form.tpl b/modules/Utils/LeightboxPrompt/theme/form.tpl index bdf78ee9d..76d9702d7 100644 --- a/modules/Utils/LeightboxPrompt/theme/form.tpl +++ b/modules/Utils/LeightboxPrompt/theme/form.tpl @@ -8,7 +8,7 @@ {foreach item=e from=$form_data} - {if isset($e.label) && !is_string($e) && $e.type!='hidden' && $e.name!='submit' && $e.name!='cancel'} + {if isset($e.label) && isset($e.name) && $e.type!='hidden' && $e.name!='submit' && $e.name!='cancel'}
{$e.label} diff --git a/modules/Utils/Menu/theme/default.css b/modules/Utils/Menu/theme/default.css index 3d4e9ccfe..46aeaafe7 100644 --- a/modules/Utils/Menu/theme/default.css +++ b/modules/Utils/Menu/theme/default.css @@ -1,5 +1,5 @@ table.root { - font-family: 'Exo';font-size: 16px; + /*font-family: 'Exo';font-size: 16px;*/ border: 0px; height:30px; list-style-type: none; @@ -106,7 +106,7 @@ a.root_item_link_none { padding: 0px 25px 0px 25px; display: block; /* for HTML standards... */ margin: 0px; - font-size: 18px; + font-size: 11px; text-align: left; text-decoration: none; white-space: nowrap; @@ -118,7 +118,7 @@ a.root_item_link_none { a.root_item_link_right { display: block; /* for HTML standards... */ margin: 0px; - font-size: 16px; + font-size: 11px; text-align: left; text-decoration: none; white-space: nowrap; @@ -169,7 +169,7 @@ img.link_bullet { .item_sub .link_icon_box { width: 22px; - height: 29px; + height: 33px; float: left; background-color: silver; } @@ -179,7 +179,7 @@ img.link_bullet { } img.link_icon { - margin: 6px auto auto 4px; + margin: 8px auto auto 4px; vertical-align: middle; z-index: 1000; /*position: absolute;*/ @@ -268,5 +268,5 @@ a.root_item_link_none:hover, a.root_item_link_right:hover { background-color: #DEB42F; color: #0A3C5C; - border: 2px solid #1FAF53; + border: 2px solid #0A3C5C; } diff --git a/modules/Utils/Messenger/Messenger_0.php b/modules/Utils/Messenger/Messenger_0.php index acc9ceadb..0cff528e5 100644 --- a/modules/Utils/Messenger/Messenger_0.php +++ b/modules/Utils/Messenger/Messenger_0.php @@ -18,6 +18,7 @@ class Utils_Messenger extends Module { private $def_date; private $real_id; private $parent_type; + private $lp; public function pop_box0() { Base_BoxCommon::pop_main(); @@ -25,8 +26,11 @@ public function pop_box0() { public function push_box0($func,$args,$const_args) { $x = ModuleManager::get_instance('/Base_Box|0'); - if(!$x) trigger_error('There is no base box module instance',E_USER_ERROR); - $x->push_main('Utils/Messenger',$func,$args,$const_args); + if(!$x){ + trigger_error('There is no base box module instance',E_USER_ERROR); + }else{ + $x->push_main('Utils/Messenger',$func,$args,$const_args); + } } public function construct($id=null,$callback_method=null,$callback_args=null,$def_date=null,$users=null,$parent=null) { diff --git a/modules/Utils/QueryBuilder/quickform_crits.php b/modules/Utils/QueryBuilder/quickform_crits.php index 7201cdeb8..ca932af88 100644 --- a/modules/Utils/QueryBuilder/quickform_crits.php +++ b/modules/Utils/QueryBuilder/quickform_crits.php @@ -7,7 +7,7 @@ * @package epesi-utils * @subpackage RecordBrowser */ -require_once("HTML/QuickForm/input.php"); +//require_once("HTML/QuickForm/input.php"); class HTML_QuickForm_crits extends HTML_QuickForm_input { diff --git a/modules/Utils/RecordBrowser/CritsValidator.php b/modules/Utils/RecordBrowser/CritsValidator.php index ce2c4bde3..f23a4b85e 100644 --- a/modules/Utils/RecordBrowser/CritsValidator.php +++ b/modules/Utils/RecordBrowser/CritsValidator.php @@ -110,7 +110,7 @@ protected function validate_single(Utils_RecordBrowser_CritsSingle $crits, $reco if ($crit_value) $result = in_array($crit_value, $r_val); else $result = empty($r_val); if ($crits->get_operator() == '!=') $result = !$result; - } elseif ($field_definition['type'] == 'text' || $field_definition['type'] == 'long text') { + } elseif (isset($field_definition['type']) && ($field_definition['type'] == 'text' || $field_definition['type'] == 'long text')) { $str_cmp = strcasecmp($r_val, $crit_value); switch ($crits->get_operator()) { case '>': $result = ($str_cmp > 0); break; diff --git a/modules/Utils/RecordBrowser/Filters/Filters_0.php b/modules/Utils/RecordBrowser/Filters/Filters_0.php index 5d5b07a3b..71123224b 100644 --- a/modules/Utils/RecordBrowser/Filters/Filters_0.php +++ b/modules/Utils/RecordBrowser/Filters/Filters_0.php @@ -186,7 +186,7 @@ protected function set_standard_filter_values() { $format_callback = $multi_adv_params['format_callback']; if ($param['single_tab'] == '__COMMON__') { - if (empty($param['array_id'])) continue; + if (empty($param['array_id'])) break; $select_options = Utils_CommonDataCommon::get_translated_tree($param['array_id'], $param['order']); } else { $crits = array(); @@ -246,7 +246,7 @@ protected function set_standard_filter_values() { $this->standard_filter_elements[] = $element_id; break; default: - continue; + break; } } $this->form->addElement('submit', 'submit', __('Show')); diff --git a/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php b/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php index 79e1899a8..91b6b62d9 100644 --- a/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php +++ b/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php @@ -1584,6 +1584,9 @@ public static function new_record( $tab, $values = array()) { } DB::Execute('INSERT INTO '.$tab.'_data_1 ('.$fields.') VALUES ('.$fields_types.')',$vals); $id = DB::Insert_ID($tab.'_data_1', 'id'); + if (!$id){ + trigger_error(DB::ErrorMsg(),E_USER_ERROR); + } if ($user) self::add_recent_entry($tab, $user, $id); if (Base_User_SettingsCommon::get('Utils_RecordBrowser',$tab.'_auto_fav')) DB::Execute('INSERT INTO '.$tab.'_favorite (user_id, '.$tab.'_id) VALUES (%d, %d)', array($user, $id)); @@ -3978,8 +3981,10 @@ public static function indexer($limit=null,&$total=0) { if(!$ret) continue; - register_shutdown_function(create_function('','@unlink("'.$lock.'");')); - if(file_exists($lock) && filemtime($lock)>time()-1200) continue; + register_shutdown_function(function() use ($lock) { + @unlink($lock); + }); + if(file_exists($lock) && filemtime($lock) > time() - 1200) continue; file_put_contents($lock,''); foreach($ret as $row) { @@ -4017,7 +4022,9 @@ public static function search_categories() { if(!$caption) continue; $ret[$tab_id] = array('caption'=>$caption,'checked'=>$tab['search_include']==1); } - uasort($ret,create_function('$a,$b','return strnatcasecmp($a["caption"],$b["caption"]);')); + uasort($ret, function($a,$b) { + return strnatcasecmp($a["caption"], $b["caption"]); + }); return $ret; } diff --git a/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php.jt b/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php.jt deleted file mode 100644 index c69ee7347..000000000 --- a/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php.jt +++ /dev/null @@ -1,4127 +0,0 @@ - - * @copyright Copyright © 2008, Janusz Tylek - * @license MIT - * @version 1.0 - * @package epesi-utils - * @subpackage RecordBrowser - */ - -defined("_VALID_ACCESS") || die('Direct access forbidden'); - -class Utils_RecordBrowserCommon extends ModuleCommon { - private static $del_or_a = ''; - public static $admin_filter = ''; - public static $table_rows = array(); - public static $hash = array(); - public static $admin_access = false; - public static $cols_order = array(); - public static $options_limit = 50; - - public static $display_callback_table = array(); - private static $clear_get_val_cache = false; - public static function display_callback_cache($tab) { - if (self::$clear_get_val_cache) { - self::$clear_get_val_cache = false; - self::$display_callback_table = array(); - } - if($tab=='__RECORDSETS__' || preg_match('/,/',$tab)) return; - if (!isset(self::$display_callback_table[$tab])) { - $ret = DB::Execute('SELECT * FROM '.$tab.'_callback WHERE freezed=1'); - while ($row = $ret->FetchRow()) - self::$display_callback_table[$tab][$row['field']] = $row['callback']; - } - } - - public static function callback_check_function($callback, $only_check_syntax = false) - { - if (is_array($callback)) $callback = implode('::', $callback); - $func = null; - if (preg_match('/^([\\\\a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*)::([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$/', $callback, $match)) { - $func = array($match[1], $match[2]); - } elseif (preg_match('/^([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$/', $callback, $match)) { - $func = $match[1]; - } - if (is_callable($func, $only_check_syntax)) { - return $func; - } - return false; - } - - public static function call_display_callback($callback, $record, $links_not_recommended, $field, $tab) - { - $callback_func = self::callback_check_function($callback, true); - if ($callback_func) { - if (is_callable($callback_func)) { - $ret = call_user_func($callback_func, $record, $links_not_recommended, $field, $tab); - } else { - $callback_str = (is_array($callback_func) ? implode('::', $callback_func) : $callback_func); - trigger_error("Callback $callback_str for field: '$field[id]', recordset: '$tab' not found", E_USER_NOTICE); - $ret = $record[$field['id']]; - } - } else { - ob_start(); - $ret = eval($callback); - if($ret===false) trigger_error($callback,E_USER_ERROR); - else print($ret); - $ret = ob_get_contents(); - ob_end_clean(); - } - return $ret; - } - - public static function call_QFfield_callback($callback, &$form, $field, $label, $mode, $default, $desc, $rb_obj, $display_callback_table = null) - { - if ($display_callback_table === null) { - $display_callback_table = self::display_callback_cache($rb_obj->tab); - } - $callback_func = self::callback_check_function($callback, true); - if ($callback_func) { - if (is_callable($callback_func)) { - call_user_func_array($callback_func, array(&$form, $field, $label, $mode, $default, $desc, $rb_obj, $display_callback_table)); - } else { - $callback_str = (is_array($callback_func) ? implode('::', $callback_func) : $callback_func); - trigger_error("Callback $callback_str for field: '$field', recordset: '{$rb_obj->tab}' not found", E_USER_NOTICE); - } - } else { - eval($callback); - } - } - - public static function get_val($tab, $field, $record, $links_not_recommended = false, $desc = null) { - static $recurrence_call_stack = array(); - self::init($tab); - if (!isset(self::$table_rows[$field])) { - if (!isset(self::$hash[$field])) trigger_error('Unknown field "'.$field.'" for recordset "'.$tab.'"',E_USER_ERROR); - $field = self::$hash[$field]; - } - - $desc = array_merge(self::$table_rows[$field], $desc?: []); - if(!array_key_exists('id',$record)) $record['id'] = null; - if (!array_key_exists($desc['id'],$record)) trigger_error($desc['id'].' - unknown field for record '.serialize($record), E_USER_ERROR); - $val = $record[$desc['id']]; - $function_call_id = implode('|', array($tab, $field, serialize($val))); - if (isset($recurrence_call_stack[$function_call_id])) { - return '!! ' . __('recurrence issue') . ' !!'; - } else { - $recurrence_call_stack[$function_call_id] = true; - } - self::display_callback_cache($tab); - if (isset(self::$display_callback_table[$tab][$field])) { - $display_callback = self::$display_callback_table[$tab][$field]; - } else { - $display_callback = self::get_default_display_callback($desc['type']); - } - - if ($display_callback) { - $ret = self::call_display_callback($display_callback, $record, $links_not_recommended, $desc, $tab); - } else { - $ret = $val; - } - - unset($recurrence_call_stack[$function_call_id]); - return $ret; - } - - //////////////////////////// - // default display callbacks - - public static function get_default_display_callback($type) { - $types = array('select', 'multiselect', 'commondata', 'autonumber', 'currency', 'checkbox', - 'date', 'timestamp', 'time', 'long text', 'file'); - if (array_search($type, $types) !== false) { - return __CLASS__. '::display_' . self::get_field_id($type); - } - return null; - } - public static function display_select($record, $nolink=false, $desc=null, $tab=null) { - $ret = '---'; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $val = $record[$desc['id']]; - $commondata_sep = '/'; - if ((is_array($val) && empty($val))) return $ret; - - $param = self::decode_select_param($desc['param']); - - if(!$param['array_id'] && $param['single_tab'] == '__COMMON__') return; - - if (!is_array($val)) $val = array($val); - - $ret = ''; - foreach ($val as $v) { - $ret .= ($ret!=='')? '
': ''; - - if ($param['single_tab'] == '__COMMON__') { - $array_id = $param['array_id']; - $path = explode('/', $v); - $tooltip = ''; - $res = ''; - if (count($path) > 1) { - $res .= Utils_CommonDataCommon::get_value($array_id . '/' . $path[0], true); - if (count($path) > 2) { - $res .= $commondata_sep . '...'; - $tooltip = ''; - $full_path = $array_id; - foreach ($path as $w) { - $full_path .= '/' . $w; - $tooltip .= ($tooltip? $commondata_sep: '').Utils_CommonDataCommon::get_value($full_path, true); - } - } - $res .= $commondata_sep; - } - $label = Utils_CommonDataCommon::get_value($array_id . '/' . $v, true); - if (!$label) break; - $res .= $label; - $res = self::no_wrap($res); - if ($tooltip) $res = '' . $res . ''; - } else { - $tab_id = self::decode_record_token($v, $param['single_tab']); - - if (!$tab_id) break; - - list($select_tab, $id) = $tab_id; - - if ($param['cols']) { - $res = self::create_linked_label($select_tab, $param['cols'], $id, $nolink); - } else { - $res = self::create_default_linked_label($select_tab, $id, $nolink); - } - } - - $ret .= $res; - } - } - - return $ret; - } - public static function display_multiselect($record, $nolink=false, $desc=null, $tab=null) { - return self::display_select($record, $nolink, $desc, $tab); - } - public static function display_commondata($record, $nolink=false, $desc=null, $tab=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $arr = explode('::', $desc['param']['array_id']); - $path = array_shift($arr); - foreach($arr as $v) $path .= '/' . $record[self::get_field_id($v)]; - $path .= '/' . $record[$desc['id']]; - $ret = Utils_CommonDataCommon::get_value($path, true); - } - - return $ret; - } - public static function display_autonumber($record, $nolink=false, $desc=null, $tab=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = $record[$desc['id']]; - - if (!$nolink && isset($record['id']) && $record['id']) - $ret = self::record_link_open_tag_r($tab, $record) . $ret . self::record_link_close_tag(); - } - - return $ret; - } - public static function display_currency($record, $nolink=false, $desc=null, $tab=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $val = Utils_CurrencyFieldCommon::get_values($record[$desc['id']]); - $ret = Utils_CurrencyFieldCommon::format($val[0], $val[1]); - } - - return $ret; - } - public static function display_checkbox($record, $nolink=false, $desc=null, $tab=null) { - $ret = ''; - if (isset($desc['id']) && array_key_exists($desc['id'], $record)) { - $ret = $record[$desc['id']]? __('Yes'): __('No'); - } - - return $ret; - } - public static function display_checkbox_icon($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = '';; - } - - return $ret; - } - public static function display_checkbox_setting($record, $nolink=false, $desc=null, $tab=null) { - $img = self::display_checkbox_icon($record, $nolink, $desc); - - $rb_obj = Utils_RecordBrowser::$rb_obj; - - if (!$img || $nolink || !$desc || !($rb_obj instanceof Utils_RecordBrowser)) return $img; - - $href = $rb_obj->create_callback_href(array('Utils_RecordBrowserCommon', 'set_checkbox_setting'), array($tab, $record['id'], $desc['id'], $record[$desc['id']]?0:1)); - - $tooltip_attrs = Utils_TooltipCommon::open_tag_attrs(__('Click to toggle')); - - return "" . $img . ''; - } - public static function set_checkbox_setting($tab, $id, $field, $active=1) { - self::update_record($tab, $id, array($field=>$active)); - } - public static function display_date($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = Base_RegionalSettingsCommon::time2reg($record[$desc['id']], false, true, false); - } - - return $ret; - } - public static function display_timestamp($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = Base_RegionalSettingsCommon::time2reg($record[$desc['id']], 'without_seconds'); - } - - return $ret; - } - public static function display_time($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']])) { - $ret = $record[$desc['id']] !== '' && $record[$desc['id']] !== false - ? Base_RegionalSettingsCommon::time2reg($record[$desc['id']], 'without_seconds', false) - : '---'; - } - - return $ret; - } - public static function display_long_text($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = self::format_long_text($record[$desc['id']]); - } - - return $ret; - } - public static function multiselect_from_common($arrid) { - return '__COMMON__::'.$arrid; - } - public static function format_long_text($text){ - $ret = htmlspecialchars($text); - $ret = str_replace("\n",'
',$ret); - $ret = Utils_BBCodeCommon::parse(htmlspecialchars_decode($ret)); - return $ret; - } - public static function encode_multi($v) { - if ($v==='') return ''; - if (is_array($v)) { - if (empty($v)) return ''; - } else $v = array($v); - return '__'.implode('__',$v).'__'; - } - public static function decode_multi($v) { - if ($v===null) return array(); - if(is_array($v)) return $v; - $v = explode('__',$v); - array_shift($v); - array_pop($v); - $ret = array(); - foreach ($v as $w) - $ret[$w] = $w; - return $ret; - } - public static function decode_commondata_param($param) { - $param = explode('__',$param); - if (isset($param[1])) { - $order = Utils_CommonDataCommon::validate_order($param[0]); - $array_id = $param[1]; - } else { - $order = 'value'; - $array_id = $param[0]; - } - return array('order'=>$order, 'order_by_key'=>$order, 'array_id'=>$array_id); - } - public static function encode_commondata_param($param) { - if (!is_array($param)) - $param = array($param); - - $order = 'value'; - if (isset($param['order']) || isset($param['order_by_key'])) { - $order = Utils_CommonDataCommon::validate_order(isset($param['order'])? $param['order']: $param['order_by_key']); - - unset($param['order']); - unset($param['order_by_key']); - } - - $array_id = implode('::', $param); - - return implode('__', array($order, $array_id)); - } - public static function decode_autonumber_param($param, &$prefix, &$pad_length, &$pad_mask) { - $parsed = explode('__', $param, 4); - if (!is_array($parsed) || count($parsed) != 3) - trigger_error("Not well formed autonumber parameter: $param", E_USER_ERROR); - list($prefix, $pad_length, $pad_mask) = $parsed; - } - public static function encode_autonumber_param($prefix, $pad_length, $pad_mask) { - return implode('__', array($prefix, $pad_length, $pad_mask)); - } - public static function format_autonumber_str($param, $id) { - self::decode_autonumber_param($param, $prefix, $pad_length, $pad_mask); - if ($id === null) - $pad_mask = '?'; - return $prefix . str_pad($id, $pad_length, $pad_mask, STR_PAD_LEFT); - } - public static function format_autonumber_str_all_records($tab, $field, $param) { - self::decode_autonumber_param($param, $prefix, $pad_length, $pad_mask); - $ids = DB::GetCol('SELECT id FROM '.$tab.'_data_1'); - DB::StartTrans(); - foreach ($ids as $id) { - $str = $prefix . str_pad($id, $pad_length, $pad_mask, STR_PAD_LEFT); - DB::Execute('UPDATE ' . $tab . '_data_1 SET indexed = 0, f_' . $field . '=%s WHERE id=%d', array($str, $id)); - } - DB::CompleteTrans(); - } - public static function decode_select_param($param) { - if (is_array($param)) return $param; - - $param = explode(';', $param); - $reference = explode('::', $param[0]); - $crits_callback = isset($param[1]) && $param[1] != '::' ? explode('::', $param[1]): null; - $adv_params_callback = isset($param[2]) && $param[2] != '::' ? explode('::', $param[2]): null; - - //in case RB records select - $select_tab = $reference[0]; - $cols = isset($reference[1]) ? array_filter(explode('|', $reference[1])) : null; - - //in case __COMMON__ - $array_id = isset($reference[1])? $reference[1]: null; - $order = isset($reference[2])? $reference[2]: 'value'; - - if ($select_tab == '__RECORDSETS__') { - $select_tabs = DB::GetCol('SELECT tab FROM recordbrowser_table_properties'); - $single_tab = false; - } - else { - $select_tabs = array_filter(explode(',',$select_tab)); - $single_tab = count($select_tabs)==1? $select_tab: false; - } - - return array( - 'single_tab'=>$single_tab? $select_tab: false, //returns single tab name, __COMMON__ or false - 'select_tabs'=>$select_tabs, //returns array of tab names - 'cols'=>$cols, // returns array of columns for formatting the display value (used in case RB records select) - 'array_id'=>$array_id, //returns array_id (used in case __COMMON__) - 'order'=>$order, //returns order code (used in case __COMMON__) - 'crits_callback'=>$crits_callback, //returns crits callback (used in case RB records select) - 'adv_params_callback'=>$adv_params_callback //returns adv_params_callback (used in case RB records select) - ); - } - - public static function decode_record_token($token, $single_tab=false) { - $kk = explode('/',$token); - if(count($kk)==1) { - if ($single_tab && is_numeric($kk[0])) { - $tab = $single_tab; - $record_id = $kk[0]; - } else return false; - } else { - $record_id = array_pop($kk); - $tab = $single_tab?$single_tab:$kk[0]; - if (!self::check_table_name($tab) || !is_numeric($record_id)) return false; - } - - return array('tab'=>$tab, 'id'=>$record_id, $tab, $record_id); - } - - public static function call_select_adv_params_callback($callback, $record=null) { - $ret = array( - 'order'=>array(), - 'cols'=>array(), - 'format_callback'=>array('Utils_RecordBrowserCommon', 'autoselect_label') - ); - - $adv_params = array(); - if (is_callable($callback)) - $adv_params = call_user_func($callback, $record); - - if (!is_array($adv_params)) - $adv_params = array(); - - return array_merge($ret, $adv_params); - } - - public static function get_select_tab_crits($param, $record=null) { - $param = self::decode_select_param($param); - - $ret = array(); - if (is_callable($param['crits_callback'])) - $ret = call_user_func($param['crits_callback'], false, $record); - - $tabs = $param['select_tabs']; - - $ret = !empty($ret)? $ret: array(); - if ($param['single_tab'] && (!is_array($ret) || !isset($ret[$param['single_tab']]))) { - $ret = array($param['single_tab'] => $ret); - } - elseif(is_array($ret) && !array_intersect($tabs, array_keys($ret))) { - $tab_crits = array(); - foreach($tabs as $tab) - $tab_crits[$tab] = $ret; - - $ret = $tab_crits; - } - - foreach ($ret as $tab=>$crits) { - if (!$tab || !self::check_table_name($tab, false, false)) { - unset($ret[$tab]); - break; - } - $access_crits = self::get_access_crits($tab, 'selection'); - if ($access_crits===false) unset($ret[$tab]); - if ($access_crits===true) break; - if (is_array($access_crits) || $access_crits instanceof Utils_RecordBrowser_CritsInterface) { - if((is_array($crits) && $crits) || $crits instanceof Utils_RecordBrowser_CritsInterface) - $ret[$tab] = self::merge_crits($crits, $access_crits); - else - $ret[$tab] = $access_crits; - } - } - - return $ret; - } - - public static function call_select_item_format_callback($callback, $tab_id, $args) { -// $args = array($tab, $tab_crits, $format_callback, $params); - - $param = self::decode_select_param($args[3]); - - $val = self::decode_record_token($tab_id, $param['single_tab']); - - if (!$val) return ''; - - list($tab, $record_id) = $val; - - $tab_caption = ''; - if (!$param['single_tab']) { - $tab_caption = self::get_caption($tab); - - $tab_caption = '[' . ((!$tab_caption || $tab_caption == '---')? $tab: $tab_caption) . '] '; - } - - $callback = is_callable($callback)? $callback: array('Utils_RecordBrowserCommon', 'autoselect_label'); - - return $tab_caption . call_user_func($callback, $tab_id, $args); - } - - public static function user_settings(){ - $ret = DB::Execute('SELECT tab, caption, icon, recent, favorites, full_history FROM recordbrowser_table_properties'); - $settings = array(0=>array(), 1=>array(), 2=>array(), 3=>array()); - while ($row = $ret->FetchRow()) { - $caption = _V($row['caption']); // ****** RecordBrowser - recordset caption - if (!self::get_access($row['tab'],'browse')) break; - if ($row['favorites'] || $row['recent']) { - $options = array('all'=>__('All')); - if ($row['favorites']) $options['favorites'] = __('Favorites'); - if ($row['recent']) $options['recent'] = __('Recent'); - if (Utils_WatchdogCommon::category_exists($row['tab'])) $options['watchdog'] = __('Watched'); - $settings[0][] = array('name'=>$row['tab'].'_default_view','label'=>$caption,'type'=>'select','values'=>$options,'default'=>'all'); - } - if ($row['favorites']) - $settings[1][] = array('name'=>$row['tab'].'_auto_fav','label'=>$caption,'type'=>'select','values'=>array(__('Disabled'), __('Enabled')),'default'=>0); - if (Utils_WatchdogCommon::category_exists($row['tab'])) { - $settings[2][] = array('name'=>$row['tab'].'_auto_subs','label'=>$caption,'type'=>'select','values'=>array(__('Disabled'), __('Enabled')),'default'=>0); - } - $settings[0][] = array('name'=>$row['tab'].'_show_filters','label'=>'','type'=>'hidden','default'=>0); - } - $final_settings = array(); - $subscribe_settings = array(); - $final_settings[] = array('name'=>'add_in_table_shown','label'=>__('Quick new record - show by default'),'type'=>'checkbox','default'=>0); - $final_settings[] = array('name'=>'hide_empty','label'=>__('Hide empty fields'),'type'=>'checkbox','default'=>0); - $final_settings[] = array('name'=>'enable_autocomplete','label'=>__('Enable autocomplete in select/multiselect at'),'type'=>'select','default'=>50, 'values'=>array(0=>__('Always'), 20=>__('%s records', array(20)), 50=>__('%s records', array(50)), 100=>__('%s records', array(100)))); - $final_settings[] = array('name'=>'grid','label'=>__('Grid edit (experimental)'),'type'=>'checkbox','default'=>0); - $final_settings[] = array('name'=>'confirm_leave','label'=>__('Confirm before leave edit page'),'type'=>'checkbox','default'=>1); - $final_settings[] = array('name'=>'header_default_view','label'=>__('Default data view'),'type'=>'header'); - $final_settings = array_merge($final_settings,$settings[0]); - $final_settings[] = array('name'=>'header_auto_fav','label'=>__('Automatically add to favorites records created by me'),'type'=>'header'); - $final_settings = array_merge($final_settings,$settings[1]); - $final_settings[] = array('name'=>'header_auto_subscriptions','label'=>__('Automatically watch records created by me'),'type'=>'header'); - $final_settings = array_merge($final_settings,$settings[2]); - return array(__('Browsing records')=>$final_settings); - } - public static function check_table_name($tab, $flush=false, $failure_on_missing=true){ - static $tables = null; - if($tab=='__RECORDSETS__' || preg_match('/,/',$tab)) return true; - if ($tables===null || $flush) { - $r = DB::GetAll('SELECT tab FROM recordbrowser_table_properties'); - $tables = array(); - foreach($r as $v) - $tables[$v['tab']] = true; - } - if (!isset($tables[$tab]) && !$flush && $failure_on_missing) trigger_error('RecordBrowser critical failure, terminating. (Requested '.serialize($tab).', available '.print_r($tables, true).')', E_USER_ERROR); - return isset($tables[$tab]); - } - public static function get_value($tab, $id, $field) { - self::init($tab); - if (isset(self::$table_rows[$field])) $field = self::$table_rows[$field]['id']; - elseif (!isset(self::$hash[$field])) trigger_error('get_value(): Unknown column: '.$field, E_USER_ERROR); - $ret = DB::GetOne('SELECT f_'.$field.' FROM '.$tab.'_data_1 WHERE id=%d', array($id)); - if ($ret===false || $ret===null) return null; - return $ret; - } - public static function count_possible_values($tab, $field) { //it ignores empty values! - self::init($tab); - if (isset(self::$table_rows[$field])) $field = self::$table_rows[$field]['id']; - elseif (!isset(self::$hash[$field])) trigger_error('count_possible_values(): Unknown column: '.$field, E_USER_ERROR); - $par = self::build_query($tab, array('!'.$field=>'')); - return DB::GetOne('SELECT COUNT(DISTINCT(f_'.$field.')) FROM '.$par['sql'], $par['vals']); - } - public static function get_possible_values($tab, $field) { - self::init($tab); - if (isset(self::$table_rows[$field])) $field = self::$table_rows[$field]['id']; - elseif (!isset(self::$hash[$field])) trigger_error('get_possible_values(): Unknown column: '.$field, E_USER_ERROR); - $par = self::build_query($tab, array('!'.$field=>'')); - return DB::GetAssoc('SELECT MIN(id), MIN(f_'.$field.') FROM'.$par['sql'].' GROUP BY f_'.$field, $par['vals']); - } - public static function get_id($tab, $field, $value) { - self::init($tab); - $where = ''; - if (!is_array($field)) $field=array($field); - if (!is_array($value)) $value=array($value); - foreach ($field as $k=>$v) { - if (!$v) break; - if (isset(self::$table_rows[$v])) $v = $field[$k] = self::$table_rows[$v]['id']; - elseif (!isset(self::$hash[$v])) trigger_error('get_id(): Unknown column: '.$v, E_USER_ERROR); - $f_id = self::$hash[$v]; - if (self::$table_rows[$f_id]['type']=='multiselect') { - $where .= ' AND f_'.$v.' '.DB::like().' '.DB::Concat(DB::qstr('%\_\_'),'%s',DB::qstr('\_\_%')); - } else $where .= ' AND f_'.$v.'=%s'; - - } - $ret = DB::GetOne('SELECT id FROM '.$tab.'_data_1 WHERE active=1'.$where, $value); - if ($ret===false || $ret===null) return null; - return $ret; - } - public static function is_active($tab, $id) { - self::init($tab); - return DB::GetOne('SELECT active FROM '.$tab.'_data_1 WHERE id=%d', array($id)); - } - public static function admin_caption() { - return array('label'=>__('Record Browser'), 'section'=>__('Data')); - } - public static function admin_access() { - return DEMO_MODE?false:true; - } - public static function admin_access_levels() { - return array( - 'records'=>array('label'=>__('Manage Records'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>1), - 'fields'=>array('label'=>__('Manage Fields'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>1), - 'settings'=>array('label'=>__('Manage Settings'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>1), - 'addons'=>array('label'=>__('Manage Addons'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>2), - 'permissions'=>array('label'=>__('Permissions'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>1), - 'pattern'=>array('label'=>__('Clipboard Pattern'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>2) - ); - } - public static function get_field_id($f) { - return preg_replace('/[^|a-z0-9]/','_',strtolower($f)); - } - public static function init($tab, $admin=false, $force=false) { - static $cache = array(); - if (!isset(self::$cols_order[$tab])) self::$cols_order[$tab] = array(); - $cache_str = $tab.'__'.$admin.'__'.md5(serialize(self::$cols_order[$tab])); - if (!$force && isset($cache[$cache_str])) { - self::$hash = $cache[$cache_str]['hash']; - return self::$table_rows = $cache[$cache_str]['rows']; - } - self::$table_rows = array(); - if($tab=='__RECORDSETS__' || preg_match('/,/',$tab)) return; - self::check_table_name($tab); - self::display_callback_cache($tab); - $ret = DB::Execute('SELECT * FROM '.$tab.'_field'.($admin?'':' WHERE active=1 AND type!=\'page_split\'').' ORDER BY position'); - self::$hash = array(); - while($row = $ret->FetchRow()) { - if ($row['field']=='id') break; - $commondata = false; - if ($row['type']=='commondata') { - $row['param'] = self::decode_commondata_param($row['param']); - $commondata = true; - } - if ($row['type'] == 'file') { - $row['param'] = json_decode($row['param'], true); - if (!is_array($row['param'])) $row['param'] = []; - if (!isset($row['param']['max_files'])) $row['param']['max_files'] = false; - } - $next_field = - array( 'name'=>str_replace('%','%%',$row['caption']?$row['caption']:$row['field']), - 'id'=>self::get_field_id($row['field']), - 'pkey'=>$row['id'], - 'type'=>$row['type'], - 'caption'=>$row['caption'], - 'visible'=>$row['visible'], - 'required'=>($row['type']=='calculated'?false:$row['required']), - 'extra'=>$row['extra'], - 'active'=>$row['active'], - 'export'=>$row['export'], - 'tooltip'=>$row['tooltip'], - 'position'=>$row['position'], - 'processing_order' => $row['processing_order'], - 'filter'=>$row['filter'], - 'style'=>$row['style'], - 'param'=>$row['param'], - 'help' =>$row['help'], - 'template'=>$row['template'] - ); - if (isset(self::$display_callback_table[$tab][$row['field']])) - $next_field['display_callback'] = self::$display_callback_table[$tab][$row['field']]; - if (($row['type']=='select' || $row['type']=='multiselect') && $row['param']) { - $pos = strpos($row['param'], ':'); - $next_field['ref_table'] = substr($row['param'], 0, $pos); - if ($next_field['ref_table']=='__COMMON__') { - $next_field['ref_field'] = '__COMMON__'; - $exploded = explode('::', $row['param']); - $next_field['commondata_array'] = $next_field['ref_table'] = $exploded[1]; - $next_field['commondata_order'] = isset($exploded[2]) ? $exploded[2] : 'value'; - $commondata = true; - } else { - $end = strpos($row['param'], ';', $pos+2); - if ($end==0) $end = strlen($row['param']); - $next_field['ref_field'] = substr($row['param'], $pos+2, $end-$pos-2); - } - } - $next_field['commondata'] = $commondata; - if ($commondata) { - if (!isset($next_field['commondata_order'])) { - if (isset($next_field['param']['order'])) { - $next_field['commondata_order'] = $next_field['param']['order']; - } else { - $next_field['commondata_order'] = 'value'; - } - } - if (!isset($next_field['commondata_array'])) { - $next_field['commondata_array'] = $next_field['param']['array_id']; - } - } - self::$table_rows[$row['field']] = $next_field; - self::$hash[$next_field['id']] = $row['field']; - } - if (!empty(self::$cols_order[$tab])) { - $rows = array(); - foreach (self::$cols_order[$tab] as $v) { - $rows[self::$hash[$v]] = self::$table_rows[self::$hash[$v]]; - unset(self::$table_rows[self::$hash[$v]]); - } - foreach(self::$table_rows as $k=>$v) - $rows[$k] = $v; - self::$table_rows = $rows; - } - $cache[$tab.'__'.$admin.'__'.md5(serialize(self::$cols_order[$tab]))] = array('rows'=>self::$table_rows,'hash'=>self::$hash); - return self::$table_rows; - } - - public static function install_new_recordset($tab, $fields=array()) { - if (!preg_match('/^[a-zA-Z_0-9]+$/',$tab)) trigger_error('Invalid table name ('.$tab.') given to install_new_recordset.',E_USER_ERROR); - if (strlen($tab)>39) trigger_error('Invalid table name ('.$tab.') given to install_new_recordset, max length is 39 characters.',E_USER_ERROR); - if (!DB::GetOne('SELECT 1 FROM recordbrowser_table_properties WHERE tab=%s', array($tab))) { - DB::Execute('INSERT INTO recordbrowser_table_properties (tab) VALUES (%s)', array($tab)); - } - - @DB::DropTable($tab.'_callback'); - @DB::DropTable($tab.'_recent'); - @DB::DropTable($tab.'_favorite'); - @DB::DropTable($tab.'_edit_history_data'); - @DB::DropTable($tab.'_edit_history'); - @DB::DropTable($tab.'_field'); - @DB::DropTable($tab.'_data_1'); - @DB::DropTable($tab.'_access_clearance'); - @DB::DropTable($tab.'_access_fields'); - @DB::DropTable($tab.'_access'); - - self::check_table_name(null, true); - DB::CreateTable($tab.'_field', - 'id I2 AUTO KEY NOTNULL,'. - 'field C(32) UNIQUE NOTNULL,'. - 'caption C(255),'. - 'type C(32),'. - 'extra I1 DEFAULT 1,'. - 'visible I1 DEFAULT 1,'. - 'tooltip I1 DEFAULT 1,'. - 'required I1 DEFAULT 1,'. - 'export I1 DEFAULT 1,'. - 'active I1 DEFAULT 1,'. - 'position I2,'. - 'processing_order I2 NOTNULL,'. - 'filter I1 DEFAULT 0,'. - 'param C(255),'. - 'style C(64),'. - 'template C(255),'. - 'help X', - array('constraints'=>'')); - DB::CreateTable($tab.'_callback', - 'field C(32),'. - 'callback C(255),'. - 'freezed I1', - array('constraints'=>'')); - - DB::Execute('INSERT INTO '.$tab.'_field(field, type, extra, visible, position, processing_order) VALUES(\'id\', \'foreign index\', 0, 0, 1, 1)'); - DB::Execute('INSERT INTO '.$tab.'_field(field, type, extra, position, processing_order) VALUES(\'General\', \'page_split\', 0, 2, 2)'); - - $fields_sql = ''; - foreach ($fields as $v) - $fields_sql .= Utils_RecordBrowserCommon::new_record_field($tab, $v, false, false); - DB::CreateTable($tab.'_data_1', - 'id I AUTO KEY,'. - 'created_on T NOT NULL,'. - 'created_by I NOT NULL,'. - 'indexed I1 NOT NULL DEFAULT 0,'. - 'active I1 NOT NULL DEFAULT 1'. - $fields_sql, - array('constraints'=>'')); - DB::CreateIndex($tab.'_idxed',$tab.'_data_1','indexed,active'); - DB::CreateIndex($tab.'_act',$tab.'_data_1','active'); - - DB::CreateTable($tab.'_edit_history', - 'id I AUTO KEY,'. - $tab.'_id I NOT NULL,'. - 'edited_on T NOT NULL,'. - 'edited_by I NOT NULL', - array('constraints'=>', FOREIGN KEY (edited_by) REFERENCES user_login(id), FOREIGN KEY ('.$tab.'_id) REFERENCES '.$tab.'_data_1(id)')); - DB::CreateTable($tab.'_edit_history_data', - 'edit_id I,'. - 'field C(32),'. - 'old_value X', - array('constraints'=>', FOREIGN KEY (edit_id) REFERENCES '.$tab.'_edit_history(id)')); - DB::CreateTable($tab.'_favorite', - 'fav_id I AUTO KEY,'. - $tab.'_id I,'. - 'user_id I', - array('constraints'=>', FOREIGN KEY (user_id) REFERENCES user_login(id), FOREIGN KEY ('.$tab.'_id) REFERENCES '.$tab.'_data_1(id)')); - DB::CreateTable($tab.'_recent', - 'recent_id I AUTO KEY,'. - $tab.'_id I,'. - 'user_id I,'. - 'visited_on T', - array('constraints'=>', FOREIGN KEY (user_id) REFERENCES user_login(id), FOREIGN KEY ('.$tab.'_id) REFERENCES '.$tab.'_data_1(id)')); - DB::CreateTable($tab.'_access', - 'id I AUTO KEY,'. - 'action C(16),'. - 'crits X', - array('constraints'=>'')); - DB::CreateTable($tab.'_access_fields', - 'rule_id I,'. - 'block_field C(32)', - array('constraints'=>', FOREIGN KEY (rule_id) REFERENCES '.$tab.'_access(id)')); - DB::CreateTable($tab.'_access_clearance', - 'rule_id I,'. - 'clearance C(32)', - array('constraints'=>', FOREIGN KEY (rule_id) REFERENCES '.$tab.'_access(id)')); - self::check_table_name($tab, true); - self::add_access($tab, 'print', 'SUPERADMIN'); - self::add_access($tab, 'export', 'SUPERADMIN'); - return true; - } - public static function enable_watchdog($tab,$watchdog_callback) { - self::check_table_name($tab); - Utils_WatchdogCommon::register_category($tab, $watchdog_callback); - } - public static function set_display_callback($tab, $field, $callback) { - self::check_table_name($tab); - self::$clear_get_val_cache = true; - if (is_array($callback)) $callback = implode('::',$callback); - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s AND freezed=1', array($field)); - DB::Execute('INSERT INTO '.$tab.'_callback (field, callback, freezed) VALUES(%s, %s, 1)', array($field, $callback)); - } - public static function set_QFfield_callback($tab, $field, $callback) { - self::check_table_name($tab); - self::$clear_get_val_cache = true; - if (is_array($callback)) $callback = implode('::',$callback); - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s AND freezed=0', array($field)); - DB::Execute('INSERT INTO '.$tab.'_callback (field, callback, freezed) VALUES(%s, %s, 0)', array($field, $callback)); - } - public static function unset_display_callback($tab, $field) { - self::check_table_name($tab); - self::$clear_get_val_cache = true; - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s AND freezed=1', array($field)); - } - public static function unset_QFfield_callback($tab, $field) { - self::check_table_name($tab); - self::$clear_get_val_cache = true; - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s AND freezed=0', array($field)); - } - - public static function uninstall_recordset($tab) { - if (!self::check_table_name($tab,true)) return; - self::$clear_get_val_cache = true; - Utils_WatchdogCommon::unregister_category($tab); - DB::DropTable($tab.'_callback'); - DB::DropTable($tab.'_recent'); - DB::DropTable($tab.'_favorite'); - DB::DropTable($tab.'_edit_history_data'); - DB::DropTable($tab.'_edit_history'); - DB::DropTable($tab.'_field'); - DB::DropTable($tab.'_data_1'); - DB::DropTable($tab.'_access_clearance'); - DB::DropTable($tab.'_access_fields'); - DB::DropTable($tab.'_access'); - DB::Execute('DELETE FROM recordbrowser_table_properties WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_processing_methods WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_browse_mode_definitions WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_clipboard_pattern WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_addon WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_access_methods WHERE tab=%s', array($tab)); - return true; - } - - public static function delete_record_field($tab, $field){ - self::init($tab); - self::$clear_get_val_cache = true; - $exists = DB::GetOne('SELECT 1 FROM '.$tab.'_field WHERE field=%s', array($field)); - if(!$exists) return; - // move to the end - self::change_field_position($tab, $field, 16000); - DB::Execute('DELETE FROM '.$tab.'_field WHERE field=%s', array($field)); - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s', array($field)); - - if (isset(self::$table_rows[$field]['id'])) { - $f_id = self::$table_rows[$field]['id']; - @DB::Execute('ALTER TABLE '.$tab.'_data_1 DROP COLUMN f_'.$f_id); - @DB::Execute('DELETE FROM '.$tab.'_access_fields WHERE block_field=%s', array($f_id)); - self::init($tab, false, true); - @DB::Execute('UPDATE '.$tab.'_data_1 SET indexed=0'); - } - } - - private static $datatypes = null; - public static function new_record_field($tab, $definition, $alter=true, $set_empty_position_before_first_page_split=true){ - if (self::$datatypes===null) { - self::$datatypes = array(); - $ret = DB::Execute('SELECT * FROM recordbrowser_datatype'); - while ($row = $ret->FetchRow()) - self::$datatypes[$row['type']] = array($row['module'], $row['func']); - } - if (!is_array($definition)) { - // Backward compatibility - got to get rid of this one someday - $args = func_get_args(); - array_shift($args); - $definition = array(); - foreach (array( 0=>'name', - 1=>'type', - 2=>'visible', - 3=>'required', - 4=>'param', - 5=>'style', - 6=>'extra', - 7=>'filter', - 8=>'position', - 9=>'processing_order', - 10=>'caption') as $k=>$w) - if (isset($args[$k])) $definition[$w] = $args[$k]; - } - if (!isset($definition['type'])) trigger_error(print_r($definition,true)); - if (!isset($definition['param'])) $definition['param'] = ''; - if (!isset($definition['caption'])) $definition['caption'] = ''; - if (!isset($definition['style'])) { - if (in_array($definition['type'], array('time','timestamp','currency'))) - $definition['style'] = $definition['type']; - else { - if (in_array($definition['type'], array('float','integer', 'autonumber'))) - $definition['style'] = 'number'; - else - $definition['style'] = ''; - } - } - if (!isset($definition['extra'])) $definition['extra'] = true; - if (!isset($definition['export'])) $definition['export'] = true; - if (!isset($definition['visible'])) $definition['visible'] = false; - if (!isset($definition['tooltip'])) $definition['tooltip'] = $definition['visible']; - if (!isset($definition['required'])) $definition['required'] = false; - if (!isset($definition['filter'])) $definition['filter'] = false; - if (!isset($definition['position'])) $definition['position'] = null; - if (!isset($definition['template'])) $definition['template'] = ''; - if (!isset($definition['help'])) $definition['help'] = ''; - $definition['template'] = is_array($definition['template'])? implode('::', $definition['template']): $definition['template']; - if (isset(self::$datatypes[$definition['type']])) $definition = call_user_func(self::$datatypes[$definition['type']], $definition); - - if (isset($definition['display_callback'])) self::set_display_callback($tab, $definition['name'], $definition['display_callback']); - if (isset($definition['QFfield_callback'])) self::set_QFfield_callback($tab, $definition['name'], $definition['QFfield_callback']); -// $field, $type, $visible, $required, $param='', $style='', $extra = true, $filter = false, $pos = null - - if (strpos($definition['name'],'|')!==false) trigger_error('Invalid field name (character | is not allowed):'.$definition['name'], E_USER_ERROR); - self::check_table_name($tab); - self::$clear_get_val_cache = true; - if ($alter) { - $exists = DB::GetOne('SELECT field FROM '.$tab.'_field WHERE field=%s', array($definition['name'])); - if ($exists) return; - } - - DB::StartTrans(); - if (is_string($definition['position'])) $definition['position'] = self::get_field_position($tab, $definition['position'])+1; - if ($definition['position']===null || $definition['position']===false) { - $first_page_split = $set_empty_position_before_first_page_split?DB::GetOne('SELECT MIN(position) FROM '.$tab.'_field WHERE type=%s AND field!=%s', array('page_split', 'General')):0; - $definition['position'] = $first_page_split?$first_page_split:DB::GetOne('SELECT MAX(position) FROM '.$tab.'_field')+1; - } - DB::Execute('UPDATE '.$tab.'_field SET position = position+1 WHERE position>=%d', array($definition['position'])); - DB::CompleteTrans(); - if (!isset($definition['processing_order'])) $definition['processing_order'] = DB::GetOne('SELECT MAX(processing_order) FROM '.$tab.'_field') + 1; - - $param = $definition['param']; - if (is_array($param)) { - if ($definition['type']=='commondata') { - $param = self::encode_commondata_param($param); - } elseif($definition['type'] == 'file') { - $param = json_encode($param); - } else { - $tmp = array(); - foreach ($param as $k=>$v) $tmp[] = $k.'::'.$v; - $param = implode(';',$tmp); - } - } - $f = self::actual_db_type($definition['type'], $param); - DB::Execute('INSERT INTO '.$tab.'_field(field, caption, type, visible, param, style, position, processing_order, extra, required, filter, export, tooltip, template, help) VALUES(%s, %s, %s, %d, %s, %s, %d, %d, %d, %d, %d, %d, %d, %s, %s)', array($definition['name'], $definition['caption'], $definition['type'], $definition['visible']?1:0, $param, $definition['style'], $definition['position'], $definition['processing_order'], $definition['extra']?1:0, $definition['required']?1:0, $definition['filter']?1:0, $definition['export']?1:0, $definition['tooltip']?1:0, $definition['template'], $definition['help'])); - $column = 'f_'.self::get_field_id($definition['name']); - if ($alter) { - self::init($tab, false, true); - if ($f!=='') { - @DB::Execute('ALTER TABLE '.$tab.'_data_1 ADD COLUMN '.$column.' '.$f); - if ($definition['type'] === 'autonumber') { - self::format_autonumber_str_all_records($tab, self::get_field_id($definition['name']), $param); - } - } - } else { - if ($f!=='') return ','.$column.' '.$f; - else return ''; - } - @DB::Execute('UPDATE '.$tab.'_data_1 SET indexed=0'); - } - public static function change_field_position($tab, $field, $new_pos){ - $new_pos = is_string($new_pos)? (self::get_field_position($tab, $new_pos)+1): $new_pos; - - if ($new_pos <= 2) return; // make sure that no field is before "General" tab split - - DB::StartTrans(); - if ($pos = self::get_field_position($tab, $field)) { - // move all following fields back - DB::Execute('UPDATE '.$tab.'_field SET position=position-1 WHERE position>%d',array($pos)); - // make place for moved field - DB::Execute('UPDATE '.$tab.'_field SET position=position+1 WHERE position>=%d',array($new_pos)); - // set new field position - DB::Execute('UPDATE '.$tab.'_field SET position=%d WHERE field=%s',array($new_pos, $field)); - } - DB::CompleteTrans(); - } - - public static function get_field_position($tab, $field){ - return DB::GetOne('SELECT position FROM '.$tab.'_field WHERE field=%s', array($field)); - } - - /** - * @param string $tab Recordset identifier. e.g. contact, company - * @param string $old_name Current field name. Not field id. e.g. "First Name" - * @param string $new_name New field name. - */ - public static function rename_field($tab, $old_name, $new_name) - { - $id = self::get_field_id($old_name); - $new_id = self::get_field_id($new_name); - self::check_table_name($tab); - - $type = DB::GetOne('SELECT type FROM ' . $tab . '_field WHERE field=%s', array($old_name)); - $old_param = DB::GetOne('SELECT param FROM ' . $tab . '_field WHERE field=%s', array($old_name)); - - $db_field_exists = !(in_array($type, ['calculated', 'hidden'], true) && !$old_param) && $type!== 'page_split'; - - DB::StartTrans(); - if ($db_field_exists) { - if (DB::is_postgresql()) { - DB::Execute('ALTER TABLE ' . $tab . '_data_1 RENAME COLUMN f_' . $id . ' TO f_' . $new_id); - } else { - - DB::RenameColumn($tab . '_data_1', 'f_' . $id, 'f_' . $new_id, self::actual_db_type($type, $old_param)); - } - DB::Execute('UPDATE ' . $tab . '_edit_history_data SET field=%s WHERE field=%s', array($new_id, $id)); - } - DB::Execute('UPDATE ' . $tab . '_field SET field=%s WHERE field=%s', array($new_name, $old_name)); - DB::Execute('UPDATE ' . $tab . '_access_fields SET block_field=%s WHERE block_field=%s', array($new_id, $id)); - DB::Execute('UPDATE ' . $tab . '_callback SET field=%s WHERE field=%s', array($new_name, $old_name)); - - $result = DB::Execute('SELECT * FROM ' . $tab . '_access'); - while ($row = $result->FetchRow()) { - $crits = self::unserialize_crits($row['crits']); - - if (!$crits) break; - - if (!is_object($crits)) - $crits = Utils_RecordBrowser_Crits::from_array($crits); - - foreach ($crits->find($id)?:[] as $c) $c->set_field($new_id); - - DB::Execute('UPDATE ' . $tab . '_access SET crits=%s WHERE id=%d', array(self::serialize_crits($crits), $row['id'])); - } - - DB::CompleteTrans(); - } - - public static function set_field_template($tab, $fields, $template) - { - Utils_RecordBrowserCommon::check_table_name($tab); - $template = is_array($template)? implode('::', $template): $template; - $fields = is_array($fields)? $fields: array($fields); - $s = array_fill(0, count($fields), '%s'); - - DB::Execute('UPDATE ' . $tab . '_field SET template=%s WHERE field IN ('. implode(',', $s) .')', array_merge(array($template), $fields)); - } - - /** - * List all installed recordsets. - * @param string $format Simple formatting of the values - * - * You can use three keys that will be replaced with values:
- * - %tab - table identifier
- * - %orig_caption - original table caption
- * - %caption - translated table caption
- * Default is '%caption'. If no caption is specified then - * table identifier is used as caption.
- * Other common usage: '%caption (%tab)' - * @return array Keys are tab identifiers, values according to $format param - */ - public static function list_installed_recordsets($format = '%caption') - { - $tabs = DB::GetAssoc('SELECT tab, caption FROM recordbrowser_table_properties'); - $ret = array(); - foreach ($tabs as $tab_id => $caption) { - if (!$caption) { - $translated_caption = $caption = $tab_id; - } else { - $translated_caption = _V($caption); - } - $ret[$tab_id] = str_replace( - array('%tab', '%orig_caption', '%caption'), - array($tab_id, $caption, $translated_caption), - $format - ); - } - return $ret; - } - - public static function actual_db_type($type, $param=null) { - $f = ''; - switch ($type) { - case 'page_split': $f = ''; break; - - case 'text': $f = DB::dict()->ActualType('C').'('.$param.')'; break; - case 'select': - $param = self::decode_select_param($param); - if($param['single_tab']) $f = DB::dict()->ActualType('I4'); - else $f = DB::dict()->ActualType('X'); - break; - case 'multiselect': $f = DB::dict()->ActualType('X'); break; - case 'commondata': $f = DB::dict()->ActualType('C').'(128)'; break; - case 'integer': $f = DB::dict()->ActualType('I4'); break; - case 'float': $f = DB::dict()->ActualType('F'); break; - case 'date': $f = DB::dict()->ActualType('D'); break; - case 'timestamp': $f = DB::dict()->ActualType('T'); break; - case 'time': $f = DB::dict()->ActualType('T'); break; - case 'long text': $f = DB::dict()->ActualType('X'); break; - case 'hidden': $f = (isset($param)?$param:''); break; - case 'calculated': $f = (isset($param)?$param:''); break; - case 'checkbox': $f = DB::dict()->ActualType('I1'); break; - case 'currency': $f = DB::dict()->ActualType('C').'(128)'; break; - case 'autonumber': $len = strlen(self::format_autonumber_str($param, null)); - $f = DB::dict()->ActualType('C') . "($len)"; break; - case 'file': $f = DB::dict()->ActualType('X'); break; - } - return $f; - } - public static function new_browse_mode_details_callback($tab, $mod, $func) { - self::check_table_name($tab); - if(!DB::GetOne('SELECT 1 FROM recordbrowser_browse_mode_definitions WHERE tab=%s AND module=%s AND func=%s', array($tab, $mod, $func))) - DB::Execute('INSERT INTO recordbrowser_browse_mode_definitions (tab, module, func) VALUES (%s, %s, %s)', array($tab, $mod, $func)); - } - - public static function delete_browse_mode_details_callback($tab, $mod, $func) { - self::check_table_name($tab); - DB::Execute('DELETE FROM recordbrowser_browse_mode_definitions WHERE tab=%s AND module=%s AND func=%s', array($tab, $mod, $func)); - } - - public static function new_addon($tab, $module, $func, $label) { - if (is_array($label)) $label= implode('::',$label); - $module = str_replace('/','_',$module); - self::delete_addon($tab, $module, $func); - $pos = DB::GetOne('SELECT MAX(pos) FROM recordbrowser_addon WHERE tab=%s', array($tab)); - if (!$pos) $pos=0; - DB::Execute('INSERT INTO recordbrowser_addon (tab, module, func, label, pos, enabled) VALUES (%s, %s, %s, %s, %d, 1)', array($tab, $module, $func, $label, $pos+1)); - } - public static function delete_addon($tab, $module, $func) { - $module = str_replace('/','_',$module); - $pos = DB::GetOne('SELECT pos FROM recordbrowser_addon WHERE tab=%s AND module=%s AND func=%s', array($tab, $module, $func)); - if ($pos===false || $pos===null) return false; - DB::Execute('DELETE FROM recordbrowser_addon WHERE tab=%s AND module=%s AND func=%s', array($tab, $module, $func)); - while (DB::GetOne('SELECT pos FROM recordbrowser_addon WHERE tab=%s AND pos=%d', array($tab, $pos+1))) { - DB::Execute('UPDATE recordbrowser_addon SET pos=pos-1 WHERE tab=%s AND pos=%d', array($tab, $pos+1)); - $pos++; - } - return true; - } - public static function set_addon_pos($tab, $module, $func, $pos) { - $module = str_replace('/','_',$module); - $old_pos = DB::GetOne('SELECT pos FROM recordbrowser_addon WHERE tab=%s AND module=%s AND func=%s', array($tab, $module, $func)); - if ($old_pos>$pos) - DB::Execute('UPDATE recordbrowser_addon SET pos=pos+1 WHERE tab=%s AND pos>=%d AND pos<%d', array($tab, $pos, $old_pos)); - else - DB::Execute('UPDATE recordbrowser_addon SET pos=pos-1 WHERE tab=%s AND pos<=%d AND pos>%d', array($tab, $pos, $old_pos)); - DB::Execute('UPDATE recordbrowser_addon SET pos=%d WHERE tab=%s AND module=%s AND func=%s', array($pos, $tab, $module, $func)); - } - public static function register_datatype($type, $module, $func) { - if(self::$datatypes!==null) self::$datatypes[$type] = array($module,$func); - DB::Execute('INSERT INTO recordbrowser_datatype (type, module, func) VALUES (%s, %s, %s)', array($type, $module, $func)); - } - public static function unregister_datatype($type) { - if(self::$datatypes!==null) unset(self::$datatypes[$type]); - DB::Execute('DELETE FROM recordbrowser_datatype WHERE type=%s', array($type)); - } - public static function new_filter($tab, $col_name) { - self::check_table_name($tab); - DB::Execute('UPDATE '.$tab.'_field SET filter=1 WHERE field=%s', array($col_name)); - } - public static function delete_filter($tab, $col_name) { - self::check_table_name($tab); - DB::Execute('UPDATE '.$tab.'_field SET filter=0 WHERE field=%s', array($col_name)); - } - public static function register_processing_callback($tab, $callback) { - if (is_array($callback)) $callback = implode('::',$callback); - if(!DB::GetOne('SELECT 1 FROM recordbrowser_processing_methods WHERE tab=%s AND func=%s', array($tab, $callback))) - DB::Execute('INSERT INTO recordbrowser_processing_methods (tab, func) VALUES (%s, %s)', array($tab, $callback)); - } - public static function unregister_processing_callback($tab, $callback) { - if (is_array($callback)) $callback = implode('::',$callback); - DB::Execute('DELETE FROM recordbrowser_processing_methods WHERE tab=%s AND func=%s', array($tab, $callback)); - } - public static function set_quickjump($tab, $col_name) { - DB::Execute('UPDATE recordbrowser_table_properties SET quickjump=%s WHERE tab=%s', array($col_name, $tab)); - } - public static function set_tpl($tab, $filename) { - DB::Execute('UPDATE recordbrowser_table_properties SET tpl=%s WHERE tab=%s', array($filename, $tab)); - } - public static function set_favorites($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET favorites=%d WHERE tab=%s', array($value?1:0, $tab)); - } - public static function set_recent($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET recent=%d WHERE tab=%s', array($value, $tab)); - } - public static function set_full_history($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET full_history=%d WHERE tab=%s', array($value?1:0, $tab)); - } - public static function set_caption($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET caption=%s WHERE tab=%s', array($value, $tab)); - } - public static function set_icon($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET icon=%s WHERE tab=%s', array($value, $tab)); - } - /** - * Enable search - * @param string $tab recordset identifier - * @param int $mode 0 - search disabled, 1 - enabled by default, 2 - optional - * @param int $priority Possible values: -2, -1, 0, 1, 2 - */ - public static function set_search($tab, $mode,$priority=0) { - DB::Execute('UPDATE recordbrowser_table_properties SET search_include=%d,search_priority=%d WHERE tab=%s', array($mode, $priority, $tab)); - } - public static function set_description_callback($tab, $callback){ - if (is_array($callback)) $callback = implode('::',$callback); - DB::Execute('UPDATE recordbrowser_table_properties SET description_callback=%s WHERE tab=%s', array($callback, $tab)); - } - - /** - * Set description fields to be used as default linked label - * - * You can use double quotes to put any text between field values - * e.g. 'Last Name, ", ", First Name,' - * - * @param string $tab recordset name - * @param string|array $fields comma separated list of fields or array of fields - */ - public static function set_description_fields($tab, $fields) - { - if (is_array($fields)) $fields = implode(',', $fields); - DB::Execute('UPDATE recordbrowser_table_properties SET description_fields=%s WHERE tab=%s', array($fields, $tab)); - } - public static function set_printer($tab,$class) { - Base_PrintCommon::register_printer(new $class()); - DB::Execute('UPDATE recordbrowser_table_properties SET printer=%s WHERE tab=%s', array($class, $tab)); - } - - public static function unset_printer($tab) - { - $printer_class = DB::GetOne('SELECT printer FROM recordbrowser_table_properties WHERE tab=%s',$tab); - if ($printer_class) { - Base_PrintCommon::unregister_printer($printer_class); - DB::Execute('UPDATE recordbrowser_table_properties SET printer=%s WHERE tab=%s', array('', $tab)); - return $printer_class; - } - return false; - } - - /** - * Enable or disable jump to id. By default it is enabled. - * - * @param string $tab Recordset identifier - * @param bool $enabled True to enable, false to disable - */ - public static function set_jump_to_id($tab, $enabled = true) - { - $sql = 'UPDATE recordbrowser_table_properties SET jump_to_id=%d WHERE tab=%s'; - DB::Execute($sql, array($enabled ? 1 : 0, $tab)); - } - public static function get_caption($tab) { - static $cache = null; - if ($cache===null) $cache = DB::GetAssoc('SELECT tab, caption FROM recordbrowser_table_properties'); - if (is_string($tab) && isset($cache[$tab])) return _V($cache[$tab]); - return '---'; - } - public static function get_description_callback($tab) { - static $cache = null; - if ($cache===null) $cache = DB::GetAssoc('SELECT tab, description_callback FROM recordbrowser_table_properties'); - - if (is_string($tab) && isset($cache[$tab])) { - if(is_string($cache[$tab]) && preg_match('/::/',$cache[$tab])) { - $cache[$tab] = explode('::',$cache[$tab]); - } - if(!is_callable($cache[$tab])) - $cache[$tab] = false; - - return $cache[$tab]; - } - - return false; - } - public static function get_description_fields($tab) { - static $cache = null; - if ($cache===null) { - $db_ret = DB::GetAssoc('SELECT tab, description_fields FROM recordbrowser_table_properties'); - foreach ($db_ret as $t => $fields) { - if ($fields) { - $fields = str_replace('"', '\'"', $fields); - $cache[$t] = array_filter(array_map('trim', str_getcsv($fields, ',', "'"))); - } - } - } - - if (is_string($tab) && isset($cache[$tab])) { - return $cache[$tab]; - } - - return false; - } - public static function get_sql_type($type) { - switch ($type) { - case 'checkbox': return '%d'; - case 'select': return '%s'; - case 'float': return '%f'; - case 'integer': return '%d'; - case 'date': return '%D'; - case 'timestamp': return '%T'; - } - return '%s'; - } - public static function set_record_properties( $tab, $id, $info = array()) { - self::check_table_name($tab); - foreach ($info as $k=>$v) - switch ($k) { - case 'created_on': DB::Execute('UPDATE '.$tab.'_data_1 SET created_on=%T WHERE id=%d', array($v, $id)); - break; - case 'created_by': DB::Execute('UPDATE '.$tab.'_data_1 SET created_by=%d WHERE id=%d', array($v, $id)); - break; - } - } - - public static function record_processing($tab, $base, $mode, $clone=null) { - self::check_table_name($tab); - static $cache = array(); - if (!isset($cache[$tab])) { - $ret = DB::Execute('SELECT * FROM recordbrowser_processing_methods WHERE tab=%s', array($tab)); - $cache[$tab] = array(); - while ($row = $ret->FetchRow()) { - $callback = explode('::',$row['func']); - if (is_callable($callback)) - $cache[$tab][] = $callback; - } - } - $current = $base; - if ($mode=='display') $result = array(); - else $result = $base; - if ($mode=='cloned') $current = array('original'=>$clone, 'clone'=>$current); - foreach ($cache[$tab] as $callback) { - $return = call_user_func($callback, $current, $mode, $tab); - if ($return===false) return false; - if ($return) { - if ($mode!='display') $current = $return; - else $result = array_merge_recursive($result, $return); - } - } - if ($mode!='display') $result = $current; - return $result; - } - - public static function new_record( $tab, $values = array()) { - self::init($tab); - $user = Acl::get_user(); - - $for_processing = $values; - foreach(self::$table_rows as $field=>$desc) - if ($desc['type']==='multiselect') { - if (!isset($for_processing[$desc['id']]) || !$for_processing[$desc['id']]) - $for_processing[$desc['id']] = array(); - } elseif (!isset($for_processing[$desc['id']])) $for_processing[$desc['id']] = ''; - - $values = self::record_processing($tab, $for_processing, 'add'); - if ($values===false) return; - - self::init($tab); - $fields = 'created_on,created_by,active'; - $fields_types = '%T,%d,%d'; - $vals = array(date('Y-m-d H:i:s'), $user, 1); - $filestorageIds = []; - foreach(self::$table_rows as $field => $desc) { - - if ($desc['type'] == 'file') { - $files = $values[$desc['id']]; - if (is_string($files)) $files = self::decode_multi($files); - if ($desc['param']['max_files'] && count($files) > $desc['param']['max_files']) { - throw new Exception('Too many files in field ' . $desc['id']); - } - $filestorageIds[$field] = Utils_FileStorageCommon::add_files($files); - $values[$desc['id']] = self::encode_multi($filestorageIds[$field]); - } - - if (($desc['type']=='calculated' || $desc['type']=='hidden') && preg_match('/^[a-z]+(\([0-9]+\))?$/i',$desc['param'])===0) break; // FIXME move DB definiton to *_field table - if (!isset($values[$desc['id']]) || $values[$desc['id']]==='') break; - if (!is_array($values[$desc['id']])) $values[$desc['id']] = trim($values[$desc['id']]); - if ($desc['type']=='long text') - $values[$desc['id']] = Utils_BBCodeCommon::optimize($values[$desc['id']]); - if ($desc['type']=='multiselect' && empty($values[$desc['id']])) break; - if ($desc['type']=='multiselect') - $values[$desc['id']] = self::encode_multi($values[$desc['id']]); - if ($desc['type']=='multiselect' || $desc['type']=='select') $values[$desc['id']] = str_replace(array('P:', 'C:'), array('contact/', 'company/'), $values[$desc['id']]); - $fields_types .= ','.self::get_sql_type($desc['type']); - $fields .= ',f_'.$desc['id']; - if (is_bool($values[$desc['id']])) $values[$desc['id']] = $values[$desc['id']]?1:0; - $vals[] = $values[$desc['id']]; - } - Utils_SafeHtml_SafeHtml::setSafeHtml(new Utils_SafeHtml_HtmlPurifier()); - foreach ($vals as $k => $v) { - $vals[$k] = Utils_SafeHtml_SafeHtml::outputSafeHtml($v); - } - DB::Execute('INSERT INTO '.$tab.'_data_1 ('.$fields.') VALUES ('.$fields_types.')',$vals); - $id = DB::Insert_ID($tab.'_data_1', 'id'); - if ($user) self::add_recent_entry($tab, $user, $id); - if (Base_User_SettingsCommon::get('Utils_RecordBrowser',$tab.'_auto_fav')) - DB::Execute('INSERT INTO '.$tab.'_favorite (user_id, '.$tab.'_id) VALUES (%d, %d)', array($user, $id)); - self::init($tab); - foreach(self::$table_rows as $field=>$desc) { - if ($desc['type']==='multiselect') { - if (!isset($values[$desc['id']])) $values[$desc['id']] = array(); - elseif (!is_array($values[$desc['id']])) - $values[$desc['id']] = self::decode_multi($values[$desc['id']]); - } - if ($desc['type'] === 'autonumber') { - $autonumber_value = self::format_autonumber_str($desc['param'], $id); - self::update_record($tab, $id, array($desc['id'] => $autonumber_value), false, null, true); - $values[$desc['id']] = $autonumber_value; - } - if ($desc['type'] === 'file') { - // update backref - Utils_FileStorageCommon::add_files($filestorageIds[$field], "rb:$tab/$id/$desc[pkey]"); - $values[$desc['id']] = $filestorageIds[$field]; - } - } - $values['id'] = $id; - self::record_processing($tab, $values, 'added'); - - if (Base_User_SettingsCommon::get('Utils_RecordBrowser',$tab.'_auto_subs')==1) - Utils_WatchdogCommon::subscribe($tab,$id); - Utils_WatchdogCommon::new_event($tab,$id,'C'); - - return $id; - } - - public static function new_record_history($tab,$id,$old_value) { - DB::Execute('INSERT INTO ' . $tab . '_edit_history(edited_on, edited_by, ' . $tab . '_id) VALUES (%T,%d,%d)', array(date('Y-m-d G:i:s'), Acl::get_user(), $id)); - $edit_id = DB::Insert_ID($tab . '_edit_history', 'id'); - DB::Execute('INSERT INTO ' . $tab . '_edit_history_data(edit_id, field, old_value) VALUES (%d,%s,%s)', array($edit_id, 'id', $old_value)); - return $edit_id; - } - - public static function update_record($tab,$id,$values,$all_fields = false, $date = null, $dont_notify = false) { - DB::StartTrans(); - self::init($tab); - $record = self::get_record($tab, $id, false); - if (!is_array($record)) { - DB::CompleteTrans(); - return false; - } - - $process_method_args = $values; - $process_method_args['id'] = $id; - foreach ($record as $k=>$v) - if (!isset($process_method_args[$k])) $process_method_args[$k] = $v; - - $values = self::record_processing($tab, $process_method_args, 'edit'); - - $diff = array(); - self::init($tab); - foreach(self::$table_rows as $field => $desc){ - if ($desc['type']=='calculated' && preg_match('/^[a-z]+(\([0-9]+\))?$/i',$desc['param'])===0) break; // FIXME move DB definiton to *_field table - if ($desc['id']=='id') break; - if (!isset($values[$desc['id']])) { - if ($all_fields) $values[$desc['id']] = ''; - else break; - } - if ($desc['type']=='checkbox') { - if ($values[$desc['id']]) $values[$desc['id']] = 1; - else $values[$desc['id']] = 0; - if ($record[$desc['id']]) $record[$desc['id']] = 1; - else $record[$desc['id']] = 0; - } - if ($desc['type']=='long text') - $values[$desc['id']] = Utils_BBCodeCommon::optimize($values[$desc['id']]); - if ($desc['type']=='multiselect') { - if (!is_array($values[$desc['id']])) $values[$desc['id']] = array($values[$desc['id']]); - $array_diff = array_diff($record[$desc['id']], $values[$desc['id']]); - if (empty($array_diff)) { - $array_diff = array_diff($values[$desc['id']], $record[$desc['id']]); - if (empty($array_diff)) break; - } - $v = self::encode_multi($values[$desc['id']]); - $old = self::encode_multi($record[$desc['id']]); - } elseif ($desc['type'] == 'file') { - $files = $values[$desc['id']]; - if (is_string($files)) { - $files = self::decode_multi($files); - } - if ($desc['param']['max_files'] && count($files) > $desc['param']['max_files']) { - throw new Exception('Too many files in field ' . $desc['id']); - } - $filestorageIds = Utils_FileStorageCommon::add_files($files, "rb:$tab/$id/$desc[pkey]"); - $values[$desc['id']] = $filestorageIds; - // Delete files not present in the field right now - $old = $record[$desc['id']]; - sort($old); - if ($old == $filestorageIds) break; - foreach ($record[$desc['id']] as $file) { - if (!in_array($file, $filestorageIds)) { - // delete file - Utils_FileStorageCommon::delete($file); - } - } - $v = self::encode_multi($filestorageIds); - $old = self::encode_multi($old); - } else { - if ($record[$desc['id']]===$values[$desc['id']]) break; - $v = $values[$desc['id']]; - $old = $record[$desc['id']]; - } - if ($v!=='') DB::Execute('UPDATE '.$tab.'_data_1 SET f_'.$desc['id'].'='.self::get_sql_type($desc['type']).' WHERE id=%d',array($v, $id)); - else DB::Execute('UPDATE '.$tab.'_data_1 SET f_'.$desc['id'].'=NULL WHERE id=%d',array($id)); - $diff[$desc['id']] = $old; - } - if(!empty($diff)) { - @DB::Execute('UPDATE '.$tab.'_data_1 SET indexed=0 WHERE id=%d',array($id)); - self::record_processing($tab, $values, 'edited'); - } - if (!$dont_notify && !empty($diff)) { - $diff = self::record_processing($tab, $diff, 'edit_changes'); - DB::Execute('INSERT INTO '.$tab.'_edit_history(edited_on, edited_by, '.$tab.'_id) VALUES (%T,%d,%d)', array((($date==null)?date('Y-m-d G:i:s'):$date), Acl::get_user(), $id)); - $edit_id = DB::Insert_ID(''.$tab.'_edit_history','id'); - foreach($diff as $k=>$v) { - if (!is_array($v)) $v = array($v); - foreach($v as $c) - DB::Execute('INSERT INTO '.$tab.'_edit_history_data(edit_id, field, old_value) VALUES (%d,%s,%s)', array($edit_id, $k, $c)); - } - Utils_WatchdogCommon::new_event($tab,$id,'E_'.$edit_id); - } - return DB::CompleteTrans(); - } - public static function add_recent_entry($tab, $user_id ,$id){ - self::check_table_name($tab); - static $rec_size = array(); - if (!isset($rec_size[$tab])) $rec_size[$tab] = DB::GetOne('SELECT recent FROM recordbrowser_table_properties WHERE tab=%s', array($tab)); - $ids = array(); - if ($rec_size[$tab]) { - $ret = DB::SelectLimit('SELECT '.$tab.'_id FROM '.$tab.'_recent WHERE user_id = %d ORDER BY visited_on DESC', - $rec_size[$tab], - -1, - array($user_id)); - while($row = $ret->FetchRow()) { - if ($row[$tab.'_id']==$id || !$row[$tab.'_id']) break; - if (count($ids)>=$rec_size[$tab]-1) break; - $ids[] = $row[$tab.'_id']; - } - } - if (empty($ids)) $where = ''; - else $where = ' AND '.$tab.'_id NOT IN ('.implode(',',$ids).')'; - DB::Execute('DELETE FROM '.$tab.'_recent WHERE user_id = %d'.$where, - array($user_id)); - if ($rec_size[$tab]) - DB::Execute('INSERT INTO '.$tab.'_recent ('.$tab.'_id, user_id, visited_on) VALUES (%d, %d, %T)', - array($id, - $user_id, - date('Y-m-d H:i:s'))); - } - public static function merge_crits($a = array(), $b = array(), $or=false) { - return Utils_RecordBrowser_Crits::merge($a, $b, $or); - } - public static function build_query($tab, $crits = null, $admin = false, $order = array(), $tab_alias = 'r') { - static $stack = array(); - static $cache; - if (!is_object($crits)) { - $crits = Utils_RecordBrowser_Crits::from_array($crits); - } - $cache_key = $tab . '__' . $tab_alias . '__' . md5(serialize($crits)) . '__' . $admin . '__' . md5(serialize($order)) . '__' . Base_AclCommon::get_user(); - if (isset($cache[$cache_key])) { - return $cache[$cache_key]; - } - - $access_crits = ($admin || in_array($tab, $stack)) ? true : self::get_access_crits($tab, 'browse'); - if ($access_crits === false) return array(); - elseif ($access_crits !== true) { - $crits = self::merge_crits($crits, $access_crits); - } - - if ($admin) { - $admin_filter = str_replace('', $tab_alias, self::$admin_filter); - } else { - $admin_filter = $tab_alias . '.active=1 AND '; - } - array_push($stack, $tab); - $query_builder = new Utils_RecordBrowser_QueryBuilder($tab, $tab_alias, $admin); - $ret = $query_builder->build_query($crits, $order, $admin_filter); - $cache[$cache_key] = $ret; - array_pop($stack); - return $ret; - } - - /** - * Get records count - * - * @param string $tab - * @param array|Utils_RecordBrowser_Crits $crits - * @param bool $admin - * @param array $order Just for SQL cache optimization. Same query will be used to fetch records - * - * @return int records count - */ - public static function get_records_count( $tab, $crits = null, $admin = false, $order = array()) { - $par = self::build_query($tab, $crits, $admin, $order); - if (empty($par) || !$par) return 0; - return DB::GetOne('SELECT COUNT(*) FROM'.$par['sql'], $par['vals']); - } - public static function get_next_and_prev_record( $tab, $crits, $order, $id, $last = null) { - $par = self::build_query($tab, $crits, false, $order); - if (empty($par) || !$par) return null; - if ($last===null || is_array($last)) { - /* Just failsafe - should not happen */ - $ret = DB::GetCol('SELECT id FROM'.$par['sql'].$par['order'], $par['vals']); - if ($ret===false || $ret===null) return null; - $k = array_search($id,$ret); - return array( 'next'=>isset($ret[$k+1])?$ret[$k+1]:null, - 'curr'=>$k, - 'prev'=>isset($ret[$k-1])?$ret[$k-1]:null); - } else { - $r = DB::SelectLimit('SELECT id FROM'.$par['sql'].$par['order'],3,($last!=0?$last-1:$last), $par['vals']); - $ret = array(); - while ($row=$r->FetchRow()) { - $ret[] = $row['id']; - } - if ($ret===false || $ret===null) return null; - if ($last===0) $ret = array(0=>null, 2=>isset($ret[1])?$ret[1]:null); - return array( 'next'=>isset($ret[2])?$ret[2]:null, - 'curr'=>$last, - 'prev'=>isset($ret[0])?$ret[0]:null); - } - } - - /** - * @param string $tab Recordset identifier - * @param array|Utils_RecordBrowser_Crits $crits - * @param array $cols not used anymore - * @param array $order - * @param int|array $limit nr of rows or array('offset'=>X, 'numrows'=>Y); - * @param bool $admin - * - * @return array|bool - */ - public static function get_records( $tab, $crits = array(), $cols = array(), $order = array(), $limit = array(), $admin = false) { - if (!$tab) return false; - if (is_numeric($limit)) { - $limit = array('numrows'=>$limit,'offset'=>0); - } else { - if (!isset($limit['offset'])) $limit['offset'] = 0; - if (!isset($limit['numrows'])) $limit['numrows'] = -1; - } - if (!$order) $order = array(); - $tab_alias = 'r'; - $fields = "$tab_alias.*"; - self::init($tab); - $par = self::build_query($tab, $crits, $admin, $order); - if (empty($par)) return array(); - $ret = DB::SelectLimit('SELECT '.$fields.' FROM'.$par['sql'].$par['order'], $limit['numrows'], $limit['offset'], $par['vals']); - $records = array(); - self::init($tab); - $fields = self::$table_rows; - while ($row = $ret->FetchRow()) { - if (isset($records[$row['id']])) { - break; - } - $r = array( 'id'=>$row['id'], - ':active'=>$row['active'], - 'created_by'=>$row['created_by'], - 'created_on'=>$row['created_on']); - foreach($fields as $desc){ - if (isset($row['f_'.$desc['id']])) { - if ($desc['type'] == 'multiselect' || $desc['type'] == 'file') { - $r[$desc['id']] = self::decode_multi($row['f_' . $desc['id']]); - } elseif ($desc['type']=='text' || $desc['type']=='long text') { - $r[$desc['id']] = $row['f_' . $desc['id']]; - } else { - $r[$desc['id']] = $row['f_' . $desc['id']]; - } - } else { - if ($desc['type']=='multiselect') $r[$desc['id']] = array(); - else $r[$desc['id']] = ''; - } - } - if($admin || self::get_access($tab,'view',$r)) $records[$row['id']] = $r; - } - return $records; - } - public static function check_record_against_crits($tab, $id, $crits, & $problems = array()) { - if (is_numeric($id)) $r = self::get_record($tab, $id); - else $r = $id; - if (!is_object($crits)) { - $crits = Utils_RecordBrowser_Crits::from_array($crits); - } - $crits_validator = new Utils_RecordBrowser_CritsValidator($tab); - $crits->normalize(); - list($success, $issues) = $crits_validator->validate($crits, $r); - if (!$success) { - $problems = $issues; - } - return $success; - } - public static function crits_special_values() - { - $ret = array(); - $ret[] = new Utils_RecordBrowser_ReplaceValue('USER_ID', __('User Login'), Base_AclCommon::get_user()); - foreach (array('VIEW', 'VIEW_ALL', 'EDIT', 'EDIT_ALL', 'PRINT', 'PRINT_ALL', 'DELETE', 'DELETE_ALL') as $a) { - $description = 'Allow ' . str_replace('_', ' ', strtolower($a)) . ' record(s)'; - $ret[] = new Utils_RecordBrowser_ReplaceValue("ACCESS_$a", _V($description), 'Utils_RecordBrowserCommon::get_recursive_'.strtolower($a).'_access'); - } - return $ret; - } - public static function get_recursive_access($otab,&$r,$field,$action,$any) { - self::init($otab); - $desc = self::$table_rows[self::$hash[$field]]; - - $param = self::decode_select_param($desc['param']); - - if($param['single_tab']=='__COMMON__') return $r[$field]; - - $ret = true; - $field_is_empty = true; - if (!isset($r[$field])) $values = array(); - elseif(!is_array($r[$field])) $values = array($r[$field]); - else $values = $r[$field]; - foreach($values as $rid) { - if (!$rid) break; - $val = self::decode_record_token($rid, $param['single_tab']); - if(!$val) break; - list($tab, $rid) = $val; - $rr = self::get_record($tab, $rid); - $access = self::get_access($tab, $action, $rr); - $field_is_empty = false; - if($any && $access) return $r[$field]; - $ret &= $access; - } - return $field_is_empty ? true : ($ret ? true : false); - } - public static function get_recursive_view_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'view',true); - } - public static function get_recursive_view_all_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'view',false); - } - public static function get_recursive_edit_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'edit',true); - } - public static function get_recursive_edit_all_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'edit',false); - } - public static function get_recursive_print_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'print',true); - } - public static function get_recursive_print_all_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'print',false); - } - public static function get_recursive_delete_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'delete',true); - } - public static function get_recursive_delete_all_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'delete',false); - } - - public static function serialize_crits($crits) - { - $serialized = serialize($crits); - if (DB::is_postgresql()) { - $serialized = bin2hex($serialized); - } - return $serialized; - } - public static function unserialize_crits($str) - { - $ret = @unserialize($str); - if ($ret === false && DB::is_postgresql()) { - $ret = unserialize(hex2bin($str)); - } - return $ret; - } - public static function parse_access_crits($str, $human_readable = false) { - $ret = self::unserialize_crits($str); - if (!is_object($ret)) { - $ret = Utils_RecordBrowser_Crits::from_array($ret); - } - return $ret->replace_special_values($human_readable); - } - public static function add_default_access($tab) { - Utils_RecordBrowserCommon::add_access($tab, 'view', 'ACCESS:employee'); - Utils_RecordBrowserCommon::add_access($tab, 'add', 'ACCESS:employee'); - Utils_RecordBrowserCommon::add_access($tab, 'edit', 'ACCESS:employee'); - Utils_RecordBrowserCommon::add_access($tab, 'delete', 'ACCESS:employee'); - } - - public static function field_deny_access($tab, $fields, $action='', $clearance=null) { - if (!self::check_table_name($tab, false, false)) return; - if (!is_array($fields)) $fields = array($fields); - $sql = ''; - $vals = array(); - if ($clearance!=null) { - $sql .= ' WHERE NOT EXISTS (SELECT * FROM '.$tab.'_access_clearance WHERE rule_id=acs.id AND '.implode(' AND ',array_fill(0, count($clearance), 'clearance!=%s')).')'; - $vals = array_values($clearance); - } - if ($action!='') { - if ($sql) $sql .= ' AND '; - else $sql .= ' WHERE '; - $sql .= 'action=%s'; - $vals[] = $action; - } - $sql = 'SELECT id, id FROM '.$tab.'_access AS acs'.$sql; - $ids = DB::GetAssoc($sql, $vals); - foreach ($fields as $f) { - $f = self::get_field_id($f); - foreach ($ids as $id) - DB::Execute('INSERT INTO '.$tab.'_access_fields (rule_id, block_field) VALUES (%d, %s)', array($id, $f)); - } - } - public static function wipe_access($tab) { - if (!self::check_table_name($tab, false, false)) return; - DB::Execute('DELETE FROM '.$tab.'_access_clearance'); - DB::Execute('DELETE FROM '.$tab.'_access_fields'); - DB::Execute('DELETE FROM '.$tab.'_access'); - } - public static function delete_access($tab, $id) { - if (!self::check_table_name($tab, false, false)) return; - DB::Execute('DELETE FROM '.$tab.'_access_clearance WHERE rule_id=%d', array($id)); - DB::Execute('DELETE FROM '.$tab.'_access_fields WHERE rule_id=%d', array($id)); - DB::Execute('DELETE FROM '.$tab.'_access WHERE id=%d', array($id)); - } - public static function delete_access_rules($tab, $action, $clearance, $crits = array()) - { - if (!self::check_table_name($tab, false, false)) return; - if (!is_array($clearance)) $clearance = array($clearance); - $clearance_c = count($clearance); - $serialized = self::serialize_crits($crits); - $ids = DB::GetCol('SELECT id FROM ' . $tab . '_access WHERE crits=%s AND action=%s', array($serialized, $action)); - $ret = 0; - foreach ($ids as $rule_id) { - $existing_clearance = DB::GetCol('SELECT clearance FROM ' . $tab . '_access_clearance WHERE rule_id=%d', array($rule_id)); - if ($clearance_c == count($existing_clearance) && - $clearance_c == count(array_intersect($existing_clearance, $clearance))) { - self::delete_access($tab, $rule_id); - $ret += 1; - } - } - return $ret; - } - public static function add_access($tab, $action, $clearance, $crits=array(), $blocked_fields=array()) { - if (!self::check_table_name($tab, false, false)) return; - $serialized = self::serialize_crits($crits); - DB::Execute('INSERT INTO '.$tab.'_access (crits, action) VALUES (%s, %s)', array($serialized, $action)); - $rule_id = DB::Insert_ID($tab.'_access','id'); - if (!is_array($clearance)) $clearance = array($clearance); - foreach ($clearance as $c) - DB::Execute('INSERT INTO '.$tab.'_access_clearance (rule_id, clearance) VALUES (%d, %s)', array($rule_id, $c)); - foreach ($blocked_fields as $f) - DB::Execute('INSERT INTO '.$tab.'_access_fields (rule_id, block_field) VALUES (%d, %s)', array($rule_id, $f)); - } - public static function update_access($tab, $id, $action, $clearance, $crits=array(), $blocked_fields=array()) { - if(is_string($id) && in_array($id,array('grant','restrict'))) return; - elseif(!is_numeric($id)) throw new Exception('Utils_RecordBrowserCommon::update_access - id have to be a number'); - - $serialized = self::serialize_crits($crits); - DB::Execute('UPDATE ' . $tab . '_access SET crits=%s, action=%s WHERE id=%d', array($serialized, $action, $id)); - if (!is_array($clearance)) $clearance = array($clearance); - DB::Execute('DELETE FROM '.$tab.'_access_clearance WHERE rule_id=%d', array($id)); - DB::Execute('DELETE FROM '.$tab.'_access_fields WHERE rule_id=%d', array($id)); - foreach ($clearance as $c) - DB::Execute('INSERT INTO '.$tab.'_access_clearance (rule_id, clearance) VALUES (%d, %s)', array($id, $c)); - foreach ($blocked_fields as $f) - DB::Execute('INSERT INTO '.$tab.'_access_fields (rule_id, block_field) VALUES (%d, %s)', array($id, $f)); - } - - public static function register_custom_access_callback($tab, $callback, $priority = 10) - { - if (!is_callable($callback)) { - return false; - } - if (is_array($callback)) { - $callback = implode('::', $callback); - } - $existing = self::get_custom_access_callbacks($tab); - if (in_array($callback, $existing)) { - return false; - } - DB::Execute('INSERT INTO recordbrowser_access_methods (tab, func, priority) VALUES (%s, %s, %d)', array($tab, $callback, $priority)); - self::get_custom_access_callbacks(null, true); - return true; - } - - public static function unregister_custom_access_callback($tab, $callback) - { - if (is_array($callback)) { - $callback = implode('::', $callback); - } - DB::Execute('DELETE FROM recordbrowser_access_methods WHERE tab=%s AND func=%s', array($tab, $callback)); - } - - public static function get_custom_access_callbacks($tab = null, $force_reload = false) - { - static $custom_access_callbacks; - if ($force_reload || $custom_access_callbacks === null) { - $custom_access_callbacks = array(); - $db = DB::GetAll('SELECT * FROM recordbrowser_access_methods ORDER BY priority DESC'); - foreach ($db as $row) { - if (!isset($custom_access_callbacks[$row['tab']])) { - $custom_access_callbacks[$row['tab']] = array(); - } - $custom_access_callbacks[$row['tab']][] = $row['func']; - } - } - if ($tab === null) { - return $custom_access_callbacks; - } - - return isset($custom_access_callbacks[$tab]) ? $custom_access_callbacks[$tab] : array(); - } - public static function call_custom_access_callbacks($tab, $action, $record = null) - { - $callbacks = self::get_custom_access_callbacks($tab); - $ret = array('grant'=>null, 'restrict'=>null); - foreach ($callbacks as $callback) { - $callback_crits = call_user_func($callback, $action, $record, $tab); - - if (is_bool($callback_crits)) { - $ret[$callback_crits? 'grant': 'restrict'] = true; - break; - } - - if ($callback_crits === null) break; - - // if callback return is crits or crits array use it by default in restrict mode for backward compatibility - $crits = array( - 'grant' => null, - 'restrict' => $callback_crits - ); - - if (is_array($callback_crits) && (isset($callback_crits['grant']) || isset($callback_crits['restrict']))) { - // if restrict rules are not set make sure the restrict crits are clean - if (! isset($callback_crits['restrict'])) $callback_crits['restrict'] = null; - $crits = array_merge($crits, $callback_crits); - } - - if (!$crits['grant']) - $crits['grant'] = null; - - foreach ($crits as $mode => $c) { - $c = is_array($c) ? Utils_RecordBrowser_Crits::from_array($c): $c; - - if ($c instanceof Utils_RecordBrowser_Crits) - $ret[$mode] = ($ret[$mode] !== null) ? self::merge_crits($ret[$mode], $c, $mode === 'grant'): $c; - elseif (is_bool($c)) - $ret[$mode] = $c; - } - } - - return $ret; - } - - /** - * - * Check if user has access to recordset, record or recordset fields based on action performed - * - * @param string $tab - * @param string $action - * @param array $record - * @param boolean $return_crits - deprecated, use method Utils_RecordBrowserCommon::get_access_crits instead - * @param string $return_in_array - deprecated, use method Utils_RecordBrowserCommon::get_access_rule_crits instead - * @return false - deny access | array - fields access array - */ - public static function get_access($tab, $action, $record=null, $return_crits=false, $return_in_array=false){ - $access = Utils_RecordBrowser_Access::create($tab, $action, $record); - - //start deprecated code - used for backward compatibility - if ($return_crits) { - if ($return_in_array) - return $access->getRuleCrits(); - - return $access->getCrits();; - } - //end deprecated code - - return $access->getUserAccess(self::$admin_access); - } - - /** - * @param string $tab - * @param string $action - * @param array $record - * @return null|boolean|Utils_RecordBrowser_Crits - */ - public static function get_access_crits($tab, $action, $record=null) { - $access = Utils_RecordBrowser_Access::create($tab, $action, $record); - - return $access->getCrits(); - } - - /** - * @param string $tab - * @param string $action - * @param array $record - * @return array - rule_id => rule - */ - public static function get_access_rule_crits($tab, $action, $record=null) { - $access = Utils_RecordBrowser_Access::create($tab, $action, $record); - - return $access->getRuleCrits(); - } - - public static function is_record_active($record) { - if (isset($record[':active']) && !$record[':active']) - return false; - - return true; - } - - public static function get_record_info($tab, $id) { - self::check_table_name($tab); - $created = DB::GetRow('SELECT created_on, created_by FROM '.$tab.'_data_1 WHERE id=%d', array($id)); - $edited = DB::GetRow('SELECT edited_on, edited_by FROM '.$tab.'_edit_history WHERE '.$tab.'_id=%d ORDER BY edited_on DESC', array($id)); - if (!isset($edited['edited_on'])) $edited['edited_on'] = null; - if (!isset($edited['edited_by'])) $edited['edited_by'] = null; - if (!isset($created['created_on'])) trigger_error('There is no such record as '.$id.' in table '.$tab, E_USER_ERROR); - return array( 'created_on'=>$created['created_on'],'created_by'=>$created['created_by'], - 'edited_on'=>$edited['edited_on'],'edited_by'=>$edited['edited_by'], - 'id'=>$id); - } - public static function get_fav_button($tab, $id, $isfav = null) { - $tag_id = 'rb_fav_button_'.$tab.'_'.$id; - return ''.self::get_fav_button_tags($tab, $id, $isfav).''; - } - public static function get_fav_button_tags($tab, $id, $isfav = null) { - self::check_table_name($tab); - $star_on = Base_ThemeCommon::get_template_file('Utils_RecordBrowser','star_fav.png'); - $star_off = Base_ThemeCommon::get_template_file('Utils_RecordBrowser','star_nofav.png'); - load_js('modules/Utils/RecordBrowser/favorites.js'); - if ($isfav===null) $isfav = DB::GetOne('SELECT '.$tab.'_id FROM '.$tab.'_favorite WHERE user_id=%d AND '.$tab.'_id=%d', array(Acl::get_user(), $id)); - $tag_id = 'rb_fav_button_'.$tab.'_'.$id; - return ''.__('Click to remove it from your favorites'):__('Click to add this item to favorites'))).' onclick="utils_recordbrowser_set_favorite('.($isfav?0:1).',\''.$tab.'\','.$id.',\''.$tag_id.'\')" href="javascript:void(0);">'; - } - public static function set_favs($tab, $id, $state) { - self::check_table_name($tab); - if ($state) { - if (DB::GetOne('SELECT * FROM '.$tab.'_favorite WHERE user_id=%d AND '.$tab.'_id=%d', array(Acl::get_user(), $id))) return; - DB::Execute('INSERT INTO '.$tab.'_favorite (user_id, '.$tab.'_id) VALUES (%d, %d)', array(Acl::get_user(), $id)); - } else { - DB::Execute('DELETE FROM '.$tab.'_favorite WHERE user_id=%d AND '.$tab.'_id=%d', array(Acl::get_user(), $id)); - } - } - public static function get_html_record_info($tab, $id){ - if (is_string($id)) { - // to separate id in recurrent event - $tmp = explode('_', $id); - $id = $tmp[0]; - } - if (is_numeric($id)) $info = Utils_RecordBrowserCommon::get_record_info($tab, $id); - elseif (is_array($id)) $info = $id; - else trigger_error('Cannot decode record id: ' . print_r($id, true), E_USER_ERROR); - if (isset($info['id'])) $id = $info['id']; - - // If CRM Module is not installed get user login only - $created_by = Base_UserCommon::get_user_label($info['created_by']); - $htmlinfo=array( - __('Record ID').':'=>$id, - __('Created by').':'=>$created_by, - __('Created on').':'=>Base_RegionalSettingsCommon::time2reg($info['created_on']) - ); - if ($info['edited_on']!==null) { - $htmlinfo=$htmlinfo+array( - __('Edited by').':'=>$info['edited_by']!==null?Base_UserCommon::get_user_label($info['edited_by']):'', - __('Edited on').':'=>Base_RegionalSettingsCommon::time2reg($info['edited_on']) - ); - } - - return Utils_TooltipCommon::format_info_tooltip($htmlinfo); - } - public static function get_record($tab, $id, $htmlspecialchars=true) { - if (!is_numeric($id)) return null; - if (isset($id)) { - if(!self::check_table_name($tab,false,false)) return null; - self::init($tab); - $row = DB::GetRow('SELECT * FROM '.$tab.'_data_1 WHERE id=%d', array($id)); - $record = array('id'=>$id); - if (!isset($row['active'])) return null; - foreach(array('created_by','created_on') as $v) - $record[$v] = $row[$v]; - $record[':active'] = $row['active']; - foreach(self::$table_rows as $field=>$desc) { - if ($desc['type']==='multiselect' || $desc['type'] === 'file') { - if (!isset($row['f_'.$desc['id']])) $r = array(); - else $r = self::decode_multi($row['f_'.$desc['id']]); - $record[$desc['id']] = $r; - } else { - $record[$desc['id']] = (isset($row['f_'.$desc['id']])?$row['f_'.$desc['id']]:''); - if ($htmlspecialchars && $desc['type'] == 'text') $record[$desc['id']] = htmlspecialchars($record[$desc['id']]); - } - } - return $record; - } else { - return null; - } - } - - public static function get_record_respecting_access($tab, $id, $access_mode = 'view', $htmlspecialchars = true) - { - $record = self::get_record($tab, $id, $htmlspecialchars); - return self::filter_record_by_access($tab, $record, $access_mode); - } - - public static function filter_record_by_access($tab, $record, $access_mode = 'view') - { - if (!$record) { - return $record; - } - $access = self::get_access($tab, $access_mode, $record); - if (is_array($access)) { - foreach ($access as $field => $has_access) { - if (!$has_access) { - $record[$field] = null; - } - } - } else if (!$access) { - $record = false; - } - return $record; - } - - /** - * Change record state: active / inactive. Soft delete. - * - * @param $tab Recordset identifier - * @param $id Record ID - * @param $state Active / Inactive state - * - * @return bool True when status has been changed, false otherwise - */ - public static function set_active($tab, $id, $state) - { - self::check_table_name($tab); - $current = DB::GetOne('SELECT active FROM ' . $tab . '_data_1 WHERE id=%d', array($id)); - if ($current == ($state ? 1 : 0)) { - return false; - } - $record = self::get_record($tab, $id); - if (!$record) { - return false; - } - $values = self::record_processing($tab, $record, $state ? 'restore' : 'delete'); - if ($values === false) { - return false; - } - @DB::Execute('UPDATE ' . $tab . '_data_1 SET active=%d,indexed=0 WHERE id=%d', array($state ? 1 : 0, $id)); - $tab_prop = DB::GetRow('SELECT id,search_include FROM recordbrowser_table_properties WHERE tab=%s',array($tab)); - if ($tab_prop['search_include'] > 0) { - DB::Execute('DELETE FROM recordbrowser_search_index WHERE tab_id=%d AND record_id=%d',array($tab_prop['id'],$id)); - } - $edit_id = self::new_record_history($tab,$id,$state ? 'RESTORED' : 'DELETED'); - Utils_WatchdogCommon::new_event($tab, $id, ($state ? 'R' : 'D').'_'.$edit_id); - self::record_processing($tab, $record, $state ? 'restored' : 'deleted'); - return true; - } - - /** - * Delete record. - * - * @param string $tab Recordset identifier - * @param int $id Record ID - * @param bool $perma Delete permanently with all edit history - * - * @return bool True when record has been deleted, false otherwise - */ - public static function delete_record($tab, $id, $perma = false) - { - $ret = false; - if (!$perma) { - $ret = self::set_active($tab, $id, false); - } elseif (self::check_table_name($tab)) { - $record = self::get_record($tab, $id); - $values = self::record_processing($tab, $record, 'delete'); - if ($values === false) { - $ret = false; - } else { - self::delete_record_history($tab, $id); - self::delete_from_favorite($tab, $id); - self::delete_from_recent($tab, $id); - - DB::Execute('DELETE FROM ' . $tab . '_data_1 WHERE id=%d', array($id)); - $ret = DB::Affected_Rows() > 0; - if ($ret) { - self::record_processing($tab, $record, 'deleted'); - } - } - } - return $ret; - } - - /** - * Delete all history entries for specified record. - * - * @param $tab Recordset identifier - * @param $id Record ID - * - * @return int Number of affected edits deleted - */ - public static function delete_record_history($tab, $id) - { - $sql = 'DELETE FROM ' . $tab . '_edit_history_data WHERE edit_id IN' . - ' (SELECT id FROM ' . $tab . '_edit_history WHERE ' . $tab . '_id = %d)'; - DB::Execute($sql, array($id)); - $sql = 'DELETE FROM ' . $tab . '_edit_history WHERE ' . $tab . '_id = %d'; - DB::Execute($sql, array($id)); - return DB::Affected_Rows(); - } - - /** - * Delete favorites entries for specified record. - * - * @param $tab Recordset identifier - * @param $id Record ID - * - * @return int Number of favorites entries deleted - */ - public static function delete_from_favorite($tab, $id) - { - $sql = 'DELETE FROM ' . $tab . '_favorite WHERE ' . $tab . '_id = %d'; - DB::Execute($sql, array($id)); - return DB::Affected_Rows(); - } - - /** - * Delete recent entries for specified record. - * - * @param $tab Recordset identifier - * @param $id Record ID - * - * @return int Number of recent entries deleted - */ - public static function delete_from_recent($tab, $id) - { - $sql = 'DELETE FROM ' . $tab . '_recent WHERE ' . $tab . '_id = %d'; - DB::Execute($sql, array($id)); - return DB::Affected_Rows(); - } - - /** - * Restore record. - * - * @param $tab Recordset identifier - * @param $id Record ID - * - * @return bool True when record has been restored, false otherwise - */ - public static function restore_record($tab, $id) { - return self::set_active($tab, $id, true); - } - public static function no_wrap($s) { - $content_no_wrap = $s; - preg_match_all('/>([^\<\>]*)'.$tab.' - '.$def_md5.' - '.$id.' - '.$check_defaults); -// print('
'); - if (isset($_REQUEST['__add_record_to_RB_table']) && - isset($_REQUEST['__add_record_id']) && - isset($_REQUEST['__add_record_def']) && - ($tab==$_REQUEST['__add_record_to_RB_table']) && - (!$check_defaults || $def_md5==$_REQUEST['__add_record_def']) && - ($id==$_REQUEST['__add_record_id'])) { - unset($_REQUEST['__add_record_to_RB_table']); - unset($_REQUEST['__add_record_id']); - unset($_REQUEST['__add_record_def']); - Base_BoxCommon::push_module(Utils_RecordBrowser::module_name(),'view_entry',array('add', null, $def), array($tab)); - return array(); - } - return array('__add_record_to_RB_table'=>$tab, '__add_record_id'=>$id, '__add_record_def'=>$def_md5); - } - public static function create_new_record_href($tab, $def, $id='none', $check_defaults=true, $multiple_defaults=false){ - if($multiple_defaults) { - static $done = false; - if($done) return Libs_LeightboxCommon::get_open_href('actionbar_rb_new_record'); - eval_js_once('actionbar_rb_new_record_deactivate = function(){leightbox_deactivate(\'actionbar_rb_new_record\');}'); - $th = Base_ThemeCommon::init_smarty(); - $cds = array(); - foreach ($def as $k=>$v) { - $cds[] = array( 'label'=>_V($k), - 'open'=>'', - 'icon'=>$v['icon'], - 'close'=>'' - ); - } - $th->assign('custom_defaults', $cds); - ob_start(); - Base_ThemeCommon::display_smarty($th,'Utils_RecordBrowser','new_record_leightbox'); - $panel = ob_get_clean(); - Libs_LeightboxCommon::display('actionbar_rb_new_record',$panel,__('New record')); - $done = true; - return Libs_LeightboxCommon::get_open_href('actionbar_rb_new_record'); - } else - return Module::create_href(self::get_new_record_href($tab,$def, $id, $check_defaults)); - } - public static function get_record_href_array($tab, $id, $action='view'){ - self::check_table_name($tab); - if (isset($_REQUEST['__jump_to_RB_table']) && - ($tab==$_REQUEST['__jump_to_RB_table']) && - ($id==$_REQUEST['__jump_to_RB_record']) && - ($action==$_REQUEST['__jump_to_RB_action'])) { - unset($_REQUEST['__jump_to_RB_record']); - unset($_REQUEST['__jump_to_RB_table']); - unset($_REQUEST['__jump_to_RB_action']); - Base_BoxCommon::push_module(Utils_RecordBrowser::module_name(),'view_entry_with_REQUEST',array($action, $id, array(), true, $_REQUEST),array($tab)); - return array(); - } - return array('__jump_to_RB_table'=>$tab, '__jump_to_RB_record'=>$id, '__jump_to_RB_action'=>$action); - } - public static function create_record_href($tab, $id, $action='view',$more=array()){ - if(MOBILE_DEVICE) { - $cap = DB::GetOne('SELECT caption FROM recordbrowser_table_properties WHERE tab=%s',array($tab)); - return mobile_stack_href(array('Utils_RecordBrowserCommon','mobile_rb_view'),array($tab,$id),$cap); - } - return Module::create_href(self::get_record_href_array($tab,$id,$action)+$more); - } - public static function record_link_open_tag_r($tab, $record, $nolink=false, $action='view', $more=array()) - { - self::check_table_name($tab); - $ret = ''; - if (!isset($record['id']) || !is_numeric($record['id'])) { - return self::$del_or_a = ''; - } - if (class_exists('Utils_RecordBrowser') && - isset(Utils_RecordBrowser::$access_override) && - Utils_RecordBrowser::$access_override['tab']==$tab && - Utils_RecordBrowser::$access_override['id']==$record['id']) { - self::$del_or_a = ''; - if (!$nolink) $ret = ''; - else self::$del_or_a = ''; - } else { - $ret = ''; - $tip = ''; - self::$del_or_a = ''; - $has_access = self::get_access($tab, 'view', $record); - - if (!self::is_record_active($record)) { - $tip = __('This record was deleted from the system, please edit current record or contact system administrator'); - $ret = ''; - self::$del_or_a = ''; - } - if (!$has_access) { - $tip .= ($tip?'
':'').__('You don\'t have permission to view this record.'); - } - $tip = $tip ? Utils_TooltipCommon::open_tag_attrs($tip) : ''; - if (!$nolink) { - if($has_access) { - $href = self::create_record_href($tab, $record['id'], $action, $more); - $ret = '
'.$ret; - self::$del_or_a .= ''; - } else { - $ret = ''.$ret; - self::$del_or_a .= ''; - } - } - } - return $ret; - } - - public static function record_link_open_tag($tab, $id, $nolink=false, $action='view', $more=array()){ - self::check_table_name($tab); - $ret = ''; - if (!is_numeric($id)) { - return self::$del_or_a = ''; - } - if (class_exists('Utils_RecordBrowser') && - isset(Utils_RecordBrowser::$access_override) && - Utils_RecordBrowser::$access_override['tab']==$tab && - Utils_RecordBrowser::$access_override['id']==$id) { - self::$del_or_a = ''; - if (!$nolink) $ret = ''; - else self::$del_or_a = ''; - } else { - $record = self::get_record($tab, $id); - $ret = self::record_link_open_tag_r($tab, $record, $nolink, $action, $more); - } - return $ret; - } - public static function record_link_close_tag(){ - return self::$del_or_a; - } - public static function create_linked_label($tab, $cols, $id, $nolink=false, $tooltip=false, $more=array()){ - if (!is_numeric($id)) return ''; - if (!is_array($cols)) - $cols = explode('|', $cols); - - $record = self::get_record($tab, $id); - $fields = array_map(array('Utils_RecordBrowserCommon', 'get_field_id'), $cols); - $record_vals = self::get_record_vals($tab, $record, true, $fields, false); - if (empty($record_vals)) return ''; - - $vals = array(); - foreach ($fields as $field) { - if (empty($record_vals[$field])) break; - $vals[] = $record_vals[$field]; - } - $record_label = implode(' ', $vals); - if (!$record_label) $record_label = self::get_caption($tab) . ": " . sprintf("#%06d", $id); - $text = self::create_record_tooltip($record_label, $tab, $id, $nolink, $tooltip); - - return self::record_link_open_tag_r($tab, $record, $nolink, 'view', $more) . - $text . self::record_link_close_tag(); - } - public static function create_linked_text($text, $tab, $id, $nolink=false, $tooltip=true, $more=array()){ - if ($nolink) return $text; - - if (!is_numeric($id)) return ''; - - $text = self::create_record_tooltip($text, $tab, $id, $nolink, $tooltip); - - return self::record_link_open_tag($tab, $id, $nolink, 'view', $more) . - $text . self::record_link_close_tag(); - } - public static function create_record_tooltip($text, $tab, $id, $nolink=false, $tooltip=true){ - if (!$tooltip || $nolink || Utils_TooltipCommon::is_tooltip_code_in_str($text)) - return $text; - - if (!is_array($tooltip)) - return self::create_default_record_tooltip_ajax($text, $tab, $id); - - //args name => expected index (in case of numeric indexed array) - $tooltip_create_args = array('tip'=>0, 'args'=>1, 'help'=>1, 'max_width'=>2); - - foreach ($tooltip_create_args as $name=>&$key) { - switch (true) { - case isset($tooltip[$name]): - $key = $tooltip[$name]; - break; - case isset($tooltip[$key]): - $key = $tooltip[$key]; - break; - default: - $key = null; - break; - } - } - - if (is_callable($tooltip_create_args['tip'])) { - unset($tooltip_create_args['help']); - - if (!is_array($tooltip_create_args['args'])) - $tooltip_create_args['args'] = array($tooltip_create_args['args']); - - $tooltip_create_callback = array('Utils_TooltipCommon', 'ajax_create'); - } - else { - unset($tooltip_create_args['args']); - $tooltip_create_callback = array('Utils_TooltipCommon', 'create'); - } - - array_unshift($tooltip_create_args, $text); - - //remove null values from end of the create_tooltip_args to ensure default argument values are set in the callback - while (is_null(end($tooltip_create_args))) - array_pop($tooltip_create_args); - - return call_user_func_array($tooltip_create_callback, $tooltip_create_args); - } - public static function get_record_vals($tab, $record, $nolink=false, $fields = array(), $silent = true){ - if (is_numeric($record)) $record = self::get_record($tab, $record); - if (!is_array($record)) return array(); - - self::init($tab); - if (empty($fields)) { - $fields = array_keys(self::$hash); - } - else { - $available_fields = array_intersect(array_keys(self::$hash), $fields); - - if (!$silent && count($available_fields) != count($fields)) { - trigger_error('Unknown field names: ' . implode(', ', array_diff($fields, $available_fields)), E_USER_ERROR); - } - - $fields = $available_fields; - } - - $ret = array(); - foreach ($fields as $field) { - if (!isset($record[$field])) break; - - $ret[$field] = self::get_val($tab, $field, $record, $nolink); - } - return $ret; - } - public static function create_default_linked_label($tab, $id, $nolink=false, $table_name=true, $detailed_tooltip = true){ - if (!is_numeric($id)) return ''; - $record = self::get_record($tab,$id); - if(!$record) return ''; - $description_callback = self::get_description_callback($tab); - $description_fields = self::get_description_fields($tab); - $access = self::get_access($tab, 'view', $record); - - $tab_caption = self::get_caption($tab); - if(!$tab_caption || $tab_caption == '---') $tab_caption = $tab; - - $label = ''; - if ($access) { - if ($description_fields) { - $put_space_before = false; - foreach ($description_fields as $field) { - if ($field[0] === '"') { - $label .= trim($field, '"'); - $put_space_before = false; - } else { - $field_id = self::get_field_id($field); - if ($access === true || (array_key_exists($field_id, $access) && $access[$field_id])) { - $field_val = self::get_val($tab, $field, $record, true); - if ($field_val) { - if ($put_space_before) $label .= ' '; - $label .= $field_val; - $put_space_before = true; - } - } - } - } - } elseif ($description_callback) { - $label = call_user_func($description_callback, $record, $nolink); - } else { - $field = DB::GetOne('SELECT field FROM ' . $tab . '_field WHERE (type=\'autonumber\' OR ((type=\'text\' OR type=\'commondata\' OR type=\'integer\' OR type=\'date\') AND required=1)) AND visible=1 AND active=1 ORDER BY position'); - if ($field) { - $label = self::get_val($tab, $field, $record, $nolink); - } - } - } - if (!$label) { - $label = sprintf("%s: #%06d", $tab_caption, $id); - } else { - $label = ($table_name? $tab_caption . ': ': '') . $label; - } - - $ret = self::record_link_open_tag_r($tab, $record, $nolink) . $label . self::record_link_close_tag(); - if ($nolink == false && $detailed_tooltip) { - $ret = self::create_default_record_tooltip_ajax($ret, $tab, $id); - } - return $ret; - } - - public static function create_default_record_tooltip_ajax($string, $tab, $id, $force = false) - { - if ($force == false && Utils_TooltipCommon::is_tooltip_code_in_str($string)) { - return $string; - } - $string = Utils_TooltipCommon::ajax_create($string, array(__CLASS__, 'default_record_tooltip'), array($tab, $id)); - return $string; - } - - public static function get_record_tooltip_data($tab, $record_id) - { - $record = self::get_record($tab, $record_id); - if (!$record[':active']) { - return array(); - } - $cols = self::init($tab); - $access = self::get_access($tab, 'view', $record); - $data = array(); - foreach ($cols as $desc) { - if ($desc['tooltip'] && $access[$desc['id']]) { - $data[_V($desc['name'])] = self::get_val($tab, $desc['id'], $record, true); - } - } - return $data; - } - public static function default_record_tooltip($tab, $record_id) - { - $data = self::get_record_tooltip_data($tab, $record_id); - return Utils_TooltipCommon::format_info_tooltip($data); - } - public static function display_linked_field_label($record, $nolink=false, $desc=null, $tab = ''){ - return Utils_RecordBrowserCommon::create_linked_label_r($tab, $desc['id'], $record, $nolink); - } - public static function create_linked_label_r($tab, $cols, $r, $nolink=false, $tooltip=false){ - if (!is_array($cols)) - $cols = array($cols); - $open_tag = self::record_link_open_tag_r($tab, $r, $nolink); - $close_tag = self::record_link_close_tag(); - self::init($tab); - $vals = array(); - foreach ($cols as $col) { - if (isset(self::$table_rows[$col])) - $col = self::$table_rows[$col]['id']; - elseif (!isset(self::$hash[$col])) - trigger_error('Unknown column name: ' . $col, E_USER_ERROR); - if ($r[$col]) - $vals[] = $r[$col]; - } - $text = self::create_record_tooltip(implode(' ', $vals), $tab, $r['id'], $nolink, $tooltip); - - return $open_tag . $text . $close_tag; - } - public static function record_bbcode($tab, $fields, $text, $record_id, $opt, $tag = null) { - if (!is_numeric($record_id)) { - $parts = explode(' ', $text); - $crits = array(); - foreach ($parts as $k=>$v) { - $v = "%$v%"; - $chr = '('; - foreach ($fields as $f) { - $crits[$chr.str_repeat('_', $k).$f] = $v; - $chr='|'; - } - } - $rec = Utils_RecordBrowserCommon::get_records($tab, $crits, array(), array(), 1); - if (is_array($rec) && !empty($rec)) $rec = array_shift($rec); - else { - $crits = array(); - foreach ($parts as $k=>$v) { - $v = "%$v%"; - $chr = '('; - foreach ($fields as $f) { - $crits[$chr.str_repeat('_', $k).'~'.$f] = $v; - $chr='|'; - } - } - $rec = Utils_RecordBrowserCommon::get_records($tab, $crits, array(), array(), 1); - if (is_array($rec)) $rec = array_shift($rec); - else $rec = null; - } - } else { - $rec = Utils_RecordBrowserCommon::get_record($tab, $record_id); - } - if ($opt) { - if (!$rec) return null; - $tag_param = $rec['id']; - if ($tag == 'rb') $tag_param = "$tab/$tag_param"; - return Utils_BBCodeCommon::create_bbcode(null, $tag_param, $text); - } - if ($rec) { - $access = self::get_access($tab, 'view', $rec); - if (!$access) { - $text = "[" . __('Link to record') . ']'; - } - if (!$text) { - if ($fields) { - return self::create_linked_label_r($tab, $fields, $rec); - } - return self::create_default_linked_label($tab, $rec['id']); - } - return Utils_RecordBrowserCommon::record_link_open_tag_r($tab, $rec).$text.Utils_RecordBrowserCommon::record_link_close_tag(); - } - $msg = __('Record not found'); - if ($tag == 'rb') { - if (!self::check_table_name($tab, false, false)) { - $msg = __('Recordset not found'); - } - return Utils_BBCodeCommon::create_bbcode($tag, "$tab/$record_id", $text, $msg); - } - return Utils_BBCodeCommon::create_bbcode($tag, $record_id, $text, $msg); - } - public static function applet_settings($some_more = array()) { - $some_more = array_merge($some_more,array( - array('label'=>__('Actions'),'name'=>'actions_header','type'=>'header'), - array('label'=>__('Info'),'name'=>'actions_info','type'=>'checkbox','default'=>true), - array('label'=>__('View'),'name'=>'actions_view','type'=>'checkbox','default'=>false), - array('label'=>__('Edit'),'name'=>'actions_edit','type'=>'checkbox','default'=>true), - array('label'=>__('Delete'),'name'=>'actions_delete','type'=>'checkbox','default'=>false), - array('label'=>__('View edit history'),'name'=>'actions_history','type'=>'checkbox','default'=>false), - )); - return $some_more; - } - - /** - * Returns older version of te record. - * - * @param RecordSet - name of the recordset - * @param Record ID - ID of the record - * @param Revision ID - RB will backtrace all edits on that record down-to and including edit with this ID - */ - public static function get_record_revision($tab, $id, $rev_id) { - self::init($tab); - $r = self::get_record($tab, $id); - $ret = DB::Execute('SELECT id, edited_on, edited_by FROM '.$tab.'_edit_history WHERE '.$tab.'_id=%d AND id>=%d ORDER BY edited_on DESC, id DESC',array($id, $rev_id)); - while ($row = $ret->FetchRow()) { - $changed = array(); - $ret2 = DB::Execute('SELECT * FROM '.$tab.'_edit_history_data WHERE edit_id=%d',array($row['id'])); - while($row2 = $ret2->FetchRow()) { - $k = $row2['field']; - $v = $row2['old_value']; - if ($k=='id') $r['active'] = ($v!='DELETED'); - else { - if (!isset(self::$hash[$k])) break; - $r[$k] = $v; - } - } - } - return $r; - } - - public static function get_edit_details($tab, $rid, $edit_id,$details=true) { - return self::get_edit_details_modify_record($tab, $rid, $edit_id,$details); - } - - public static function get_edit_details_modify_record($tab, $rid, $edit_id, $details=true) { - self::init($tab); - if (is_numeric($rid)) { - $prev_rev = DB::GetOne('SELECT MIN(id) FROM '.$tab.'_edit_history WHERE '.$tab.'_id=%d AND id>%d', array($rid, $edit_id)); - $r = self::get_record_revision($tab, $rid, $prev_rev); - } else $r = $rid; - $edit_info = DB::GetRow('SELECT * FROM '.$tab.'_edit_history WHERE id=%d',array($edit_id)); - $event_display = array('what'=>'Error, Invalid event: '.$edit_id); - if (!$edit_info) return $event_display; - - $event_display = array( - 'who'=>Base_UserCommon::get_user_label($edit_info['edited_by'], true), - 'when'=>Base_RegionalSettingsCommon::time2reg($edit_info['edited_on']), - 'what'=>array() - ); - $edit_details = DB::GetAssoc('SELECT field, old_value FROM '.$tab.'_edit_history_data WHERE edit_id=%d',array($edit_id)); - self::init($tab); // because get_user_label messes up - foreach ($r as $k=>$v) { - if (isset(self::$hash[$k]) && self::$table_rows[self::$hash[$k]]['type']=='multiselect') - $r[$k] = self::decode_multi($r[$k]); // We have to decode all fields, because access and some display relay on it, regardless which field changed - } - $r2 = $r; - foreach ($edit_details as $k=>$v) { - $k = self::get_field_id($k); // failsafe - if (!isset(self::$hash[$k])) break; - if (self::$table_rows[self::$hash[$k]]['type']=='multiselect') { - $v = $edit_details[$k] = self::decode_multi($v); - } - $r2[$k] = $v; - } - $access = self::get_access($tab,'view',$r); - $modifications_to_show = 0; - foreach ($edit_details as $k=>$v) { - if($k=='id') { - $modifications_to_show += 1; - if (!$details) break; // do not generate content when we dont want them - $event_display['what'] = _V($v); - break; - } - $k = self::get_field_id($k); // failsafe - if (!isset(self::$hash[$k])) break; - if (!$access[$k]) break; - $modifications_to_show += 1; - if (!$details) break; // do not generate content when we dont want them - self::init($tab); - $field = self::$hash[$k]; - $desc = self::$table_rows[$field]; - $event_display['what'][] = array( - _V($desc['name']), - self::get_val($tab, $field, $r2, true, $desc), - self::get_val($tab, $field, $r, true, $desc) - ); - } - if ($modifications_to_show) - return $event_display; - return null; - } - - public static function get_edit_details_label($tab, $rid, $edit_id,$details = true) { - $ret = self::watchdog_label($tab, '', $rid, array('E_'.$edit_id), '', $details); - return $ret['events']; - } - - public static function watchdog_label($tab, $cat, $rid, $events = array(), $label = null, $details = true) { - $ret = array('category'=>$cat); - if ($rid!==null) { - $r = self::get_record($tab, $rid); - if ($r===null) return null; - if (!self::get_access($tab, 'view', $r)) return null; - if (is_array($label) && is_callable($label)) { - $label = self::create_linked_text(call_user_func($label, $r, true), $tab, $rid); - } elseif ($label) { - $label = self::create_linked_label_r($tab, $label, $r, false, true); - } else { - $label = self::create_default_linked_label($tab, $rid, false, false); - } - - $ret['title'] = $label; - $ret['view_href'] = Utils_RecordBrowserCommon::create_record_href($tab, $rid); - $events_display = array(); - $events = array_reverse($events); - $other_events = array(); - $header = false; - foreach ($events as $v) { - if (count($events_display)>20) { - $other_events[__('And more...')] = 1; - break; - } - $param = explode('_', $v); - switch ($param[0]) { - case 'C': $what = 'Created'; - $event_display = array( - 'who'=> Base_UserCommon::get_user_label($r['created_by'], true), - 'when'=>Base_RegionalSettingsCommon::time2reg($r['created_on']), - 'what'=>_V($what) - ); - break; - case 'D': if (!isset($what)) $what = 'Deleted'; - case 'R': if (!isset($what)) $what = 'Restored'; - if(!isset($param[1])) { - $event_display = array( - 'who' => '', - 'when' => '', - 'what' => _V($what) - ); - break; - } - case 'E': $event_display = self::get_edit_details_modify_record($tab, $r['id'], $param[1] ,$details); - if (isset($event_display['what']) && !empty($event_display['what'])) $header = true; - break; - - case 'N': $event_display = false; - switch($param[1]) { - case '+': - $action = __('Note linked'); - break; - case '-': - $action = __('Note unlinked'); - break; - default: - if (!isset($other_events[$param[1]])) $other_events[$param[1]] = 0; - $other_events[$param[1]]++; - $event_display = null; - break; - } - if($event_display===false) { - $date = isset($param[3]) ? Base_RegionalSettingsCommon::time2reg($param[3]) : ''; - $who = isset($param[4]) ? Base_UserCommon::get_user_label($param[4], true) : ''; - $action .= ' - ' . self::create_default_linked_label('utils_attachment', $param[2]); - $event_display = array('what'=>$action, - 'who' => $who, - 'when' => $date); - } - break; - default: $event_display = array('what'=>_V($v)); - } - if ($event_display) $events_display[] = $event_display; - } - foreach ($other_events as $k=>$v) - $events_display[] = array('what'=>_V($k).($v>1?' ['.$v.']':'')); - - if ($events_display) { - $theme = Base_ThemeCommon::init_smarty(); - - if ($header) { - $theme->assign('header', array(__('Field'), __('Old value'), __('New value'))); - } - - $theme->assign('events', $events_display); - - $tpl = 'changes_list'; - if (Utils_WatchdogCommon::email_mode()) { - $record_data = self::get_record_tooltip_data($tab, $rid); - $theme->assign('record', $record_data); - $tpl = 'changes_list_email'; - } - ob_start(); - Base_ThemeCommon::display_smarty($theme,'Utils_RecordBrowser', $tpl); - $output = ob_get_clean(); - - $ret['events'] = $output; - } else { - // if we've generated empty events for certain record, then - // it's possible that some of the fields, that have changed, - // are hidden so we have to check if there are any other events - // If all events are the same and output is empty we can safely - // mark all as notified. - $all_events = Utils_WatchdogCommon::check_if_notified($tab, $rid); - if (count($all_events) == count($events)) { - Utils_WatchdogCommon::notified($tab, $rid); - } - $ret = null; - } - } - return $ret; - } - public static function get_tables($tab){ - return array( $tab.'_callback', - $tab.'_recent', - $tab.'_favorite', - $tab.'_edit_history_data', - $tab.'_edit_history', - $tab.'_field', - $tab.'_data_1'); - } - - public static function applet_new_record_button($tab, $defaults = array()) { - if (!self::get_access($tab, 'add')) return ''; - return ''; - } - - public static function get_calculated_id($tab, $field, $id) { - return $tab.'__'.$field.'___'.$id; - } - - public static function check_for_jump() { - if (isset($_REQUEST['__jump_to_RB_table']) && - isset($_REQUEST['__jump_to_RB_record'])) { - $tab = $_REQUEST['__jump_to_RB_table']; - $id = $_REQUEST['__jump_to_RB_record']; - $action = $_REQUEST['__jump_to_RB_action']; - if (!is_numeric($id)) return false; - Utils_RecordBrowserCommon::check_table_name($tab); - if (!self::get_access($tab,'browse')) return false; - if (!DB::GetOne('SELECT id FROM '.$tab.'_data_1 WHERE id=%d', $id)) return false; - unset($_REQUEST['__jump_to_RB_record']); - unset($_REQUEST['__jump_to_RB_table']); - unset($_REQUEST['__jump_to_RB_action']); - Base_BoxCommon::push_module(Utils_RecordBrowser::module_name(),'view_entry_with_REQUEST',array($action, $id, array(), true, $_REQUEST),array($tab)); - return true; - } - return false; - } - - public static function cut_string($str, $len, $tooltip=true, &$cut=null) { - return $str; - if ($len==-1) return $str; - $ret = ''; - $strings = explode('
',$str); - foreach ($strings as $str) { - if ($ret) $ret .= '
'; - $label = ''; - $i = 0; - $curr_len = 0; - $tags = array(); - $inside = 0; - preg_match_all('/./u', $str, $a); - $a = $a[0]; - $strlen = count($a); - while ($curr_len<=$len && $i<$strlen) { - if ($a[$i] == '&' && !$inside) { - $e = -1; - if (isset($a[$i+3]) && $a[$i+3]==';') $e = 3; - elseif (isset($a[$i+4]) && $a[$i+4]==';') $e = 4; - elseif (isset($a[$i+5]) && $a[$i+5]==';') $e = 5; - if ($e!=-1) { - $hsc = implode("", array_slice($a, $i, $e+1)); - if ($hsc==' ' || strlen(htmlspecialchars_decode($hsc))==1) { - $label .= implode("", array_slice($a, $i, $e)); - $i += $e; - $curr_len++; - } - } - } elseif ($a[$i] == '<' && !$inside) { - $inside = 1; - if (isset($a[$i+1]) && $a[$i+1] == '/') { - if (!empty($tags)) array_pop($tags); - } else { - $j = 1; - $next_tag = ''; - while ($i+$j<=$strlen && $a[$i+$j]!=' ' && $a[$i+$j]!='>' && $a[$i+$j]!='/') { - $next_tag .= $a[$i+$j]; - $j++; - } - $tags[] = $next_tag; - } - } elseif ($a[$i] == '"' && $inside==1) { - $inside = 2; - } elseif ($a[$i] == '"' && $inside==2) { - $inside = 1; - } elseif ($a[$i] == '>' && $inside==1) { - if ($i>0 && $a[$i-1] == '/') array_pop($tags); - $inside = 0; - } elseif (!$inside) { - $curr_len++; - } - $label .= $a[$i]; - $i++; - } - if ($i<$strlen) { - $cut = true; - $label .= '...'; - if ($tooltip) { - if (!strpos($str, 'Utils_Toltip__showTip(')) $label = ''.$label.''; - else $label = preg_replace('/Utils_Toltip__showTip\(\'(.*?)\'/', 'Utils_Toltip__showTip(\''.escapeJS(htmlspecialchars($str)).'
$1\'', $label); - } - } - while (!empty($tags)) $label .= ''; - $ret .= $label; - } - return $ret; - } - - public static function build_cols_array($tab, $arg) { - self::init($tab); - $arg = array_flip($arg); - $ret = array(); - foreach (self::$table_rows as $desc) { - if ($desc['visible'] && !isset($arg[$desc['id']])) $ret[$desc['id']] = false; - elseif (!$desc['visible'] && isset($arg[$desc['id']])) $ret[$desc['id']] = true; - } - return $ret; - } - - public static function autoselect_label($tab_id, $args) { -// $args = array($tab, $tab_crits, $format_callback, $params); - - $param = self::decode_select_param($args[3]); - - $val = self::decode_record_token($tab_id, $param['single_tab']); - - if (!$val) return ''; - - list($tab, $record_id) = $val; - - if ($param['cols']) - return self::create_linked_label($tab, $param['cols'], $record_id, true); - else - return self::create_default_linked_label($tab, $record_id, true, false); - } - - private static $automulti_order_tabs; - public static function automulti_order_by($a,$b) { - $aa = _V($a); - $bb = _V($b); - $aam = preg_match(self::$automulti_order_tabs,$aa) || preg_match(self::$automulti_order_tabs,$a); - $bbm = preg_match(self::$automulti_order_tabs,$bb) || preg_match(self::$automulti_order_tabs,$b); - if($aam && !$bbm) - return -1; - if($bbm && !$aam) - return 1; - return strcasecmp($aa,$bb); - } - - public static function automulti_suggestbox($str, $tab, $tab_crits, $f_callback, $param) { - $param = self::decode_select_param($param); - - $words = array_filter(explode(' ',$str)); - $words_db = $words; - self::$automulti_order_tabs = array(); - foreach($words_db as & $w) { - if(mb_strlen($w)>=3) self::$automulti_order_tabs[] = preg_quote($w,'/'); - $w = "%$w%"; - } - self::$automulti_order_tabs = '/('.implode('|',self::$automulti_order_tabs).')/i'; - - $tabs = $param['select_tabs']; - foreach($tabs as & $t) $t = DB::qstr($t); - $tabs = DB::GetAssoc('SELECT tab,caption FROM recordbrowser_table_properties WHERE tab IN ('.implode(',',$tabs).')'); - - $single_tab = $param['single_tab']; - - uasort($tabs,array('Utils_RecordBrowserCommon','automulti_order_by')); - - $ret = array(); - - //backward compatibility - if ($single_tab) { - if (is_array($tab_crits) && !isset($tab_crits[$single_tab])) $tab_crits = array($single_tab=>$tab_crits); - } - foreach($tabs as $t=>$caption) { - if(!empty($tab_crits) && !isset($tab_crits[$t])) break; - - $access_crits = self::get_access_crits($t, 'selection'); - if ($access_crits===false) break; - if ($access_crits!==true && (is_array($access_crits) || $access_crits instanceof Utils_RecordBrowser_CritsInterface)) { - if((is_array($tab_crits[$t]) && $tab_crits[$t]) || $tab_crits[$t] instanceof Utils_RecordBrowser_CritsInterface) - $tab_crits[$t] = self::merge_crits($tab_crits[$t], $access_crits); - else - $tab_crits[$t] = $access_crits; - } - - $fields = $param['cols']; - if(!$fields) $fields = DB::GetCol("SELECT field FROM {$t}_field WHERE active=1 AND visible=1 AND (type NOT IN ('calculated','page_split','hidden') OR (type='calculated' AND param is not null AND param!=''))"); - - $words_db_tmp = $words_db; - $words_tmp = $words; - if (!$single_tab) { - foreach ($words_tmp as $pos => $word) { - $expr = '/' . preg_quote($word, '/') . '/i'; - if (preg_match($expr, $caption) || preg_match($expr, _V($caption))) { - unset($words_db_tmp[$pos]); - unset($words_tmp[$pos]); - } - } - } - $str_db = '%' . implode(' ', $words_tmp) . '%'; - - $crits2A = array(); - $crits2B = array(); - $order = array(); - foreach ($fields as $f) { - $field_id = self::get_field_id($f); - $crits2A = self::merge_crits($crits2A, array('~' . $field_id => $str_db), true); - $crits2B = self::merge_crits($crits2B, array('~' . $field_id => $words_db_tmp), true); - $order[$field_id] = 'ASC'; - } - $crits3A = self::merge_crits(isset($tab_crits[$t])?$tab_crits[$t]:array(),$crits2A); - $crits3B = self::merge_crits(isset($tab_crits[$t])?$tab_crits[$t]:array(),$crits2B); - - $records = self::get_records($t, $crits3A, array(), $order, 10); - - foreach ($records as $r) { - if(!self::get_access($t,'view',$r)) break; - $ret[($single_tab?'':$t.'/').$r['id']] = self::call_select_item_format_callback($f_callback, $t.'/'.$r['id'], array($tab, $crits3A, $f_callback, $param)); - } - - $records = self::get_records($t, $crits3B, array(), $order, 10); - - foreach ($records as $r) { - if(isset($ret[($single_tab?'':$t.'/').$r['id']]) || - !self::get_access($t,'view',$r)) break; - $ret[($single_tab?'':$t.'/').$r['id']] = self::call_select_item_format_callback($f_callback, $t.'/'.$r['id'], array($tab, $crits3B, $f_callback, $param)); - } - - if(count($ret)>=10) break; - } - return $ret; - } - -/** - * Function to manipulate clipboard pattern - * @param string $tab recordbrowser table name - * @param string|null $pattern pattern, or when it's null the pattern stays the same, only enable state changes - * @param bool $enabled new enabled state of clipboard pattern - * @param bool $force make it true to allow any changes or overwrite when clipboard pattern exist - * @return bool true if any changes were made, false otherwise - */ - public static function set_clipboard_pattern($tab, $pattern, $enabled = true, $force = false) { - $ret = null; - $enabled = $enabled ? 1 : 0; - $r = self::get_clipboard_pattern($tab, true); - /* when pattern exists and i can overwrite it... */ - if($r && $force) { - /* just change enabled state, when pattern is null */ - if($pattern === null) { - $ret = DB::Execute('UPDATE recordbrowser_clipboard_pattern SET enabled=%d WHERE tab=%s',array($enabled,$tab)); - } else { - /* delete if it's not necessary to hold any value */ - if($enabled == 0 && strlen($pattern) == 0) $ret = DB::Execute('DELETE FROM recordbrowser_clipboard_pattern WHERE tab = %s', array($tab)); - /* or update values */ - else $ret = DB::Execute('UPDATE recordbrowser_clipboard_pattern SET pattern=%s,enabled=%d WHERE tab=%s',array($pattern,$enabled,$tab)); - } - } - /* there is no such pattern in database so create it*/ - if(!$r) { - $ret = DB::Execute('INSERT INTO recordbrowser_clipboard_pattern values (%s,%s,%d)',array($tab, $pattern, $enabled)); - } - if($ret) return true; - return false; - } - -/** - * Returns clipboard pattern string only if it is enabled. If 'with_state' is true return value is associative array with pattern and enabled keys. - * @param string $tab name of RecordBrowser table - * @param bool $with_state return also state of pattern - * @return string|array string by default, array when with_state=true - */ - public static function get_clipboard_pattern($tab, $with_state = false) { - if($with_state) { - $ret = DB::GetArray('SELECT pattern,enabled FROM recordbrowser_clipboard_pattern WHERE tab=%s', array($tab)); - if(sizeof($ret)) return $ret[0]; - } - return DB::GetOne('SELECT pattern FROM recordbrowser_clipboard_pattern WHERE tab=%s AND enabled=1', array($tab)); - } - - public static function replace_clipboard_pattern($text, $data) { - /* some complicate preg match to find every occurence - * of %{ .. {f_name} .. } pattern - */ - $match = []; - if (preg_match_all('/%\{(([^%\}\{]*?\{[^%\}\{]+?\}[^%\}\{]*?)+?)\}/', $text, $match)) { // match for all patterns %{...{..}...} - foreach ($match[0] as $k => $matched_string) { - $text_replace = $match[1][$k]; - $changed = false; - $second_match = []; - while(preg_match('/\{(.+?)\}/', $text_replace, $second_match)) { // match for keys in braces {key} - $replace_value = ''; - if(array_key_exists($second_match[1], $data)) { - $replace_value = $data[$second_match[1]]; - $changed = true; - } - $text_replace = str_replace($second_match[0], $replace_value, $text_replace); - } - if(! $changed ) $text_replace = ''; - $text = str_replace($matched_string, $text_replace, $text); - } - } - - return $text; - } - - public static function get_field_tooltip($label) { - if(strpos($label,'Utils_Tooltip')!==false) return $label; - $args = func_get_args(); - array_shift($args); - return Utils_TooltipCommon::ajax_create($label, array('Utils_RecordBrowserCommon', 'ajax_get_field_tooltip'), $args); - } - - public static function ajax_get_field_tooltip() { - $args = func_get_args(); - $type = array_shift($args); - switch ($type) { - case 'autonumber': - case 'calculated': return __('This field is not editable'); - case 'integer': - case 'float': return __('Enter a numeric value in the text field'); - case 'checkbox': return __('Click to switch between checked/unchecked state'); - case 'currency': return __('Enter the amount in text field and select currency'); - case 'text': $ret = __('Enter the text in the text field'); - if (isset($args[0]) && is_numeric($args[0])) $ret .= '
'.__('Maximum allowed length is %s characters', array(''.$args[0].'')); - return $ret; - case 'long text': $example_text = __('Example text'); - return __('Enter the text in the text area').'
'.__('Maximum allowed length is %s characters', array('400')).'
'.'
'. - __('BBCodes are supported:').'
'. - '[b]'.$example_text.'[/b] - '.$example_text.''.'
'. - '[u]'.$example_text.'[/u] - '.$example_text.''.'
'. - '[i]'.$example_text.'[/i] - '.$example_text.''; - case 'date': return __('Enter the date in your selected format').'
'.__('Click on the text field to bring up a popup Calendar that allows you to pick the date').'
'.__('Click again on the text field to close popup Calendar'); - case 'timestamp': return __('Enter the date in your selected format and the time using select elements').'
'.__('Click on the text field to bring up a popup Calendar that allows you to pick the date').'
'.__('Click again on the text field to close popup Calendar').'
'.__('You can change 12/24-hour format in Control Panel, Regional Settings'); - case 'time': return __('Enter the time using select elements').'
'.__('You can change 12/24-hour format in Control Panel, Regional Settings'); - case 'commondata': $ret = __('Select value'); - if (isset($args[0])) $ret .= ' '.__('from %s table', array(''.str_replace('_', '/', $args[0]).'')); - return $ret; - case 'select': $ret = __('Select one'); - if (isset($args[0])) { - if (is_array($args[0])) { - $cap = array(); - foreach ($args[0] as $t) $cap[] = ''.self::get_caption($t).''; - $cap = implode(' '.__('or').' ',$cap); - } else $cap = ''.self::get_caption($args[0]).''; - $ret .= ' '.__('of').' '.$cap; - } - if (isset($args[1])) { - $val = self::crits_to_words($args[0], $args[1]); - if ($val) $ret .= ' '.__('for which').'
   '.$val; - } - return $ret; - case 'multiselect': $ret = __('Select multiple'); - if (isset($args[0])) { - if (is_array($args[0])) { - $cap = array(); - foreach ($args[0] as $t) $cap[] = ''.self::get_caption($t).''; - $cap = implode(' '.__('or').' ',$cap); - } else $cap = ''.self::get_caption($args[0]).''; - $ret .= ' '.$cap; - } - if (isset($args[1])) { - $val = self::crits_to_words($args[0], $args[1]); - if ($val) $ret .= ' '.__('for which').'
   '.$val; - } - return $ret; - } - return __('No additional information'); - } - - public static $date_values = array('-1 year'=>'1 year back','-6 months'=>'6 months back','-3 months'=>'3 months back','-2 months'=>'2 months back','-1 month'=>'1 month back','-2 weeks'=>'2 weeks back','-1 week'=>'1 week back','-6 days'=>'6 days back','-5 days'=>'5 days back','-4 days'=>'4 days back','-3 days'=>'3 days back','-2 days'=>'2 days back','-1 days'=>'1 days back','today'=>'current day','+1 days'=>'1 days forward','+2 days'=>'2 days forward','+3 days'=>'3 days forward','+4 days'=>'4 days forward','+5 days'=>'5 days forward','+6 days'=>'6 days forward','+1 week'=>'1 week forward','+2 weeks'=>'2 weeks forward','+1 month'=>'1 month forward','+2 months'=>'2 months forward','+3 months'=>'3 months forward','+6 months'=>'6 months forward','+1 year'=>'1 year forward'); - public static function crits_to_words($tab, $crits, $html_decoration=true) { - if (!is_object($crits)) { - $crits = Utils_RecordBrowser_Crits::from_array($crits); - } - $crits = $crits->replace_special_values(true); - $c2w = new Utils_RecordBrowser_CritsToWords($tab); - $c2w->enable_html_decoration($html_decoration); - return $c2w->to_words($crits); - } - - public static function get_printer($tab) - { - $class = DB::GetOne('SELECT printer FROM recordbrowser_table_properties WHERE tab=%s',$tab); - if($class && class_exists($class)) - return new $class(); - return new Utils_RecordBrowser_RecordPrinter(); - } - //////////////////////////// - // default QFfield callbacks - - public static function get_default_QFfield_callback($type) { - $types = array('hidden', 'checkbox', 'calculated', 'integer', 'float', - 'currency', 'text', 'long text', 'date', 'timestamp', 'time', - 'commondata', 'select', 'multiselect', 'autonumber', 'file'); - if (array_search($type, $types) !== false) { - return __CLASS__. '::QFfield_' . self::get_field_id($type); - } - return null; - } - - public static function QFfield_static_display(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if ($mode !== 'add' && $mode !== 'edit') { - if ($desc['type'] != 'checkbox' || isset($rb_obj->display_callback_table[$field])) { - $def = self::get_val($rb_obj->tab, $field, $rb_obj->record, false, $desc); - $form->addElement('static', $field, $label, $def, array('id' => $field)); - return true; - } - } - return false; - } - - public static function QFfield_hidden(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - $form->addElement('hidden', $field); - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_checkbox(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $el = $form->addElement('advcheckbox', $field, $label, '', array('id' => $field)); - $el->setValues(array('0','1')); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_calculated(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('static', $field, $label); - if (!is_array($rb_obj->record)) - $values = $rb_obj->custom_defaults; - else { - $values = $rb_obj->record; - if (is_array($rb_obj->custom_defaults)) - $values = $values + $rb_obj->custom_defaults; - } - $val = isset($values[$desc['id']]) ? - self::get_val($rb_obj->tab, $field, $values, true, $desc) - : ''; - if (!$val) - $val = '[' . __('formula') . ']'; - $record_id = isset($rb_obj->record['id']) ? $rb_obj->record['id'] : null; - $form->setDefaults(array($field => '
' . $val . '
')); - } - - public static function QFfield_integer(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('text', $field, $label, array('id' => $field)); - $form->addRule($field, __('Only integer numbers are allowed.'), 'regex', '/^\-?[0-9]*$/'); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_float(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('text', $field, $label, array('id' => $field)); - $form->addRule($field, __('Only numbers are allowed.'), 'numeric'); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_currency(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('currency', $field, $label, (isset($desc['param']) && is_array($desc['param']))?$desc['param']:array(), array('id' => $field)); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - // set element value to persist currency over soft submit - if ($form->isSubmitted() && $form->exportValue('submited') == false) { - $default = $form->exportValue($field); - $form->getElement($field)->setValue($default); - } - } - - public static function QFfield_text(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type'], $desc['param']); - $form->addElement('text', $field, $label, array('id' => $field, 'maxlength' => $desc['param'])); - $form->addRule($field, __('Maximum length for this field is %s characters.', array($desc['param'])), 'maxlength', $desc['param']); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_long_text(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('textarea', $field, $label, array('id' => $field)); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_date(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('datepicker', $field, $label, array('id' => $field)); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function timestamp_required($v) { - return $v['__datepicker'] !== '' && Base_RegionalSettingsCommon::reg2time($v['__datepicker'], false) !== false; - } - - public static function QFfield_timestamp(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $f_param = array('id' => $field); - if ($desc['param']) - $f_param['optionIncrement'] = array('i' => $desc['param']); - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('timestamp', $field, $label, $f_param); - static $rule_defined = false; - if (!$rule_defined) { - $form->registerRule('timestamp_required', 'callback', 'timestamp_required', __CLASS__); - $rule_defined = true; - } - if (isset($desc['required']) && $desc['required']) - $form->addRule($field, __('Field required'), 'timestamp_required'); - if ($mode !== 'add' && $default) - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_time(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $time_format = Base_RegionalSettingsCommon::time_12h() ? 'h:i a' : 'H:i'; - $lang_code = Base_LangCommon::get_lang_code(); - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $minute_increment = 5; - if ($desc['param']) { - $minute_increment = $desc['param']; - } - $form->addElement('timestamp', $field, $label, array('date' => false, 'format' => $time_format, 'optionIncrement' => array('i' => $minute_increment), 'language' => $lang_code, 'id' => $field)); - if ($mode !== 'add' && $default) - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_commondata(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $param = explode('::', $desc['param']['array_id']); - foreach ($param as $k => $v) - if ($k != 0) - $param[$k] = self::get_field_id($v); - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type'], $desc['param']['array_id']); - $form->addElement($desc['type'], $field, $label, $param, array('empty_option' => true, 'order' => $desc['param']['order']), array('id' => $field)); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_select(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $record = $rb_obj->record; - $comp = array(); - $param = self::decode_select_param($desc['param']); - $multi_adv_params = self::call_select_adv_params_callback($param['adv_params_callback'], $record); - $format_callback = $multi_adv_params['format_callback']; - $rec_count = 0; - if ($param['single_tab'] == '__COMMON__') { - if (empty($param['array_id'])) - trigger_error("Commondata array id not set for field: $field", E_USER_ERROR); - $data = Utils_CommonDataCommon::get_translated_tree($param['array_id'], $param['order']); - if (!is_array($data)) - $data = array(); - $comp = $comp + $data; - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, 'commondata', $param['array_id']); - } else { - $tab_crits = self::get_select_tab_crits($param, $record); - - $tabs = array_keys($tab_crits); - - foreach($tabs as $t) { - $rec_count += Utils_RecordBrowserCommon::get_records_count($t, $tab_crits[$t]); - - if ($rec_count > Utils_RecordBrowserCommon::$options_limit) break; - } - if ($rec_count <= Utils_RecordBrowserCommon::$options_limit) { - foreach($tabs as $t) { - $records = Utils_RecordBrowserCommon::get_records($t, $tab_crits[$t], array(), $multi_adv_params['order']); - foreach($records as $key=>$rec) { - if(!self::get_access($t,'view',$rec)) break; - $tab_id = ($param['single_tab']?'':$t.'/').$key; - $comp[$tab_id] = self::call_select_item_format_callback($multi_adv_params['format_callback'], $tab_id, array($rb_obj->tab, $tab_crits[$t], $multi_adv_params['format_callback'], $param)); - } - } - } - - if (isset($record[$field])) { - if (!is_array($record[$field])) { - if ($record[$field] != '') - $record[$field] = array($record[$field] => $record[$field]); - else - $record[$field] = array(); - } - } - if ($default) { - if (!is_array($default)) - $record[$field][$default] = $default; - else { - foreach ($default as $v) - $record[$field][$v] = $v; - } - } - if (isset($record[$field])) { - foreach ($record[$field] as $tab_id) { - if (isset($comp[$tab_id])) break; - $vals = self::decode_record_token($tab_id, $param['single_tab']); - if (!$vals) break; - list($t,$rid) = $vals; - if (!isset($tab_crits[$t])) break; - $comp[$tab_id] = self::call_select_item_format_callback($multi_adv_params['format_callback'], $tab_id, array($rb_obj->tab, $tab_crits[$t], $multi_adv_params['format_callback'], $param)); - } - } - if (empty($multi_adv_params['order'])) - natcasesort($comp); - - if($param['single_tab']) - $label = self::get_field_tooltip($label, $desc['type'], $param['single_tab'], $tab_crits[$param['single_tab']]); - } - if ($rec_count > Utils_RecordBrowserCommon::$options_limit) { - if ($desc['type'] == 'multiselect') { - $el = $form->addElement('automulti', $field, $label, array('Utils_RecordBrowserCommon', 'automulti_suggestbox'), array($rb_obj->tab, $tab_crits, $format_callback, $desc['param']), $format_callback); - if (method_exists($rb_obj, 'init_module')) { // fixes mobile edit issue - to be removed when mobile.php will be removed - ${'rp_' . $field} = $rb_obj->init_module(Utils_RecordBrowser_RecordPicker::module_name(), array()); - $filters_defaults = isset($multi_adv_params['filters_defaults']) ? $multi_adv_params['filters_defaults'] : array(); - $rb_obj->display_module(${'rp_' . $field}, array($tabs, $field, $format_callback, $param['crits_callback']?:$tab_crits, array(), array(), array(), $filters_defaults)); - $el->set_search_button('create_open_href() . ' ' . Utils_TooltipCommon::open_tag_attrs(__('Advanced Selection')) . ' href="javascript:void(0);">'); - } - } else - $el = $form->addElement('autoselect', $field, $label, $comp, array(array('Utils_RecordBrowserCommon', 'automulti_suggestbox'), array($rb_obj->tab, $tab_crits, $format_callback, $desc['param'])), $format_callback); - } else { - if ($desc['type'] === 'select') - $comp = array('' => '---') + $comp; - $form->addElement($desc['type'], $field, $label, $comp, array('id' => $field)); - } - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_multiselect(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - self::QFfield_select($form, $field, $label, $mode, $default, $desc, $rb_obj); - } - - public static function QFfield_autonumber(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $value = $default ? $default : self::format_autonumber_str($desc['param'], null); - $form->addElement('static', $field, $label); - $record_id = isset($rb_obj->record['id']) ? $rb_obj->record['id'] : null; - $field_id = Utils_RecordBrowserCommon::get_calculated_id($rb_obj->tab, $field, $record_id); - $val = '
' . $value . '
'; - $form->setDefaults(array($field => $val)); - } - - //region File - public static function display_file($r, $nolink=false, $desc=null, $tab=null) - { - $labels = []; - $inline_nodes = []; - $fileStorageIds = self::decode_multi($r[$desc['id']]); - $fileHandler = new Utils_RecordBrowser_FileActionHandler(); - foreach($fileStorageIds as $fileStorageId) { - if(!empty($fileStorageId)) { - $actions = $fileHandler->getActionUrlsRB($fileStorageId, $tab, $r['id'], $desc['id']); - $labels[]= Utils_FileStorageCommon::get_file_label($fileStorageId, $nolink, true, $actions); - if (!($desc['nopreview']?? false)) - $inline_nodes[]= Utils_FileStorageCommon::get_file_inline_node($fileStorageId, $actions, $desc['max-width']?? '200px'); - } - } - $inline_nodes = array_filter($inline_nodes); - - return implode('
', $labels) . ($inline_nodes? '
': '') . implode(' ', $inline_nodes); - } - - public static function QFfield_file(&$form, $field, $label, $mode, $default, $desc, $rb_obj) - { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - $record_id = isset($rb_obj->record['id']) ? $rb_obj->record['id'] : 'new'; - $module_id = md5($rb_obj->tab . '/' . $record_id . '/' . $field); - /** @var Utils_FileUpload_Dropzone $dropzoneField */ - $dropzoneField = Utils_RecordBrowser::$rb_obj->init_module('Utils_FileUpload#Dropzone', null, $module_id); - $default = self::decode_multi($default); - if ($default) { - $files = []; - foreach ($default as $filestorageId) { - $meta = Utils_FileStorageCommon::meta($filestorageId); - $arr = [ - 'filename' => $meta['filename'], - 'type' => $meta['type'], - 'size' => $meta['size'], - ]; - $backref = substr($meta['backref'], 0, 3) == 'rb:' ? explode('/', substr($meta['backref'], 3)) : []; - if (count($backref) === 3) { - list ($br_tab, $br_record, $br_field) = $backref; - $file_handler = new Utils_RecordBrowser_FileActionHandler(); - $actions = $file_handler->getActionUrlsRB($filestorageId, $br_tab, $br_record, $br_field); - if (isset($actions['preview'])) { - $arr['file'] = $actions['preview']; - } - } - $files[$filestorageId] = $arr; - } - $dropzoneField->set_defaults($files); - } - if (isset($desc['param']['max_files']) && $desc['param']['max_files'] !== false) { - $dropzoneField->set_max_files($desc['param']['max_files']); - } - if (isset($desc['param']['accepted_files']) && $desc['param']['accepted_files'] !== false) { - $dropzoneField->set_accepted_files($desc['param']['accepted_files']); - } - $dropzoneField->add_to_form($form, $field, $label); - } - //endregion - - public static function cron() { - return array('indexer' => 10); - } - - public static function index_record($tab,$record,$table_rows=null,$tab_id=null) { - if($tab_id===null) $tab_id = DB::GetOne('SELECT id FROM recordbrowser_table_properties WHERE tab=%s',array($tab)); - if($table_rows===null) $table_rows = self::init($tab); - - $record = self::record_processing($tab, $record, 'index'); - DB::StartTrans(); - if($record) { - DB::Execute('DELETE FROM recordbrowser_search_index WHERE tab_id=%d AND record_id=%d',array($tab_id,$record['id'])); - $cleanup_str = function($value) { - $decoded = html_entity_decode($value); - $added_spaces = str_replace('<', ' <', $decoded); - $stripped = strip_tags($added_spaces); - $removed_spaces = preg_replace('/[ ]+/', ' ', $stripped); - return mb_strtolower(trim($removed_spaces)); - }; - $insert_vals = array(); - foreach($table_rows as $field_info) { - $field = $field_info['id']; - if(!isset($record[$field])) break; - ob_start(); - $text = self::get_val($tab,$field,$record, true); - ob_end_clean(); - $text = $cleanup_str($text); - if ($text) { - $insert_vals[] = $tab_id; - $insert_vals[] = $record['id']; - $insert_vals[] = $field_info['pkey']; - $insert_vals[] = $text; - } - } - $insert_query = implode(',', array_fill(0, count($insert_vals) / 4, '(%d, %d, %d, %s)')); - DB::Execute('INSERT INTO recordbrowser_search_index VALUES ' . $insert_query, $insert_vals); - } - DB::Execute('UPDATE '.$tab.'_data_1 SET indexed=1 WHERE id=%d',array($record['id'])); - DB::CompleteTrans(); - } - - public static function clear_search_index($tab) - { - $tab_id = DB::GetOne('SELECT id FROM recordbrowser_table_properties WHERE tab=%s',array($tab)); - if ($tab_id) { - DB::Execute('DELETE FROM recordbrowser_search_index WHERE tab_id=%d',array($tab_id)); - DB::Execute('UPDATE ' . $tab . '_data_1 SET indexed=0'); - return true; - } - return false; - } - - public static function indexer($limit=null,&$total=0) { - $limit_sum = 0; - $limit_file = DATA_DIR.'/Utils_RecordBrowser/limit'; - if(defined('RB_INDEXER_LIMIT_QUERIES')) { //limit queries per hour - $time = time(); - $limit_time = 0; - if(file_exists($limit_file)) { - $tmp = array_filter(explode("\n",file_get_contents($limit_file))); - $limit_time = array_shift($tmp); - if($limit_time>$time-3600) { - $limit_sum = array_sum($tmp); - if($limit_sum>RB_INDEXER_LIMIT_QUERIES) return; - } - } - if($limit_sum==0) - file_put_contents($limit_file,$time."\n", LOCK_EX); - } - - if(!$limit) $limit = defined('RB_INDEXER_LIMIT_RECORDS') ? RB_INDEXER_LIMIT_RECORDS : 300; - $tabs = DB::GetAssoc('SELECT id,tab FROM recordbrowser_table_properties WHERE search_include>0'); - foreach($tabs as $tab_id=>$tab) { - $lock = DATA_DIR.'/Utils_RecordBrowser/'.$tab_id.'.lock'; - if(file_exists($lock) && filemtime($lock)>time()-1200) break; - - $table_rows = self::init($tab); - self::$admin_filter = ' .indexed=0 AND .active=1 AND '; - $ret = self::get_records($tab,array(),array(),array(),$limit,true); - self::$admin_filter = ''; - - if(!$ret) break; - - register_shutdown_function(create_function('','@unlink("'.$lock.'");')); - if(file_exists($lock) && filemtime($lock)>time()-1200) break; - file_put_contents($lock,''); - - foreach($ret as $row) { - self::index_record($tab,$row,$table_rows,$tab_id); - - $total++; - if($total>=$limit) break; - if(defined('RB_INDEXER_LIMIT_QUERIES') && RB_INDEXER_LIMIT_QUERIES<$limit_sum+DB::GetQueriesQty()) break; - } - - @unlink($lock); - - if($total>=$limit) break; - if(defined('RB_INDEXER_LIMIT_QUERIES') && RB_INDEXER_LIMIT_QUERIES<$limit_sum+DB::GetQueriesQty()) break; - } - - if(defined('RB_INDEXER_LIMIT_QUERIES')) { - file_put_contents($limit_file,DB::GetQueriesQty()."\n",FILE_APPEND | LOCK_EX); - } - - } - - public static function search($search, $categories) - { - $x = new Utils_RecordBrowser_Search($categories); - $ret = $x->search_results($search); - return $ret; - } - - public static function search_categories() { - $tabs = DB::GetAssoc('SELECT t.id,t.tab,t.search_include FROM recordbrowser_table_properties t WHERE t.search_include>0 AND t.id IN (SELECT DISTINCT m.tab_id FROM recordbrowser_search_index m)'); - $ret = array(); - foreach($tabs as $tab_id=>$tab) { - $caption = self::get_caption($tab['tab']); - if(!$caption) break; - $ret[$tab_id] = array('caption'=>$caption,'checked'=>$tab['search_include']==1); - } - uasort($ret,create_function('$a,$b','return strnatcasecmp($a["caption"],$b["caption"]);')); - return $ret; - } - - /////////////////////////////////////////// - // mobile devices - - public static function mobile_rb($table,array $crits=array(),array $sort=array(),$info=array(),$defaults=array()) { - $_SESSION['rb_'.$table.'_defaults'] = $defaults; - require_once('modules/Utils/RecordBrowser/mobile.php'); - } - - public static function mobile_rb_view($tab,$id) { - if (Utils_RecordBrowserCommon::get_access($tab, 'browse')===false) { - print(__('You are not authorised to browse this data.')); - return; - } - self::add_recent_entry($tab, Acl::get_user() ,$id); - $rec = self::get_record($tab,$id); - - $access = Utils_RecordBrowserCommon::get_access($tab, 'view',$rec); - if (is_array($access)) - foreach ($access as $k=>$v) - if (!$v) $rec[$k] = ''; - - $cols = Utils_RecordBrowserCommon::init($tab); - if(IPHONE) { - print('
    '); - foreach($cols as $k=>$col) { - $val = Utils_RecordBrowserCommon::get_val($tab,$k,$rec,true,$col); - if($val==='') break; - print('
  • '._V($col['name']).': '.$val.'
  • '); // TRSL - } - print('
'); - } else { - foreach($cols as $k=>$col) { - $val = Utils_RecordBrowserCommon::get_val($tab,$k,$rec,true,$col); - if($val==='') break; - print(_V($col['name']).': '.$val.'
'); // TRSL - } - } - - if(Utils_RecordBrowserCommon::get_access($tab, 'edit', $rec)) - print(''.__('Edit').''.(IPHONE?'':'
')); - - if(Utils_RecordBrowserCommon::get_access($tab, 'delete', $rec)) - print(''.__('Delete').''.(IPHONE?'':'
')); - - } - - public static function mobile_rb_edit($tab,$id) { - if($id===false) - $rec = array(); - else - $rec = self::get_record($tab,$id); - $cols = Utils_RecordBrowserCommon::init($tab); - - $defaults = array(); - if($id===false) { - $mode = 'add'; - $access = array(); - $defaults = self::record_processing($tab, $defaults, 'adding'); - } else { - $mode = 'edit'; - $access = Utils_RecordBrowserCommon::get_access($tab, 'view',$rec); - if (is_array($access)) - foreach ($access as $k=>$v) - if (!$v) unset($rec[$k]); - $defaults = $rec = self::record_processing($tab, $rec, 'editing'); - } - - $QFfield_callback_table = array(); - $ret = DB::Execute('SELECT * FROM '.$tab.'_callback WHERE freezed=0'); - while ($row = $ret->FetchRow()) { - $QFfield_callback_table[$row['field']] = $row['callback']; - } - $defaults = array_merge($defaults,$_SESSION['rb_'.$tab.'_defaults']); - - $qf = new HTML_QuickForm('rb_edit', 'post', 'mobile.php?'.http_build_query($_GET)); - foreach($cols as $field=>$args) { - if(isset($access[$args['id']]) && !$access[$args['id']]) break; - - if(isset($rec[$args['id']])) - $val = $rec[$args['id']]; - elseif(isset($defaults[$args['id']])) - $val = $defaults[$args['id']]; - else - $val = null; - $label = _V($args['name']); // TRSL - if(isset($QFfield_callback_table[$field])) { - $mobile_rb = new Utils_RecordBrowserMobile($tab, $rec); - self::call_QFfield_callback($QFfield_callback_table[$field], $qf, $args['id'], $label, $mode, $val, $args, $mobile_rb, null); - if($mode=='edit') - unset($defaults[$args['id']]); - break; - } - - switch ($args['type']) { - case 'calculated': - $qf->addElement('static', $args['id'], $label); - if (!is_array($rec)) - $values = $defaults; - else { - $values = $rec; - if (is_array($defaults)) $values = $values + $defaults; - } - if(!isset($values[$args['id']])) $values[$args['id']] = ''; - $val = Utils_RecordBrowserCommon::get_val($tab, $field, $values, true, $args); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'integer': - case 'float': - $qf->addElement('text', $args['id'], $label); - if ($args['type'] == 'integer') - $qf->addRule($args['id'], __('Only integer numbers are allowed.'), 'regex', '/^[0-9]*$/'); - else - $qf->addRule($args['id'], __('Only numbers are allowed.'), 'numeric'); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'checkbox': - $qf->addElement('checkbox', $args['id'], $label, ''); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'currency': - $qf->addElement('currency', $args['id'], $label); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'text': - $qf->addElement('text', $args['id'], $label, array('maxlength' => $args['param'])); - $qf->addRule($args['id'], __('Maximum length for this field is %s characters.', array($args['param'])), 'maxlength', $args['param']); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'long text': - $qf->addElement('textarea', $args['id'], $label, array('maxlength' => 200)); - $qf->addRule($args['id'], __('Maximum length for this field in mobile edition is 200 chars.'), 'maxlengt', 200); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'commondata': - $param = explode('::', $args['param']['array_id']); - foreach ($param as $k => $v) if ($k != 0) $param[$k] = self::get_field_id($v); - if (count($param) == 1) { - $qf->addElement($args['type'], $args['id'], $label, $param, array('empty_option' => true, 'id' => $args['id'], 'order' => $args['param']['order'])); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - } - break; - case 'select': $comp = array(); - $ref = explode(';',$args['param']); - if (isset($ref[1])) $crits_callback = $ref[1]; - else $crits_callback = null; - if (isset($ref[2])) $multi_adv_params = call_user_func(explode('::',$ref[2])); - else $multi_adv_params = null; - if (!isset($multi_adv_params) || !is_array($multi_adv_params)) $multi_adv_params = array(); - if (!isset($multi_adv_params['order'])) $multi_adv_params['order'] = array(); - if (!isset($multi_adv_params['cols'])) $multi_adv_params['cols'] = array(); - if (!isset($multi_adv_params['format_callback'])) $multi_adv_params['format_callback'] = array(); - $ref = $ref[0]; - @(list($tab2, $col) = explode('::',$ref)); - if (!isset($col)) trigger_error($field); - if($tab2=='__RECORDSETS__') break; //skip multi recordsets chained selector - if ($tab2=='__COMMON__') { - $data = Utils_CommonDataCommon::get_translated_tree($col); - if (!is_array($data)) $data = array(); - $comp = $comp+$data; - } else { - if (isset($crits_callback)) { - $crit_callback = explode('::',$crits_callback); - if (is_callable($crit_callback)) { - $crits = call_user_func($crit_callback, false, $rec); - $adv_crits = call_user_func($crit_callback, true, $rec); - } else $crits = $adv_crits = array(); - if ($adv_crits === $crits) $adv_crits = null; - if ($adv_crits !== null) { - break; //skip record picker - } - } else $crits = array(); - $col = explode('|',$col); - $col_id = array(); - foreach ($col as $c) $col_id[] = self::get_field_id($c); - $records = Utils_RecordBrowserCommon::get_records($tab2, $crits, empty($multi_adv_params['format_callback'])?$col_id:array(), !empty($multi_adv_params['order'])?$multi_adv_params['order']:array()); - $ext_rec = array(); - if (isset($rec[$args['id']])) { - if (!is_array($rec[$args['id']])) { - if ($rec[$args['id']]!='') $rec[$args['id']] = array($rec[$args['id']]=>$rec[$args['id']]); else $rec[$args['id']] = array(); - } - } - if (isset($defaults[$args['id']])) { - if (!is_array($defaults[$args['id']])) - $rec[$args['id']][$defaults[$args['id']]] = $defaults[$args['id']]; - else { - foreach ($defaults[$args['id']] as $v) - $rec[$args['id']][$v] = $v; - } - } - $single_column = (count($col_id)==1); - if (isset($rec[$args['id']])) { - $ext_rec = array_flip($rec[$args['id']]); - foreach($ext_rec as $k=>$v) { - $c = Utils_RecordBrowserCommon::get_record($tab2, $k); - if (!empty($multi_adv_params['format_callback'])) $n = call_user_func($multi_adv_params['format_callback'], $c); - else { - if ($single_column) $n = $c[$col_id[0]]; - else { - $n = array(); - foreach ($col_id as $cid) $n[] = $c[$cid]; - $n = implode(' ',$n); - } - } - $comp[$k] = $n; - } - } - if (!empty($multi_adv_params['order'])) natcasesort($comp); - foreach ($records as $k=>$v) { - if (!empty($multi_adv_params['format_callback'])) $n = call_user_func($multi_adv_params['format_callback'], $v); - else { -// $n = $v[$col_id]; - if ($single_column) $n = $v[$col_id[0]]; - else { - $n = array(); - foreach ($col_id as $cid) $n[] = $v[$cid]; - $n = implode(' ',$n); - } - } - $comp[$k] = $n; - unset($ext_rec[$v['id']]); - } - if (empty($multi_adv_params['order'])) natcasesort($comp); - } - if ($args['type']==='select') $comp = array(''=>'---')+$comp; - $qf->addElement($args['type'], $args['id'], $label, $comp, array('id'=>$args['id'])); - if($id!==false) - $qf->setDefaults(array($args['id']=>$rec[$args['id']])); - break; - case 'date': $qf->addElement('date',$args['id'],$label,array('format'=>'d M Y', 'minYear'=>date('Y')-95,'maxYear'=>date('Y')+5, 'addEmptyOption'=>true, 'emptyOptionText'=>'--')); - if ($val) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'timestamp': $qf->addElement('date',$args['id'],$label,array('format'=>'d M Y H:i', 'minYear'=>date('Y')-95,'maxYear'=>date('Y')+5, 'addEmptyOption'=>true, 'emptyOptionText'=>'--')); - if($val) { - $default = Base_RegionalSettingsCommon::time2reg($val, true, true, true, false); - $qf->setDefaults(array($args['id'] => $default)); - } - break; - case 'time': $qf->addElement('date',$args['id'],$label,array('format'=>'H:i', 'addEmptyOption'=>true, 'emptyOptionText'=>'--')); - if($val) { - $default = Base_RegionalSettingsCommon::time2reg($val, true, true, true, false); - $qf->setDefaults(array($args['id'] => $default)); - } - break; - case 'multiselect': //ignore - if($id===false) break; - $val = Utils_RecordBrowserCommon::get_val($tab,$field,$rec,true,$args); - if($val==='') break; - $qf->addElement('static',$args['id'],$label); - $qf->setDefaults(array($args['id']=>$val)); - unset($defaults[$args['id']]); - break; - } - if($args['required']) - $qf->addRule($args['id'],__('Field required'),'required'); - } - - $qf->addElement('submit', 'submit_button', __('Save'),IPHONE?'class="button white"':''); - - if($qf->validate()) { - $values = $qf->exportValues(); - foreach ($cols as $v) { - if ($v['type']=='checkbox' && !isset($values[$v['id']])) $values[$v['id']]=0; - elseif($v['type']=='date') { - if(is_array($values[$v['id']]) && $values[$v['id']]['Y']!=='' && $values[$v['id']]['M']!=='' && $values[$v['id']]['d']!=='') - $values[$v['id']] = sprintf("%d-%02d-%02d", $values[$v['id']]['Y'], $values[$v['id']]['M'], $values[$v['id']]['d']); - else - $values[$v['id']] = ''; - } elseif($v['type']=='timestamp') { - if($values[$v['id']]['Y']!=='' && $values[$v['id']]['M']!=='' && $values[$v['id']]['d']!=='' && $values[$v['id']]['H']!=='' && $values[$v['id']]['i']!=='') { - $timestamp = $values[$v['id']]['Y'] . '-' . $values[$v['id']]['M'] . '-' . $values[$v['id']]['d'] . ' ' . $values[$v['id']]['H'] . ':' . $values[$v['id']]['i']; - $values[$v['id']] = Base_RegionalSettingsCommon::reg2time($timestamp, true); - } else - $values[$v['id']] = ''; - } elseif($v['type']=='time') { - if($values[$v['id']]['H']!=='' && $values[$v['id']]['i']!=='') { - $time = recalculate_time(date('Y-m-d'), $values[$v['id']]); - $timestamp = Base_RegionalSettingsCommon::reg2time(date('1970-01-01 H:i:s', $time), true); - $values[$v['id']] = date('1970-01-01 H:i:s', $timestamp); - } else - $values[$v['id']] = ''; - } - } - foreach ($defaults as $k=>$v) - if (!isset($values[$k])) $values[$k] = $v; - if($id!==false) { - $values['id'] = $id; - Utils_RecordBrowserCommon::update_record($tab, $id, $values); - } else { - $id = Utils_RecordBrowserCommon::new_record($tab, $values); - } - return false; - } - - $renderer =& $qf->defaultRenderer(); - $qf->accept($renderer); - print($renderer->toHtml()); - } - - public static function mobile_rb_delete($tab, $id) { - if(!isset($_GET['del_ok'])) { - print(''.__('Cancel deletion').''); - print(''.__('Delete').''); - } else { - if($_GET['del_ok']) - Utils_RecordBrowserCommon::delete_record($tab, $id); - return 2; - return false; - } - return true; - } -} - -class Utils_RecordBrowserMobile { // mini class to simulate full RB object, TODO: consider passing tab and record as statics linked to RBCommon instead - public $tab; - public $record; - - public function __construct($tab, $record) { - $this->tab = $tab; - $this->record = $record; - } -} - -function rb_or($crits, $_ = null) -{ - $args = func_get_args(); - if (count($args) > 1) { - foreach ($args as $k => $v) { - if (is_array($v)) { - $args[$k] = new Utils_RecordBrowser_Crits($v, true); - } - } - $crits = $args; - } else { - $crits = $args[0]; - } - $ret = new Utils_RecordBrowser_Crits($crits, true); - return $ret; -} - -function rb_and($crits, $_ = null) -{ - $args = func_get_args(); - if (count($args) > 1) { - foreach ($args as $k => $v) { - if (is_array($v)) { - $args[$k] = new Utils_RecordBrowser_Crits($v); - } - } - $crits = $args; - } else { - $crits = $args[0]; - } - $ret = new Utils_RecordBrowser_Crits($crits); - return $ret; -} - -require_once 'modules/Utils/RecordBrowser/object_wrapper/include.php'; - -Utils_RecordBrowser_Crits::register_special_value_callback(array('Utils_RecordBrowserCommon', 'crits_special_values')); - -if(!READ_ONLY_SESSION) { - if(!isset($_SESSION['rb_indexer_token'])) - $_SESSION['rb_indexer_token'] = md5(microtime(true)); - load_js('modules/Utils/RecordBrowser/indexer.js'); - eval_js_once('rb_indexer("'.$_SESSION['rb_indexer_token'].'")'); -} -?> \ No newline at end of file diff --git a/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php.orig b/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php.orig deleted file mode 100644 index 3592b09e7..000000000 --- a/modules/Utils/RecordBrowser/RecordBrowserCommon_0.php.orig +++ /dev/null @@ -1,4127 +0,0 @@ - - * @copyright Copyright © 2008, Janusz Tylek - * @license MIT - * @version 1.0 - * @package epesi-utils - * @subpackage RecordBrowser - */ - -defined("_VALID_ACCESS") || die('Direct access forbidden'); - -class Utils_RecordBrowserCommon extends ModuleCommon { - private static $del_or_a = ''; - public static $admin_filter = ''; - public static $table_rows = array(); - public static $hash = array(); - public static $admin_access = false; - public static $cols_order = array(); - public static $options_limit = 50; - - public static $display_callback_table = array(); - private static $clear_get_val_cache = false; - public static function display_callback_cache($tab) { - if (self::$clear_get_val_cache) { - self::$clear_get_val_cache = false; - self::$display_callback_table = array(); - } - if($tab=='__RECORDSETS__' || preg_match('/,/',$tab)) return; - if (!isset(self::$display_callback_table[$tab])) { - $ret = DB::Execute('SELECT * FROM '.$tab.'_callback WHERE freezed=1'); - while ($row = $ret->FetchRow()) - self::$display_callback_table[$tab][$row['field']] = $row['callback']; - } - } - - public static function callback_check_function($callback, $only_check_syntax = false) - { - if (is_array($callback)) $callback = implode('::', $callback); - $func = null; - if (preg_match('/^([\\\\a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*)::([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$/', $callback, $match)) { - $func = array($match[1], $match[2]); - } elseif (preg_match('/^([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$/', $callback, $match)) { - $func = $match[1]; - } - if (is_callable($func, $only_check_syntax)) { - return $func; - } - return false; - } - - public static function call_display_callback($callback, $record, $links_not_recommended, $field, $tab) - { - $callback_func = self::callback_check_function($callback, true); - if ($callback_func) { - if (is_callable($callback_func)) { - $ret = call_user_func($callback_func, $record, $links_not_recommended, $field, $tab); - } else { - $callback_str = (is_array($callback_func) ? implode('::', $callback_func) : $callback_func); - trigger_error("Callback $callback_str for field: '$field[id]', recordset: '$tab' not found", E_USER_NOTICE); - $ret = $record[$field['id']]; - } - } else { - ob_start(); - $ret = eval($callback); - if($ret===false) trigger_error($callback,E_USER_ERROR); - else print($ret); - $ret = ob_get_contents(); - ob_end_clean(); - } - return $ret; - } - - public static function call_QFfield_callback($callback, &$form, $field, $label, $mode, $default, $desc, $rb_obj, $display_callback_table = null) - { - if ($display_callback_table === null) { - $display_callback_table = self::display_callback_cache($rb_obj->tab); - } - $callback_func = self::callback_check_function($callback, true); - if ($callback_func) { - if (is_callable($callback_func)) { - call_user_func_array($callback_func, array(&$form, $field, $label, $mode, $default, $desc, $rb_obj, $display_callback_table)); - } else { - $callback_str = (is_array($callback_func) ? implode('::', $callback_func) : $callback_func); - trigger_error("Callback $callback_str for field: '$field', recordset: '{$rb_obj->tab}' not found", E_USER_NOTICE); - } - } else { - eval($callback); - } - } - - public static function get_val($tab, $field, $record, $links_not_recommended = false, $desc = null) { - static $recurrence_call_stack = array(); - self::init($tab); - if (!isset(self::$table_rows[$field])) { - if (!isset(self::$hash[$field])) trigger_error('Unknown field "'.$field.'" for recordset "'.$tab.'"',E_USER_ERROR); - $field = self::$hash[$field]; - } - - $desc = array_merge(self::$table_rows[$field], $desc?: []); - if(!array_key_exists('id',$record)) $record['id'] = null; - if (!array_key_exists($desc['id'],$record)) trigger_error($desc['id'].' - unknown field for record '.serialize($record), E_USER_ERROR); - $val = $record[$desc['id']]; - $function_call_id = implode('|', array($tab, $field, serialize($val))); - if (isset($recurrence_call_stack[$function_call_id])) { - return '!! ' . __('recurrence issue') . ' !!'; - } else { - $recurrence_call_stack[$function_call_id] = true; - } - self::display_callback_cache($tab); - if (isset(self::$display_callback_table[$tab][$field])) { - $display_callback = self::$display_callback_table[$tab][$field]; - } else { - $display_callback = self::get_default_display_callback($desc['type']); - } - - if ($display_callback) { - $ret = self::call_display_callback($display_callback, $record, $links_not_recommended, $desc, $tab); - } else { - $ret = $val; - } - - unset($recurrence_call_stack[$function_call_id]); - return $ret; - } - - //////////////////////////// - // default display callbacks - - public static function get_default_display_callback($type) { - $types = array('select', 'multiselect', 'commondata', 'autonumber', 'currency', 'checkbox', - 'date', 'timestamp', 'time', 'long text', 'file'); - if (array_search($type, $types) !== false) { - return __CLASS__. '::display_' . self::get_field_id($type); - } - return null; - } - public static function display_select($record, $nolink=false, $desc=null, $tab=null) { - $ret = '---'; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $val = $record[$desc['id']]; - $commondata_sep = '/'; - if ((is_array($val) && empty($val))) return $ret; - - $param = self::decode_select_param($desc['param']); - - if(!$param['array_id'] && $param['single_tab'] == '__COMMON__') return; - - if (!is_array($val)) $val = array($val); - - $ret = ''; - foreach ($val as $v) { - $ret .= ($ret!=='')? '
': ''; - - if ($param['single_tab'] == '__COMMON__') { - $array_id = $param['array_id']; - $path = explode('/', $v); - $tooltip = ''; - $res = ''; - if (count($path) > 1) { - $res .= Utils_CommonDataCommon::get_value($array_id . '/' . $path[0], true); - if (count($path) > 2) { - $res .= $commondata_sep . '...'; - $tooltip = ''; - $full_path = $array_id; - foreach ($path as $w) { - $full_path .= '/' . $w; - $tooltip .= ($tooltip? $commondata_sep: '').Utils_CommonDataCommon::get_value($full_path, true); - } - } - $res .= $commondata_sep; - } - $label = Utils_CommonDataCommon::get_value($array_id . '/' . $v, true); - if (!$label) continue; - $res .= $label; - $res = self::no_wrap($res); - if ($tooltip) $res = '' . $res . ''; - } else { - $tab_id = self::decode_record_token($v, $param['single_tab']); - - if (!$tab_id) continue; - - list($select_tab, $id) = $tab_id; - - if ($param['cols']) { - $res = self::create_linked_label($select_tab, $param['cols'], $id, $nolink); - } else { - $res = self::create_default_linked_label($select_tab, $id, $nolink); - } - } - - $ret .= $res; - } - } - - return $ret; - } - public static function display_multiselect($record, $nolink=false, $desc=null, $tab=null) { - return self::display_select($record, $nolink, $desc, $tab); - } - public static function display_commondata($record, $nolink=false, $desc=null, $tab=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $arr = explode('::', $desc['param']['array_id']); - $path = array_shift($arr); - foreach($arr as $v) $path .= '/' . $record[self::get_field_id($v)]; - $path .= '/' . $record[$desc['id']]; - $ret = Utils_CommonDataCommon::get_value($path, true); - } - - return $ret; - } - public static function display_autonumber($record, $nolink=false, $desc=null, $tab=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = $record[$desc['id']]; - - if (!$nolink && isset($record['id']) && $record['id']) - $ret = self::record_link_open_tag_r($tab, $record) . $ret . self::record_link_close_tag(); - } - - return $ret; - } - public static function display_currency($record, $nolink=false, $desc=null, $tab=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $val = Utils_CurrencyFieldCommon::get_values($record[$desc['id']]); - $ret = Utils_CurrencyFieldCommon::format($val[0], $val[1]); - } - - return $ret; - } - public static function display_checkbox($record, $nolink=false, $desc=null, $tab=null) { - $ret = ''; - if (isset($desc['id']) && array_key_exists($desc['id'], $record)) { - $ret = $record[$desc['id']]? __('Yes'): __('No'); - } - - return $ret; - } - public static function display_checkbox_icon($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = '';; - } - - return $ret; - } - public static function display_checkbox_setting($record, $nolink=false, $desc=null, $tab=null) { - $img = self::display_checkbox_icon($record, $nolink, $desc); - - $rb_obj = Utils_RecordBrowser::$rb_obj; - - if (!$img || $nolink || !$desc || !($rb_obj instanceof Utils_RecordBrowser)) return $img; - - $href = $rb_obj->create_callback_href(array('Utils_RecordBrowserCommon', 'set_checkbox_setting'), array($tab, $record['id'], $desc['id'], $record[$desc['id']]?0:1)); - - $tooltip_attrs = Utils_TooltipCommon::open_tag_attrs(__('Click to toggle')); - - return "" . $img . ''; - } - public static function set_checkbox_setting($tab, $id, $field, $active=1) { - self::update_record($tab, $id, array($field=>$active)); - } - public static function display_date($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = Base_RegionalSettingsCommon::time2reg($record[$desc['id']], false, true, false); - } - - return $ret; - } - public static function display_timestamp($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = Base_RegionalSettingsCommon::time2reg($record[$desc['id']], 'without_seconds'); - } - - return $ret; - } - public static function display_time($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']])) { - $ret = $record[$desc['id']] !== '' && $record[$desc['id']] !== false - ? Base_RegionalSettingsCommon::time2reg($record[$desc['id']], 'without_seconds', false) - : '---'; - } - - return $ret; - } - public static function display_long_text($record, $nolink, $desc=null) { - $ret = ''; - if (isset($desc['id']) && isset($record[$desc['id']]) && $record[$desc['id']]!=='') { - $ret = self::format_long_text($record[$desc['id']]); - } - - return $ret; - } - public static function multiselect_from_common($arrid) { - return '__COMMON__::'.$arrid; - } - public static function format_long_text($text){ - $ret = htmlspecialchars($text); - $ret = str_replace("\n",'
',$ret); - $ret = Utils_BBCodeCommon::parse(htmlspecialchars_decode($ret)); - return $ret; - } - public static function encode_multi($v) { - if ($v==='') return ''; - if (is_array($v)) { - if (empty($v)) return ''; - } else $v = array($v); - return '__'.implode('__',$v).'__'; - } - public static function decode_multi($v) { - if ($v===null) return array(); - if(is_array($v)) return $v; - $v = explode('__',$v); - array_shift($v); - array_pop($v); - $ret = array(); - foreach ($v as $w) - $ret[$w] = $w; - return $ret; - } - public static function decode_commondata_param($param) { - $param = explode('__',$param); - if (isset($param[1])) { - $order = Utils_CommonDataCommon::validate_order($param[0]); - $array_id = $param[1]; - } else { - $order = 'value'; - $array_id = $param[0]; - } - return array('order'=>$order, 'order_by_key'=>$order, 'array_id'=>$array_id); - } - public static function encode_commondata_param($param) { - if (!is_array($param)) - $param = array($param); - - $order = 'value'; - if (isset($param['order']) || isset($param['order_by_key'])) { - $order = Utils_CommonDataCommon::validate_order(isset($param['order'])? $param['order']: $param['order_by_key']); - - unset($param['order']); - unset($param['order_by_key']); - } - - $array_id = implode('::', $param); - - return implode('__', array($order, $array_id)); - } - public static function decode_autonumber_param($param, &$prefix, &$pad_length, &$pad_mask) { - $parsed = explode('__', $param, 4); - if (!is_array($parsed) || count($parsed) != 3) - trigger_error("Not well formed autonumber parameter: $param", E_USER_ERROR); - list($prefix, $pad_length, $pad_mask) = $parsed; - } - public static function encode_autonumber_param($prefix, $pad_length, $pad_mask) { - return implode('__', array($prefix, $pad_length, $pad_mask)); - } - public static function format_autonumber_str($param, $id) { - self::decode_autonumber_param($param, $prefix, $pad_length, $pad_mask); - if ($id === null) - $pad_mask = '?'; - return $prefix . str_pad($id, $pad_length, $pad_mask, STR_PAD_LEFT); - } - public static function format_autonumber_str_all_records($tab, $field, $param) { - self::decode_autonumber_param($param, $prefix, $pad_length, $pad_mask); - $ids = DB::GetCol('SELECT id FROM '.$tab.'_data_1'); - DB::StartTrans(); - foreach ($ids as $id) { - $str = $prefix . str_pad($id, $pad_length, $pad_mask, STR_PAD_LEFT); - DB::Execute('UPDATE ' . $tab . '_data_1 SET indexed = 0, f_' . $field . '=%s WHERE id=%d', array($str, $id)); - } - DB::CompleteTrans(); - } - public static function decode_select_param($param) { - if (is_array($param)) return $param; - - $param = explode(';', $param); - $reference = explode('::', $param[0]); - $crits_callback = isset($param[1]) && $param[1] != '::' ? explode('::', $param[1]): null; - $adv_params_callback = isset($param[2]) && $param[2] != '::' ? explode('::', $param[2]): null; - - //in case RB records select - $select_tab = $reference[0]; - $cols = isset($reference[1]) ? array_filter(explode('|', $reference[1])) : null; - - //in case __COMMON__ - $array_id = isset($reference[1])? $reference[1]: null; - $order = isset($reference[2])? $reference[2]: 'value'; - - if ($select_tab == '__RECORDSETS__') { - $select_tabs = DB::GetCol('SELECT tab FROM recordbrowser_table_properties'); - $single_tab = false; - } - else { - $select_tabs = array_filter(explode(',',$select_tab)); - $single_tab = count($select_tabs)==1? $select_tab: false; - } - - return array( - 'single_tab'=>$single_tab? $select_tab: false, //returns single tab name, __COMMON__ or false - 'select_tabs'=>$select_tabs, //returns array of tab names - 'cols'=>$cols, // returns array of columns for formatting the display value (used in case RB records select) - 'array_id'=>$array_id, //returns array_id (used in case __COMMON__) - 'order'=>$order, //returns order code (used in case __COMMON__) - 'crits_callback'=>$crits_callback, //returns crits callback (used in case RB records select) - 'adv_params_callback'=>$adv_params_callback //returns adv_params_callback (used in case RB records select) - ); - } - - public static function decode_record_token($token, $single_tab=false) { - $kk = explode('/',$token); - if(count($kk)==1) { - if ($single_tab && is_numeric($kk[0])) { - $tab = $single_tab; - $record_id = $kk[0]; - } else return false; - } else { - $record_id = array_pop($kk); - $tab = $single_tab?$single_tab:$kk[0]; - if (!self::check_table_name($tab) || !is_numeric($record_id)) return false; - } - - return array('tab'=>$tab, 'id'=>$record_id, $tab, $record_id); - } - - public static function call_select_adv_params_callback($callback, $record=null) { - $ret = array( - 'order'=>array(), - 'cols'=>array(), - 'format_callback'=>array('Utils_RecordBrowserCommon', 'autoselect_label') - ); - - $adv_params = array(); - if (is_callable($callback)) - $adv_params = call_user_func($callback, $record); - - if (!is_array($adv_params)) - $adv_params = array(); - - return array_merge($ret, $adv_params); - } - - public static function get_select_tab_crits($param, $record=null) { - $param = self::decode_select_param($param); - - $ret = array(); - if (is_callable($param['crits_callback'])) - $ret = call_user_func($param['crits_callback'], false, $record); - - $tabs = $param['select_tabs']; - - $ret = !empty($ret)? $ret: array(); - if ($param['single_tab'] && (!is_array($ret) || !isset($ret[$param['single_tab']]))) { - $ret = array($param['single_tab'] => $ret); - } - elseif(is_array($ret) && !array_intersect($tabs, array_keys($ret))) { - $tab_crits = array(); - foreach($tabs as $tab) - $tab_crits[$tab] = $ret; - - $ret = $tab_crits; - } - - foreach ($ret as $tab=>$crits) { - if (!$tab || !self::check_table_name($tab, false, false)) { - unset($ret[$tab]); - continue; - } - $access_crits = self::get_access_crits($tab, 'selection'); - if ($access_crits===false) unset($ret[$tab]); - if ($access_crits===true) continue; - if (is_array($access_crits) || $access_crits instanceof Utils_RecordBrowser_CritsInterface) { - if((is_array($crits) && $crits) || $crits instanceof Utils_RecordBrowser_CritsInterface) - $ret[$tab] = self::merge_crits($crits, $access_crits); - else - $ret[$tab] = $access_crits; - } - } - - return $ret; - } - - public static function call_select_item_format_callback($callback, $tab_id, $args) { -// $args = array($tab, $tab_crits, $format_callback, $params); - - $param = self::decode_select_param($args[3]); - - $val = self::decode_record_token($tab_id, $param['single_tab']); - - if (!$val) return ''; - - list($tab, $record_id) = $val; - - $tab_caption = ''; - if (!$param['single_tab']) { - $tab_caption = self::get_caption($tab); - - $tab_caption = '[' . ((!$tab_caption || $tab_caption == '---')? $tab: $tab_caption) . '] '; - } - - $callback = is_callable($callback)? $callback: array('Utils_RecordBrowserCommon', 'autoselect_label'); - - return $tab_caption . call_user_func($callback, $tab_id, $args); - } - - public static function user_settings(){ - $ret = DB::Execute('SELECT tab, caption, icon, recent, favorites, full_history FROM recordbrowser_table_properties'); - $settings = array(0=>array(), 1=>array(), 2=>array(), 3=>array()); - while ($row = $ret->FetchRow()) { - $caption = _V($row['caption']); // ****** RecordBrowser - recordset caption - if (!self::get_access($row['tab'],'browse')) continue; - if ($row['favorites'] || $row['recent']) { - $options = array('all'=>__('All')); - if ($row['favorites']) $options['favorites'] = __('Favorites'); - if ($row['recent']) $options['recent'] = __('Recent'); - if (Utils_WatchdogCommon::category_exists($row['tab'])) $options['watchdog'] = __('Watched'); - $settings[0][] = array('name'=>$row['tab'].'_default_view','label'=>$caption,'type'=>'select','values'=>$options,'default'=>'all'); - } - if ($row['favorites']) - $settings[1][] = array('name'=>$row['tab'].'_auto_fav','label'=>$caption,'type'=>'select','values'=>array(__('Disabled'), __('Enabled')),'default'=>0); - if (Utils_WatchdogCommon::category_exists($row['tab'])) { - $settings[2][] = array('name'=>$row['tab'].'_auto_subs','label'=>$caption,'type'=>'select','values'=>array(__('Disabled'), __('Enabled')),'default'=>0); - } - $settings[0][] = array('name'=>$row['tab'].'_show_filters','label'=>'','type'=>'hidden','default'=>0); - } - $final_settings = array(); - $subscribe_settings = array(); - $final_settings[] = array('name'=>'add_in_table_shown','label'=>__('Quick new record - show by default'),'type'=>'checkbox','default'=>0); - $final_settings[] = array('name'=>'hide_empty','label'=>__('Hide empty fields'),'type'=>'checkbox','default'=>0); - $final_settings[] = array('name'=>'enable_autocomplete','label'=>__('Enable autocomplete in select/multiselect at'),'type'=>'select','default'=>50, 'values'=>array(0=>__('Always'), 20=>__('%s records', array(20)), 50=>__('%s records', array(50)), 100=>__('%s records', array(100)))); - $final_settings[] = array('name'=>'grid','label'=>__('Grid edit (experimental)'),'type'=>'checkbox','default'=>0); - $final_settings[] = array('name'=>'confirm_leave','label'=>__('Confirm before leave edit page'),'type'=>'checkbox','default'=>1); - $final_settings[] = array('name'=>'header_default_view','label'=>__('Default data view'),'type'=>'header'); - $final_settings = array_merge($final_settings,$settings[0]); - $final_settings[] = array('name'=>'header_auto_fav','label'=>__('Automatically add to favorites records created by me'),'type'=>'header'); - $final_settings = array_merge($final_settings,$settings[1]); - $final_settings[] = array('name'=>'header_auto_subscriptions','label'=>__('Automatically watch records created by me'),'type'=>'header'); - $final_settings = array_merge($final_settings,$settings[2]); - return array(__('Browsing records')=>$final_settings); - } - public static function check_table_name($tab, $flush=false, $failure_on_missing=true){ - static $tables = null; - if($tab=='__RECORDSETS__' || preg_match('/,/',$tab)) return true; - if ($tables===null || $flush) { - $r = DB::GetAll('SELECT tab FROM recordbrowser_table_properties'); - $tables = array(); - foreach($r as $v) - $tables[$v['tab']] = true; - } - if (!isset($tables[$tab]) && !$flush && $failure_on_missing) trigger_error('RecordBrowser critical failure, terminating. (Requested '.serialize($tab).', available '.print_r($tables, true).')', E_USER_ERROR); - return isset($tables[$tab]); - } - public static function get_value($tab, $id, $field) { - self::init($tab); - if (isset(self::$table_rows[$field])) $field = self::$table_rows[$field]['id']; - elseif (!isset(self::$hash[$field])) trigger_error('get_value(): Unknown column: '.$field, E_USER_ERROR); - $ret = DB::GetOne('SELECT f_'.$field.' FROM '.$tab.'_data_1 WHERE id=%d', array($id)); - if ($ret===false || $ret===null) return null; - return $ret; - } - public static function count_possible_values($tab, $field) { //it ignores empty values! - self::init($tab); - if (isset(self::$table_rows[$field])) $field = self::$table_rows[$field]['id']; - elseif (!isset(self::$hash[$field])) trigger_error('count_possible_values(): Unknown column: '.$field, E_USER_ERROR); - $par = self::build_query($tab, array('!'.$field=>'')); - return DB::GetOne('SELECT COUNT(DISTINCT(f_'.$field.')) FROM '.$par['sql'], $par['vals']); - } - public static function get_possible_values($tab, $field) { - self::init($tab); - if (isset(self::$table_rows[$field])) $field = self::$table_rows[$field]['id']; - elseif (!isset(self::$hash[$field])) trigger_error('get_possible_values(): Unknown column: '.$field, E_USER_ERROR); - $par = self::build_query($tab, array('!'.$field=>'')); - return DB::GetAssoc('SELECT MIN(id), MIN(f_'.$field.') FROM'.$par['sql'].' GROUP BY f_'.$field, $par['vals']); - } - public static function get_id($tab, $field, $value) { - self::init($tab); - $where = ''; - if (!is_array($field)) $field=array($field); - if (!is_array($value)) $value=array($value); - foreach ($field as $k=>$v) { - if (!$v) continue; - if (isset(self::$table_rows[$v])) $v = $field[$k] = self::$table_rows[$v]['id']; - elseif (!isset(self::$hash[$v])) trigger_error('get_id(): Unknown column: '.$v, E_USER_ERROR); - $f_id = self::$hash[$v]; - if (self::$table_rows[$f_id]['type']=='multiselect') { - $where .= ' AND f_'.$v.' '.DB::like().' '.DB::Concat(DB::qstr('%\_\_'),'%s',DB::qstr('\_\_%')); - } else $where .= ' AND f_'.$v.'=%s'; - - } - $ret = DB::GetOne('SELECT id FROM '.$tab.'_data_1 WHERE active=1'.$where, $value); - if ($ret===false || $ret===null) return null; - return $ret; - } - public static function is_active($tab, $id) { - self::init($tab); - return DB::GetOne('SELECT active FROM '.$tab.'_data_1 WHERE id=%d', array($id)); - } - public static function admin_caption() { - return array('label'=>__('Record Browser'), 'section'=>__('Data')); - } - public static function admin_access() { - return DEMO_MODE?false:true; - } - public static function admin_access_levels() { - return array( - 'records'=>array('label'=>__('Manage Records'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>1), - 'fields'=>array('label'=>__('Manage Fields'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>1), - 'settings'=>array('label'=>__('Manage Settings'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>1), - 'addons'=>array('label'=>__('Manage Addons'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>2), - 'permissions'=>array('label'=>__('Permissions'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>1), - 'pattern'=>array('label'=>__('Clipboard Pattern'), 'values'=>array(0=>__('No access'), 1=>__('View'), 2=>__('Full')), 'default'=>2) - ); - } - public static function get_field_id($f) { - return preg_replace('/[^|a-z0-9]/','_',strtolower($f)); - } - public static function init($tab, $admin=false, $force=false) { - static $cache = array(); - if (!isset(self::$cols_order[$tab])) self::$cols_order[$tab] = array(); - $cache_str = $tab.'__'.$admin.'__'.md5(serialize(self::$cols_order[$tab])); - if (!$force && isset($cache[$cache_str])) { - self::$hash = $cache[$cache_str]['hash']; - return self::$table_rows = $cache[$cache_str]['rows']; - } - self::$table_rows = array(); - if($tab=='__RECORDSETS__' || preg_match('/,/',$tab)) return; - self::check_table_name($tab); - self::display_callback_cache($tab); - $ret = DB::Execute('SELECT * FROM '.$tab.'_field'.($admin?'':' WHERE active=1 AND type!=\'page_split\'').' ORDER BY position'); - self::$hash = array(); - while($row = $ret->FetchRow()) { - if ($row['field']=='id') continue; - $commondata = false; - if ($row['type']=='commondata') { - $row['param'] = self::decode_commondata_param($row['param']); - $commondata = true; - } - if ($row['type'] == 'file') { - $row['param'] = json_decode($row['param'], true); - if (!is_array($row['param'])) $row['param'] = []; - if (!isset($row['param']['max_files'])) $row['param']['max_files'] = false; - } - $next_field = - array( 'name'=>str_replace('%','%%',$row['caption']?$row['caption']:$row['field']), - 'id'=>self::get_field_id($row['field']), - 'pkey'=>$row['id'], - 'type'=>$row['type'], - 'caption'=>$row['caption'], - 'visible'=>$row['visible'], - 'required'=>($row['type']=='calculated'?false:$row['required']), - 'extra'=>$row['extra'], - 'active'=>$row['active'], - 'export'=>$row['export'], - 'tooltip'=>$row['tooltip'], - 'position'=>$row['position'], - 'processing_order' => $row['processing_order'], - 'filter'=>$row['filter'], - 'style'=>$row['style'], - 'param'=>$row['param'], - 'help' =>$row['help'], - 'template'=>$row['template'] - ); - if (isset(self::$display_callback_table[$tab][$row['field']])) - $next_field['display_callback'] = self::$display_callback_table[$tab][$row['field']]; - if (($row['type']=='select' || $row['type']=='multiselect') && $row['param']) { - $pos = strpos($row['param'], ':'); - $next_field['ref_table'] = substr($row['param'], 0, $pos); - if ($next_field['ref_table']=='__COMMON__') { - $next_field['ref_field'] = '__COMMON__'; - $exploded = explode('::', $row['param']); - $next_field['commondata_array'] = $next_field['ref_table'] = $exploded[1]; - $next_field['commondata_order'] = isset($exploded[2]) ? $exploded[2] : 'value'; - $commondata = true; - } else { - $end = strpos($row['param'], ';', $pos+2); - if ($end==0) $end = strlen($row['param']); - $next_field['ref_field'] = substr($row['param'], $pos+2, $end-$pos-2); - } - } - $next_field['commondata'] = $commondata; - if ($commondata) { - if (!isset($next_field['commondata_order'])) { - if (isset($next_field['param']['order'])) { - $next_field['commondata_order'] = $next_field['param']['order']; - } else { - $next_field['commondata_order'] = 'value'; - } - } - if (!isset($next_field['commondata_array'])) { - $next_field['commondata_array'] = $next_field['param']['array_id']; - } - } - self::$table_rows[$row['field']] = $next_field; - self::$hash[$next_field['id']] = $row['field']; - } - if (!empty(self::$cols_order[$tab])) { - $rows = array(); - foreach (self::$cols_order[$tab] as $v) { - $rows[self::$hash[$v]] = self::$table_rows[self::$hash[$v]]; - unset(self::$table_rows[self::$hash[$v]]); - } - foreach(self::$table_rows as $k=>$v) - $rows[$k] = $v; - self::$table_rows = $rows; - } - $cache[$tab.'__'.$admin.'__'.md5(serialize(self::$cols_order[$tab]))] = array('rows'=>self::$table_rows,'hash'=>self::$hash); - return self::$table_rows; - } - - public static function install_new_recordset($tab, $fields=array()) { - if (!preg_match('/^[a-zA-Z_0-9]+$/',$tab)) trigger_error('Invalid table name ('.$tab.') given to install_new_recordset.',E_USER_ERROR); - if (strlen($tab)>39) trigger_error('Invalid table name ('.$tab.') given to install_new_recordset, max length is 39 characters.',E_USER_ERROR); - if (!DB::GetOne('SELECT 1 FROM recordbrowser_table_properties WHERE tab=%s', array($tab))) { - DB::Execute('INSERT INTO recordbrowser_table_properties (tab) VALUES (%s)', array($tab)); - } - - @DB::DropTable($tab.'_callback'); - @DB::DropTable($tab.'_recent'); - @DB::DropTable($tab.'_favorite'); - @DB::DropTable($tab.'_edit_history_data'); - @DB::DropTable($tab.'_edit_history'); - @DB::DropTable($tab.'_field'); - @DB::DropTable($tab.'_data_1'); - @DB::DropTable($tab.'_access_clearance'); - @DB::DropTable($tab.'_access_fields'); - @DB::DropTable($tab.'_access'); - - self::check_table_name(null, true); - DB::CreateTable($tab.'_field', - 'id I2 AUTO KEY NOTNULL,'. - 'field C(32) UNIQUE NOTNULL,'. - 'caption C(255),'. - 'type C(32),'. - 'extra I1 DEFAULT 1,'. - 'visible I1 DEFAULT 1,'. - 'tooltip I1 DEFAULT 1,'. - 'required I1 DEFAULT 1,'. - 'export I1 DEFAULT 1,'. - 'active I1 DEFAULT 1,'. - 'position I2,'. - 'processing_order I2 NOTNULL,'. - 'filter I1 DEFAULT 0,'. - 'param C(255),'. - 'style C(64),'. - 'template C(255),'. - 'help X', - array('constraints'=>'')); - DB::CreateTable($tab.'_callback', - 'field C(32),'. - 'callback C(255),'. - 'freezed I1', - array('constraints'=>'')); - - DB::Execute('INSERT INTO '.$tab.'_field(field, type, extra, visible, position, processing_order) VALUES(\'id\', \'foreign index\', 0, 0, 1, 1)'); - DB::Execute('INSERT INTO '.$tab.'_field(field, type, extra, position, processing_order) VALUES(\'General\', \'page_split\', 0, 2, 2)'); - - $fields_sql = ''; - foreach ($fields as $v) - $fields_sql .= Utils_RecordBrowserCommon::new_record_field($tab, $v, false, false); - DB::CreateTable($tab.'_data_1', - 'id I AUTO KEY,'. - 'created_on T NOT NULL,'. - 'created_by I NOT NULL,'. - 'indexed I1 NOT NULL DEFAULT 0,'. - 'active I1 NOT NULL DEFAULT 1'. - $fields_sql, - array('constraints'=>'')); - DB::CreateIndex($tab.'_idxed',$tab.'_data_1','indexed,active'); - DB::CreateIndex($tab.'_act',$tab.'_data_1','active'); - - DB::CreateTable($tab.'_edit_history', - 'id I AUTO KEY,'. - $tab.'_id I NOT NULL,'. - 'edited_on T NOT NULL,'. - 'edited_by I NOT NULL', - array('constraints'=>', FOREIGN KEY (edited_by) REFERENCES user_login(id), FOREIGN KEY ('.$tab.'_id) REFERENCES '.$tab.'_data_1(id)')); - DB::CreateTable($tab.'_edit_history_data', - 'edit_id I,'. - 'field C(32),'. - 'old_value X', - array('constraints'=>', FOREIGN KEY (edit_id) REFERENCES '.$tab.'_edit_history(id)')); - DB::CreateTable($tab.'_favorite', - 'fav_id I AUTO KEY,'. - $tab.'_id I,'. - 'user_id I', - array('constraints'=>', FOREIGN KEY (user_id) REFERENCES user_login(id), FOREIGN KEY ('.$tab.'_id) REFERENCES '.$tab.'_data_1(id)')); - DB::CreateTable($tab.'_recent', - 'recent_id I AUTO KEY,'. - $tab.'_id I,'. - 'user_id I,'. - 'visited_on T', - array('constraints'=>', FOREIGN KEY (user_id) REFERENCES user_login(id), FOREIGN KEY ('.$tab.'_id) REFERENCES '.$tab.'_data_1(id)')); - DB::CreateTable($tab.'_access', - 'id I AUTO KEY,'. - 'action C(16),'. - 'crits X', - array('constraints'=>'')); - DB::CreateTable($tab.'_access_fields', - 'rule_id I,'. - 'block_field C(32)', - array('constraints'=>', FOREIGN KEY (rule_id) REFERENCES '.$tab.'_access(id)')); - DB::CreateTable($tab.'_access_clearance', - 'rule_id I,'. - 'clearance C(32)', - array('constraints'=>', FOREIGN KEY (rule_id) REFERENCES '.$tab.'_access(id)')); - self::check_table_name($tab, true); - self::add_access($tab, 'print', 'SUPERADMIN'); - self::add_access($tab, 'export', 'SUPERADMIN'); - return true; - } - public static function enable_watchdog($tab,$watchdog_callback) { - self::check_table_name($tab); - Utils_WatchdogCommon::register_category($tab, $watchdog_callback); - } - public static function set_display_callback($tab, $field, $callback) { - self::check_table_name($tab); - self::$clear_get_val_cache = true; - if (is_array($callback)) $callback = implode('::',$callback); - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s AND freezed=1', array($field)); - DB::Execute('INSERT INTO '.$tab.'_callback (field, callback, freezed) VALUES(%s, %s, 1)', array($field, $callback)); - } - public static function set_QFfield_callback($tab, $field, $callback) { - self::check_table_name($tab); - self::$clear_get_val_cache = true; - if (is_array($callback)) $callback = implode('::',$callback); - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s AND freezed=0', array($field)); - DB::Execute('INSERT INTO '.$tab.'_callback (field, callback, freezed) VALUES(%s, %s, 0)', array($field, $callback)); - } - public static function unset_display_callback($tab, $field) { - self::check_table_name($tab); - self::$clear_get_val_cache = true; - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s AND freezed=1', array($field)); - } - public static function unset_QFfield_callback($tab, $field) { - self::check_table_name($tab); - self::$clear_get_val_cache = true; - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s AND freezed=0', array($field)); - } - - public static function uninstall_recordset($tab) { - if (!self::check_table_name($tab,true)) return; - self::$clear_get_val_cache = true; - Utils_WatchdogCommon::unregister_category($tab); - DB::DropTable($tab.'_callback'); - DB::DropTable($tab.'_recent'); - DB::DropTable($tab.'_favorite'); - DB::DropTable($tab.'_edit_history_data'); - DB::DropTable($tab.'_edit_history'); - DB::DropTable($tab.'_field'); - DB::DropTable($tab.'_data_1'); - DB::DropTable($tab.'_access_clearance'); - DB::DropTable($tab.'_access_fields'); - DB::DropTable($tab.'_access'); - DB::Execute('DELETE FROM recordbrowser_table_properties WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_processing_methods WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_browse_mode_definitions WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_clipboard_pattern WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_addon WHERE tab=%s', array($tab)); - DB::Execute('DELETE FROM recordbrowser_access_methods WHERE tab=%s', array($tab)); - return true; - } - - public static function delete_record_field($tab, $field){ - self::init($tab); - self::$clear_get_val_cache = true; - $exists = DB::GetOne('SELECT 1 FROM '.$tab.'_field WHERE field=%s', array($field)); - if(!$exists) return; - // move to the end - self::change_field_position($tab, $field, 16000); - DB::Execute('DELETE FROM '.$tab.'_field WHERE field=%s', array($field)); - DB::Execute('DELETE FROM '.$tab.'_callback WHERE field=%s', array($field)); - - if (isset(self::$table_rows[$field]['id'])) { - $f_id = self::$table_rows[$field]['id']; - @DB::Execute('ALTER TABLE '.$tab.'_data_1 DROP COLUMN f_'.$f_id); - @DB::Execute('DELETE FROM '.$tab.'_access_fields WHERE block_field=%s', array($f_id)); - self::init($tab, false, true); - @DB::Execute('UPDATE '.$tab.'_data_1 SET indexed=0'); - } - } - - private static $datatypes = null; - public static function new_record_field($tab, $definition, $alter=true, $set_empty_position_before_first_page_split=true){ - if (self::$datatypes===null) { - self::$datatypes = array(); - $ret = DB::Execute('SELECT * FROM recordbrowser_datatype'); - while ($row = $ret->FetchRow()) - self::$datatypes[$row['type']] = array($row['module'], $row['func']); - } - if (!is_array($definition)) { - // Backward compatibility - got to get rid of this one someday - $args = func_get_args(); - array_shift($args); - $definition = array(); - foreach (array( 0=>'name', - 1=>'type', - 2=>'visible', - 3=>'required', - 4=>'param', - 5=>'style', - 6=>'extra', - 7=>'filter', - 8=>'position', - 9=>'processing_order', - 10=>'caption') as $k=>$w) - if (isset($args[$k])) $definition[$w] = $args[$k]; - } - if (!isset($definition['type'])) trigger_error(print_r($definition,true)); - if (!isset($definition['param'])) $definition['param'] = ''; - if (!isset($definition['caption'])) $definition['caption'] = ''; - if (!isset($definition['style'])) { - if (in_array($definition['type'], array('time','timestamp','currency'))) - $definition['style'] = $definition['type']; - else { - if (in_array($definition['type'], array('float','integer', 'autonumber'))) - $definition['style'] = 'number'; - else - $definition['style'] = ''; - } - } - if (!isset($definition['extra'])) $definition['extra'] = true; - if (!isset($definition['export'])) $definition['export'] = true; - if (!isset($definition['visible'])) $definition['visible'] = false; - if (!isset($definition['tooltip'])) $definition['tooltip'] = $definition['visible']; - if (!isset($definition['required'])) $definition['required'] = false; - if (!isset($definition['filter'])) $definition['filter'] = false; - if (!isset($definition['position'])) $definition['position'] = null; - if (!isset($definition['template'])) $definition['template'] = ''; - if (!isset($definition['help'])) $definition['help'] = ''; - $definition['template'] = is_array($definition['template'])? implode('::', $definition['template']): $definition['template']; - if (isset(self::$datatypes[$definition['type']])) $definition = call_user_func(self::$datatypes[$definition['type']], $definition); - - if (isset($definition['display_callback'])) self::set_display_callback($tab, $definition['name'], $definition['display_callback']); - if (isset($definition['QFfield_callback'])) self::set_QFfield_callback($tab, $definition['name'], $definition['QFfield_callback']); -// $field, $type, $visible, $required, $param='', $style='', $extra = true, $filter = false, $pos = null - - if (strpos($definition['name'],'|')!==false) trigger_error('Invalid field name (character | is not allowed):'.$definition['name'], E_USER_ERROR); - self::check_table_name($tab); - self::$clear_get_val_cache = true; - if ($alter) { - $exists = DB::GetOne('SELECT field FROM '.$tab.'_field WHERE field=%s', array($definition['name'])); - if ($exists) return; - } - - DB::StartTrans(); - if (is_string($definition['position'])) $definition['position'] = self::get_field_position($tab, $definition['position'])+1; - if ($definition['position']===null || $definition['position']===false) { - $first_page_split = $set_empty_position_before_first_page_split?DB::GetOne('SELECT MIN(position) FROM '.$tab.'_field WHERE type=%s AND field!=%s', array('page_split', 'General')):0; - $definition['position'] = $first_page_split?$first_page_split:DB::GetOne('SELECT MAX(position) FROM '.$tab.'_field')+1; - } - DB::Execute('UPDATE '.$tab.'_field SET position = position+1 WHERE position>=%d', array($definition['position'])); - DB::CompleteTrans(); - if (!isset($definition['processing_order'])) $definition['processing_order'] = DB::GetOne('SELECT MAX(processing_order) FROM '.$tab.'_field') + 1; - - $param = $definition['param']; - if (is_array($param)) { - if ($definition['type']=='commondata') { - $param = self::encode_commondata_param($param); - } elseif($definition['type'] == 'file') { - $param = json_encode($param); - } else { - $tmp = array(); - foreach ($param as $k=>$v) $tmp[] = $k.'::'.$v; - $param = implode(';',$tmp); - } - } - $f = self::actual_db_type($definition['type'], $param); - DB::Execute('INSERT INTO '.$tab.'_field(field, caption, type, visible, param, style, position, processing_order, extra, required, filter, export, tooltip, template, help) VALUES(%s, %s, %s, %d, %s, %s, %d, %d, %d, %d, %d, %d, %d, %s, %s)', array($definition['name'], $definition['caption'], $definition['type'], $definition['visible']?1:0, $param, $definition['style'], $definition['position'], $definition['processing_order'], $definition['extra']?1:0, $definition['required']?1:0, $definition['filter']?1:0, $definition['export']?1:0, $definition['tooltip']?1:0, $definition['template'], $definition['help'])); - $column = 'f_'.self::get_field_id($definition['name']); - if ($alter) { - self::init($tab, false, true); - if ($f!=='') { - @DB::Execute('ALTER TABLE '.$tab.'_data_1 ADD COLUMN '.$column.' '.$f); - if ($definition['type'] === 'autonumber') { - self::format_autonumber_str_all_records($tab, self::get_field_id($definition['name']), $param); - } - } - } else { - if ($f!=='') return ','.$column.' '.$f; - else return ''; - } - @DB::Execute('UPDATE '.$tab.'_data_1 SET indexed=0'); - } - public static function change_field_position($tab, $field, $new_pos){ - $new_pos = is_string($new_pos)? (self::get_field_position($tab, $new_pos)+1): $new_pos; - - if ($new_pos <= 2) return; // make sure that no field is before "General" tab split - - DB::StartTrans(); - if ($pos = self::get_field_position($tab, $field)) { - // move all following fields back - DB::Execute('UPDATE '.$tab.'_field SET position=position-1 WHERE position>%d',array($pos)); - // make place for moved field - DB::Execute('UPDATE '.$tab.'_field SET position=position+1 WHERE position>=%d',array($new_pos)); - // set new field position - DB::Execute('UPDATE '.$tab.'_field SET position=%d WHERE field=%s',array($new_pos, $field)); - } - DB::CompleteTrans(); - } - - public static function get_field_position($tab, $field){ - return DB::GetOne('SELECT position FROM '.$tab.'_field WHERE field=%s', array($field)); - } - - /** - * @param string $tab Recordset identifier. e.g. contact, company - * @param string $old_name Current field name. Not field id. e.g. "First Name" - * @param string $new_name New field name. - */ - public static function rename_field($tab, $old_name, $new_name) - { - $id = self::get_field_id($old_name); - $new_id = self::get_field_id($new_name); - self::check_table_name($tab); - - $type = DB::GetOne('SELECT type FROM ' . $tab . '_field WHERE field=%s', array($old_name)); - $old_param = DB::GetOne('SELECT param FROM ' . $tab . '_field WHERE field=%s', array($old_name)); - - $db_field_exists = !(in_array($type, ['calculated', 'hidden'], true) && !$old_param) && $type!== 'page_split'; - - DB::StartTrans(); - if ($db_field_exists) { - if (DB::is_postgresql()) { - DB::Execute('ALTER TABLE ' . $tab . '_data_1 RENAME COLUMN f_' . $id . ' TO f_' . $new_id); - } else { - - DB::RenameColumn($tab . '_data_1', 'f_' . $id, 'f_' . $new_id, self::actual_db_type($type, $old_param)); - } - DB::Execute('UPDATE ' . $tab . '_edit_history_data SET field=%s WHERE field=%s', array($new_id, $id)); - } - DB::Execute('UPDATE ' . $tab . '_field SET field=%s WHERE field=%s', array($new_name, $old_name)); - DB::Execute('UPDATE ' . $tab . '_access_fields SET block_field=%s WHERE block_field=%s', array($new_id, $id)); - DB::Execute('UPDATE ' . $tab . '_callback SET field=%s WHERE field=%s', array($new_name, $old_name)); - - $result = DB::Execute('SELECT * FROM ' . $tab . '_access'); - while ($row = $result->FetchRow()) { - $crits = self::unserialize_crits($row['crits']); - - if (!$crits) continue; - - if (!is_object($crits)) - $crits = Utils_RecordBrowser_Crits::from_array($crits); - - foreach ($crits->find($id)?:[] as $c) $c->set_field($new_id); - - DB::Execute('UPDATE ' . $tab . '_access SET crits=%s WHERE id=%d', array(self::serialize_crits($crits), $row['id'])); - } - - DB::CompleteTrans(); - } - - public static function set_field_template($tab, $fields, $template) - { - Utils_RecordBrowserCommon::check_table_name($tab); - $template = is_array($template)? implode('::', $template): $template; - $fields = is_array($fields)? $fields: array($fields); - $s = array_fill(0, count($fields), '%s'); - - DB::Execute('UPDATE ' . $tab . '_field SET template=%s WHERE field IN ('. implode(',', $s) .')', array_merge(array($template), $fields)); - } - - /** - * List all installed recordsets. - * @param string $format Simple formatting of the values - * - * You can use three keys that will be replaced with values:
- * - %tab - table identifier
- * - %orig_caption - original table caption
- * - %caption - translated table caption
- * Default is '%caption'. If no caption is specified then - * table identifier is used as caption.
- * Other common usage: '%caption (%tab)' - * @return array Keys are tab identifiers, values according to $format param - */ - public static function list_installed_recordsets($format = '%caption') - { - $tabs = DB::GetAssoc('SELECT tab, caption FROM recordbrowser_table_properties'); - $ret = array(); - foreach ($tabs as $tab_id => $caption) { - if (!$caption) { - $translated_caption = $caption = $tab_id; - } else { - $translated_caption = _V($caption); - } - $ret[$tab_id] = str_replace( - array('%tab', '%orig_caption', '%caption'), - array($tab_id, $caption, $translated_caption), - $format - ); - } - return $ret; - } - - public static function actual_db_type($type, $param=null) { - $f = ''; - switch ($type) { - case 'page_split': $f = ''; break; - - case 'text': $f = DB::dict()->ActualType('C').'('.$param.')'; break; - case 'select': - $param = self::decode_select_param($param); - if($param['single_tab']) $f = DB::dict()->ActualType('I4'); - else $f = DB::dict()->ActualType('X'); - break; - case 'multiselect': $f = DB::dict()->ActualType('X'); break; - case 'commondata': $f = DB::dict()->ActualType('C').'(128)'; break; - case 'integer': $f = DB::dict()->ActualType('I4'); break; - case 'float': $f = DB::dict()->ActualType('F'); break; - case 'date': $f = DB::dict()->ActualType('D'); break; - case 'timestamp': $f = DB::dict()->ActualType('T'); break; - case 'time': $f = DB::dict()->ActualType('T'); break; - case 'long text': $f = DB::dict()->ActualType('X'); break; - case 'hidden': $f = (isset($param)?$param:''); break; - case 'calculated': $f = (isset($param)?$param:''); break; - case 'checkbox': $f = DB::dict()->ActualType('I1'); break; - case 'currency': $f = DB::dict()->ActualType('C').'(128)'; break; - case 'autonumber': $len = strlen(self::format_autonumber_str($param, null)); - $f = DB::dict()->ActualType('C') . "($len)"; break; - case 'file': $f = DB::dict()->ActualType('X'); break; - } - return $f; - } - public static function new_browse_mode_details_callback($tab, $mod, $func) { - self::check_table_name($tab); - if(!DB::GetOne('SELECT 1 FROM recordbrowser_browse_mode_definitions WHERE tab=%s AND module=%s AND func=%s', array($tab, $mod, $func))) - DB::Execute('INSERT INTO recordbrowser_browse_mode_definitions (tab, module, func) VALUES (%s, %s, %s)', array($tab, $mod, $func)); - } - - public static function delete_browse_mode_details_callback($tab, $mod, $func) { - self::check_table_name($tab); - DB::Execute('DELETE FROM recordbrowser_browse_mode_definitions WHERE tab=%s AND module=%s AND func=%s', array($tab, $mod, $func)); - } - - public static function new_addon($tab, $module, $func, $label) { - if (is_array($label)) $label= implode('::',$label); - $module = str_replace('/','_',$module); - self::delete_addon($tab, $module, $func); - $pos = DB::GetOne('SELECT MAX(pos) FROM recordbrowser_addon WHERE tab=%s', array($tab)); - if (!$pos) $pos=0; - DB::Execute('INSERT INTO recordbrowser_addon (tab, module, func, label, pos, enabled) VALUES (%s, %s, %s, %s, %d, 1)', array($tab, $module, $func, $label, $pos+1)); - } - public static function delete_addon($tab, $module, $func) { - $module = str_replace('/','_',$module); - $pos = DB::GetOne('SELECT pos FROM recordbrowser_addon WHERE tab=%s AND module=%s AND func=%s', array($tab, $module, $func)); - if ($pos===false || $pos===null) return false; - DB::Execute('DELETE FROM recordbrowser_addon WHERE tab=%s AND module=%s AND func=%s', array($tab, $module, $func)); - while (DB::GetOne('SELECT pos FROM recordbrowser_addon WHERE tab=%s AND pos=%d', array($tab, $pos+1))) { - DB::Execute('UPDATE recordbrowser_addon SET pos=pos-1 WHERE tab=%s AND pos=%d', array($tab, $pos+1)); - $pos++; - } - return true; - } - public static function set_addon_pos($tab, $module, $func, $pos) { - $module = str_replace('/','_',$module); - $old_pos = DB::GetOne('SELECT pos FROM recordbrowser_addon WHERE tab=%s AND module=%s AND func=%s', array($tab, $module, $func)); - if ($old_pos>$pos) - DB::Execute('UPDATE recordbrowser_addon SET pos=pos+1 WHERE tab=%s AND pos>=%d AND pos<%d', array($tab, $pos, $old_pos)); - else - DB::Execute('UPDATE recordbrowser_addon SET pos=pos-1 WHERE tab=%s AND pos<=%d AND pos>%d', array($tab, $pos, $old_pos)); - DB::Execute('UPDATE recordbrowser_addon SET pos=%d WHERE tab=%s AND module=%s AND func=%s', array($pos, $tab, $module, $func)); - } - public static function register_datatype($type, $module, $func) { - if(self::$datatypes!==null) self::$datatypes[$type] = array($module,$func); - DB::Execute('INSERT INTO recordbrowser_datatype (type, module, func) VALUES (%s, %s, %s)', array($type, $module, $func)); - } - public static function unregister_datatype($type) { - if(self::$datatypes!==null) unset(self::$datatypes[$type]); - DB::Execute('DELETE FROM recordbrowser_datatype WHERE type=%s', array($type)); - } - public static function new_filter($tab, $col_name) { - self::check_table_name($tab); - DB::Execute('UPDATE '.$tab.'_field SET filter=1 WHERE field=%s', array($col_name)); - } - public static function delete_filter($tab, $col_name) { - self::check_table_name($tab); - DB::Execute('UPDATE '.$tab.'_field SET filter=0 WHERE field=%s', array($col_name)); - } - public static function register_processing_callback($tab, $callback) { - if (is_array($callback)) $callback = implode('::',$callback); - if(!DB::GetOne('SELECT 1 FROM recordbrowser_processing_methods WHERE tab=%s AND func=%s', array($tab, $callback))) - DB::Execute('INSERT INTO recordbrowser_processing_methods (tab, func) VALUES (%s, %s)', array($tab, $callback)); - } - public static function unregister_processing_callback($tab, $callback) { - if (is_array($callback)) $callback = implode('::',$callback); - DB::Execute('DELETE FROM recordbrowser_processing_methods WHERE tab=%s AND func=%s', array($tab, $callback)); - } - public static function set_quickjump($tab, $col_name) { - DB::Execute('UPDATE recordbrowser_table_properties SET quickjump=%s WHERE tab=%s', array($col_name, $tab)); - } - public static function set_tpl($tab, $filename) { - DB::Execute('UPDATE recordbrowser_table_properties SET tpl=%s WHERE tab=%s', array($filename, $tab)); - } - public static function set_favorites($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET favorites=%d WHERE tab=%s', array($value?1:0, $tab)); - } - public static function set_recent($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET recent=%d WHERE tab=%s', array($value, $tab)); - } - public static function set_full_history($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET full_history=%d WHERE tab=%s', array($value?1:0, $tab)); - } - public static function set_caption($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET caption=%s WHERE tab=%s', array($value, $tab)); - } - public static function set_icon($tab, $value) { - DB::Execute('UPDATE recordbrowser_table_properties SET icon=%s WHERE tab=%s', array($value, $tab)); - } - /** - * Enable search - * @param string $tab recordset identifier - * @param int $mode 0 - search disabled, 1 - enabled by default, 2 - optional - * @param int $priority Possible values: -2, -1, 0, 1, 2 - */ - public static function set_search($tab, $mode,$priority=0) { - DB::Execute('UPDATE recordbrowser_table_properties SET search_include=%d,search_priority=%d WHERE tab=%s', array($mode, $priority, $tab)); - } - public static function set_description_callback($tab, $callback){ - if (is_array($callback)) $callback = implode('::',$callback); - DB::Execute('UPDATE recordbrowser_table_properties SET description_callback=%s WHERE tab=%s', array($callback, $tab)); - } - - /** - * Set description fields to be used as default linked label - * - * You can use double quotes to put any text between field values - * e.g. 'Last Name, ", ", First Name,' - * - * @param string $tab recordset name - * @param string|array $fields comma separated list of fields or array of fields - */ - public static function set_description_fields($tab, $fields) - { - if (is_array($fields)) $fields = implode(',', $fields); - DB::Execute('UPDATE recordbrowser_table_properties SET description_fields=%s WHERE tab=%s', array($fields, $tab)); - } - public static function set_printer($tab,$class) { - Base_PrintCommon::register_printer(new $class()); - DB::Execute('UPDATE recordbrowser_table_properties SET printer=%s WHERE tab=%s', array($class, $tab)); - } - - public static function unset_printer($tab) - { - $printer_class = DB::GetOne('SELECT printer FROM recordbrowser_table_properties WHERE tab=%s',$tab); - if ($printer_class) { - Base_PrintCommon::unregister_printer($printer_class); - DB::Execute('UPDATE recordbrowser_table_properties SET printer=%s WHERE tab=%s', array('', $tab)); - return $printer_class; - } - return false; - } - - /** - * Enable or disable jump to id. By default it is enabled. - * - * @param string $tab Recordset identifier - * @param bool $enabled True to enable, false to disable - */ - public static function set_jump_to_id($tab, $enabled = true) - { - $sql = 'UPDATE recordbrowser_table_properties SET jump_to_id=%d WHERE tab=%s'; - DB::Execute($sql, array($enabled ? 1 : 0, $tab)); - } - public static function get_caption($tab) { - static $cache = null; - if ($cache===null) $cache = DB::GetAssoc('SELECT tab, caption FROM recordbrowser_table_properties'); - if (is_string($tab) && isset($cache[$tab])) return _V($cache[$tab]); - return '---'; - } - public static function get_description_callback($tab) { - static $cache = null; - if ($cache===null) $cache = DB::GetAssoc('SELECT tab, description_callback FROM recordbrowser_table_properties'); - - if (is_string($tab) && isset($cache[$tab])) { - if(is_string($cache[$tab]) && preg_match('/::/',$cache[$tab])) { - $cache[$tab] = explode('::',$cache[$tab]); - } - if(!is_callable($cache[$tab])) - $cache[$tab] = false; - - return $cache[$tab]; - } - - return false; - } - public static function get_description_fields($tab) { - static $cache = null; - if ($cache===null) { - $db_ret = DB::GetAssoc('SELECT tab, description_fields FROM recordbrowser_table_properties'); - foreach ($db_ret as $t => $fields) { - if ($fields) { - $fields = str_replace('"', '\'"', $fields); - $cache[$t] = array_filter(array_map('trim', str_getcsv($fields, ',', "'"))); - } - } - } - - if (is_string($tab) && isset($cache[$tab])) { - return $cache[$tab]; - } - - return false; - } - public static function get_sql_type($type) { - switch ($type) { - case 'checkbox': return '%d'; - case 'select': return '%s'; - case 'float': return '%f'; - case 'integer': return '%d'; - case 'date': return '%D'; - case 'timestamp': return '%T'; - } - return '%s'; - } - public static function set_record_properties( $tab, $id, $info = array()) { - self::check_table_name($tab); - foreach ($info as $k=>$v) - switch ($k) { - case 'created_on': DB::Execute('UPDATE '.$tab.'_data_1 SET created_on=%T WHERE id=%d', array($v, $id)); - break; - case 'created_by': DB::Execute('UPDATE '.$tab.'_data_1 SET created_by=%d WHERE id=%d', array($v, $id)); - break; - } - } - - public static function record_processing($tab, $base, $mode, $clone=null) { - self::check_table_name($tab); - static $cache = array(); - if (!isset($cache[$tab])) { - $ret = DB::Execute('SELECT * FROM recordbrowser_processing_methods WHERE tab=%s', array($tab)); - $cache[$tab] = array(); - while ($row = $ret->FetchRow()) { - $callback = explode('::',$row['func']); - if (is_callable($callback)) - $cache[$tab][] = $callback; - } - } - $current = $base; - if ($mode=='display') $result = array(); - else $result = $base; - if ($mode=='cloned') $current = array('original'=>$clone, 'clone'=>$current); - foreach ($cache[$tab] as $callback) { - $return = call_user_func($callback, $current, $mode, $tab); - if ($return===false) return false; - if ($return) { - if ($mode!='display') $current = $return; - else $result = array_merge_recursive($result, $return); - } - } - if ($mode!='display') $result = $current; - return $result; - } - - public static function new_record( $tab, $values = array()) { - self::init($tab); - $user = Acl::get_user(); - - $for_processing = $values; - foreach(self::$table_rows as $field=>$desc) - if ($desc['type']==='multiselect') { - if (!isset($for_processing[$desc['id']]) || !$for_processing[$desc['id']]) - $for_processing[$desc['id']] = array(); - } elseif (!isset($for_processing[$desc['id']])) $for_processing[$desc['id']] = ''; - - $values = self::record_processing($tab, $for_processing, 'add'); - if ($values===false) return; - - self::init($tab); - $fields = 'created_on,created_by,active'; - $fields_types = '%T,%d,%d'; - $vals = array(date('Y-m-d H:i:s'), $user, 1); - $filestorageIds = []; - foreach(self::$table_rows as $field => $desc) { - - if ($desc['type'] == 'file') { - $files = $values[$desc['id']]; - if (is_string($files)) $files = self::decode_multi($files); - if ($desc['param']['max_files'] && count($files) > $desc['param']['max_files']) { - throw new Exception('Too many files in field ' . $desc['id']); - } - $filestorageIds[$field] = Utils_FileStorageCommon::add_files($files); - $values[$desc['id']] = self::encode_multi($filestorageIds[$field]); - } - - if (($desc['type']=='calculated' || $desc['type']=='hidden') && preg_match('/^[a-z]+(\([0-9]+\))?$/i',$desc['param'])===0) continue; // FIXME move DB definiton to *_field table - if (!isset($values[$desc['id']]) || $values[$desc['id']]==='') continue; - if (!is_array($values[$desc['id']])) $values[$desc['id']] = trim($values[$desc['id']]); - if ($desc['type']=='long text') - $values[$desc['id']] = Utils_BBCodeCommon::optimize($values[$desc['id']]); - if ($desc['type']=='multiselect' && empty($values[$desc['id']])) continue; - if ($desc['type']=='multiselect') - $values[$desc['id']] = self::encode_multi($values[$desc['id']]); - if ($desc['type']=='multiselect' || $desc['type']=='select') $values[$desc['id']] = str_replace(array('P:', 'C:'), array('contact/', 'company/'), $values[$desc['id']]); - $fields_types .= ','.self::get_sql_type($desc['type']); - $fields .= ',f_'.$desc['id']; - if (is_bool($values[$desc['id']])) $values[$desc['id']] = $values[$desc['id']]?1:0; - $vals[] = $values[$desc['id']]; - } - Utils_SafeHtml_SafeHtml::setSafeHtml(new Utils_SafeHtml_HtmlPurifier()); - foreach ($vals as $k => $v) { - $vals[$k] = Utils_SafeHtml_SafeHtml::outputSafeHtml($v); - } - DB::Execute('INSERT INTO '.$tab.'_data_1 ('.$fields.') VALUES ('.$fields_types.')',$vals); - $id = DB::Insert_ID($tab.'_data_1', 'id'); - if ($user) self::add_recent_entry($tab, $user, $id); - if (Base_User_SettingsCommon::get('Utils_RecordBrowser',$tab.'_auto_fav')) - DB::Execute('INSERT INTO '.$tab.'_favorite (user_id, '.$tab.'_id) VALUES (%d, %d)', array($user, $id)); - self::init($tab); - foreach(self::$table_rows as $field=>$desc) { - if ($desc['type']==='multiselect') { - if (!isset($values[$desc['id']])) $values[$desc['id']] = array(); - elseif (!is_array($values[$desc['id']])) - $values[$desc['id']] = self::decode_multi($values[$desc['id']]); - } - if ($desc['type'] === 'autonumber') { - $autonumber_value = self::format_autonumber_str($desc['param'], $id); - self::update_record($tab, $id, array($desc['id'] => $autonumber_value), false, null, true); - $values[$desc['id']] = $autonumber_value; - } - if ($desc['type'] === 'file') { - // update backref - Utils_FileStorageCommon::add_files($filestorageIds[$field], "rb:$tab/$id/$desc[pkey]"); - $values[$desc['id']] = $filestorageIds[$field]; - } - } - $values['id'] = $id; - self::record_processing($tab, $values, 'added'); - - if (Base_User_SettingsCommon::get('Utils_RecordBrowser',$tab.'_auto_subs')==1) - Utils_WatchdogCommon::subscribe($tab,$id); - Utils_WatchdogCommon::new_event($tab,$id,'C'); - - return $id; - } - - public static function new_record_history($tab,$id,$old_value) { - DB::Execute('INSERT INTO ' . $tab . '_edit_history(edited_on, edited_by, ' . $tab . '_id) VALUES (%T,%d,%d)', array(date('Y-m-d G:i:s'), Acl::get_user(), $id)); - $edit_id = DB::Insert_ID($tab . '_edit_history', 'id'); - DB::Execute('INSERT INTO ' . $tab . '_edit_history_data(edit_id, field, old_value) VALUES (%d,%s,%s)', array($edit_id, 'id', $old_value)); - return $edit_id; - } - - public static function update_record($tab,$id,$values,$all_fields = false, $date = null, $dont_notify = false) { - DB::StartTrans(); - self::init($tab); - $record = self::get_record($tab, $id, false); - if (!is_array($record)) { - DB::CompleteTrans(); - return false; - } - - $process_method_args = $values; - $process_method_args['id'] = $id; - foreach ($record as $k=>$v) - if (!isset($process_method_args[$k])) $process_method_args[$k] = $v; - - $values = self::record_processing($tab, $process_method_args, 'edit'); - - $diff = array(); - self::init($tab); - foreach(self::$table_rows as $field => $desc){ - if ($desc['type']=='calculated' && preg_match('/^[a-z]+(\([0-9]+\))?$/i',$desc['param'])===0) continue; // FIXME move DB definiton to *_field table - if ($desc['id']=='id') continue; - if (!isset($values[$desc['id']])) { - if ($all_fields) $values[$desc['id']] = ''; - else continue; - } - if ($desc['type']=='checkbox') { - if ($values[$desc['id']]) $values[$desc['id']] = 1; - else $values[$desc['id']] = 0; - if ($record[$desc['id']]) $record[$desc['id']] = 1; - else $record[$desc['id']] = 0; - } - if ($desc['type']=='long text') - $values[$desc['id']] = Utils_BBCodeCommon::optimize($values[$desc['id']]); - if ($desc['type']=='multiselect') { - if (!is_array($values[$desc['id']])) $values[$desc['id']] = array($values[$desc['id']]); - $array_diff = array_diff($record[$desc['id']], $values[$desc['id']]); - if (empty($array_diff)) { - $array_diff = array_diff($values[$desc['id']], $record[$desc['id']]); - if (empty($array_diff)) continue; - } - $v = self::encode_multi($values[$desc['id']]); - $old = self::encode_multi($record[$desc['id']]); - } elseif ($desc['type'] == 'file') { - $files = $values[$desc['id']]; - if (is_string($files)) { - $files = self::decode_multi($files); - } - if ($desc['param']['max_files'] && count($files) > $desc['param']['max_files']) { - throw new Exception('Too many files in field ' . $desc['id']); - } - $filestorageIds = Utils_FileStorageCommon::add_files($files, "rb:$tab/$id/$desc[pkey]"); - $values[$desc['id']] = $filestorageIds; - // Delete files not present in the field right now - $old = $record[$desc['id']]; - sort($old); - if ($old == $filestorageIds) continue; - foreach ($record[$desc['id']] as $file) { - if (!in_array($file, $filestorageIds)) { - // delete file - Utils_FileStorageCommon::delete($file); - } - } - $v = self::encode_multi($filestorageIds); - $old = self::encode_multi($old); - } else { - if ($record[$desc['id']]===$values[$desc['id']]) continue; - $v = $values[$desc['id']]; - $old = $record[$desc['id']]; - } - if ($v!=='') DB::Execute('UPDATE '.$tab.'_data_1 SET f_'.$desc['id'].'='.self::get_sql_type($desc['type']).' WHERE id=%d',array($v, $id)); - else DB::Execute('UPDATE '.$tab.'_data_1 SET f_'.$desc['id'].'=NULL WHERE id=%d',array($id)); - $diff[$desc['id']] = $old; - } - if(!empty($diff)) { - @DB::Execute('UPDATE '.$tab.'_data_1 SET indexed=0 WHERE id=%d',array($id)); - self::record_processing($tab, $values, 'edited'); - } - if (!$dont_notify && !empty($diff)) { - $diff = self::record_processing($tab, $diff, 'edit_changes'); - DB::Execute('INSERT INTO '.$tab.'_edit_history(edited_on, edited_by, '.$tab.'_id) VALUES (%T,%d,%d)', array((($date==null)?date('Y-m-d G:i:s'):$date), Acl::get_user(), $id)); - $edit_id = DB::Insert_ID(''.$tab.'_edit_history','id'); - foreach($diff as $k=>$v) { - if (!is_array($v)) $v = array($v); - foreach($v as $c) - DB::Execute('INSERT INTO '.$tab.'_edit_history_data(edit_id, field, old_value) VALUES (%d,%s,%s)', array($edit_id, $k, $c)); - } - Utils_WatchdogCommon::new_event($tab,$id,'E_'.$edit_id); - } - return DB::CompleteTrans(); - } - public static function add_recent_entry($tab, $user_id ,$id){ - self::check_table_name($tab); - static $rec_size = array(); - if (!isset($rec_size[$tab])) $rec_size[$tab] = DB::GetOne('SELECT recent FROM recordbrowser_table_properties WHERE tab=%s', array($tab)); - $ids = array(); - if ($rec_size[$tab]) { - $ret = DB::SelectLimit('SELECT '.$tab.'_id FROM '.$tab.'_recent WHERE user_id = %d ORDER BY visited_on DESC', - $rec_size[$tab], - -1, - array($user_id)); - while($row = $ret->FetchRow()) { - if ($row[$tab.'_id']==$id || !$row[$tab.'_id']) continue; - if (count($ids)>=$rec_size[$tab]-1) continue; - $ids[] = $row[$tab.'_id']; - } - } - if (empty($ids)) $where = ''; - else $where = ' AND '.$tab.'_id NOT IN ('.implode(',',$ids).')'; - DB::Execute('DELETE FROM '.$tab.'_recent WHERE user_id = %d'.$where, - array($user_id)); - if ($rec_size[$tab]) - DB::Execute('INSERT INTO '.$tab.'_recent ('.$tab.'_id, user_id, visited_on) VALUES (%d, %d, %T)', - array($id, - $user_id, - date('Y-m-d H:i:s'))); - } - public static function merge_crits($a = array(), $b = array(), $or=false) { - return Utils_RecordBrowser_Crits::merge($a, $b, $or); - } - public static function build_query($tab, $crits = null, $admin = false, $order = array(), $tab_alias = 'r') { - static $stack = array(); - static $cache; - if (!is_object($crits)) { - $crits = Utils_RecordBrowser_Crits::from_array($crits); - } - $cache_key = $tab . '__' . $tab_alias . '__' . md5(serialize($crits)) . '__' . $admin . '__' . md5(serialize($order)) . '__' . Base_AclCommon::get_user(); - if (isset($cache[$cache_key])) { - return $cache[$cache_key]; - } - - $access_crits = ($admin || in_array($tab, $stack)) ? true : self::get_access_crits($tab, 'browse'); - if ($access_crits === false) return array(); - elseif ($access_crits !== true) { - $crits = self::merge_crits($crits, $access_crits); - } - - if ($admin) { - $admin_filter = str_replace('', $tab_alias, self::$admin_filter); - } else { - $admin_filter = $tab_alias . '.active=1 AND '; - } - array_push($stack, $tab); - $query_builder = new Utils_RecordBrowser_QueryBuilder($tab, $tab_alias, $admin); - $ret = $query_builder->build_query($crits, $order, $admin_filter); - $cache[$cache_key] = $ret; - array_pop($stack); - return $ret; - } - - /** - * Get records count - * - * @param string $tab - * @param array|Utils_RecordBrowser_Crits $crits - * @param bool $admin - * @param array $order Just for SQL cache optimization. Same query will be used to fetch records - * - * @return int records count - */ - public static function get_records_count( $tab, $crits = null, $admin = false, $order = array()) { - $par = self::build_query($tab, $crits, $admin, $order); - if (empty($par) || !$par) return 0; - return DB::GetOne('SELECT COUNT(*) FROM'.$par['sql'], $par['vals']); - } - public static function get_next_and_prev_record( $tab, $crits, $order, $id, $last = null) { - $par = self::build_query($tab, $crits, false, $order); - if (empty($par) || !$par) return null; - if ($last===null || is_array($last)) { - /* Just failsafe - should not happen */ - $ret = DB::GetCol('SELECT id FROM'.$par['sql'].$par['order'], $par['vals']); - if ($ret===false || $ret===null) return null; - $k = array_search($id,$ret); - return array( 'next'=>isset($ret[$k+1])?$ret[$k+1]:null, - 'curr'=>$k, - 'prev'=>isset($ret[$k-1])?$ret[$k-1]:null); - } else { - $r = DB::SelectLimit('SELECT id FROM'.$par['sql'].$par['order'],3,($last!=0?$last-1:$last), $par['vals']); - $ret = array(); - while ($row=$r->FetchRow()) { - $ret[] = $row['id']; - } - if ($ret===false || $ret===null) return null; - if ($last===0) $ret = array(0=>null, 2=>isset($ret[1])?$ret[1]:null); - return array( 'next'=>isset($ret[2])?$ret[2]:null, - 'curr'=>$last, - 'prev'=>isset($ret[0])?$ret[0]:null); - } - } - - /** - * @param string $tab Recordset identifier - * @param array|Utils_RecordBrowser_Crits $crits - * @param array $cols not used anymore - * @param array $order - * @param int|array $limit nr of rows or array('offset'=>X, 'numrows'=>Y); - * @param bool $admin - * - * @return array|bool - */ - public static function get_records( $tab, $crits = array(), $cols = array(), $order = array(), $limit = array(), $admin = false) { - if (!$tab) return false; - if (is_numeric($limit)) { - $limit = array('numrows'=>$limit,'offset'=>0); - } else { - if (!isset($limit['offset'])) $limit['offset'] = 0; - if (!isset($limit['numrows'])) $limit['numrows'] = -1; - } - if (!$order) $order = array(); - $tab_alias = 'r'; - $fields = "$tab_alias.*"; - self::init($tab); - $par = self::build_query($tab, $crits, $admin, $order); - if (empty($par)) return array(); - $ret = DB::SelectLimit('SELECT '.$fields.' FROM'.$par['sql'].$par['order'], $limit['numrows'], $limit['offset'], $par['vals']); - $records = array(); - self::init($tab); - $fields = self::$table_rows; - while ($row = $ret->FetchRow()) { - if (isset($records[$row['id']])) { - continue; - } - $r = array( 'id'=>$row['id'], - ':active'=>$row['active'], - 'created_by'=>$row['created_by'], - 'created_on'=>$row['created_on']); - foreach($fields as $desc){ - if (isset($row['f_'.$desc['id']])) { - if ($desc['type'] == 'multiselect' || $desc['type'] == 'file') { - $r[$desc['id']] = self::decode_multi($row['f_' . $desc['id']]); - } elseif ($desc['type']=='text' || $desc['type']=='long text') { - $r[$desc['id']] = $row['f_' . $desc['id']]; - } else { - $r[$desc['id']] = $row['f_' . $desc['id']]; - } - } else { - if ($desc['type']=='multiselect') $r[$desc['id']] = array(); - else $r[$desc['id']] = ''; - } - } - if($admin || self::get_access($tab,'view',$r)) $records[$row['id']] = $r; - } - return $records; - } - public static function check_record_against_crits($tab, $id, $crits, & $problems = array()) { - if (is_numeric($id)) $r = self::get_record($tab, $id); - else $r = $id; - if (!is_object($crits)) { - $crits = Utils_RecordBrowser_Crits::from_array($crits); - } - $crits_validator = new Utils_RecordBrowser_CritsValidator($tab); - $crits->normalize(); - list($success, $issues) = $crits_validator->validate($crits, $r); - if (!$success) { - $problems = $issues; - } - return $success; - } - public static function crits_special_values() - { - $ret = array(); - $ret[] = new Utils_RecordBrowser_ReplaceValue('USER_ID', __('User Login'), Base_AclCommon::get_user()); - foreach (array('VIEW', 'VIEW_ALL', 'EDIT', 'EDIT_ALL', 'PRINT', 'PRINT_ALL', 'DELETE', 'DELETE_ALL') as $a) { - $description = 'Allow ' . str_replace('_', ' ', strtolower($a)) . ' record(s)'; - $ret[] = new Utils_RecordBrowser_ReplaceValue("ACCESS_$a", _V($description), 'Utils_RecordBrowserCommon::get_recursive_'.strtolower($a).'_access'); - } - return $ret; - } - public static function get_recursive_access($otab,&$r,$field,$action,$any) { - self::init($otab); - $desc = self::$table_rows[self::$hash[$field]]; - - $param = self::decode_select_param($desc['param']); - - if($param['single_tab']=='__COMMON__') return $r[$field]; - - $ret = true; - $field_is_empty = true; - if (!isset($r[$field])) $values = array(); - elseif(!is_array($r[$field])) $values = array($r[$field]); - else $values = $r[$field]; - foreach($values as $rid) { - if (!$rid) continue; - $val = self::decode_record_token($rid, $param['single_tab']); - if(!$val) continue; - list($tab, $rid) = $val; - $rr = self::get_record($tab, $rid); - $access = self::get_access($tab, $action, $rr); - $field_is_empty = false; - if($any && $access) return $r[$field]; - $ret &= $access; - } - return $field_is_empty ? true : ($ret ? true : false); - } - public static function get_recursive_view_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'view',true); - } - public static function get_recursive_view_all_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'view',false); - } - public static function get_recursive_edit_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'edit',true); - } - public static function get_recursive_edit_all_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'edit',false); - } - public static function get_recursive_print_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'print',true); - } - public static function get_recursive_print_all_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'print',false); - } - public static function get_recursive_delete_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'delete',true); - } - public static function get_recursive_delete_all_access($tab,&$r,$field) { - return self::get_recursive_access($tab,$r,$field,'delete',false); - } - - public static function serialize_crits($crits) - { - $serialized = serialize($crits); - if (DB::is_postgresql()) { - $serialized = bin2hex($serialized); - } - return $serialized; - } - public static function unserialize_crits($str) - { - $ret = @unserialize($str); - if ($ret === false && DB::is_postgresql()) { - $ret = unserialize(hex2bin($str)); - } - return $ret; - } - public static function parse_access_crits($str, $human_readable = false) { - $ret = self::unserialize_crits($str); - if (!is_object($ret)) { - $ret = Utils_RecordBrowser_Crits::from_array($ret); - } - return $ret->replace_special_values($human_readable); - } - public static function add_default_access($tab) { - Utils_RecordBrowserCommon::add_access($tab, 'view', 'ACCESS:employee'); - Utils_RecordBrowserCommon::add_access($tab, 'add', 'ACCESS:employee'); - Utils_RecordBrowserCommon::add_access($tab, 'edit', 'ACCESS:employee'); - Utils_RecordBrowserCommon::add_access($tab, 'delete', 'ACCESS:employee'); - } - - public static function field_deny_access($tab, $fields, $action='', $clearance=null) { - if (!self::check_table_name($tab, false, false)) return; - if (!is_array($fields)) $fields = array($fields); - $sql = ''; - $vals = array(); - if ($clearance!=null) { - $sql .= ' WHERE NOT EXISTS (SELECT * FROM '.$tab.'_access_clearance WHERE rule_id=acs.id AND '.implode(' AND ',array_fill(0, count($clearance), 'clearance!=%s')).')'; - $vals = array_values($clearance); - } - if ($action!='') { - if ($sql) $sql .= ' AND '; - else $sql .= ' WHERE '; - $sql .= 'action=%s'; - $vals[] = $action; - } - $sql = 'SELECT id, id FROM '.$tab.'_access AS acs'.$sql; - $ids = DB::GetAssoc($sql, $vals); - foreach ($fields as $f) { - $f = self::get_field_id($f); - foreach ($ids as $id) - DB::Execute('INSERT INTO '.$tab.'_access_fields (rule_id, block_field) VALUES (%d, %s)', array($id, $f)); - } - } - public static function wipe_access($tab) { - if (!self::check_table_name($tab, false, false)) return; - DB::Execute('DELETE FROM '.$tab.'_access_clearance'); - DB::Execute('DELETE FROM '.$tab.'_access_fields'); - DB::Execute('DELETE FROM '.$tab.'_access'); - } - public static function delete_access($tab, $id) { - if (!self::check_table_name($tab, false, false)) return; - DB::Execute('DELETE FROM '.$tab.'_access_clearance WHERE rule_id=%d', array($id)); - DB::Execute('DELETE FROM '.$tab.'_access_fields WHERE rule_id=%d', array($id)); - DB::Execute('DELETE FROM '.$tab.'_access WHERE id=%d', array($id)); - } - public static function delete_access_rules($tab, $action, $clearance, $crits = array()) - { - if (!self::check_table_name($tab, false, false)) return; - if (!is_array($clearance)) $clearance = array($clearance); - $clearance_c = count($clearance); - $serialized = self::serialize_crits($crits); - $ids = DB::GetCol('SELECT id FROM ' . $tab . '_access WHERE crits=%s AND action=%s', array($serialized, $action)); - $ret = 0; - foreach ($ids as $rule_id) { - $existing_clearance = DB::GetCol('SELECT clearance FROM ' . $tab . '_access_clearance WHERE rule_id=%d', array($rule_id)); - if ($clearance_c == count($existing_clearance) && - $clearance_c == count(array_intersect($existing_clearance, $clearance))) { - self::delete_access($tab, $rule_id); - $ret += 1; - } - } - return $ret; - } - public static function add_access($tab, $action, $clearance, $crits=array(), $blocked_fields=array()) { - if (!self::check_table_name($tab, false, false)) return; - $serialized = self::serialize_crits($crits); - DB::Execute('INSERT INTO '.$tab.'_access (crits, action) VALUES (%s, %s)', array($serialized, $action)); - $rule_id = DB::Insert_ID($tab.'_access','id'); - if (!is_array($clearance)) $clearance = array($clearance); - foreach ($clearance as $c) - DB::Execute('INSERT INTO '.$tab.'_access_clearance (rule_id, clearance) VALUES (%d, %s)', array($rule_id, $c)); - foreach ($blocked_fields as $f) - DB::Execute('INSERT INTO '.$tab.'_access_fields (rule_id, block_field) VALUES (%d, %s)', array($rule_id, $f)); - } - public static function update_access($tab, $id, $action, $clearance, $crits=array(), $blocked_fields=array()) { - if(is_string($id) && in_array($id,array('grant','restrict'))) return; - elseif(!is_numeric($id)) throw new Exception('Utils_RecordBrowserCommon::update_access - id have to be a number'); - - $serialized = self::serialize_crits($crits); - DB::Execute('UPDATE ' . $tab . '_access SET crits=%s, action=%s WHERE id=%d', array($serialized, $action, $id)); - if (!is_array($clearance)) $clearance = array($clearance); - DB::Execute('DELETE FROM '.$tab.'_access_clearance WHERE rule_id=%d', array($id)); - DB::Execute('DELETE FROM '.$tab.'_access_fields WHERE rule_id=%d', array($id)); - foreach ($clearance as $c) - DB::Execute('INSERT INTO '.$tab.'_access_clearance (rule_id, clearance) VALUES (%d, %s)', array($id, $c)); - foreach ($blocked_fields as $f) - DB::Execute('INSERT INTO '.$tab.'_access_fields (rule_id, block_field) VALUES (%d, %s)', array($id, $f)); - } - - public static function register_custom_access_callback($tab, $callback, $priority = 10) - { - if (!is_callable($callback)) { - return false; - } - if (is_array($callback)) { - $callback = implode('::', $callback); - } - $existing = self::get_custom_access_callbacks($tab); - if (in_array($callback, $existing)) { - return false; - } - DB::Execute('INSERT INTO recordbrowser_access_methods (tab, func, priority) VALUES (%s, %s, %d)', array($tab, $callback, $priority)); - self::get_custom_access_callbacks(null, true); - return true; - } - - public static function unregister_custom_access_callback($tab, $callback) - { - if (is_array($callback)) { - $callback = implode('::', $callback); - } - DB::Execute('DELETE FROM recordbrowser_access_methods WHERE tab=%s AND func=%s', array($tab, $callback)); - } - - public static function get_custom_access_callbacks($tab = null, $force_reload = false) - { - static $custom_access_callbacks; - if ($force_reload || $custom_access_callbacks === null) { - $custom_access_callbacks = array(); - $db = DB::GetAll('SELECT * FROM recordbrowser_access_methods ORDER BY priority DESC'); - foreach ($db as $row) { - if (!isset($custom_access_callbacks[$row['tab']])) { - $custom_access_callbacks[$row['tab']] = array(); - } - $custom_access_callbacks[$row['tab']][] = $row['func']; - } - } - if ($tab === null) { - return $custom_access_callbacks; - } - - return isset($custom_access_callbacks[$tab]) ? $custom_access_callbacks[$tab] : array(); - } - public static function call_custom_access_callbacks($tab, $action, $record = null) - { - $callbacks = self::get_custom_access_callbacks($tab); - $ret = array('grant'=>null, 'restrict'=>null); - foreach ($callbacks as $callback) { - $callback_crits = call_user_func($callback, $action, $record, $tab); - - if (is_bool($callback_crits)) { - $ret[$callback_crits? 'grant': 'restrict'] = true; - break; - } - - if ($callback_crits === null) continue; - - // if callback return is crits or crits array use it by default in restrict mode for backward compatibility - $crits = array( - 'grant' => null, - 'restrict' => $callback_crits - ); - - if (is_array($callback_crits) && (isset($callback_crits['grant']) || isset($callback_crits['restrict']))) { - // if restrict rules are not set make sure the restrict crits are clean - if (! isset($callback_crits['restrict'])) $callback_crits['restrict'] = null; - $crits = array_merge($crits, $callback_crits); - } - - if (!$crits['grant']) - $crits['grant'] = null; - - foreach ($crits as $mode => $c) { - $c = is_array($c) ? Utils_RecordBrowser_Crits::from_array($c): $c; - - if ($c instanceof Utils_RecordBrowser_Crits) - $ret[$mode] = ($ret[$mode] !== null) ? self::merge_crits($ret[$mode], $c, $mode === 'grant'): $c; - elseif (is_bool($c)) - $ret[$mode] = $c; - } - } - - return $ret; - } - - /** - * - * Check if user has access to recordset, record or recordset fields based on action performed - * - * @param string $tab - * @param string $action - * @param array $record - * @param boolean $return_crits - deprecated, use method Utils_RecordBrowserCommon::get_access_crits instead - * @param string $return_in_array - deprecated, use method Utils_RecordBrowserCommon::get_access_rule_crits instead - * @return false - deny access | array - fields access array - */ - public static function get_access($tab, $action, $record=null, $return_crits=false, $return_in_array=false){ - $access = Utils_RecordBrowser_Access::create($tab, $action, $record); - - //start deprecated code - used for backward compatibility - if ($return_crits) { - if ($return_in_array) - return $access->getRuleCrits(); - - return $access->getCrits();; - } - //end deprecated code - - return $access->getUserAccess(self::$admin_access); - } - - /** - * @param string $tab - * @param string $action - * @param array $record - * @return null|boolean|Utils_RecordBrowser_Crits - */ - public static function get_access_crits($tab, $action, $record=null) { - $access = Utils_RecordBrowser_Access::create($tab, $action, $record); - - return $access->getCrits(); - } - - /** - * @param string $tab - * @param string $action - * @param array $record - * @return array - rule_id => rule - */ - public static function get_access_rule_crits($tab, $action, $record=null) { - $access = Utils_RecordBrowser_Access::create($tab, $action, $record); - - return $access->getRuleCrits(); - } - - public static function is_record_active($record) { - if (isset($record[':active']) && !$record[':active']) - return false; - - return true; - } - - public static function get_record_info($tab, $id) { - self::check_table_name($tab); - $created = DB::GetRow('SELECT created_on, created_by FROM '.$tab.'_data_1 WHERE id=%d', array($id)); - $edited = DB::GetRow('SELECT edited_on, edited_by FROM '.$tab.'_edit_history WHERE '.$tab.'_id=%d ORDER BY edited_on DESC', array($id)); - if (!isset($edited['edited_on'])) $edited['edited_on'] = null; - if (!isset($edited['edited_by'])) $edited['edited_by'] = null; - if (!isset($created['created_on'])) trigger_error('There is no such record as '.$id.' in table '.$tab, E_USER_ERROR); - return array( 'created_on'=>$created['created_on'],'created_by'=>$created['created_by'], - 'edited_on'=>$edited['edited_on'],'edited_by'=>$edited['edited_by'], - 'id'=>$id); - } - public static function get_fav_button($tab, $id, $isfav = null) { - $tag_id = 'rb_fav_button_'.$tab.'_'.$id; - return ''.self::get_fav_button_tags($tab, $id, $isfav).''; - } - public static function get_fav_button_tags($tab, $id, $isfav = null) { - self::check_table_name($tab); - $star_on = Base_ThemeCommon::get_template_file('Utils_RecordBrowser','star_fav.png'); - $star_off = Base_ThemeCommon::get_template_file('Utils_RecordBrowser','star_nofav.png'); - load_js('modules/Utils/RecordBrowser/favorites.js'); - if ($isfav===null) $isfav = DB::GetOne('SELECT '.$tab.'_id FROM '.$tab.'_favorite WHERE user_id=%d AND '.$tab.'_id=%d', array(Acl::get_user(), $id)); - $tag_id = 'rb_fav_button_'.$tab.'_'.$id; - return ''.__('Click to remove it from your favorites'):__('Click to add this item to favorites'))).' onclick="utils_recordbrowser_set_favorite('.($isfav?0:1).',\''.$tab.'\','.$id.',\''.$tag_id.'\')" href="javascript:void(0);">'; - } - public static function set_favs($tab, $id, $state) { - self::check_table_name($tab); - if ($state) { - if (DB::GetOne('SELECT * FROM '.$tab.'_favorite WHERE user_id=%d AND '.$tab.'_id=%d', array(Acl::get_user(), $id))) return; - DB::Execute('INSERT INTO '.$tab.'_favorite (user_id, '.$tab.'_id) VALUES (%d, %d)', array(Acl::get_user(), $id)); - } else { - DB::Execute('DELETE FROM '.$tab.'_favorite WHERE user_id=%d AND '.$tab.'_id=%d', array(Acl::get_user(), $id)); - } - } - public static function get_html_record_info($tab, $id){ - if (is_string($id)) { - // to separate id in recurrent event - $tmp = explode('_', $id); - $id = $tmp[0]; - } - if (is_numeric($id)) $info = Utils_RecordBrowserCommon::get_record_info($tab, $id); - elseif (is_array($id)) $info = $id; - else trigger_error('Cannot decode record id: ' . print_r($id, true), E_USER_ERROR); - if (isset($info['id'])) $id = $info['id']; - - // If CRM Module is not installed get user login only - $created_by = Base_UserCommon::get_user_label($info['created_by']); - $htmlinfo=array( - __('Record ID').':'=>$id, - __('Created by').':'=>$created_by, - __('Created on').':'=>Base_RegionalSettingsCommon::time2reg($info['created_on']) - ); - if ($info['edited_on']!==null) { - $htmlinfo=$htmlinfo+array( - __('Edited by').':'=>$info['edited_by']!==null?Base_UserCommon::get_user_label($info['edited_by']):'', - __('Edited on').':'=>Base_RegionalSettingsCommon::time2reg($info['edited_on']) - ); - } - - return Utils_TooltipCommon::format_info_tooltip($htmlinfo); - } - public static function get_record($tab, $id, $htmlspecialchars=true) { - if (!is_numeric($id)) return null; - if (isset($id)) { - if(!self::check_table_name($tab,false,false)) return null; - self::init($tab); - $row = DB::GetRow('SELECT * FROM '.$tab.'_data_1 WHERE id=%d', array($id)); - $record = array('id'=>$id); - if (!isset($row['active'])) return null; - foreach(array('created_by','created_on') as $v) - $record[$v] = $row[$v]; - $record[':active'] = $row['active']; - foreach(self::$table_rows as $field=>$desc) { - if ($desc['type']==='multiselect' || $desc['type'] === 'file') { - if (!isset($row['f_'.$desc['id']])) $r = array(); - else $r = self::decode_multi($row['f_'.$desc['id']]); - $record[$desc['id']] = $r; - } else { - $record[$desc['id']] = (isset($row['f_'.$desc['id']])?$row['f_'.$desc['id']]:''); - if ($htmlspecialchars && $desc['type'] == 'text') $record[$desc['id']] = htmlspecialchars($record[$desc['id']]); - } - } - return $record; - } else { - return null; - } - } - - public static function get_record_respecting_access($tab, $id, $access_mode = 'view', $htmlspecialchars = true) - { - $record = self::get_record($tab, $id, $htmlspecialchars); - return self::filter_record_by_access($tab, $record, $access_mode); - } - - public static function filter_record_by_access($tab, $record, $access_mode = 'view') - { - if (!$record) { - return $record; - } - $access = self::get_access($tab, $access_mode, $record); - if (is_array($access)) { - foreach ($access as $field => $has_access) { - if (!$has_access) { - $record[$field] = null; - } - } - } else if (!$access) { - $record = false; - } - return $record; - } - - /** - * Change record state: active / inactive. Soft delete. - * - * @param $tab Recordset identifier - * @param $id Record ID - * @param $state Active / Inactive state - * - * @return bool True when status has been changed, false otherwise - */ - public static function set_active($tab, $id, $state) - { - self::check_table_name($tab); - $current = DB::GetOne('SELECT active FROM ' . $tab . '_data_1 WHERE id=%d', array($id)); - if ($current == ($state ? 1 : 0)) { - return false; - } - $record = self::get_record($tab, $id); - if (!$record) { - return false; - } - $values = self::record_processing($tab, $record, $state ? 'restore' : 'delete'); - if ($values === false) { - return false; - } - @DB::Execute('UPDATE ' . $tab . '_data_1 SET active=%d,indexed=0 WHERE id=%d', array($state ? 1 : 0, $id)); - $tab_prop = DB::GetRow('SELECT id,search_include FROM recordbrowser_table_properties WHERE tab=%s',array($tab)); - if ($tab_prop['search_include'] > 0) { - DB::Execute('DELETE FROM recordbrowser_search_index WHERE tab_id=%d AND record_id=%d',array($tab_prop['id'],$id)); - } - $edit_id = self::new_record_history($tab,$id,$state ? 'RESTORED' : 'DELETED'); - Utils_WatchdogCommon::new_event($tab, $id, ($state ? 'R' : 'D').'_'.$edit_id); - self::record_processing($tab, $record, $state ? 'restored' : 'deleted'); - return true; - } - - /** - * Delete record. - * - * @param string $tab Recordset identifier - * @param int $id Record ID - * @param bool $perma Delete permanently with all edit history - * - * @return bool True when record has been deleted, false otherwise - */ - public static function delete_record($tab, $id, $perma = false) - { - $ret = false; - if (!$perma) { - $ret = self::set_active($tab, $id, false); - } elseif (self::check_table_name($tab)) { - $record = self::get_record($tab, $id); - $values = self::record_processing($tab, $record, 'delete'); - if ($values === false) { - $ret = false; - } else { - self::delete_record_history($tab, $id); - self::delete_from_favorite($tab, $id); - self::delete_from_recent($tab, $id); - - DB::Execute('DELETE FROM ' . $tab . '_data_1 WHERE id=%d', array($id)); - $ret = DB::Affected_Rows() > 0; - if ($ret) { - self::record_processing($tab, $record, 'deleted'); - } - } - } - return $ret; - } - - /** - * Delete all history entries for specified record. - * - * @param $tab Recordset identifier - * @param $id Record ID - * - * @return int Number of affected edits deleted - */ - public static function delete_record_history($tab, $id) - { - $sql = 'DELETE FROM ' . $tab . '_edit_history_data WHERE edit_id IN' . - ' (SELECT id FROM ' . $tab . '_edit_history WHERE ' . $tab . '_id = %d)'; - DB::Execute($sql, array($id)); - $sql = 'DELETE FROM ' . $tab . '_edit_history WHERE ' . $tab . '_id = %d'; - DB::Execute($sql, array($id)); - return DB::Affected_Rows(); - } - - /** - * Delete favorites entries for specified record. - * - * @param $tab Recordset identifier - * @param $id Record ID - * - * @return int Number of favorites entries deleted - */ - public static function delete_from_favorite($tab, $id) - { - $sql = 'DELETE FROM ' . $tab . '_favorite WHERE ' . $tab . '_id = %d'; - DB::Execute($sql, array($id)); - return DB::Affected_Rows(); - } - - /** - * Delete recent entries for specified record. - * - * @param $tab Recordset identifier - * @param $id Record ID - * - * @return int Number of recent entries deleted - */ - public static function delete_from_recent($tab, $id) - { - $sql = 'DELETE FROM ' . $tab . '_recent WHERE ' . $tab . '_id = %d'; - DB::Execute($sql, array($id)); - return DB::Affected_Rows(); - } - - /** - * Restore record. - * - * @param $tab Recordset identifier - * @param $id Record ID - * - * @return bool True when record has been restored, false otherwise - */ - public static function restore_record($tab, $id) { - return self::set_active($tab, $id, true); - } - public static function no_wrap($s) { - $content_no_wrap = $s; - preg_match_all('/>([^\<\>]*)'.$tab.' - '.$def_md5.' - '.$id.' - '.$check_defaults); -// print('
'); - if (isset($_REQUEST['__add_record_to_RB_table']) && - isset($_REQUEST['__add_record_id']) && - isset($_REQUEST['__add_record_def']) && - ($tab==$_REQUEST['__add_record_to_RB_table']) && - (!$check_defaults || $def_md5==$_REQUEST['__add_record_def']) && - ($id==$_REQUEST['__add_record_id'])) { - unset($_REQUEST['__add_record_to_RB_table']); - unset($_REQUEST['__add_record_id']); - unset($_REQUEST['__add_record_def']); - Base_BoxCommon::push_module(Utils_RecordBrowser::module_name(),'view_entry',array('add', null, $def), array($tab)); - return array(); - } - return array('__add_record_to_RB_table'=>$tab, '__add_record_id'=>$id, '__add_record_def'=>$def_md5); - } - public static function create_new_record_href($tab, $def, $id='none', $check_defaults=true, $multiple_defaults=false){ - if($multiple_defaults) { - static $done = false; - if($done) return Libs_LeightboxCommon::get_open_href('actionbar_rb_new_record'); - eval_js_once('actionbar_rb_new_record_deactivate = function(){leightbox_deactivate(\'actionbar_rb_new_record\');}'); - $th = Base_ThemeCommon::init_smarty(); - $cds = array(); - foreach ($def as $k=>$v) { - $cds[] = array( 'label'=>_V($k), - 'open'=>'', - 'icon'=>$v['icon'], - 'close'=>'' - ); - } - $th->assign('custom_defaults', $cds); - ob_start(); - Base_ThemeCommon::display_smarty($th,'Utils_RecordBrowser','new_record_leightbox'); - $panel = ob_get_clean(); - Libs_LeightboxCommon::display('actionbar_rb_new_record',$panel,__('New record')); - $done = true; - return Libs_LeightboxCommon::get_open_href('actionbar_rb_new_record'); - } else - return Module::create_href(self::get_new_record_href($tab,$def, $id, $check_defaults)); - } - public static function get_record_href_array($tab, $id, $action='view'){ - self::check_table_name($tab); - if (isset($_REQUEST['__jump_to_RB_table']) && - ($tab==$_REQUEST['__jump_to_RB_table']) && - ($id==$_REQUEST['__jump_to_RB_record']) && - ($action==$_REQUEST['__jump_to_RB_action'])) { - unset($_REQUEST['__jump_to_RB_record']); - unset($_REQUEST['__jump_to_RB_table']); - unset($_REQUEST['__jump_to_RB_action']); - Base_BoxCommon::push_module(Utils_RecordBrowser::module_name(),'view_entry_with_REQUEST',array($action, $id, array(), true, $_REQUEST),array($tab)); - return array(); - } - return array('__jump_to_RB_table'=>$tab, '__jump_to_RB_record'=>$id, '__jump_to_RB_action'=>$action); - } - public static function create_record_href($tab, $id, $action='view',$more=array()){ - if(MOBILE_DEVICE) { - $cap = DB::GetOne('SELECT caption FROM recordbrowser_table_properties WHERE tab=%s',array($tab)); - return mobile_stack_href(array('Utils_RecordBrowserCommon','mobile_rb_view'),array($tab,$id),$cap); - } - return Module::create_href(self::get_record_href_array($tab,$id,$action)+$more); - } - public static function record_link_open_tag_r($tab, $record, $nolink=false, $action='view', $more=array()) - { - self::check_table_name($tab); - $ret = ''; - if (!isset($record['id']) || !is_numeric($record['id'])) { - return self::$del_or_a = ''; - } - if (class_exists('Utils_RecordBrowser') && - isset(Utils_RecordBrowser::$access_override) && - Utils_RecordBrowser::$access_override['tab']==$tab && - Utils_RecordBrowser::$access_override['id']==$record['id']) { - self::$del_or_a = ''; - if (!$nolink) $ret = ''; - else self::$del_or_a = ''; - } else { - $ret = ''; - $tip = ''; - self::$del_or_a = ''; - $has_access = self::get_access($tab, 'view', $record); - - if (!self::is_record_active($record)) { - $tip = __('This record was deleted from the system, please edit current record or contact system administrator'); - $ret = ''; - self::$del_or_a = ''; - } - if (!$has_access) { - $tip .= ($tip?'
':'').__('You don\'t have permission to view this record.'); - } - $tip = $tip ? Utils_TooltipCommon::open_tag_attrs($tip) : ''; - if (!$nolink) { - if($has_access) { - $href = self::create_record_href($tab, $record['id'], $action, $more); - $ret = '
'.$ret; - self::$del_or_a .= ''; - } else { - $ret = ''.$ret; - self::$del_or_a .= ''; - } - } - } - return $ret; - } - - public static function record_link_open_tag($tab, $id, $nolink=false, $action='view', $more=array()){ - self::check_table_name($tab); - $ret = ''; - if (!is_numeric($id)) { - return self::$del_or_a = ''; - } - if (class_exists('Utils_RecordBrowser') && - isset(Utils_RecordBrowser::$access_override) && - Utils_RecordBrowser::$access_override['tab']==$tab && - Utils_RecordBrowser::$access_override['id']==$id) { - self::$del_or_a = ''; - if (!$nolink) $ret = ''; - else self::$del_or_a = ''; - } else { - $record = self::get_record($tab, $id); - $ret = self::record_link_open_tag_r($tab, $record, $nolink, $action, $more); - } - return $ret; - } - public static function record_link_close_tag(){ - return self::$del_or_a; - } - public static function create_linked_label($tab, $cols, $id, $nolink=false, $tooltip=false, $more=array()){ - if (!is_numeric($id)) return ''; - if (!is_array($cols)) - $cols = explode('|', $cols); - - $record = self::get_record($tab, $id); - $fields = array_map(array('Utils_RecordBrowserCommon', 'get_field_id'), $cols); - $record_vals = self::get_record_vals($tab, $record, true, $fields, false); - if (empty($record_vals)) return ''; - - $vals = array(); - foreach ($fields as $field) { - if (empty($record_vals[$field])) continue; - $vals[] = $record_vals[$field]; - } - $record_label = implode(' ', $vals); - if (!$record_label) $record_label = self::get_caption($tab) . ": " . sprintf("#%06d", $id); - $text = self::create_record_tooltip($record_label, $tab, $id, $nolink, $tooltip); - - return self::record_link_open_tag_r($tab, $record, $nolink, 'view', $more) . - $text . self::record_link_close_tag(); - } - public static function create_linked_text($text, $tab, $id, $nolink=false, $tooltip=true, $more=array()){ - if ($nolink) return $text; - - if (!is_numeric($id)) return ''; - - $text = self::create_record_tooltip($text, $tab, $id, $nolink, $tooltip); - - return self::record_link_open_tag($tab, $id, $nolink, 'view', $more) . - $text . self::record_link_close_tag(); - } - public static function create_record_tooltip($text, $tab, $id, $nolink=false, $tooltip=true){ - if (!$tooltip || $nolink || Utils_TooltipCommon::is_tooltip_code_in_str($text)) - return $text; - - if (!is_array($tooltip)) - return self::create_default_record_tooltip_ajax($text, $tab, $id); - - //args name => expected index (in case of numeric indexed array) - $tooltip_create_args = array('tip'=>0, 'args'=>1, 'help'=>1, 'max_width'=>2); - - foreach ($tooltip_create_args as $name=>&$key) { - switch (true) { - case isset($tooltip[$name]): - $key = $tooltip[$name]; - break; - case isset($tooltip[$key]): - $key = $tooltip[$key]; - break; - default: - $key = null; - break; - } - } - - if (is_callable($tooltip_create_args['tip'])) { - unset($tooltip_create_args['help']); - - if (!is_array($tooltip_create_args['args'])) - $tooltip_create_args['args'] = array($tooltip_create_args['args']); - - $tooltip_create_callback = array('Utils_TooltipCommon', 'ajax_create'); - } - else { - unset($tooltip_create_args['args']); - $tooltip_create_callback = array('Utils_TooltipCommon', 'create'); - } - - array_unshift($tooltip_create_args, $text); - - //remove null values from end of the create_tooltip_args to ensure default argument values are set in the callback - while (is_null(end($tooltip_create_args))) - array_pop($tooltip_create_args); - - return call_user_func_array($tooltip_create_callback, $tooltip_create_args); - } - public static function get_record_vals($tab, $record, $nolink=false, $fields = array(), $silent = true){ - if (is_numeric($record)) $record = self::get_record($tab, $record); - if (!is_array($record)) return array(); - - self::init($tab); - if (empty($fields)) { - $fields = array_keys(self::$hash); - } - else { - $available_fields = array_intersect(array_keys(self::$hash), $fields); - - if (!$silent && count($available_fields) != count($fields)) { - trigger_error('Unknown field names: ' . implode(', ', array_diff($fields, $available_fields)), E_USER_ERROR); - } - - $fields = $available_fields; - } - - $ret = array(); - foreach ($fields as $field) { - if (!isset($record[$field])) continue; - - $ret[$field] = self::get_val($tab, $field, $record, $nolink); - } - return $ret; - } - public static function create_default_linked_label($tab, $id, $nolink=false, $table_name=true, $detailed_tooltip = true){ - if (!is_numeric($id)) return ''; - $record = self::get_record($tab,$id); - if(!$record) return ''; - $description_callback = self::get_description_callback($tab); - $description_fields = self::get_description_fields($tab); - $access = self::get_access($tab, 'view', $record); - - $tab_caption = self::get_caption($tab); - if(!$tab_caption || $tab_caption == '---') $tab_caption = $tab; - - $label = ''; - if ($access) { - if ($description_fields) { - $put_space_before = false; - foreach ($description_fields as $field) { - if ($field[0] === '"') { - $label .= trim($field, '"'); - $put_space_before = false; - } else { - $field_id = self::get_field_id($field); - if ($access === true || (array_key_exists($field_id, $access) && $access[$field_id])) { - $field_val = self::get_val($tab, $field, $record, true); - if ($field_val) { - if ($put_space_before) $label .= ' '; - $label .= $field_val; - $put_space_before = true; - } - } - } - } - } elseif ($description_callback) { - $label = call_user_func($description_callback, $record, $nolink); - } else { - $field = DB::GetOne('SELECT field FROM ' . $tab . '_field WHERE (type=\'autonumber\' OR ((type=\'text\' OR type=\'commondata\' OR type=\'integer\' OR type=\'date\') AND required=1)) AND visible=1 AND active=1 ORDER BY position'); - if ($field) { - $label = self::get_val($tab, $field, $record, $nolink); - } - } - } - if (!$label) { - $label = sprintf("%s: #%06d", $tab_caption, $id); - } else { - $label = ($table_name? $tab_caption . ': ': '') . $label; - } - - $ret = self::record_link_open_tag_r($tab, $record, $nolink) . $label . self::record_link_close_tag(); - if ($nolink == false && $detailed_tooltip) { - $ret = self::create_default_record_tooltip_ajax($ret, $tab, $id); - } - return $ret; - } - - public static function create_default_record_tooltip_ajax($string, $tab, $id, $force = false) - { - if ($force == false && Utils_TooltipCommon::is_tooltip_code_in_str($string)) { - return $string; - } - $string = Utils_TooltipCommon::ajax_create($string, array(__CLASS__, 'default_record_tooltip'), array($tab, $id)); - return $string; - } - - public static function get_record_tooltip_data($tab, $record_id) - { - $record = self::get_record($tab, $record_id); - if (!$record[':active']) { - return array(); - } - $cols = self::init($tab); - $access = self::get_access($tab, 'view', $record); - $data = array(); - foreach ($cols as $desc) { - if ($desc['tooltip'] && $access[$desc['id']]) { - $data[_V($desc['name'])] = self::get_val($tab, $desc['id'], $record, true); - } - } - return $data; - } - public static function default_record_tooltip($tab, $record_id) - { - $data = self::get_record_tooltip_data($tab, $record_id); - return Utils_TooltipCommon::format_info_tooltip($data); - } - public static function display_linked_field_label($record, $nolink=false, $desc=null, $tab = ''){ - return Utils_RecordBrowserCommon::create_linked_label_r($tab, $desc['id'], $record, $nolink); - } - public static function create_linked_label_r($tab, $cols, $r, $nolink=false, $tooltip=false){ - if (!is_array($cols)) - $cols = array($cols); - $open_tag = self::record_link_open_tag_r($tab, $r, $nolink); - $close_tag = self::record_link_close_tag(); - self::init($tab); - $vals = array(); - foreach ($cols as $col) { - if (isset(self::$table_rows[$col])) - $col = self::$table_rows[$col]['id']; - elseif (!isset(self::$hash[$col])) - trigger_error('Unknown column name: ' . $col, E_USER_ERROR); - if ($r[$col]) - $vals[] = $r[$col]; - } - $text = self::create_record_tooltip(implode(' ', $vals), $tab, $r['id'], $nolink, $tooltip); - - return $open_tag . $text . $close_tag; - } - public static function record_bbcode($tab, $fields, $text, $record_id, $opt, $tag = null) { - if (!is_numeric($record_id)) { - $parts = explode(' ', $text); - $crits = array(); - foreach ($parts as $k=>$v) { - $v = "%$v%"; - $chr = '('; - foreach ($fields as $f) { - $crits[$chr.str_repeat('_', $k).$f] = $v; - $chr='|'; - } - } - $rec = Utils_RecordBrowserCommon::get_records($tab, $crits, array(), array(), 1); - if (is_array($rec) && !empty($rec)) $rec = array_shift($rec); - else { - $crits = array(); - foreach ($parts as $k=>$v) { - $v = "%$v%"; - $chr = '('; - foreach ($fields as $f) { - $crits[$chr.str_repeat('_', $k).'~'.$f] = $v; - $chr='|'; - } - } - $rec = Utils_RecordBrowserCommon::get_records($tab, $crits, array(), array(), 1); - if (is_array($rec)) $rec = array_shift($rec); - else $rec = null; - } - } else { - $rec = Utils_RecordBrowserCommon::get_record($tab, $record_id); - } - if ($opt) { - if (!$rec) return null; - $tag_param = $rec['id']; - if ($tag == 'rb') $tag_param = "$tab/$tag_param"; - return Utils_BBCodeCommon::create_bbcode(null, $tag_param, $text); - } - if ($rec) { - $access = self::get_access($tab, 'view', $rec); - if (!$access) { - $text = "[" . __('Link to record') . ']'; - } - if (!$text) { - if ($fields) { - return self::create_linked_label_r($tab, $fields, $rec); - } - return self::create_default_linked_label($tab, $rec['id']); - } - return Utils_RecordBrowserCommon::record_link_open_tag_r($tab, $rec).$text.Utils_RecordBrowserCommon::record_link_close_tag(); - } - $msg = __('Record not found'); - if ($tag == 'rb') { - if (!self::check_table_name($tab, false, false)) { - $msg = __('Recordset not found'); - } - return Utils_BBCodeCommon::create_bbcode($tag, "$tab/$record_id", $text, $msg); - } - return Utils_BBCodeCommon::create_bbcode($tag, $record_id, $text, $msg); - } - public static function applet_settings($some_more = array()) { - $some_more = array_merge($some_more,array( - array('label'=>__('Actions'),'name'=>'actions_header','type'=>'header'), - array('label'=>__('Info'),'name'=>'actions_info','type'=>'checkbox','default'=>true), - array('label'=>__('View'),'name'=>'actions_view','type'=>'checkbox','default'=>false), - array('label'=>__('Edit'),'name'=>'actions_edit','type'=>'checkbox','default'=>true), - array('label'=>__('Delete'),'name'=>'actions_delete','type'=>'checkbox','default'=>false), - array('label'=>__('View edit history'),'name'=>'actions_history','type'=>'checkbox','default'=>false), - )); - return $some_more; - } - - /** - * Returns older version of te record. - * - * @param RecordSet - name of the recordset - * @param Record ID - ID of the record - * @param Revision ID - RB will backtrace all edits on that record down-to and including edit with this ID - */ - public static function get_record_revision($tab, $id, $rev_id) { - self::init($tab); - $r = self::get_record($tab, $id); - $ret = DB::Execute('SELECT id, edited_on, edited_by FROM '.$tab.'_edit_history WHERE '.$tab.'_id=%d AND id>=%d ORDER BY edited_on DESC, id DESC',array($id, $rev_id)); - while ($row = $ret->FetchRow()) { - $changed = array(); - $ret2 = DB::Execute('SELECT * FROM '.$tab.'_edit_history_data WHERE edit_id=%d',array($row['id'])); - while($row2 = $ret2->FetchRow()) { - $k = $row2['field']; - $v = $row2['old_value']; - if ($k=='id') $r['active'] = ($v!='DELETED'); - else { - if (!isset(self::$hash[$k])) continue; - $r[$k] = $v; - } - } - } - return $r; - } - - public static function get_edit_details($tab, $rid, $edit_id,$details=true) { - return self::get_edit_details_modify_record($tab, $rid, $edit_id,$details); - } - - public static function get_edit_details_modify_record($tab, $rid, $edit_id, $details=true) { - self::init($tab); - if (is_numeric($rid)) { - $prev_rev = DB::GetOne('SELECT MIN(id) FROM '.$tab.'_edit_history WHERE '.$tab.'_id=%d AND id>%d', array($rid, $edit_id)); - $r = self::get_record_revision($tab, $rid, $prev_rev); - } else $r = $rid; - $edit_info = DB::GetRow('SELECT * FROM '.$tab.'_edit_history WHERE id=%d',array($edit_id)); - $event_display = array('what'=>'Error, Invalid event: '.$edit_id); - if (!$edit_info) return $event_display; - - $event_display = array( - 'who'=>Base_UserCommon::get_user_label($edit_info['edited_by'], true), - 'when'=>Base_RegionalSettingsCommon::time2reg($edit_info['edited_on']), - 'what'=>array() - ); - $edit_details = DB::GetAssoc('SELECT field, old_value FROM '.$tab.'_edit_history_data WHERE edit_id=%d',array($edit_id)); - self::init($tab); // because get_user_label messes up - foreach ($r as $k=>$v) { - if (isset(self::$hash[$k]) && self::$table_rows[self::$hash[$k]]['type']=='multiselect') - $r[$k] = self::decode_multi($r[$k]); // We have to decode all fields, because access and some display relay on it, regardless which field changed - } - $r2 = $r; - foreach ($edit_details as $k=>$v) { - $k = self::get_field_id($k); // failsafe - if (!isset(self::$hash[$k])) continue; - if (self::$table_rows[self::$hash[$k]]['type']=='multiselect') { - $v = $edit_details[$k] = self::decode_multi($v); - } - $r2[$k] = $v; - } - $access = self::get_access($tab,'view',$r); - $modifications_to_show = 0; - foreach ($edit_details as $k=>$v) { - if($k=='id') { - $modifications_to_show += 1; - if (!$details) continue; // do not generate content when we dont want them - $event_display['what'] = _V($v); - continue; - } - $k = self::get_field_id($k); // failsafe - if (!isset(self::$hash[$k])) continue; - if (!$access[$k]) continue; - $modifications_to_show += 1; - if (!$details) continue; // do not generate content when we dont want them - self::init($tab); - $field = self::$hash[$k]; - $desc = self::$table_rows[$field]; - $event_display['what'][] = array( - _V($desc['name']), - self::get_val($tab, $field, $r2, true, $desc), - self::get_val($tab, $field, $r, true, $desc) - ); - } - if ($modifications_to_show) - return $event_display; - return null; - } - - public static function get_edit_details_label($tab, $rid, $edit_id,$details = true) { - $ret = self::watchdog_label($tab, '', $rid, array('E_'.$edit_id), '', $details); - return $ret['events']; - } - - public static function watchdog_label($tab, $cat, $rid, $events = array(), $label = null, $details = true) { - $ret = array('category'=>$cat); - if ($rid!==null) { - $r = self::get_record($tab, $rid); - if ($r===null) return null; - if (!self::get_access($tab, 'view', $r)) return null; - if (is_array($label) && is_callable($label)) { - $label = self::create_linked_text(call_user_func($label, $r, true), $tab, $rid); - } elseif ($label) { - $label = self::create_linked_label_r($tab, $label, $r, false, true); - } else { - $label = self::create_default_linked_label($tab, $rid, false, false); - } - - $ret['title'] = $label; - $ret['view_href'] = Utils_RecordBrowserCommon::create_record_href($tab, $rid); - $events_display = array(); - $events = array_reverse($events); - $other_events = array(); - $header = false; - foreach ($events as $v) { - if (count($events_display)>20) { - $other_events[__('And more...')] = 1; - break; - } - $param = explode('_', $v); - switch ($param[0]) { - case 'C': $what = 'Created'; - $event_display = array( - 'who'=> Base_UserCommon::get_user_label($r['created_by'], true), - 'when'=>Base_RegionalSettingsCommon::time2reg($r['created_on']), - 'what'=>_V($what) - ); - break; - case 'D': if (!isset($what)) $what = 'Deleted'; - case 'R': if (!isset($what)) $what = 'Restored'; - if(!isset($param[1])) { - $event_display = array( - 'who' => '', - 'when' => '', - 'what' => _V($what) - ); - break; - } - case 'E': $event_display = self::get_edit_details_modify_record($tab, $r['id'], $param[1] ,$details); - if (isset($event_display['what']) && !empty($event_display['what'])) $header = true; - break; - - case 'N': $event_display = false; - switch($param[1]) { - case '+': - $action = __('Note linked'); - break; - case '-': - $action = __('Note unlinked'); - break; - default: - if (!isset($other_events[$param[1]])) $other_events[$param[1]] = 0; - $other_events[$param[1]]++; - $event_display = null; - break; - } - if($event_display===false) { - $date = isset($param[3]) ? Base_RegionalSettingsCommon::time2reg($param[3]) : ''; - $who = isset($param[4]) ? Base_UserCommon::get_user_label($param[4], true) : ''; - $action .= ' - ' . self::create_default_linked_label('utils_attachment', $param[2]); - $event_display = array('what'=>$action, - 'who' => $who, - 'when' => $date); - } - break; - default: $event_display = array('what'=>_V($v)); - } - if ($event_display) $events_display[] = $event_display; - } - foreach ($other_events as $k=>$v) - $events_display[] = array('what'=>_V($k).($v>1?' ['.$v.']':'')); - - if ($events_display) { - $theme = Base_ThemeCommon::init_smarty(); - - if ($header) { - $theme->assign('header', array(__('Field'), __('Old value'), __('New value'))); - } - - $theme->assign('events', $events_display); - - $tpl = 'changes_list'; - if (Utils_WatchdogCommon::email_mode()) { - $record_data = self::get_record_tooltip_data($tab, $rid); - $theme->assign('record', $record_data); - $tpl = 'changes_list_email'; - } - ob_start(); - Base_ThemeCommon::display_smarty($theme,'Utils_RecordBrowser', $tpl); - $output = ob_get_clean(); - - $ret['events'] = $output; - } else { - // if we've generated empty events for certain record, then - // it's possible that some of the fields, that have changed, - // are hidden so we have to check if there are any other events - // If all events are the same and output is empty we can safely - // mark all as notified. - $all_events = Utils_WatchdogCommon::check_if_notified($tab, $rid); - if (count($all_events) == count($events)) { - Utils_WatchdogCommon::notified($tab, $rid); - } - $ret = null; - } - } - return $ret; - } - public static function get_tables($tab){ - return array( $tab.'_callback', - $tab.'_recent', - $tab.'_favorite', - $tab.'_edit_history_data', - $tab.'_edit_history', - $tab.'_field', - $tab.'_data_1'); - } - - public static function applet_new_record_button($tab, $defaults = array()) { - if (!self::get_access($tab, 'add')) return ''; - return ''; - } - - public static function get_calculated_id($tab, $field, $id) { - return $tab.'__'.$field.'___'.$id; - } - - public static function check_for_jump() { - if (isset($_REQUEST['__jump_to_RB_table']) && - isset($_REQUEST['__jump_to_RB_record'])) { - $tab = $_REQUEST['__jump_to_RB_table']; - $id = $_REQUEST['__jump_to_RB_record']; - $action = $_REQUEST['__jump_to_RB_action']; - if (!is_numeric($id)) return false; - Utils_RecordBrowserCommon::check_table_name($tab); - if (!self::get_access($tab,'browse')) return false; - if (!DB::GetOne('SELECT id FROM '.$tab.'_data_1 WHERE id=%d', $id)) return false; - unset($_REQUEST['__jump_to_RB_record']); - unset($_REQUEST['__jump_to_RB_table']); - unset($_REQUEST['__jump_to_RB_action']); - Base_BoxCommon::push_module(Utils_RecordBrowser::module_name(),'view_entry_with_REQUEST',array($action, $id, array(), true, $_REQUEST),array($tab)); - return true; - } - return false; - } - - public static function cut_string($str, $len, $tooltip=true, &$cut=null) { - return $str; - if ($len==-1) return $str; - $ret = ''; - $strings = explode('
',$str); - foreach ($strings as $str) { - if ($ret) $ret .= '
'; - $label = ''; - $i = 0; - $curr_len = 0; - $tags = array(); - $inside = 0; - preg_match_all('/./u', $str, $a); - $a = $a[0]; - $strlen = count($a); - while ($curr_len<=$len && $i<$strlen) { - if ($a[$i] == '&' && !$inside) { - $e = -1; - if (isset($a[$i+3]) && $a[$i+3]==';') $e = 3; - elseif (isset($a[$i+4]) && $a[$i+4]==';') $e = 4; - elseif (isset($a[$i+5]) && $a[$i+5]==';') $e = 5; - if ($e!=-1) { - $hsc = implode("", array_slice($a, $i, $e+1)); - if ($hsc==' ' || strlen(htmlspecialchars_decode($hsc))==1) { - $label .= implode("", array_slice($a, $i, $e)); - $i += $e; - $curr_len++; - } - } - } elseif ($a[$i] == '<' && !$inside) { - $inside = 1; - if (isset($a[$i+1]) && $a[$i+1] == '/') { - if (!empty($tags)) array_pop($tags); - } else { - $j = 1; - $next_tag = ''; - while ($i+$j<=$strlen && $a[$i+$j]!=' ' && $a[$i+$j]!='>' && $a[$i+$j]!='/') { - $next_tag .= $a[$i+$j]; - $j++; - } - $tags[] = $next_tag; - } - } elseif ($a[$i] == '"' && $inside==1) { - $inside = 2; - } elseif ($a[$i] == '"' && $inside==2) { - $inside = 1; - } elseif ($a[$i] == '>' && $inside==1) { - if ($i>0 && $a[$i-1] == '/') array_pop($tags); - $inside = 0; - } elseif (!$inside) { - $curr_len++; - } - $label .= $a[$i]; - $i++; - } - if ($i<$strlen) { - $cut = true; - $label .= '...'; - if ($tooltip) { - if (!strpos($str, 'Utils_Toltip__showTip(')) $label = ''.$label.''; - else $label = preg_replace('/Utils_Toltip__showTip\(\'(.*?)\'/', 'Utils_Toltip__showTip(\''.escapeJS(htmlspecialchars($str)).'
$1\'', $label); - } - } - while (!empty($tags)) $label .= ''; - $ret .= $label; - } - return $ret; - } - - public static function build_cols_array($tab, $arg) { - self::init($tab); - $arg = array_flip($arg); - $ret = array(); - foreach (self::$table_rows as $desc) { - if ($desc['visible'] && !isset($arg[$desc['id']])) $ret[$desc['id']] = false; - elseif (!$desc['visible'] && isset($arg[$desc['id']])) $ret[$desc['id']] = true; - } - return $ret; - } - - public static function autoselect_label($tab_id, $args) { -// $args = array($tab, $tab_crits, $format_callback, $params); - - $param = self::decode_select_param($args[3]); - - $val = self::decode_record_token($tab_id, $param['single_tab']); - - if (!$val) return ''; - - list($tab, $record_id) = $val; - - if ($param['cols']) - return self::create_linked_label($tab, $param['cols'], $record_id, true); - else - return self::create_default_linked_label($tab, $record_id, true, false); - } - - private static $automulti_order_tabs; - public static function automulti_order_by($a,$b) { - $aa = _V($a); - $bb = _V($b); - $aam = preg_match(self::$automulti_order_tabs,$aa) || preg_match(self::$automulti_order_tabs,$a); - $bbm = preg_match(self::$automulti_order_tabs,$bb) || preg_match(self::$automulti_order_tabs,$b); - if($aam && !$bbm) - return -1; - if($bbm && !$aam) - return 1; - return strcasecmp($aa,$bb); - } - - public static function automulti_suggestbox($str, $tab, $tab_crits, $f_callback, $param) { - $param = self::decode_select_param($param); - - $words = array_filter(explode(' ',$str)); - $words_db = $words; - self::$automulti_order_tabs = array(); - foreach($words_db as & $w) { - if(mb_strlen($w)>=3) self::$automulti_order_tabs[] = preg_quote($w,'/'); - $w = "%$w%"; - } - self::$automulti_order_tabs = '/('.implode('|',self::$automulti_order_tabs).')/i'; - - $tabs = $param['select_tabs']; - foreach($tabs as & $t) $t = DB::qstr($t); - $tabs = DB::GetAssoc('SELECT tab,caption FROM recordbrowser_table_properties WHERE tab IN ('.implode(',',$tabs).')'); - - $single_tab = $param['single_tab']; - - uasort($tabs,array('Utils_RecordBrowserCommon','automulti_order_by')); - - $ret = array(); - - //backward compatibility - if ($single_tab) { - if (is_array($tab_crits) && !isset($tab_crits[$single_tab])) $tab_crits = array($single_tab=>$tab_crits); - } - foreach($tabs as $t=>$caption) { - if(!empty($tab_crits) && !isset($tab_crits[$t])) continue; - - $access_crits = self::get_access_crits($t, 'selection'); - if ($access_crits===false) continue; - if ($access_crits!==true && (is_array($access_crits) || $access_crits instanceof Utils_RecordBrowser_CritsInterface)) { - if((is_array($tab_crits[$t]) && $tab_crits[$t]) || $tab_crits[$t] instanceof Utils_RecordBrowser_CritsInterface) - $tab_crits[$t] = self::merge_crits($tab_crits[$t], $access_crits); - else - $tab_crits[$t] = $access_crits; - } - - $fields = $param['cols']; - if(!$fields) $fields = DB::GetCol("SELECT field FROM {$t}_field WHERE active=1 AND visible=1 AND (type NOT IN ('calculated','page_split','hidden') OR (type='calculated' AND param is not null AND param!=''))"); - - $words_db_tmp = $words_db; - $words_tmp = $words; - if (!$single_tab) { - foreach ($words_tmp as $pos => $word) { - $expr = '/' . preg_quote($word, '/') . '/i'; - if (preg_match($expr, $caption) || preg_match($expr, _V($caption))) { - unset($words_db_tmp[$pos]); - unset($words_tmp[$pos]); - } - } - } - $str_db = '%' . implode(' ', $words_tmp) . '%'; - - $crits2A = array(); - $crits2B = array(); - $order = array(); - foreach ($fields as $f) { - $field_id = self::get_field_id($f); - $crits2A = self::merge_crits($crits2A, array('~' . $field_id => $str_db), true); - $crits2B = self::merge_crits($crits2B, array('~' . $field_id => $words_db_tmp), true); - $order[$field_id] = 'ASC'; - } - $crits3A = self::merge_crits(isset($tab_crits[$t])?$tab_crits[$t]:array(),$crits2A); - $crits3B = self::merge_crits(isset($tab_crits[$t])?$tab_crits[$t]:array(),$crits2B); - - $records = self::get_records($t, $crits3A, array(), $order, 10); - - foreach ($records as $r) { - if(!self::get_access($t,'view',$r)) continue; - $ret[($single_tab?'':$t.'/').$r['id']] = self::call_select_item_format_callback($f_callback, $t.'/'.$r['id'], array($tab, $crits3A, $f_callback, $param)); - } - - $records = self::get_records($t, $crits3B, array(), $order, 10); - - foreach ($records as $r) { - if(isset($ret[($single_tab?'':$t.'/').$r['id']]) || - !self::get_access($t,'view',$r)) continue; - $ret[($single_tab?'':$t.'/').$r['id']] = self::call_select_item_format_callback($f_callback, $t.'/'.$r['id'], array($tab, $crits3B, $f_callback, $param)); - } - - if(count($ret)>=10) break; - } - return $ret; - } - -/** - * Function to manipulate clipboard pattern - * @param string $tab recordbrowser table name - * @param string|null $pattern pattern, or when it's null the pattern stays the same, only enable state changes - * @param bool $enabled new enabled state of clipboard pattern - * @param bool $force make it true to allow any changes or overwrite when clipboard pattern exist - * @return bool true if any changes were made, false otherwise - */ - public static function set_clipboard_pattern($tab, $pattern, $enabled = true, $force = false) { - $ret = null; - $enabled = $enabled ? 1 : 0; - $r = self::get_clipboard_pattern($tab, true); - /* when pattern exists and i can overwrite it... */ - if($r && $force) { - /* just change enabled state, when pattern is null */ - if($pattern === null) { - $ret = DB::Execute('UPDATE recordbrowser_clipboard_pattern SET enabled=%d WHERE tab=%s',array($enabled,$tab)); - } else { - /* delete if it's not necessary to hold any value */ - if($enabled == 0 && strlen($pattern) == 0) $ret = DB::Execute('DELETE FROM recordbrowser_clipboard_pattern WHERE tab = %s', array($tab)); - /* or update values */ - else $ret = DB::Execute('UPDATE recordbrowser_clipboard_pattern SET pattern=%s,enabled=%d WHERE tab=%s',array($pattern,$enabled,$tab)); - } - } - /* there is no such pattern in database so create it*/ - if(!$r) { - $ret = DB::Execute('INSERT INTO recordbrowser_clipboard_pattern values (%s,%s,%d)',array($tab, $pattern, $enabled)); - } - if($ret) return true; - return false; - } - -/** - * Returns clipboard pattern string only if it is enabled. If 'with_state' is true return value is associative array with pattern and enabled keys. - * @param string $tab name of RecordBrowser table - * @param bool $with_state return also state of pattern - * @return string|array string by default, array when with_state=true - */ - public static function get_clipboard_pattern($tab, $with_state = false) { - if($with_state) { - $ret = DB::GetArray('SELECT pattern,enabled FROM recordbrowser_clipboard_pattern WHERE tab=%s', array($tab)); - if(sizeof($ret)) return $ret[0]; - } - return DB::GetOne('SELECT pattern FROM recordbrowser_clipboard_pattern WHERE tab=%s AND enabled=1', array($tab)); - } - - public static function replace_clipboard_pattern($text, $data) { - /* some complicate preg match to find every occurence - * of %{ .. {f_name} .. } pattern - */ - $match = []; - if (preg_match_all('/%\{(([^%\}\{]*?\{[^%\}\{]+?\}[^%\}\{]*?)+?)\}/', $text, $match)) { // match for all patterns %{...{..}...} - foreach ($match[0] as $k => $matched_string) { - $text_replace = $match[1][$k]; - $changed = false; - $second_match = []; - while(preg_match('/\{(.+?)\}/', $text_replace, $second_match)) { // match for keys in braces {key} - $replace_value = ''; - if(array_key_exists($second_match[1], $data)) { - $replace_value = $data[$second_match[1]]; - $changed = true; - } - $text_replace = str_replace($second_match[0], $replace_value, $text_replace); - } - if(! $changed ) $text_replace = ''; - $text = str_replace($matched_string, $text_replace, $text); - } - } - - return $text; - } - - public static function get_field_tooltip($label) { - if(strpos($label,'Utils_Tooltip')!==false) return $label; - $args = func_get_args(); - array_shift($args); - return Utils_TooltipCommon::ajax_create($label, array('Utils_RecordBrowserCommon', 'ajax_get_field_tooltip'), $args); - } - - public static function ajax_get_field_tooltip() { - $args = func_get_args(); - $type = array_shift($args); - switch ($type) { - case 'autonumber': - case 'calculated': return __('This field is not editable'); - case 'integer': - case 'float': return __('Enter a numeric value in the text field'); - case 'checkbox': return __('Click to switch between checked/unchecked state'); - case 'currency': return __('Enter the amount in text field and select currency'); - case 'text': $ret = __('Enter the text in the text field'); - if (isset($args[0]) && is_numeric($args[0])) $ret .= '
'.__('Maximum allowed length is %s characters', array(''.$args[0].'')); - return $ret; - case 'long text': $example_text = __('Example text'); - return __('Enter the text in the text area').'
'.__('Maximum allowed length is %s characters', array('400')).'
'.'
'. - __('BBCodes are supported:').'
'. - '[b]'.$example_text.'[/b] - '.$example_text.''.'
'. - '[u]'.$example_text.'[/u] - '.$example_text.''.'
'. - '[i]'.$example_text.'[/i] - '.$example_text.''; - case 'date': return __('Enter the date in your selected format').'
'.__('Click on the text field to bring up a popup Calendar that allows you to pick the date').'
'.__('Click again on the text field to close popup Calendar'); - case 'timestamp': return __('Enter the date in your selected format and the time using select elements').'
'.__('Click on the text field to bring up a popup Calendar that allows you to pick the date').'
'.__('Click again on the text field to close popup Calendar').'
'.__('You can change 12/24-hour format in Control Panel, Regional Settings'); - case 'time': return __('Enter the time using select elements').'
'.__('You can change 12/24-hour format in Control Panel, Regional Settings'); - case 'commondata': $ret = __('Select value'); - if (isset($args[0])) $ret .= ' '.__('from %s table', array(''.str_replace('_', '/', $args[0]).'')); - return $ret; - case 'select': $ret = __('Select one'); - if (isset($args[0])) { - if (is_array($args[0])) { - $cap = array(); - foreach ($args[0] as $t) $cap[] = ''.self::get_caption($t).''; - $cap = implode(' '.__('or').' ',$cap); - } else $cap = ''.self::get_caption($args[0]).''; - $ret .= ' '.__('of').' '.$cap; - } - if (isset($args[1])) { - $val = self::crits_to_words($args[0], $args[1]); - if ($val) $ret .= ' '.__('for which').'
   '.$val; - } - return $ret; - case 'multiselect': $ret = __('Select multiple'); - if (isset($args[0])) { - if (is_array($args[0])) { - $cap = array(); - foreach ($args[0] as $t) $cap[] = ''.self::get_caption($t).''; - $cap = implode(' '.__('or').' ',$cap); - } else $cap = ''.self::get_caption($args[0]).''; - $ret .= ' '.$cap; - } - if (isset($args[1])) { - $val = self::crits_to_words($args[0], $args[1]); - if ($val) $ret .= ' '.__('for which').'
   '.$val; - } - return $ret; - } - return __('No additional information'); - } - - public static $date_values = array('-1 year'=>'1 year back','-6 months'=>'6 months back','-3 months'=>'3 months back','-2 months'=>'2 months back','-1 month'=>'1 month back','-2 weeks'=>'2 weeks back','-1 week'=>'1 week back','-6 days'=>'6 days back','-5 days'=>'5 days back','-4 days'=>'4 days back','-3 days'=>'3 days back','-2 days'=>'2 days back','-1 days'=>'1 days back','today'=>'current day','+1 days'=>'1 days forward','+2 days'=>'2 days forward','+3 days'=>'3 days forward','+4 days'=>'4 days forward','+5 days'=>'5 days forward','+6 days'=>'6 days forward','+1 week'=>'1 week forward','+2 weeks'=>'2 weeks forward','+1 month'=>'1 month forward','+2 months'=>'2 months forward','+3 months'=>'3 months forward','+6 months'=>'6 months forward','+1 year'=>'1 year forward'); - public static function crits_to_words($tab, $crits, $html_decoration=true) { - if (!is_object($crits)) { - $crits = Utils_RecordBrowser_Crits::from_array($crits); - } - $crits = $crits->replace_special_values(true); - $c2w = new Utils_RecordBrowser_CritsToWords($tab); - $c2w->enable_html_decoration($html_decoration); - return $c2w->to_words($crits); - } - - public static function get_printer($tab) - { - $class = DB::GetOne('SELECT printer FROM recordbrowser_table_properties WHERE tab=%s',$tab); - if($class && class_exists($class)) - return new $class(); - return new Utils_RecordBrowser_RecordPrinter(); - } - //////////////////////////// - // default QFfield callbacks - - public static function get_default_QFfield_callback($type) { - $types = array('hidden', 'checkbox', 'calculated', 'integer', 'float', - 'currency', 'text', 'long text', 'date', 'timestamp', 'time', - 'commondata', 'select', 'multiselect', 'autonumber', 'file'); - if (array_search($type, $types) !== false) { - return __CLASS__. '::QFfield_' . self::get_field_id($type); - } - return null; - } - - public static function QFfield_static_display(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if ($mode !== 'add' && $mode !== 'edit') { - if ($desc['type'] != 'checkbox' || isset($rb_obj->display_callback_table[$field])) { - $def = self::get_val($rb_obj->tab, $field, $rb_obj->record, false, $desc); - $form->addElement('static', $field, $label, $def, array('id' => $field)); - return true; - } - } - return false; - } - - public static function QFfield_hidden(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - $form->addElement('hidden', $field); - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_checkbox(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $el = $form->addElement('advcheckbox', $field, $label, '', array('id' => $field)); - $el->setValues(array('0','1')); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_calculated(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('static', $field, $label); - if (!is_array($rb_obj->record)) - $values = $rb_obj->custom_defaults; - else { - $values = $rb_obj->record; - if (is_array($rb_obj->custom_defaults)) - $values = $values + $rb_obj->custom_defaults; - } - $val = isset($values[$desc['id']]) ? - self::get_val($rb_obj->tab, $field, $values, true, $desc) - : ''; - if (!$val) - $val = '[' . __('formula') . ']'; - $record_id = isset($rb_obj->record['id']) ? $rb_obj->record['id'] : null; - $form->setDefaults(array($field => '
' . $val . '
')); - } - - public static function QFfield_integer(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('text', $field, $label, array('id' => $field)); - $form->addRule($field, __('Only integer numbers are allowed.'), 'regex', '/^\-?[0-9]*$/'); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_float(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('text', $field, $label, array('id' => $field)); - $form->addRule($field, __('Only numbers are allowed.'), 'numeric'); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_currency(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('currency', $field, $label, (isset($desc['param']) && is_array($desc['param']))?$desc['param']:array(), array('id' => $field)); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - // set element value to persist currency over soft submit - if ($form->isSubmitted() && $form->exportValue('submited') == false) { - $default = $form->exportValue($field); - $form->getElement($field)->setValue($default); - } - } - - public static function QFfield_text(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type'], $desc['param']); - $form->addElement('text', $field, $label, array('id' => $field, 'maxlength' => $desc['param'])); - $form->addRule($field, __('Maximum length for this field is %s characters.', array($desc['param'])), 'maxlength', $desc['param']); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_long_text(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('textarea', $field, $label, array('id' => $field)); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_date(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('datepicker', $field, $label, array('id' => $field)); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function timestamp_required($v) { - return $v['__datepicker'] !== '' && Base_RegionalSettingsCommon::reg2time($v['__datepicker'], false) !== false; - } - - public static function QFfield_timestamp(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $f_param = array('id' => $field); - if ($desc['param']) - $f_param['optionIncrement'] = array('i' => $desc['param']); - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $form->addElement('timestamp', $field, $label, $f_param); - static $rule_defined = false; - if (!$rule_defined) { - $form->registerRule('timestamp_required', 'callback', 'timestamp_required', __CLASS__); - $rule_defined = true; - } - if (isset($desc['required']) && $desc['required']) - $form->addRule($field, __('Field required'), 'timestamp_required'); - if ($mode !== 'add' && $default) - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_time(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $time_format = Base_RegionalSettingsCommon::time_12h() ? 'h:i a' : 'H:i'; - $lang_code = Base_LangCommon::get_lang_code(); - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $minute_increment = 5; - if ($desc['param']) { - $minute_increment = $desc['param']; - } - $form->addElement('timestamp', $field, $label, array('date' => false, 'format' => $time_format, 'optionIncrement' => array('i' => $minute_increment), 'language' => $lang_code, 'id' => $field)); - if ($mode !== 'add' && $default) - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_commondata(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $param = explode('::', $desc['param']['array_id']); - foreach ($param as $k => $v) - if ($k != 0) - $param[$k] = self::get_field_id($v); - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type'], $desc['param']['array_id']); - $form->addElement($desc['type'], $field, $label, $param, array('empty_option' => true, 'order' => $desc['param']['order']), array('id' => $field)); - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_select(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - - $record = $rb_obj->record; - $comp = array(); - $param = self::decode_select_param($desc['param']); - $multi_adv_params = self::call_select_adv_params_callback($param['adv_params_callback'], $record); - $format_callback = $multi_adv_params['format_callback']; - $rec_count = 0; - if ($param['single_tab'] == '__COMMON__') { - if (empty($param['array_id'])) - trigger_error("Commondata array id not set for field: $field", E_USER_ERROR); - $data = Utils_CommonDataCommon::get_translated_tree($param['array_id'], $param['order']); - if (!is_array($data)) - $data = array(); - $comp = $comp + $data; - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, 'commondata', $param['array_id']); - } else { - $tab_crits = self::get_select_tab_crits($param, $record); - - $tabs = array_keys($tab_crits); - - foreach($tabs as $t) { - $rec_count += Utils_RecordBrowserCommon::get_records_count($t, $tab_crits[$t]); - - if ($rec_count > Utils_RecordBrowserCommon::$options_limit) break; - } - if ($rec_count <= Utils_RecordBrowserCommon::$options_limit) { - foreach($tabs as $t) { - $records = Utils_RecordBrowserCommon::get_records($t, $tab_crits[$t], array(), $multi_adv_params['order']); - foreach($records as $key=>$rec) { - if(!self::get_access($t,'view',$rec)) continue; - $tab_id = ($param['single_tab']?'':$t.'/').$key; - $comp[$tab_id] = self::call_select_item_format_callback($multi_adv_params['format_callback'], $tab_id, array($rb_obj->tab, $tab_crits[$t], $multi_adv_params['format_callback'], $param)); - } - } - } - - if (isset($record[$field])) { - if (!is_array($record[$field])) { - if ($record[$field] != '') - $record[$field] = array($record[$field] => $record[$field]); - else - $record[$field] = array(); - } - } - if ($default) { - if (!is_array($default)) - $record[$field][$default] = $default; - else { - foreach ($default as $v) - $record[$field][$v] = $v; - } - } - if (isset($record[$field])) { - foreach ($record[$field] as $tab_id) { - if (isset($comp[$tab_id])) continue; - $vals = self::decode_record_token($tab_id, $param['single_tab']); - if (!$vals) continue; - list($t,$rid) = $vals; - if (!isset($tab_crits[$t])) continue; - $comp[$tab_id] = self::call_select_item_format_callback($multi_adv_params['format_callback'], $tab_id, array($rb_obj->tab, $tab_crits[$t], $multi_adv_params['format_callback'], $param)); - } - } - if (empty($multi_adv_params['order'])) - natcasesort($comp); - - if($param['single_tab']) - $label = self::get_field_tooltip($label, $desc['type'], $param['single_tab'], $tab_crits[$param['single_tab']]); - } - if ($rec_count > Utils_RecordBrowserCommon::$options_limit) { - if ($desc['type'] == 'multiselect') { - $el = $form->addElement('automulti', $field, $label, array('Utils_RecordBrowserCommon', 'automulti_suggestbox'), array($rb_obj->tab, $tab_crits, $format_callback, $desc['param']), $format_callback); - if (method_exists($rb_obj, 'init_module')) { // fixes mobile edit issue - to be removed when mobile.php will be removed - ${'rp_' . $field} = $rb_obj->init_module(Utils_RecordBrowser_RecordPicker::module_name(), array()); - $filters_defaults = isset($multi_adv_params['filters_defaults']) ? $multi_adv_params['filters_defaults'] : array(); - $rb_obj->display_module(${'rp_' . $field}, array($tabs, $field, $format_callback, $param['crits_callback']?:$tab_crits, array(), array(), array(), $filters_defaults)); - $el->set_search_button('create_open_href() . ' ' . Utils_TooltipCommon::open_tag_attrs(__('Advanced Selection')) . ' href="javascript:void(0);">'); - } - } else - $el = $form->addElement('autoselect', $field, $label, $comp, array(array('Utils_RecordBrowserCommon', 'automulti_suggestbox'), array($rb_obj->tab, $tab_crits, $format_callback, $desc['param'])), $format_callback); - } else { - if ($desc['type'] === 'select') - $comp = array('' => '---') + $comp; - $form->addElement($desc['type'], $field, $label, $comp, array('id' => $field)); - } - if ($mode !== 'add') - $form->setDefaults(array($field => $default)); - } - - public static function QFfield_multiselect(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - self::QFfield_select($form, $field, $label, $mode, $default, $desc, $rb_obj); - } - - public static function QFfield_autonumber(&$form, $field, $label, $mode, $default, $desc, $rb_obj) { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - $label = Utils_RecordBrowserCommon::get_field_tooltip($label, $desc['type']); - $value = $default ? $default : self::format_autonumber_str($desc['param'], null); - $form->addElement('static', $field, $label); - $record_id = isset($rb_obj->record['id']) ? $rb_obj->record['id'] : null; - $field_id = Utils_RecordBrowserCommon::get_calculated_id($rb_obj->tab, $field, $record_id); - $val = '
' . $value . '
'; - $form->setDefaults(array($field => $val)); - } - - //region File - public static function display_file($r, $nolink=false, $desc=null, $tab=null) - { - $labels = []; - $inline_nodes = []; - $fileStorageIds = self::decode_multi($r[$desc['id']]); - $fileHandler = new Utils_RecordBrowser_FileActionHandler(); - foreach($fileStorageIds as $fileStorageId) { - if(!empty($fileStorageId)) { - $actions = $fileHandler->getActionUrlsRB($fileStorageId, $tab, $r['id'], $desc['id']); - $labels[]= Utils_FileStorageCommon::get_file_label($fileStorageId, $nolink, true, $actions); - if (!($desc['nopreview']?? false)) - $inline_nodes[]= Utils_FileStorageCommon::get_file_inline_node($fileStorageId, $actions, $desc['max-width']?? '200px'); - } - } - $inline_nodes = array_filter($inline_nodes); - - return implode('
', $labels) . ($inline_nodes? '
': '') . implode(' ', $inline_nodes); - } - - public static function QFfield_file(&$form, $field, $label, $mode, $default, $desc, $rb_obj) - { - if (self::QFfield_static_display($form, $field, $label, $mode, $default, $desc, $rb_obj)) - return; - $record_id = isset($rb_obj->record['id']) ? $rb_obj->record['id'] : 'new'; - $module_id = md5($rb_obj->tab . '/' . $record_id . '/' . $field); - /** @var Utils_FileUpload_Dropzone $dropzoneField */ - $dropzoneField = Utils_RecordBrowser::$rb_obj->init_module('Utils_FileUpload#Dropzone', null, $module_id); - $default = self::decode_multi($default); - if ($default) { - $files = []; - foreach ($default as $filestorageId) { - $meta = Utils_FileStorageCommon::meta($filestorageId); - $arr = [ - 'filename' => $meta['filename'], - 'type' => $meta['type'], - 'size' => $meta['size'], - ]; - $backref = substr($meta['backref'], 0, 3) == 'rb:' ? explode('/', substr($meta['backref'], 3)) : []; - if (count($backref) === 3) { - list ($br_tab, $br_record, $br_field) = $backref; - $file_handler = new Utils_RecordBrowser_FileActionHandler(); - $actions = $file_handler->getActionUrlsRB($filestorageId, $br_tab, $br_record, $br_field); - if (isset($actions['preview'])) { - $arr['file'] = $actions['preview']; - } - } - $files[$filestorageId] = $arr; - } - $dropzoneField->set_defaults($files); - } - if (isset($desc['param']['max_files']) && $desc['param']['max_files'] !== false) { - $dropzoneField->set_max_files($desc['param']['max_files']); - } - if (isset($desc['param']['accepted_files']) && $desc['param']['accepted_files'] !== false) { - $dropzoneField->set_accepted_files($desc['param']['accepted_files']); - } - $dropzoneField->add_to_form($form, $field, $label); - } - //endregion - - public static function cron() { - return array('indexer' => 10); - } - - public static function index_record($tab,$record,$table_rows=null,$tab_id=null) { - if($tab_id===null) $tab_id = DB::GetOne('SELECT id FROM recordbrowser_table_properties WHERE tab=%s',array($tab)); - if($table_rows===null) $table_rows = self::init($tab); - - $record = self::record_processing($tab, $record, 'index'); - DB::StartTrans(); - if($record) { - DB::Execute('DELETE FROM recordbrowser_search_index WHERE tab_id=%d AND record_id=%d',array($tab_id,$record['id'])); - $cleanup_str = function($value) { - $decoded = html_entity_decode($value); - $added_spaces = str_replace('<', ' <', $decoded); - $stripped = strip_tags($added_spaces); - $removed_spaces = preg_replace('/[ ]+/', ' ', $stripped); - return mb_strtolower(trim($removed_spaces)); - }; - $insert_vals = array(); - foreach($table_rows as $field_info) { - $field = $field_info['id']; - if(!isset($record[$field])) continue; - ob_start(); - $text = self::get_val($tab,$field,$record, true); - ob_end_clean(); - $text = $cleanup_str($text); - if ($text) { - $insert_vals[] = $tab_id; - $insert_vals[] = $record['id']; - $insert_vals[] = $field_info['pkey']; - $insert_vals[] = $text; - } - } - $insert_query = implode(',', array_fill(0, count($insert_vals) / 4, '(%d, %d, %d, %s)')); - DB::Execute('INSERT INTO recordbrowser_search_index VALUES ' . $insert_query, $insert_vals); - } - DB::Execute('UPDATE '.$tab.'_data_1 SET indexed=1 WHERE id=%d',array($record['id'])); - DB::CompleteTrans(); - } - - public static function clear_search_index($tab) - { - $tab_id = DB::GetOne('SELECT id FROM recordbrowser_table_properties WHERE tab=%s',array($tab)); - if ($tab_id) { - DB::Execute('DELETE FROM recordbrowser_search_index WHERE tab_id=%d',array($tab_id)); - DB::Execute('UPDATE ' . $tab . '_data_1 SET indexed=0'); - return true; - } - return false; - } - - public static function indexer($limit=null,&$total=0) { - $limit_sum = 0; - $limit_file = DATA_DIR.'/Utils_RecordBrowser/limit'; - if(defined('RB_INDEXER_LIMIT_QUERIES')) { //limit queries per hour - $time = time(); - $limit_time = 0; - if(file_exists($limit_file)) { - $tmp = array_filter(explode("\n",file_get_contents($limit_file))); - $limit_time = array_shift($tmp); - if($limit_time>$time-3600) { - $limit_sum = array_sum($tmp); - if($limit_sum>RB_INDEXER_LIMIT_QUERIES) return; - } - } - if($limit_sum==0) - file_put_contents($limit_file,$time."\n", LOCK_EX); - } - - if(!$limit) $limit = defined('RB_INDEXER_LIMIT_RECORDS') ? RB_INDEXER_LIMIT_RECORDS : 300; - $tabs = DB::GetAssoc('SELECT id,tab FROM recordbrowser_table_properties WHERE search_include>0'); - foreach($tabs as $tab_id=>$tab) { - $lock = DATA_DIR.'/Utils_RecordBrowser/'.$tab_id.'.lock'; - if(file_exists($lock) && filemtime($lock)>time()-1200) continue; - - $table_rows = self::init($tab); - self::$admin_filter = ' .indexed=0 AND .active=1 AND '; - $ret = self::get_records($tab,array(),array(),array(),$limit,true); - self::$admin_filter = ''; - - if(!$ret) continue; - - register_shutdown_function(create_function('','@unlink("'.$lock.'");')); - if(file_exists($lock) && filemtime($lock)>time()-1200) continue; - file_put_contents($lock,''); - - foreach($ret as $row) { - self::index_record($tab,$row,$table_rows,$tab_id); - - $total++; - if($total>=$limit) break; - if(defined('RB_INDEXER_LIMIT_QUERIES') && RB_INDEXER_LIMIT_QUERIES<$limit_sum+DB::GetQueriesQty()) break; - } - - @unlink($lock); - - if($total>=$limit) break; - if(defined('RB_INDEXER_LIMIT_QUERIES') && RB_INDEXER_LIMIT_QUERIES<$limit_sum+DB::GetQueriesQty()) break; - } - - if(defined('RB_INDEXER_LIMIT_QUERIES')) { - file_put_contents($limit_file,DB::GetQueriesQty()."\n",FILE_APPEND | LOCK_EX); - } - - } - - public static function search($search, $categories) - { - $x = new Utils_RecordBrowser_Search($categories); - $ret = $x->search_results($search); - return $ret; - } - - public static function search_categories() { - $tabs = DB::GetAssoc('SELECT t.id,t.tab,t.search_include FROM recordbrowser_table_properties t WHERE t.search_include>0 AND t.id IN (SELECT DISTINCT m.tab_id FROM recordbrowser_search_index m)'); - $ret = array(); - foreach($tabs as $tab_id=>$tab) { - $caption = self::get_caption($tab['tab']); - if(!$caption) continue; - $ret[$tab_id] = array('caption'=>$caption,'checked'=>$tab['search_include']==1); - } - uasort($ret,create_function('$a,$b','return strnatcasecmp($a["caption"],$b["caption"]);')); - return $ret; - } - - /////////////////////////////////////////// - // mobile devices - - public static function mobile_rb($table,array $crits=array(),array $sort=array(),$info=array(),$defaults=array()) { - $_SESSION['rb_'.$table.'_defaults'] = $defaults; - require_once('modules/Utils/RecordBrowser/mobile.php'); - } - - public static function mobile_rb_view($tab,$id) { - if (Utils_RecordBrowserCommon::get_access($tab, 'browse')===false) { - print(__('You are not authorised to browse this data.')); - return; - } - self::add_recent_entry($tab, Acl::get_user() ,$id); - $rec = self::get_record($tab,$id); - - $access = Utils_RecordBrowserCommon::get_access($tab, 'view',$rec); - if (is_array($access)) - foreach ($access as $k=>$v) - if (!$v) $rec[$k] = ''; - - $cols = Utils_RecordBrowserCommon::init($tab); - if(IPHONE) { - print('
    '); - foreach($cols as $k=>$col) { - $val = Utils_RecordBrowserCommon::get_val($tab,$k,$rec,true,$col); - if($val==='') continue; - print('
  • '._V($col['name']).': '.$val.'
  • '); // TRSL - } - print('
'); - } else { - foreach($cols as $k=>$col) { - $val = Utils_RecordBrowserCommon::get_val($tab,$k,$rec,true,$col); - if($val==='') continue; - print(_V($col['name']).': '.$val.'
'); // TRSL - } - } - - if(Utils_RecordBrowserCommon::get_access($tab, 'edit', $rec)) - print(''.__('Edit').''.(IPHONE?'':'
')); - - if(Utils_RecordBrowserCommon::get_access($tab, 'delete', $rec)) - print(''.__('Delete').''.(IPHONE?'':'
')); - - } - - public static function mobile_rb_edit($tab,$id) { - if($id===false) - $rec = array(); - else - $rec = self::get_record($tab,$id); - $cols = Utils_RecordBrowserCommon::init($tab); - - $defaults = array(); - if($id===false) { - $mode = 'add'; - $access = array(); - $defaults = self::record_processing($tab, $defaults, 'adding'); - } else { - $mode = 'edit'; - $access = Utils_RecordBrowserCommon::get_access($tab, 'view',$rec); - if (is_array($access)) - foreach ($access as $k=>$v) - if (!$v) unset($rec[$k]); - $defaults = $rec = self::record_processing($tab, $rec, 'editing'); - } - - $QFfield_callback_table = array(); - $ret = DB::Execute('SELECT * FROM '.$tab.'_callback WHERE freezed=0'); - while ($row = $ret->FetchRow()) { - $QFfield_callback_table[$row['field']] = $row['callback']; - } - $defaults = array_merge($defaults,$_SESSION['rb_'.$tab.'_defaults']); - - $qf = new HTML_QuickForm('rb_edit', 'post', 'mobile.php?'.http_build_query($_GET)); - foreach($cols as $field=>$args) { - if(isset($access[$args['id']]) && !$access[$args['id']]) continue; - - if(isset($rec[$args['id']])) - $val = $rec[$args['id']]; - elseif(isset($defaults[$args['id']])) - $val = $defaults[$args['id']]; - else - $val = null; - $label = _V($args['name']); // TRSL - if(isset($QFfield_callback_table[$field])) { - $mobile_rb = new Utils_RecordBrowserMobile($tab, $rec); - self::call_QFfield_callback($QFfield_callback_table[$field], $qf, $args['id'], $label, $mode, $val, $args, $mobile_rb, null); - if($mode=='edit') - unset($defaults[$args['id']]); - continue; - } - - switch ($args['type']) { - case 'calculated': - $qf->addElement('static', $args['id'], $label); - if (!is_array($rec)) - $values = $defaults; - else { - $values = $rec; - if (is_array($defaults)) $values = $values + $defaults; - } - if(!isset($values[$args['id']])) $values[$args['id']] = ''; - $val = Utils_RecordBrowserCommon::get_val($tab, $field, $values, true, $args); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'integer': - case 'float': - $qf->addElement('text', $args['id'], $label); - if ($args['type'] == 'integer') - $qf->addRule($args['id'], __('Only integer numbers are allowed.'), 'regex', '/^[0-9]*$/'); - else - $qf->addRule($args['id'], __('Only numbers are allowed.'), 'numeric'); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'checkbox': - $qf->addElement('checkbox', $args['id'], $label, ''); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'currency': - $qf->addElement('currency', $args['id'], $label); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'text': - $qf->addElement('text', $args['id'], $label, array('maxlength' => $args['param'])); - $qf->addRule($args['id'], __('Maximum length for this field is %s characters.', array($args['param'])), 'maxlength', $args['param']); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'long text': - $qf->addElement('textarea', $args['id'], $label, array('maxlength' => 200)); - $qf->addRule($args['id'], __('Maximum length for this field in mobile edition is 200 chars.'), 'maxlengt', 200); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'commondata': - $param = explode('::', $args['param']['array_id']); - foreach ($param as $k => $v) if ($k != 0) $param[$k] = self::get_field_id($v); - if (count($param) == 1) { - $qf->addElement($args['type'], $args['id'], $label, $param, array('empty_option' => true, 'id' => $args['id'], 'order' => $args['param']['order'])); - if ($val !== null) - $qf->setDefaults(array($args['id'] => $val)); - } - break; - case 'select': $comp = array(); - $ref = explode(';',$args['param']); - if (isset($ref[1])) $crits_callback = $ref[1]; - else $crits_callback = null; - if (isset($ref[2])) $multi_adv_params = call_user_func(explode('::',$ref[2])); - else $multi_adv_params = null; - if (!isset($multi_adv_params) || !is_array($multi_adv_params)) $multi_adv_params = array(); - if (!isset($multi_adv_params['order'])) $multi_adv_params['order'] = array(); - if (!isset($multi_adv_params['cols'])) $multi_adv_params['cols'] = array(); - if (!isset($multi_adv_params['format_callback'])) $multi_adv_params['format_callback'] = array(); - $ref = $ref[0]; - @(list($tab2, $col) = explode('::',$ref)); - if (!isset($col)) trigger_error($field); - if($tab2=='__RECORDSETS__') continue; //skip multi recordsets chained selector - if ($tab2=='__COMMON__') { - $data = Utils_CommonDataCommon::get_translated_tree($col); - if (!is_array($data)) $data = array(); - $comp = $comp+$data; - } else { - if (isset($crits_callback)) { - $crit_callback = explode('::',$crits_callback); - if (is_callable($crit_callback)) { - $crits = call_user_func($crit_callback, false, $rec); - $adv_crits = call_user_func($crit_callback, true, $rec); - } else $crits = $adv_crits = array(); - if ($adv_crits === $crits) $adv_crits = null; - if ($adv_crits !== null) { - continue; //skip record picker - } - } else $crits = array(); - $col = explode('|',$col); - $col_id = array(); - foreach ($col as $c) $col_id[] = self::get_field_id($c); - $records = Utils_RecordBrowserCommon::get_records($tab2, $crits, empty($multi_adv_params['format_callback'])?$col_id:array(), !empty($multi_adv_params['order'])?$multi_adv_params['order']:array()); - $ext_rec = array(); - if (isset($rec[$args['id']])) { - if (!is_array($rec[$args['id']])) { - if ($rec[$args['id']]!='') $rec[$args['id']] = array($rec[$args['id']]=>$rec[$args['id']]); else $rec[$args['id']] = array(); - } - } - if (isset($defaults[$args['id']])) { - if (!is_array($defaults[$args['id']])) - $rec[$args['id']][$defaults[$args['id']]] = $defaults[$args['id']]; - else { - foreach ($defaults[$args['id']] as $v) - $rec[$args['id']][$v] = $v; - } - } - $single_column = (count($col_id)==1); - if (isset($rec[$args['id']])) { - $ext_rec = array_flip($rec[$args['id']]); - foreach($ext_rec as $k=>$v) { - $c = Utils_RecordBrowserCommon::get_record($tab2, $k); - if (!empty($multi_adv_params['format_callback'])) $n = call_user_func($multi_adv_params['format_callback'], $c); - else { - if ($single_column) $n = $c[$col_id[0]]; - else { - $n = array(); - foreach ($col_id as $cid) $n[] = $c[$cid]; - $n = implode(' ',$n); - } - } - $comp[$k] = $n; - } - } - if (!empty($multi_adv_params['order'])) natcasesort($comp); - foreach ($records as $k=>$v) { - if (!empty($multi_adv_params['format_callback'])) $n = call_user_func($multi_adv_params['format_callback'], $v); - else { -// $n = $v[$col_id]; - if ($single_column) $n = $v[$col_id[0]]; - else { - $n = array(); - foreach ($col_id as $cid) $n[] = $v[$cid]; - $n = implode(' ',$n); - } - } - $comp[$k] = $n; - unset($ext_rec[$v['id']]); - } - if (empty($multi_adv_params['order'])) natcasesort($comp); - } - if ($args['type']==='select') $comp = array(''=>'---')+$comp; - $qf->addElement($args['type'], $args['id'], $label, $comp, array('id'=>$args['id'])); - if($id!==false) - $qf->setDefaults(array($args['id']=>$rec[$args['id']])); - break; - case 'date': $qf->addElement('date',$args['id'],$label,array('format'=>'d M Y', 'minYear'=>date('Y')-95,'maxYear'=>date('Y')+5, 'addEmptyOption'=>true, 'emptyOptionText'=>'--')); - if ($val) - $qf->setDefaults(array($args['id'] => $val)); - break; - case 'timestamp': $qf->addElement('date',$args['id'],$label,array('format'=>'d M Y H:i', 'minYear'=>date('Y')-95,'maxYear'=>date('Y')+5, 'addEmptyOption'=>true, 'emptyOptionText'=>'--')); - if($val) { - $default = Base_RegionalSettingsCommon::time2reg($val, true, true, true, false); - $qf->setDefaults(array($args['id'] => $default)); - } - break; - case 'time': $qf->addElement('date',$args['id'],$label,array('format'=>'H:i', 'addEmptyOption'=>true, 'emptyOptionText'=>'--')); - if($val) { - $default = Base_RegionalSettingsCommon::time2reg($val, true, true, true, false); - $qf->setDefaults(array($args['id'] => $default)); - } - break; - case 'multiselect': //ignore - if($id===false) continue; - $val = Utils_RecordBrowserCommon::get_val($tab,$field,$rec,true,$args); - if($val==='') continue; - $qf->addElement('static',$args['id'],$label); - $qf->setDefaults(array($args['id']=>$val)); - unset($defaults[$args['id']]); - break; - } - if($args['required']) - $qf->addRule($args['id'],__('Field required'),'required'); - } - - $qf->addElement('submit', 'submit_button', __('Save'),IPHONE?'class="button white"':''); - - if($qf->validate()) { - $values = $qf->exportValues(); - foreach ($cols as $v) { - if ($v['type']=='checkbox' && !isset($values[$v['id']])) $values[$v['id']]=0; - elseif($v['type']=='date') { - if(is_array($values[$v['id']]) && $values[$v['id']]['Y']!=='' && $values[$v['id']]['M']!=='' && $values[$v['id']]['d']!=='') - $values[$v['id']] = sprintf("%d-%02d-%02d", $values[$v['id']]['Y'], $values[$v['id']]['M'], $values[$v['id']]['d']); - else - $values[$v['id']] = ''; - } elseif($v['type']=='timestamp') { - if($values[$v['id']]['Y']!=='' && $values[$v['id']]['M']!=='' && $values[$v['id']]['d']!=='' && $values[$v['id']]['H']!=='' && $values[$v['id']]['i']!=='') { - $timestamp = $values[$v['id']]['Y'] . '-' . $values[$v['id']]['M'] . '-' . $values[$v['id']]['d'] . ' ' . $values[$v['id']]['H'] . ':' . $values[$v['id']]['i']; - $values[$v['id']] = Base_RegionalSettingsCommon::reg2time($timestamp, true); - } else - $values[$v['id']] = ''; - } elseif($v['type']=='time') { - if($values[$v['id']]['H']!=='' && $values[$v['id']]['i']!=='') { - $time = recalculate_time(date('Y-m-d'), $values[$v['id']]); - $timestamp = Base_RegionalSettingsCommon::reg2time(date('1970-01-01 H:i:s', $time), true); - $values[$v['id']] = date('1970-01-01 H:i:s', $timestamp); - } else - $values[$v['id']] = ''; - } - } - foreach ($defaults as $k=>$v) - if (!isset($values[$k])) $values[$k] = $v; - if($id!==false) { - $values['id'] = $id; - Utils_RecordBrowserCommon::update_record($tab, $id, $values); - } else { - $id = Utils_RecordBrowserCommon::new_record($tab, $values); - } - return false; - } - - $renderer =& $qf->defaultRenderer(); - $qf->accept($renderer); - print($renderer->toHtml()); - } - - public static function mobile_rb_delete($tab, $id) { - if(!isset($_GET['del_ok'])) { - print(''.__('Cancel deletion').''); - print(''.__('Delete').''); - } else { - if($_GET['del_ok']) - Utils_RecordBrowserCommon::delete_record($tab, $id); - return 2; - return false; - } - return true; - } -} - -class Utils_RecordBrowserMobile { // mini class to simulate full RB object, TODO: consider passing tab and record as statics linked to RBCommon instead - public $tab; - public $record; - - public function __construct($tab, $record) { - $this->tab = $tab; - $this->record = $record; - } -} - -function rb_or($crits, $_ = null) -{ - $args = func_get_args(); - if (count($args) > 1) { - foreach ($args as $k => $v) { - if (is_array($v)) { - $args[$k] = new Utils_RecordBrowser_Crits($v, true); - } - } - $crits = $args; - } else { - $crits = $args[0]; - } - $ret = new Utils_RecordBrowser_Crits($crits, true); - return $ret; -} - -function rb_and($crits, $_ = null) -{ - $args = func_get_args(); - if (count($args) > 1) { - foreach ($args as $k => $v) { - if (is_array($v)) { - $args[$k] = new Utils_RecordBrowser_Crits($v); - } - } - $crits = $args; - } else { - $crits = $args[0]; - } - $ret = new Utils_RecordBrowser_Crits($crits); - return $ret; -} - -require_once 'modules/Utils/RecordBrowser/object_wrapper/include.php'; - -Utils_RecordBrowser_Crits::register_special_value_callback(array('Utils_RecordBrowserCommon', 'crits_special_values')); - -if(!READ_ONLY_SESSION) { - if(!isset($_SESSION['rb_indexer_token'])) - $_SESSION['rb_indexer_token'] = md5(microtime(true)); - load_js('modules/Utils/RecordBrowser/indexer.js'); - eval_js_once('rb_indexer("'.$_SESSION['rb_indexer_token'].'")'); -} -?> \ No newline at end of file diff --git a/modules/Utils/RecordBrowser/RecordBrowser_0.php b/modules/Utils/RecordBrowser/RecordBrowser_0.php index cfbaac2e5..e712cf44b 100644 --- a/modules/Utils/RecordBrowser/RecordBrowser_0.php +++ b/modules/Utils/RecordBrowser/RecordBrowser_0.php @@ -695,7 +695,7 @@ public function show_data($crits = array(), $cols = array(), $order = array(), $ $records = Utils_RecordBrowserCommon::get_records($this->tab, $crits, array(), $order, $limit, $admin); if(!$records) { $last_offset = $this->get_module_variable('last_offset'); - while(!$records) { + while(!$records && isset($limit['offset'])) { if($last_offset>$limit['offset'] && ($limit['offset']-$limit['numrows'])>=0) $limit['offset'] -= $limit['numrows']; elseif(($limit['offset']+$limit['numrows'])<$this->amount_of_records) diff --git a/modules/Utils/RecordBrowser/RecordPickerFS/RecordPickerFS_0.php b/modules/Utils/RecordBrowser/RecordPickerFS/RecordPickerFS_0.php index a3fa7a414..c9e90e479 100644 --- a/modules/Utils/RecordBrowser/RecordPickerFS/RecordPickerFS_0.php +++ b/modules/Utils/RecordBrowser/RecordPickerFS/RecordPickerFS_0.php @@ -38,22 +38,21 @@ public function cancel() { $GLOBALS['rpfs_old_sel'] = $this->get_module_variable('old_selected',array()); Base_BoxCommon::pop_main(); } - - public function show($tab, $crits=array(), $cols=array(), $order=array(), $filters=array(),$filters_defaults=array(),$path=null,$caption=null) { + /* Add additionals $rb_params (partial compatibility with RB) + * $rb_params are identical as at $rb + */ + public function show($tab, $crits=array(), $cols=array(), $order=array(), $filters=array(),$filters_defaults=array(),$path=null,$caption=null,$custom_filters=array(),$rb_params = array()) { $this->caption = $caption; $rb = $this->init_module(Utils_RecordBrowser::module_name(), $tab, $tab.'_picker'); - foreach ($filters as $field => $filter) { - if (!is_array($filter)) continue; - - $rb->set_custom_filter($field, $filter); - } if($filters_defaults) $rb->set_filters_defaults($filters_defaults); -// $rb->adv_search = true; - $rb->disable_actions(); - + //add custom filters + foreach($custom_filters as $field=>$arr) + $rb->set_custom_filter($field,$arr); + //end + foreach ($rb_params as $k=>$v){ + $rb->$k($v); + } $this->display_module($rb, array($crits, $cols, $order, $filters, $path), 'recordpicker_fs'); - Base_ActionBarCommon::add('save', __('Commit Selection'), $this->create_callback_href(array($this,'back'))); - Base_ActionBarCommon::add('back', __('Cancel'), $this->create_callback_href(array($this,'cancel'))); } public function create_open_link($label,$form = null,$select = null) { diff --git a/modules/Utils/RecordBrowser/Reports/ReportsInstall.php b/modules/Utils/RecordBrowser/Reports/ReportsInstall.php index 279420578..ea24aacdd 100644 --- a/modules/Utils/RecordBrowser/Reports/ReportsInstall.php +++ b/modules/Utils/RecordBrowser/Reports/ReportsInstall.php @@ -33,8 +33,8 @@ public function requires($v) { array('name'=>Utils_TabbedBrowserInstall::module_name(),'version'=>0), array('name'=>Libs_QuickFormInstall::module_name(),'version'=>0), array('name'=>Utils_RecordBrowserInstall::module_name(),'version'=>0), - array('name'=>Utils_GenericBrowserInstall::module_name(),'version'=>0), - array('name'=>Libs_OpenFlashChartInstall::module_name(),'version'=>0)); + array('name'=>Utils_GenericBrowserInstall::module_name(),'version'=>0) + ); } public static function info() { diff --git a/modules/Utils/RecordBrowser/Reports/Reports_0.php b/modules/Utils/RecordBrowser/Reports/Reports_0.php index 9f1f49dea..e4a75ef4e 100644 --- a/modules/Utils/RecordBrowser/Reports/Reports_0.php +++ b/modules/Utils/RecordBrowser/Reports/Reports_0.php @@ -26,7 +26,6 @@ class Utils_RecordBrowser_Reports extends Module { private $date_range; private $pdf = false; private $csv = false; - private $charts = false; private $pdf_ob = null; private $csv_ob = array(); private $widths = array(); @@ -509,7 +508,9 @@ public function make_table() { $first = ''; foreach($ggrow as $grow) { $csv_row = array(); - foreach($grow as $elem) $csv_row[] = html_entity_decode(strip_tags(preg_replace('/<(h|b)r\s*\/?>/i',"\n",isset($elem['value'])?$elem['value']:(!is_array($elem)?$elem:'?')))); + foreach($grow as $elem) { + $csv_row[] = html_entity_decode(strip_tags(preg_replace('/<(h|b)r\s*\/?>/i',"\n",isset($elem['value'])?$elem['value']:(!is_array($elem)?$elem:'?')))); + } if(!$first && $csv_row[0]) $first = $csv_row[0]; elseif(!$csv_row[0]) $csv_row[0] = $first; $this->csv_ob[] = $csv_row; @@ -611,7 +612,9 @@ public function make_table() { $first = ''; foreach($ggrow as $grow) { $csv_row = array(); - foreach($grow as $elem) $csv_row[] = html_entity_decode(strip_tags(preg_replace('/<(h|b)r\s*\/?>/i',"\n",isset($elem['value'])?$elem['value']:(!is_array($elem)?$elem:'?')))); + foreach($grow as $elem) { + $csv_row[] = html_entity_decode(strip_tags(preg_replace('/<(h|b)r\s*\/?>/i',"\n",isset($elem['value'])?$elem['value']:(!is_array($elem)?$elem:'?')))); + } if(!$first && $csv_row[0]) $first = $csv_row[0]; elseif(!$csv_row[0]) $csv_row[0] = $first; $this->csv_ob[] = $csv_row; @@ -627,405 +630,6 @@ public function make_table() { } } - public function draw_chart($r,$ref_rec,$gb_captions) { - $f = $this->init_module(Libs_OpenFlashChart::module_name()); - $f2 = $this->init_module(Libs_OpenFlashChart::module_name()); - $results = call_user_func($this->display_cell_callback, $r); - - $title = new OFC_Elements_Title( $ref_rec ); - $f->set_title( $title ); - $f2->set_title( $title ); - $labels = array(); - foreach($gb_captions as $cap) - $labels[] = $cap['name']; - $x_ax = new OFC_Elements_Axis_X(); - $x_ax->set_labels_from_array($labels); - $f->set_x_axis($x_ax); - $f2->set_x_axis($x_ax); - $max = 5; - $max2 = 5; - $curr = false; - $num = false; - - if (empty($this->categories)) { - $arr = array(); - $bar = new OFC_Charts_Line(); - $bar->set_colour(self::$colours[0]); - foreach ($results as & $res_ref) { - if (is_array($res_ref)) - $res_ref = array_pop($res_ref); - $val = (float)strip_tags($res_ref); - $arr[] = $val; - if($this->format=='currency') { - if($max2<$val) $max2=$val; - } else { - if($max<$val) $max=$val; - } - } - $bar->set_values( $arr ); - if($this->format=='currency') { - $f2->add_element( $bar ); - $curr = true; - } else { - $f->add_element( $bar ); - $num = true; - } - } else { - $color = 0; - foreach ($this->categories as $q=>$c) { - $bar = new OFC_Charts_Line(); - $bar->set_colour(self::$colours[$color%count(self::$colours)]); - $color++; - $bar->set_key(strip_tags($c),10); - $arr = array(); - foreach ($results as $v) { - if (is_array($v[$c])) $v[$c] = reset($v[$c]); - $val = (float)strip_tags($v[$c]); - $arr[] = $val; - if($this->format[$c]=='currency') { - if($max2<$val) $max2=$val; - } else { - if($max<$val) $max=$val; - } - } - $bar->set_values( $arr ); - if($this->format[$c]=='currency') { - $f2->add_element( $bar ); - $curr = true; - } else { - $f->add_element( $bar ); - $num = true; - } - } - } - - if($num) { - $y_ax = new OFC_Elements_Axis_Y(); - $y_ax->set_range(0,$max); - $y_ax->set_steps($max/10); - $f->set_y_axis($y_ax); - - $f->set_width(950); - $f->set_height(400); - - $this->display_module($f); - print('
'); - } - - if($curr) { - $y_ax = new OFC_Elements_Axis_Y(); - $y_ax->set_range(0,$max2); - $y_ax->set_steps($max2/10); - $f2->set_y_axis($y_ax); - - $f2->set_width(950); - $f2->set_height(400); - - $this->display_module($f2); - print('
'); - } - - } - - public function draw_summary_chart($gb_captions) { - $f = $this->init_module(Libs_OpenFlashChart::module_name()); //row summary numeric - $f2 = $this->init_module(Libs_OpenFlashChart::module_name()); //row summary currency - $fc = $this->init_module(Libs_OpenFlashChart::module_name()); //columns summary numeric - $fc2 = $this->init_module(Libs_OpenFlashChart::module_name()); //columns summary currency - - $title = new OFC_Elements_Title( "Summary by row" ); - $f->set_title( $title ); - $f2->set_title( $title ); - if(!empty($this->categories)) { - $labels = array(); - $labels_c = array(); - foreach ($this->categories as $q=>$c) { - if($this->format[$c]=='currency') { - $labels_c[] = strip_tags($c); - } else { - $labels[] = strip_tags($c); - } - } - $x_ax = new OFC_Elements_Axis_X(); - $x_ax->set_labels_from_array($labels); - $f->set_x_axis($x_ax); - $x_ax = new OFC_Elements_Axis_X(); - $x_ax->set_labels_from_array($labels_c); - $f2->set_x_axis($x_ax); - } - - $title = new OFC_Elements_Title( "Summary by column" ); - $fc->set_title( $title ); - $fc2->set_title( $title ); - $labels = array(); - foreach($gb_captions as $cap) - $labels[] = $cap['name']; - $x_ax = new OFC_Elements_Axis_X(); - $x_ax->set_labels_from_array($labels); - $fc->set_x_axis($x_ax); - $fc2->set_x_axis($x_ax); - $max = 5; - $max2 = 5; - $maxc = 5; - $maxc2 = 5; - $curr = false; - $num = false; - $col_total=array(); - - $color = 0; - foreach($this->ref_records as $k=>$r) { - $results = call_user_func($this->display_cell_callback, $r); - - $ref_rec = call_user_func($this->ref_record_display_callback, $r,true); - - $bar = new OFC_Charts_Bar_Glass(); - $bar->set_colour(self::$colours[$color%count(self::$colours)]); - $color++; - $bar->set_key(strip_tags($ref_rec),10); - - if(empty($this->categories)) { - $total = 0; - $i = 0; - foreach ($results as & $res_ref) { - if (is_array($res_ref)) - $res_ref = array_pop($res_ref); - $val = strip_tags($res_ref); - $total += $val; - if (!isset($this->cols_total[$i])) $this->cols_total[$i] = array(); - $this->cols_total[$i][0] += $val; - $i++; - } - $bar->set_values(array($total)); - if($this->format=='currency') { - if ($total > $max2) - $max2 = $total; - $f2->add_element( $bar ); - $curr = true; - } else { - if ($total > $max) - $max = $total; - $f->add_element( $bar ); - $num = true; - } - } else { - $bar_c = new OFC_Charts_Bar_Glass(); - $bar_c->set_colour(self::$colours[$color%count(self::$colours)]); - $bar_c->set_key(strip_tags($ref_rec),10); - $arr = array(); - $arr_c = array(); - foreach ($this->categories as $q=>$c) { - $total = 0; - if(!isset($this->cols_total[$c])) $this->cols_total[$c] = array(); - $i=0; - foreach ($results as $v) { - if (is_array($v[$c])) $v[$c] = reset($v[$c]); - $val = (float)strip_tags($v[$c]); - $total += $val; - if (!isset($this->cols_total[$c][$i])) $this->cols_total[$c][$i] = 0; - $this->cols_total[$c][$i] += $val; - $i++; - } - if($this->format[$c]=='currency') { - $arr_c[] = $total; - if($max2<$total) $max2 = $total; - } else { - $arr[] = $total; - if($max<$total) $max = $total; - } - } - if(!empty($arr)) { - $bar->set_values( $arr ); - $f->add_element( $bar ); - $num = true; - } - if(!empty($arr_c)) { - $bar_c->set_values( $arr_c ); - $f2->add_element( $bar_c ); - $curr = true; - } - } - } - - - if($num) { - $y_ax = new OFC_Elements_Axis_Y(); - $y_ax->set_range(0,$max); - $y_ax->set_steps($max/10); - $f->set_y_axis($y_ax); - - $f->set_width(950); - $f->set_height(400); - - $this->display_module($f); - print('
'); - } - - if($curr) { - $y_ax = new OFC_Elements_Axis_Y(); - $y_ax->set_range(0,$max2); - $y_ax->set_steps($max2/10); - $f2->set_y_axis($y_ax); - - $f2->set_width(950); - $f2->set_height(400); - - $this->display_module($f2); - print('
'); - } - - if(empty($this->categories)) { - $bar = new OFC_Charts_Bar_Glass(); - $bar->set_colour(self::$colours[0]); - $bar->set_key('Total',10); - $mm = 5; - $values = array(); - foreach($this->cols_total as $val) { - $rval = $val[0]; - if($mm < $rval) $mm = $rval; - $values[] = $rval; - } - $bar->set_values($values); - if($this->format=='currency') { - $maxc2 = $mm; - $fc2->add_element( $bar ); - } else { - $maxc = $mm; - $fc->add_element( $bar ); - } - } else { - $i = 0; - foreach($this->cols_total as $k=>$arr) { - $bar = new OFC_Charts_Bar_Glass(); - $bar->set_colour(self::$colours[$i%count(self::$colours)]); - $bar->set_key(strip_tags($k),10); - $bar->set_values($arr); - $mm = 5; - foreach($arr as $val) - if($mm<$val) $mm=$val; - if($this->format[$k]=='currency') { - if($mm>$maxc2) $maxc2 = $mm; - $fc2->add_element( $bar ); - } else { - if($mm>$maxc) $maxc = $mm; - $fc->add_element( $bar ); - } - $i++; - } - } - - - if($num) { - $y_ax = new OFC_Elements_Axis_Y(); - $y_ax->set_range(0,$maxc); - $y_ax->set_steps($maxc/10); - $fc->set_y_axis($y_ax); - - $fc->set_width(950); - $fc->set_height(400); - - $this->display_module($fc); - print('
'); - } - - if($curr) { - $y_ax = new OFC_Elements_Axis_X(); - $y_ax->set_range(0,$maxc2); - $y_ax->set_steps($maxc2/10); - $fc2->set_y_axis($y_ax); - - $fc2->set_width(950); - $fc2->set_height(400); - - $this->display_module($fc2); - print('
'); - } - - } - - public function draw_category_chart($ref_rec,$gb_captions) { - $f = $this->init_module(Libs_OpenFlashChart::module_name()); - - $title = new OFC_Elements_Title( $ref_rec ); - $f->set_title( $title ); - $labels = array(); - foreach($gb_captions as $cap) - $labels[] = $cap['name']; - $x_ax = new OFC_Elements_Axis_X(); - $x_ax->set_labels_from_array($labels); - $f->set_x_axis($x_ax); - $max = 5; - - $color = 0; - foreach($this->ref_records as $q=>$r) { - $results = call_user_func($this->display_cell_callback, $r); - - $title2 = strip_tags(call_user_func($this->ref_record_display_callback, $r,true)); - $bar = new OFC_Charts_Line(); - $bar->set_colour(self::$colours[$color%count(self::$colours)]); - $color++; - $bar->set_key($title2,10); - $arr = array(); - foreach ($results as $v) { - if($ref_rec) { - if (is_array($v[$ref_rec])) - $v[$ref_rec] = array_pop($v[$ref_rec]); - $val = (float)strip_tags($v[$ref_rec]); - } else { - if (is_array($v)) - $v = array_pop($v); - $val = (float)strip_tags($v); - } - $arr[] = $val; - if($max<$val) $max=$val; - } - $bar->set_values( $arr ); - $f->add_element( $bar ); - } - - $y_ax = new OFC_Elements_Axis_Y(); - $y_ax->set_range(0,$max); - $y_ax->set_steps($max/10); - $f->set_y_axis($y_ax); - - $f->set_width(950); - $f->set_height(400); - - $this->display_module($f); - } - - public function make_charts() { - if (empty($this->ref_records)) { - print('There were no records to display report for.'); - return; - } - - - $this->cols_total = array(); - /***** MAIN TABLE *****/ - $row_count = 1; - $gb_captions = $this->gb_captions; - array_shift($gb_captions); - if (!empty($this->categories)) array_shift($gb_captions); - - $tb = $this->init_module(Utils_TabbedBrowser::module_name()); - foreach($this->ref_records as $k=>$r) { - $title = strip_tags(call_user_func($this->ref_record_display_callback, $r,true)); - $tb->set_tab($title, array($this,'draw_chart'),array($r,$title,$gb_captions)); - } - if (empty($this->categories)) { - $title = 'All'; - $tb->set_tab($title, array($this,'draw_category_chart'),array('',$gb_captions)); - } else { - foreach ($this->categories as $q=>$c) { - $title = strip_tags($c); - $tb->set_tab($title, array($this,'draw_category_chart'),array($c,$gb_captions)); - } - } - $tb->set_tab('Summary', array($this,'draw_summary_chart'),array($gb_captions)); - $this->display_module($tb); - $this->tag(); - } - public function from_to_date() { $start = $this->date_range['from_'.$this->date_range['date_range_type']]; $end = $this->date_range['to_'.$this->date_range['date_range_type']]; @@ -1064,57 +668,44 @@ public function set_pdf_filename($arg) { $this->pdf_filename = $arg; } - public function body($pdf=false, $charts=false) { + public function body($pdf=false) { if ($this->is_back()) return false; if ($this->date_range=='error') return; Base_ThemeCommon::load_css('Utils/RecordBrowser/Reports'); $this->pdf = $pdf || isset($_REQUEST['rb_reports_enable_pdf']); $this->csv = isset($_REQUEST['rb_reports_enable_csv']); unset($_REQUEST['rb_reports_enable_pdf']); - $this->charts = $charts; if ($this->pdf) { $this->pdf_ob = $this->init_module(Libs_TCPDF::module_name(), 'L'); $this->pdf_ob->set_title($this->pdf_title); $this->pdf_ob->set_subject($this->pdf_subject); $this->pdf_ob->prepare_header(); $this->pdf_ob->AddPage(); - } elseif (!$this->charts && !$this->csv) { - Base_ActionBarCommon::add('report',__('Charts'),$this->create_callback_href(array($this, 'body'), array(false,true))); } - if($this->charts) - $this->make_charts(); - else - $this->make_table(); + $this->make_table(); if($this->csv) { $this->set_module_variable('csv',$this->csv_ob); } - - if($charts) { - Base_ActionBarCommon::add('report',__('Table'),$this->create_back_href()); - return true; - } else { - if(!$this->csv) { - if ($this->pdf){ - Base_ActionBarCommon::add('save',__('Download PDF'),'target="_blank" href="'.$this->pdf_ob->get_href($this->pdf_filename).'"'); - self::$pdf_ready = 1; - } elseif ($this->pdf_title!='' && self::$pdf_ready == 0) { - if (count($this->gb_captions)<20) - Base_ActionBarCommon::add('print',__('Create PDF'),$this->create_href(array('rb_reports_enable_pdf'=>1))); - else - Base_ActionBarCommon::add('print',__('Create PDF'),'',__('Too many columns to prepare printable version - please limit number of columns')); - } - } - if($this->pdf_filename && !$this->pdf) { - if ($this->csv) - Base_ActionBarCommon::add('save',__('Download CSV'),'target="_blank" href="'.$this->get_module_dir().'/csv.php?'.http_build_query(array('p'=>$this->get_path(),'id'=>CID,'filename'=>$this->pdf_filename)).'"'); - else - Base_ActionBarCommon::add('print',__('Create CSV'),$this->create_href(array('rb_reports_enable_csv'=>1))); + if(!$this->csv) { + if ($this->pdf){ + Base_ActionBarCommon::add('save',__('Download PDF'),'target="_blank" href="'.$this->pdf_ob->get_href($this->pdf_filename).'"'); + self::$pdf_ready = 1; + } elseif ($this->pdf_title!='' && self::$pdf_ready == 0) { + if (count($this->gb_captions)<20) + Base_ActionBarCommon::add('print',__('Create PDF'),$this->create_href(array('rb_reports_enable_pdf'=>1))); + else + Base_ActionBarCommon::add('print',__('Create PDF'),'',__('Too many columns to prepare printable version - please limit number of columns')); } } - return false; + if($this->pdf_filename && !$this->pdf) { + if ($this->csv) + Base_ActionBarCommon::add('save',__('Download CSV'),'target="_blank" href="'.$this->get_module_dir().'/csv.php?'.http_build_query(array('p'=>$this->get_path(),'id'=>CID,'filename'=>$this->pdf_filename)).'"'); + else + Base_ActionBarCommon::add('print',__('Create CSV'),$this->create_href(array('rb_reports_enable_csv'=>1))); + } + return false; } - } ?> diff --git a/modules/Utils/RecordBrowser/Reports/csv.php b/modules/Utils/RecordBrowser/Reports/csv.php index 9930a87b3..58986a8d6 100644 --- a/modules/Utils/RecordBrowser/Reports/csv.php +++ b/modules/Utils/RecordBrowser/Reports/csv.php @@ -3,8 +3,9 @@ * Download file * * @author Paul Bukowski - * @copyright Copyright © 2006, Janusz Tylek - * @version 1.0 + * @copyright Copyright © 2006, Telaxus LLC + * @version 1.1 + * @Modified by praski * @license MIT * @package epesi-libs * @subpackage tcpdf @@ -17,18 +18,93 @@ define('CID', $id); define('READ_ONLY_SESSION',true); require_once('../../../../include.php'); +ModuleManager::load_modules(); +$params = Utils_CommonDataCommon::get_array('System/csv_export_params'); +$text_space_indicator = $params['text_space_indicator']; +$text_space_separator = $params['text_space_separator']; +$field_separator = $params['field_separator']; +$charset = $params['charset']; +$decimal_separator = $params['decimal_separator']; $csv = Module::static_get_module_variable($p,'csv',null); -if (headers_sent()) +if (headers_sent()){ die('Some data has already been output to browser, can\'t send PDF file'); -if ($csv===null) - die('Invalid link'); +} +if ($csv===null){ + die('Invalid link'); +} + +$end_line_type = $params['end_line_type']; +switch (strtoupper($end_line_type)){ + case ('LIN'): + case ('LINUX'): + case ('UNI'): + case ('UNIX'): + $end_line_type = "\n"; + break; + case ('WIN'): + case ('WINDOWS'): + $end_line_type = "\r\n"; + break; + case ('MAC'): + case ('MACINTOSH'): + $end_line_type = "\r"; + break; + default: + $end_line_type = "\n"; + break; +} + header('Content-Type: text/csv'); //header('Content-Length: '.strlen($buffer)); header('Content-disposition: attachment;filename="'.$filename.'.csv"'); $fp = fopen('php://output', 'w'); -foreach($csv as $array) - fputcsv($fp, $array); -fclose($fp); \ No newline at end of file +ob_start(function($buffer) use ($end_line_type,$text_space_indicator,$text_space_separator) { + return EOLConversion($buffer, $end_line_type,$text_space_indicator,$text_space_separator); +}); + +foreach($csv as $array){ + $array_converted = array(); + foreach ($array as $str){ + $array_converted[] = UtfToCharset($str,$text_space_indicator,$text_space_separator,$field_separator,$charset); + } + fputcsv($fp, $array_converted, $field_separator, htmlspecialchars_decode($text_space_separator)); +} +fclose($fp); + +function UtfToCharset($str,$text_space_indicator,$text_space_separator,$field_separator,$charset){ + $ret = str_replace(array($field_separator,$text_space_separator,"\r\n","\n","\r"),array(' ','',' ',' ',' '),$str); //We do not want field separator char inside oryginal text and endof line. + if (strtoupper($charset) <> 'UTF-8'){ + $ret = charset_conversion($ret,$charset); + } + return $ret; +} +function charset_conversion($string,$charset){ + if (function_exists('iconv')) { + $ret = iconv('UTF-8', $charset.'//TRANSLIT', $string); + }else{ + $ret = $string; + } + return $ret; +} + +function EOLConversion($string, $end_line_type, $text_space_indicator, $text_space_separator) { + if ($text_space_indicator){ //do not remove space indicator character + $text_space_separator = ''; + } + return str_replace(array(PHP_EOL,$text_space_separator), array($end_line_type,''), $string); +} +//PR190323 From oryginal RB CSV export + function rb_csv_export_format_currency_value($v, $symbol) + { + static $currency_decimal_signs = null; + static $currency_thou_signs; + if ($currency_decimal_signs === null) { + $currency_decimal_signs = DB::GetAssoc('SELECT symbol, decimal_sign FROM utils_currency'); + $currency_thou_signs = DB::GetAssoc('SELECT symbol, thousand_sign FROM utils_currency'); + } + $v = str_replace(array($currency_thou_signs[$symbol],$currency_decimal_signs[$symbol]), array('',$decimal_separator), $v); + return $v; + } diff --git a/modules/Utils/RecordBrowser/Reports/theme/date_picker.tpl b/modules/Utils/RecordBrowser/Reports/theme/date_picker.tpl index 1a72af65d..125467bed 100644 --- a/modules/Utils/RecordBrowser/Reports/theme/date_picker.tpl +++ b/modules/Utils/RecordBrowser/Reports/theme/date_picker.tpl @@ -1,7 +1,7 @@ {$form_open}
- +{assign var=counter value=1} {assign var=block value=0} @@ -13,14 +13,24 @@ - + {assign var=counter value=$counter+1} + {if $counter > 4} + {assign var=counter value=1} + + + + + + {/if} {/if} {/foreach} {if $show_dates}
{$e.label} + {$e.html}

+
diff --git a/modules/Utils/RecordBrowser/theme/Record_picker.tpl b/modules/Utils/RecordBrowser/theme/Record_picker.tpl index a5212ee0a..7e57a2e63 100644 --- a/modules/Utils/RecordBrowser/theme/Record_picker.tpl +++ b/modules/Utils/RecordBrowser/theme/Record_picker.tpl @@ -1,7 +1,7 @@ - {if $select_form != ""} + {if isset($select_form) && $select_form != ""} @@ -9,13 +9,13 @@ + {if isset($filters.controls) && $filters.controls} + {/if} - {if $filters.elements} + {if isset($filters.elements) && $filters.elements}
{$select_form}
- {if $select_all.js!=""} + {if $select_all.js!=""} - {/if} - {if $deselect_all.js!=""} + {/if} + {if $deselect_all.js!=""} {/if} - {if isset($close_leightbox)} + {if isset($close_leightbox)} {/if}
@@ -23,13 +23,15 @@
{if $filters.controls} {$filters.controls} {/if}
{$filters.elements} diff --git a/modules/Utils/TabbedBrowser/theme/default.css b/modules/Utils/TabbedBrowser/theme/default.css index 61d9ec6f0..c6135858d 100644 --- a/modules/Utils/TabbedBrowser/theme/default.css +++ b/modules/Utils/TabbedBrowser/theme/default.css @@ -1,6 +1,11 @@ .border_bottom{ - border-bottom: 1px solid #7b9cbd; + border-bottom: 4px solid #7b9cbd; margin-bottom: 6px; + /* css3 shadow */ + -webkit-box-shadow: 0px -2px 3px #303030; + -moz-box-shadow: 0px -2px 3px #303030; + box-shadow: 0px -2px 3px #303030; + /* end css3 shadow */ position: relative; z-index: 2; } @@ -12,16 +17,17 @@ } .Utils_TabbedBrowser_div .letter_search_icon { - padding: 0px 2px 0px 0; + padding: 0px 6px 0px 0; } ul.Utils_TabbedBrowser { text-align: left; font-weight: normal; - font-size: 14px; + font-size: 11px; /*border-bottom: 4px solid #828282;*/ list-style-type: none; /* padding: 13px 20px 3px 20px; */ + padding: 0px 8px; padding-top: 0px; margin-top: 0px; background: transparent; @@ -42,6 +48,16 @@ ul.Utils_TabbedBrowser li { ul.Utils_TabbedBrowser li span.tabbed_browser_selected { color: #FFFFFF; + /*dark css3 blue background gradient */ + background: #7b9cbd; /* Old browsers */ + background: -moz-linear-gradient(top, #7b9cbd 0%, #5982ac 50%, #336699 51%, #7b9cbd 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7b9cbd), color-stop(50%,#5982ac), color-stop(51%,#336699), color-stop(100%,#7b9cbd)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #7b9cbd 0%,#5982ac 50%,#336699 51%,#7b9cbd 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #7b9cbd 0%,#5982ac 50%,#336699 51%,#7b9cbd 100%); /* Opera11.10+ */ + background: -ms-linear-gradient(top, #7b9cbd 0%,#5982ac 50%,#336699 51%,#7b9cbd 100%); /* IE10+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7b9cbd', endColorstr='#7b9cbd',GradientType=0 ); /* IE6-9 */ + background: linear-gradient(top, #7b9cbd 0%,#5982ac 50%,#336699 51%,#7b9cbd 100%); /* W3C */ + /*dark css3 blue background gradient */ position: relative; z-index: 3; @@ -57,6 +73,32 @@ ul.Utils_TabbedBrowser li span { padding: 8px 10px 8px 10px; position: relative; z-index: 1; + + /*dark css3 green background image gradient */ + background: #709c70; /* Old browsers */ + background: -moz-linear-gradient(top, #709c70 0%, #4d844d 49%, #226622 51%, #649464 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#709c70), color-stop(49%,#4d844d), color-stop(51%,#226622), color-stop(100%,#649464)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #709c70 0%,#4d844d 49%,#226622 51%,#649464 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #709c70 0%,#4d844d 49%,#226622 51%,#649464 100%); /* Opera11.10+ */ + background: -ms-linear-gradient(top, #709c70 0%,#4d844d 49%,#226622 51%,#649464 100%); /* IE10+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#35b135', endColorstr='#2d602d',GradientType=0 ); /* IE6-9 */ + background: linear-gradient(top, #709c70 0%,#4d844d 49%,#226622 51%,#649464 100%); /* W3C */ + /* end dark css3 green background gradient */ + + /* css3 border radius */ + -webkit-border-top-left-radius: 3px; + -webkit-border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 0px; + -webkit-border-bottom-left-radius: 0px; + -moz-border-radius-topleft: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 0px; + -moz-border-radius-bottomleft: 0px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-bottom-right-radius: 0px; + border-bottom-left-radius: 0px; + /* end css3 border radius */ } ul.Utils_TabbedBrowser li a { @@ -75,6 +117,18 @@ ul.Utils_TabbedBrowser li img.tab_icon { ul.Utils_TabbedBrowser span:hover { cursor: pointer; text-decoration: underline; + + /*light css3 green background gradient */ + background: #226622; /* Old browsers */ + background: -moz-linear-gradient(top, #71b871 0%, #58ab58 49%, #379b37 51%, #63b163 95%, #226622 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#71b871), color-stop(49%,#58ab58), color-stop(51%,#379b37), color-stop(95%,#63b163), color-stop(100%,#226622)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #71b871 0%,#58ab58 49%,#379b37 51%,#63b163 95%,#226622 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #71b871 0%,#58ab58 49%,#379b37 51%,#63b163 95%,#226622 100%); /* Opera11.10+ */ + background: -ms-linear-gradient(top, #71b871 0%,#58ab58 49%,#379b37 51%,#63b163 95%,#226622 100%); /* IE10+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#5ada5a', endColorstr='#308630',GradientType=0 ); /* IE6-9 */ + background: linear-gradient(top, #71b871 0%,#58ab58 49%,#379b37 51%,#63b163 95%,#226622 100%); /* W3C */ + /* end light css3 green background gradient */ + } ul.Utils_TabbedBrowser li div.tabbedbrowser_submenu { @@ -89,6 +143,12 @@ ul.Utils_TabbedBrowser li div.tabbedbrowser_submenu span { background-color: #555; padding-top: 0px; padding-bottom: 0px; + -webkit-border-top-left-radius: 0px; + -webkit-border-top-right-radius: 0px; + -moz-border-radius-topleft: 0px; + -moz-border-radius-topright: 0px; + border-top-left-radius: 0px; + border-top-right-radius: 0px; } ul.Utils_TabbedBrowser li div.tabbedbrowser_submenu span:hover { diff --git a/setup.php b/setup.php index 0031433f7..25e8000d9 100644 --- a/setup.php +++ b/setup.php @@ -9,7 +9,7 @@ if (version_compare(phpversion(), '7.0.0')==-1) error_reporting(E_ALL); //all without notices else - error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED); + error_reporting(E_ALL & ~E_DEPRECATED); ob_start(); ini_set('arg_separator.output','&'); @define('SYSTEM_TIMEZONE',date_default_timezone_get());