From 96b0ad84967ee6b4d661647672e19cd5b1ade2de Mon Sep 17 00:00:00 2001 From: Thilina Hasantha Date: Sun, 3 Feb 2019 13:55:39 +0100 Subject: [PATCH] A bunch of new updates from icehrm pro --- .gitignore | 27 +- Vagrantfile | 5 +- build.xml | 55 +- cache.properties | 743 +- core/admin/attendance/index.php | 21 +- core/admin/company_structure/index.php | 21 +- core/admin/dashboard/index.php | 74 +- core/admin/fieldnames/index.php | 2 +- core/admin/jobs/index.php | 21 +- core/admin/loans/index.php | 37 +- core/admin/metadata/index.php | 2 +- core/admin/modules/index.php | 21 +- core/admin/overtime/index.php | 23 +- core/admin/permissions/index.php | 33 +- core/admin/projects/index.php | 41 +- core/admin/qualifications/index.php | 39 +- core/admin/settings/index.php | 21 +- core/admin/travel/index.php | 21 +- .../users/emailTemplates/welcomeUser.html | 15 +- core/admin/users/index.php | 31 +- core/config.base.php | 8 +- core/crons/cron.php | 1 - core/data/payroll/Ghana-Payroll.txt | 312 + core/data/payroll/Sample-Country-Payroll.txt | 188 + core/data/payroll/SriLanka-Payroll.txt | 264 + core/entry_footer.php | 4 +- core/entry_header.php | 106 +- core/footer.php | 9 +- core/header.php | 99 +- core/lang/ar.po | 1962 +++ core/lang/de.po | 57 + core/lang/en.po | 57 + core/lang/es.po | 621 +- core/lang/fi.po | 1962 +++ core/lang/fr.po | 645 +- core/lang/it.po | 57 + core/lang/ja.po | 57 + core/lang/nl.po | 1962 +++ core/lang/no.po | 1962 +++ core/lang/pl.po | 697 +- core/lang/pt.po | 1962 +++ core/lang/sr.po | 1962 +++ core/lang/sv.po | 1962 +++ core/lang/zh.po | 57 + core/lib/adodb512/adodb-active-record.inc.php | 340 +- .../config/scenarios/symfony2/src | 1 - .../config/scenarios/symfony2/src/Config.php | 157 + .../symfony2/src/ConfigInterface.php | 105 + .../GlobalOptionDefaultValuesInterface.php | 10 + .../symfony2/src/Inject/ConfigForCommand.php | 127 + .../symfony2/src/Inject/ConfigForSetters.php | 47 + .../symfony2/src/Loader/ConfigLoader.php | 35 + .../src/Loader/ConfigLoaderInterface.php | 29 + .../symfony2/src/Loader/ConfigProcessor.php | 167 + .../symfony2/src/Loader/YamlConfigLoader.php | 26 + .../scenarios/symfony2/src/Util/ArrayUtil.php | 75 + .../symfony2/src/Util/ConfigFallback.php | 51 + .../symfony2/src/Util/ConfigGroup.php | 61 + .../symfony2/src/Util/ConfigMerge.php | 34 + .../symfony2/src/Util/ConfigOverlay.php | 203 + .../scenarios/symfony2/src/Util/EnvConfig.php | 96 + .../config/scenarios/symfony2/tests | 1 - .../symfony2/tests/ConfigForCommandTest.php | 130 + .../symfony2/tests/ConfigForSettersTest.php | 87 + .../symfony2/tests/ConfigGroupTest.php | 91 + .../symfony2/tests/ConfigLoaderTest.php | 29 + .../symfony2/tests/ConfigOverlayTest.php | 168 + .../symfony2/tests/ConfigProcessorTest.php | 152 + .../scenarios/symfony2/tests/ConfigTest.php | 140 + .../symfony2/tests/data/config-1.yml | 3 + .../symfony2/tests/data/config-2.yml | 3 + .../symfony2/tests/data/config-3.yml | 3 + .../symfony2/tests/scripts/install-scenario | 23 + .../symfony2/tests/scripts/prep-dependencies | 66 + .../symfony2/tests/scripts/scenarios | 12 + .../tests/src/ApplyConfigTestTarget.php | 43 + .../symfony2/tests/src/MyFooCommand.php | 47 + .../symfony2/tests/src/TestLoader.php | 36 + .../config/scenarios/symfony4/src | 1 - .../config/scenarios/symfony4/src/Config.php | 157 + .../symfony4/src/ConfigInterface.php | 105 + .../GlobalOptionDefaultValuesInterface.php | 10 + .../symfony4/src/Inject/ConfigForCommand.php | 127 + .../symfony4/src/Inject/ConfigForSetters.php | 47 + .../symfony4/src/Loader/ConfigLoader.php | 35 + .../src/Loader/ConfigLoaderInterface.php | 29 + .../symfony4/src/Loader/ConfigProcessor.php | 167 + .../symfony4/src/Loader/YamlConfigLoader.php | 26 + .../scenarios/symfony4/src/Util/ArrayUtil.php | 75 + .../symfony4/src/Util/ConfigFallback.php | 51 + .../symfony4/src/Util/ConfigGroup.php | 61 + .../symfony4/src/Util/ConfigMerge.php | 34 + .../symfony4/src/Util/ConfigOverlay.php | 203 + .../scenarios/symfony4/src/Util/EnvConfig.php | 96 + .../config/scenarios/symfony4/tests | 1 - .../symfony4/tests/ConfigForCommandTest.php | 130 + .../symfony4/tests/ConfigForSettersTest.php | 87 + .../symfony4/tests/ConfigGroupTest.php | 91 + .../symfony4/tests/ConfigLoaderTest.php | 29 + .../symfony4/tests/ConfigOverlayTest.php | 168 + .../symfony4/tests/ConfigProcessorTest.php | 152 + .../scenarios/symfony4/tests/ConfigTest.php | 140 + .../symfony4/tests/data/config-1.yml | 3 + .../symfony4/tests/data/config-2.yml | 3 + .../symfony4/tests/data/config-3.yml | 3 + .../symfony4/tests/scripts/install-scenario | 23 + .../symfony4/tests/scripts/prep-dependencies | 66 + .../symfony4/tests/scripts/scenarios | 12 + .../tests/src/ApplyConfigTestTarget.php | 43 + .../symfony4/tests/src/MyFooCommand.php | 47 + .../symfony4/tests/src/TestLoader.php | 36 + .../consolidation/robo/scenarios/symfony2/src | 1 - .../scenarios/symfony2/src/Application.php | 73 + .../symfony2/src/Collection/CallableTask.php | 62 + .../symfony2/src/Collection/Collection.php | 769 + .../src/Collection/CollectionBuilder.php | 571 + .../src/Collection/CollectionInterface.php | 151 + .../src/Collection/CollectionProcessHook.php | 35 + .../src/Collection/CompletionWrapper.php | 106 + .../symfony2/src/Collection/Element.php | 116 + .../Collection/NestedCollectionInterface.php | 12 + .../symfony2/src/Collection/TaskForEach.php | 196 + .../symfony2/src/Collection/Temporary.php | 57 + .../symfony2/src/Collection/loadTasks.php | 17 + .../symfony2/src/Common/BuilderAwareTrait.php | 45 + .../symfony2/src/Common/CommandArguments.php | 130 + .../symfony2/src/Common/CommandReceiver.php | 30 + .../symfony2/src/Common/ConfigAwareTrait.php | 109 + .../symfony2/src/Common/DynamicParams.php | 45 + .../symfony2/src/Common/ExecCommand.php | 148 + .../symfony2/src/Common/ExecOneCommand.php | 12 + .../symfony2/src/Common/ExecTrait.php | 408 + .../robo/scenarios/symfony2/src/Common/IO.php | 171 + .../symfony2/src/Common/InflectionTrait.php | 21 + .../symfony2/src/Common/InputAwareTrait.php | 51 + .../symfony2/src/Common/OutputAdapter.php | 38 + .../symfony2/src/Common/OutputAwareTrait.php | 51 + .../symfony2/src/Common/ProcessExecutor.php | 51 + .../symfony2/src/Common/ProcessUtils.php | 79 + .../symfony2/src/Common/ProgressIndicator.php | 201 + .../Common/ProgressIndicatorAwareTrait.php | 135 + .../src/Common/ResourceExistenceChecker.php | 116 + .../scenarios/symfony2/src/Common/TaskIO.php | 237 + .../symfony2/src/Common/TimeKeeper.php | 69 + .../scenarios/symfony2/src/Common/Timer.php | 37 + .../src/Common/VerbosityThresholdTrait.php | 79 + .../robo/scenarios/symfony2/src/Config.php | 9 + .../scenarios/symfony2/src/Config/Config.php | 130 + .../GlobalOptionDefaultValuesInterface.php | 17 + .../src/Contract/BuilderAwareInterface.php | 22 + .../src/Contract/CommandInterface.php | 20 + .../src/Contract/CompletionInterface.php | 18 + .../src/Contract/ConfigAwareInterface.php | 24 + .../src/Contract/IOAwareInterface.php | 13 + .../src/Contract/InflectionInterface.php | 52 + .../src/Contract/OutputAdapterInterface.php | 11 + .../src/Contract/OutputAwareInterface.php | 19 + .../src/Contract/PrintedInterface.php | 16 + .../ProgressIndicatorAwareInterface.php | 24 + .../src/Contract/ProgressInterface.php | 19 + .../src/Contract/RollbackInterface.php | 18 + .../src/Contract/SimulatedInterface.php | 18 + .../symfony2/src/Contract/TaskInterface.php | 17 + .../Contract/VerbosityThresholdInterface.php | 24 + .../src/Contract/WrappedTaskInterface.php | 10 + .../symfony2/src/Exception/TaskException.php | 13 + .../src/Exception/TaskExitException.php | 13 + .../src/GlobalOptionsEventListener.php | 146 + .../scenarios/symfony2/src/LoadAllTasks.php | 39 + .../symfony2/src/Log/ResultPrinter.php | 112 + .../symfony2/src/Log/RoboLogLevel.php | 11 + .../symfony2/src/Log/RoboLogStyle.php | 74 + .../scenarios/symfony2/src/Log/RoboLogger.php | 29 + .../robo/scenarios/symfony2/src/Result.php | 258 + .../scenarios/symfony2/src/ResultData.php | 110 + .../robo/scenarios/symfony2/src/Robo.php | 394 + .../robo/scenarios/symfony2/src/Runner.php | 465 + .../symfony2/src/SelfUpdateCommand.php | 152 + .../scenarios/symfony2/src/State/Consumer.php | 12 + .../scenarios/symfony2/src/State/Data.php | 148 + .../src/State/StateAwareInterface.php | 30 + .../symfony2/src/State/StateAwareTrait.php | 49 + .../symfony2/src/Task/ApiGen/ApiGen.php | 518 + .../symfony2/src/Task/ApiGen/loadTasks.php | 15 + .../symfony2/src/Task/Archive/Extract.php | 279 + .../symfony2/src/Task/Archive/Pack.php | 257 + .../symfony2/src/Task/Archive/loadTasks.php | 25 + .../src/Task/Assets/CssPreprocessor.php | 214 + .../symfony2/src/Task/Assets/ImageMinify.php | 716 + .../symfony2/src/Task/Assets/Less.php | 108 + .../symfony2/src/Task/Assets/Minify.php | 297 + .../symfony2/src/Task/Assets/Scss.php | 93 + .../symfony2/src/Task/Assets/loadTasks.php | 45 + .../scenarios/symfony2/src/Task/Base/Exec.php | 125 + .../symfony2/src/Task/Base/ExecStack.php | 23 + .../symfony2/src/Task/Base/ParallelExec.php | 199 + .../symfony2/src/Task/Base/SymfonyCommand.php | 75 + .../symfony2/src/Task/Base/Watch.php | 89 + .../symfony2/src/Task/Base/loadShortcuts.php | 17 + .../symfony2/src/Task/Base/loadTasks.php | 48 + .../scenarios/symfony2/src/Task/BaseTask.php | 60 + .../symfony2/src/Task/Bower/Base.php | 88 + .../symfony2/src/Task/Bower/Install.php | 36 + .../symfony2/src/Task/Bower/Update.php | 34 + .../symfony2/src/Task/Bower/loadTasks.php | 25 + .../symfony2/src/Task/CommandStack.php | 134 + .../symfony2/src/Task/Composer/Base.php | 248 + .../symfony2/src/Task/Composer/Config.php | 93 + .../src/Task/Composer/CreateProject.php | 112 + .../src/Task/Composer/DumpAutoload.php | 62 + .../symfony2/src/Task/Composer/Init.php | 115 + .../symfony2/src/Task/Composer/Install.php | 40 + .../symfony2/src/Task/Composer/Remove.php | 85 + .../src/Task/Composer/RequireDependency.php | 50 + .../symfony2/src/Task/Composer/Update.php | 40 + .../symfony2/src/Task/Composer/Validate.php | 85 + .../symfony2/src/Task/Composer/loadTasks.php | 95 + .../src/Task/Development/Changelog.php | 246 + .../Task/Development/GenerateMarkdownDoc.php | 782 + .../src/Task/Development/GenerateTask.php | 107 + .../symfony2/src/Task/Development/GitHub.php | 157 + .../src/Task/Development/GitHubRelease.php | 208 + .../src/Task/Development/OpenBrowser.php | 80 + .../src/Task/Development/PackPhar.php | 252 + .../src/Task/Development/PhpServer.php | 86 + .../symfony2/src/Task/Development/SemVer.php | 255 + .../src/Task/Development/loadTasks.php | 86 + .../symfony2/src/Task/Docker/Base.php | 28 + .../symfony2/src/Task/Docker/Build.php | 55 + .../symfony2/src/Task/Docker/Commit.php | 66 + .../symfony2/src/Task/Docker/Exec.php | 95 + .../symfony2/src/Task/Docker/Pull.php | 33 + .../symfony2/src/Task/Docker/Remove.php | 32 + .../symfony2/src/Task/Docker/Result.php | 35 + .../symfony2/src/Task/Docker/Run.php | 301 + .../symfony2/src/Task/Docker/Start.php | 41 + .../symfony2/src/Task/Docker/Stop.php | 41 + .../symfony2/src/Task/Docker/loadTasks.php | 85 + .../symfony2/src/Task/File/Concat.php | 101 + .../symfony2/src/Task/File/Replace.php | 141 + .../symfony2/src/Task/File/TmpFile.php | 72 + .../symfony2/src/Task/File/Write.php | 335 + .../symfony2/src/Task/File/loadTasks.php | 48 + .../symfony2/src/Task/Filesystem/BaseDir.php | 30 + .../symfony2/src/Task/Filesystem/CleanDir.php | 63 + .../symfony2/src/Task/Filesystem/CopyDir.php | 162 + .../src/Task/Filesystem/DeleteDir.php | 36 + .../src/Task/Filesystem/FilesystemStack.php | 154 + .../src/Task/Filesystem/FlattenDir.php | 294 + .../src/Task/Filesystem/MirrorDir.php | 40 + .../symfony2/src/Task/Filesystem/TmpDir.php | 173 + .../symfony2/src/Task/Filesystem/WorkDir.php | 126 + .../src/Task/Filesystem/loadShortcuts.php | 159 + .../src/Task/Filesystem/loadTasks.php | 85 + .../scenarios/symfony2/src/Task/Gulp/Base.php | 97 + .../scenarios/symfony2/src/Task/Gulp/Run.php | 35 + .../symfony2/src/Task/Gulp/loadTasks.php | 16 + .../scenarios/symfony2/src/Task/Npm/Base.php | 60 + .../symfony2/src/Task/Npm/Install.php | 36 + .../symfony2/src/Task/Npm/Update.php | 34 + .../symfony2/src/Task/Npm/loadTasks.php | 25 + .../symfony2/src/Task/Remote/Rsync.php | 484 + .../symfony2/src/Task/Remote/Ssh.php | 273 + .../symfony2/src/Task/Remote/loadTasks.php | 24 + .../scenarios/symfony2/src/Task/Simulator.php | 168 + .../symfony2/src/Task/StackBasedTask.php | 236 + .../symfony2/src/Task/Testing/Atoum.php | 184 + .../symfony2/src/Task/Testing/Behat.php | 163 + .../symfony2/src/Task/Testing/Codecept.php | 271 + .../symfony2/src/Task/Testing/PHPUnit.php | 199 + .../symfony2/src/Task/Testing/Phpspec.php | 116 + .../symfony2/src/Task/Testing/loadTasks.php | 55 + .../symfony2/src/Task/Vcs/GitStack.php | 177 + .../symfony2/src/Task/Vcs/HgStack.php | 153 + .../symfony2/src/Task/Vcs/SvnStack.php | 106 + .../symfony2/src/Task/Vcs/loadShortcuts.php | 35 + .../symfony2/src/Task/Vcs/loadTasks.php | 37 + .../scenarios/symfony2/src/TaskAccessor.php | 47 + .../robo/scenarios/symfony2/src/TaskInfo.php | 35 + .../robo/scenarios/symfony2/src/Tasks.php | 23 + .../consolidation/robo/scenarios/symfony4/src | 1 - .../scenarios/symfony4/src/Application.php | 73 + .../symfony4/src/Collection/CallableTask.php | 62 + .../symfony4/src/Collection/Collection.php | 769 + .../src/Collection/CollectionBuilder.php | 571 + .../src/Collection/CollectionInterface.php | 151 + .../src/Collection/CollectionProcessHook.php | 35 + .../src/Collection/CompletionWrapper.php | 106 + .../symfony4/src/Collection/Element.php | 116 + .../Collection/NestedCollectionInterface.php | 12 + .../symfony4/src/Collection/TaskForEach.php | 196 + .../symfony4/src/Collection/Temporary.php | 57 + .../symfony4/src/Collection/loadTasks.php | 17 + .../symfony4/src/Common/BuilderAwareTrait.php | 45 + .../symfony4/src/Common/CommandArguments.php | 130 + .../symfony4/src/Common/CommandReceiver.php | 30 + .../symfony4/src/Common/ConfigAwareTrait.php | 109 + .../symfony4/src/Common/DynamicParams.php | 45 + .../symfony4/src/Common/ExecCommand.php | 148 + .../symfony4/src/Common/ExecOneCommand.php | 12 + .../symfony4/src/Common/ExecTrait.php | 408 + .../robo/scenarios/symfony4/src/Common/IO.php | 171 + .../symfony4/src/Common/InflectionTrait.php | 21 + .../symfony4/src/Common/InputAwareTrait.php | 51 + .../symfony4/src/Common/OutputAdapter.php | 38 + .../symfony4/src/Common/OutputAwareTrait.php | 51 + .../symfony4/src/Common/ProcessExecutor.php | 51 + .../symfony4/src/Common/ProcessUtils.php | 79 + .../symfony4/src/Common/ProgressIndicator.php | 201 + .../Common/ProgressIndicatorAwareTrait.php | 135 + .../src/Common/ResourceExistenceChecker.php | 116 + .../scenarios/symfony4/src/Common/TaskIO.php | 237 + .../symfony4/src/Common/TimeKeeper.php | 69 + .../scenarios/symfony4/src/Common/Timer.php | 37 + .../src/Common/VerbosityThresholdTrait.php | 79 + .../robo/scenarios/symfony4/src/Config.php | 9 + .../scenarios/symfony4/src/Config/Config.php | 130 + .../GlobalOptionDefaultValuesInterface.php | 17 + .../src/Contract/BuilderAwareInterface.php | 22 + .../src/Contract/CommandInterface.php | 20 + .../src/Contract/CompletionInterface.php | 18 + .../src/Contract/ConfigAwareInterface.php | 24 + .../src/Contract/IOAwareInterface.php | 13 + .../src/Contract/InflectionInterface.php | 52 + .../src/Contract/OutputAdapterInterface.php | 11 + .../src/Contract/OutputAwareInterface.php | 19 + .../src/Contract/PrintedInterface.php | 16 + .../ProgressIndicatorAwareInterface.php | 24 + .../src/Contract/ProgressInterface.php | 19 + .../src/Contract/RollbackInterface.php | 18 + .../src/Contract/SimulatedInterface.php | 18 + .../symfony4/src/Contract/TaskInterface.php | 17 + .../Contract/VerbosityThresholdInterface.php | 24 + .../src/Contract/WrappedTaskInterface.php | 10 + .../symfony4/src/Exception/TaskException.php | 13 + .../src/Exception/TaskExitException.php | 13 + .../src/GlobalOptionsEventListener.php | 146 + .../scenarios/symfony4/src/LoadAllTasks.php | 39 + .../symfony4/src/Log/ResultPrinter.php | 112 + .../symfony4/src/Log/RoboLogLevel.php | 11 + .../symfony4/src/Log/RoboLogStyle.php | 74 + .../scenarios/symfony4/src/Log/RoboLogger.php | 29 + .../robo/scenarios/symfony4/src/Result.php | 258 + .../scenarios/symfony4/src/ResultData.php | 110 + .../robo/scenarios/symfony4/src/Robo.php | 394 + .../robo/scenarios/symfony4/src/Runner.php | 465 + .../symfony4/src/SelfUpdateCommand.php | 152 + .../scenarios/symfony4/src/State/Consumer.php | 12 + .../scenarios/symfony4/src/State/Data.php | 148 + .../src/State/StateAwareInterface.php | 30 + .../symfony4/src/State/StateAwareTrait.php | 49 + .../symfony4/src/Task/ApiGen/ApiGen.php | 518 + .../symfony4/src/Task/ApiGen/loadTasks.php | 15 + .../symfony4/src/Task/Archive/Extract.php | 279 + .../symfony4/src/Task/Archive/Pack.php | 257 + .../symfony4/src/Task/Archive/loadTasks.php | 25 + .../src/Task/Assets/CssPreprocessor.php | 214 + .../symfony4/src/Task/Assets/ImageMinify.php | 716 + .../symfony4/src/Task/Assets/Less.php | 108 + .../symfony4/src/Task/Assets/Minify.php | 297 + .../symfony4/src/Task/Assets/Scss.php | 93 + .../symfony4/src/Task/Assets/loadTasks.php | 45 + .../scenarios/symfony4/src/Task/Base/Exec.php | 125 + .../symfony4/src/Task/Base/ExecStack.php | 23 + .../symfony4/src/Task/Base/ParallelExec.php | 199 + .../symfony4/src/Task/Base/SymfonyCommand.php | 75 + .../symfony4/src/Task/Base/Watch.php | 89 + .../symfony4/src/Task/Base/loadShortcuts.php | 17 + .../symfony4/src/Task/Base/loadTasks.php | 48 + .../scenarios/symfony4/src/Task/BaseTask.php | 60 + .../symfony4/src/Task/Bower/Base.php | 88 + .../symfony4/src/Task/Bower/Install.php | 36 + .../symfony4/src/Task/Bower/Update.php | 34 + .../symfony4/src/Task/Bower/loadTasks.php | 25 + .../symfony4/src/Task/CommandStack.php | 134 + .../symfony4/src/Task/Composer/Base.php | 248 + .../symfony4/src/Task/Composer/Config.php | 93 + .../src/Task/Composer/CreateProject.php | 112 + .../src/Task/Composer/DumpAutoload.php | 62 + .../symfony4/src/Task/Composer/Init.php | 115 + .../symfony4/src/Task/Composer/Install.php | 40 + .../symfony4/src/Task/Composer/Remove.php | 85 + .../src/Task/Composer/RequireDependency.php | 50 + .../symfony4/src/Task/Composer/Update.php | 40 + .../symfony4/src/Task/Composer/Validate.php | 85 + .../symfony4/src/Task/Composer/loadTasks.php | 95 + .../src/Task/Development/Changelog.php | 246 + .../Task/Development/GenerateMarkdownDoc.php | 782 + .../src/Task/Development/GenerateTask.php | 107 + .../symfony4/src/Task/Development/GitHub.php | 157 + .../src/Task/Development/GitHubRelease.php | 208 + .../src/Task/Development/OpenBrowser.php | 80 + .../src/Task/Development/PackPhar.php | 252 + .../src/Task/Development/PhpServer.php | 86 + .../symfony4/src/Task/Development/SemVer.php | 255 + .../src/Task/Development/loadTasks.php | 86 + .../symfony4/src/Task/Docker/Base.php | 28 + .../symfony4/src/Task/Docker/Build.php | 55 + .../symfony4/src/Task/Docker/Commit.php | 66 + .../symfony4/src/Task/Docker/Exec.php | 95 + .../symfony4/src/Task/Docker/Pull.php | 33 + .../symfony4/src/Task/Docker/Remove.php | 32 + .../symfony4/src/Task/Docker/Result.php | 35 + .../symfony4/src/Task/Docker/Run.php | 301 + .../symfony4/src/Task/Docker/Start.php | 41 + .../symfony4/src/Task/Docker/Stop.php | 41 + .../symfony4/src/Task/Docker/loadTasks.php | 85 + .../symfony4/src/Task/File/Concat.php | 101 + .../symfony4/src/Task/File/Replace.php | 141 + .../symfony4/src/Task/File/TmpFile.php | 72 + .../symfony4/src/Task/File/Write.php | 335 + .../symfony4/src/Task/File/loadTasks.php | 48 + .../symfony4/src/Task/Filesystem/BaseDir.php | 30 + .../symfony4/src/Task/Filesystem/CleanDir.php | 63 + .../symfony4/src/Task/Filesystem/CopyDir.php | 162 + .../src/Task/Filesystem/DeleteDir.php | 36 + .../src/Task/Filesystem/FilesystemStack.php | 154 + .../src/Task/Filesystem/FlattenDir.php | 294 + .../src/Task/Filesystem/MirrorDir.php | 40 + .../symfony4/src/Task/Filesystem/TmpDir.php | 173 + .../symfony4/src/Task/Filesystem/WorkDir.php | 126 + .../src/Task/Filesystem/loadShortcuts.php | 159 + .../src/Task/Filesystem/loadTasks.php | 85 + .../scenarios/symfony4/src/Task/Gulp/Base.php | 97 + .../scenarios/symfony4/src/Task/Gulp/Run.php | 35 + .../symfony4/src/Task/Gulp/loadTasks.php | 16 + .../scenarios/symfony4/src/Task/Npm/Base.php | 60 + .../symfony4/src/Task/Npm/Install.php | 36 + .../symfony4/src/Task/Npm/Update.php | 34 + .../symfony4/src/Task/Npm/loadTasks.php | 25 + .../symfony4/src/Task/Remote/Rsync.php | 484 + .../symfony4/src/Task/Remote/Ssh.php | 273 + .../symfony4/src/Task/Remote/loadTasks.php | 24 + .../scenarios/symfony4/src/Task/Simulator.php | 168 + .../symfony4/src/Task/StackBasedTask.php | 236 + .../symfony4/src/Task/Testing/Atoum.php | 184 + .../symfony4/src/Task/Testing/Behat.php | 163 + .../symfony4/src/Task/Testing/Codecept.php | 271 + .../symfony4/src/Task/Testing/PHPUnit.php | 199 + .../symfony4/src/Task/Testing/Phpspec.php | 116 + .../symfony4/src/Task/Testing/loadTasks.php | 55 + .../symfony4/src/Task/Vcs/GitStack.php | 177 + .../symfony4/src/Task/Vcs/HgStack.php | 153 + .../symfony4/src/Task/Vcs/SvnStack.php | 106 + .../symfony4/src/Task/Vcs/loadShortcuts.php | 35 + .../symfony4/src/Task/Vcs/loadTasks.php | 37 + .../scenarios/symfony4/src/TaskAccessor.php | 47 + .../robo/scenarios/symfony4/src/TaskInfo.php | 35 + .../robo/scenarios/symfony4/src/Tasks.php | 23 + .../yaml-expander/scenarios/symfony2/src | 1 - .../scenarios/symfony2/src/Expander.php | 273 + .../yaml-expander/scenarios/symfony2/tests | 1 - .../symfony2/tests/phpunit/ExpanderTest.php | 99 + .../symfony2/tests/resources/valid.yml | 35 + .../yaml-expander/scenarios/symfony4/src | 1 - .../scenarios/symfony4/src/Expander.php | 273 + .../yaml-expander/scenarios/symfony4/tests | 1 - .../symfony4/tests/phpunit/ExpanderTest.php | 99 + .../symfony4/tests/resources/valid.yml | 35 + core/login.php | 9 +- core/migrations/list.php | 8 + .../v20170621_190401_report_modifications.php | 24 + .../v20180801_240003_asset_management.php | 63 + .../v20180808_250004_add_languages.php | 39 + .../v20180810_250005_performance_review.php | 72 + .../v20180912_250006_remove_null_users.php | 20 + ...181025_260001_dept_based_leave_periods.php | 26 + .../v20181106_260002_add_arabic_lang.php | 19 + .../v20190125_260003_attendance_with_map.php | 40 + core/modulejslibs.inc.php | 4 +- core/modules.php | 3 + core/modules/attendance/index.php | 21 +- core/modules/dashboard/index.php | 21 +- core/modules/dependents/index.php | 33 +- core/modules/emergency_contact/index.php | 33 +- core/modules/employees/index.php | 69 +- core/modules/loans/index.php | 33 +- core/modules/meta.json | 1 + core/modules/overtime/index.php | 26 +- core/modules/projects/index.php | 31 +- core/modules/qualifications/index.php | 21 +- core/modules/reports/index.php | 1 - core/modules/salary/index.php | 33 +- .../customTemplates/element.html | 21 + core/modules/staffdirectory/index.php | 61 + core/modules/staffdirectory/meta.json | 14 + core/modules/time_sheets/index.php | 23 +- core/modules/travel/index.php | 24 +- core/service.php | 4 +- .../Admin/Api/AttendanceActionManager.php | 23 +- .../Rest/AttendanceRestEndPoint.php | 340 + core/src/Classes/AbstractInitialize.php | 2 +- .../Approval/ApproveAdminActionManager.php | 6 +- core/src/Classes/BaseService.php | 17 +- core/src/Classes/Cron/IceCron.php | 1 - .../Task/DocumentExpiryNotificationTask.php | 140 + core/src/Classes/Data/DataReader.php | 29 + core/src/Classes/Data/Query/DataQuery.php | 262 + core/src/Classes/Data/Query/FieldMapping.php | 39 + core/src/Classes/Data/Query/Filter.php | 51 + core/src/Classes/Email/EmailSender.php | 53 +- core/src/Classes/FileService.php | 8 +- core/src/Classes/NotificationManager.php | 7 +- core/src/Classes/PermissionManager.php | 46 + core/src/Classes/RestEndPoint.php | 11 +- core/src/Classes/SubActionManager.php | 2 +- core/src/Classes/UIManager.php | 16 + core/src/Employees/Common/Model/Employee.php | 20 +- .../Employees/Rest/EmployeeRestEndPoint.php | 10 + .../User/Api/EmployeesActionManager.php | 5 +- .../Admin/Api/ExpensesActionManager.php | 55 - .../Admin/Api/ExpensesAdminManager.php | 45 - .../Expenses/Common/Model/EmployeeExpense.php | 81 - .../Common/Model/EmployeeExpenseApproval.php | 19 - .../Common/Model/ExpensesCategory.php | 36 - .../Common/Model/ExpensesPaymentMethod.php | 36 - .../User/Api/ExpensesActionManager.php | 45 - .../User/Api/ExpensesModulesManager.php | 31 - core/src/Model/BaseModel.php | 6 +- core/src/Model/Setting.php | 24 + .../Admin/Api/ModulesActionManager.php | 21 +- .../Modules/Admin/Api/ModulesAdminManager.php | 21 +- core/src/Modules/Common/Model/Module.php | 21 +- .../Admin/Api/OvertimePayrollUtils.php | 59 + core/src/Payroll/Common/Model/Payroll.php | 3 +- .../Admin/Reports/AssetUsageReport.php | 76 + .../Admin/Reports/EmployeeDetailsReport.php | 124 + .../Common/Model/StaffDirectory.php | 55 + .../Rest/StaffDirectoryRestEndPoint.php | 19 + .../User/Api/StaffDirectoryModulesManager.php | 34 + .../User/Api/TimeSheetsPayrollUtils.php | 62 + .../Users/Admin/Api/UsersActionManager.php | 21 +- core/src/Users/Admin/Api/UsersEmailSender.php | 4 +- core/src/Users/Common/Model/User.php | 21 +- core/src/Users/Common/Model/UserRole.php | 21 +- core/templates/email/emailBody.html | 378 +- deployment/clients/dev/config.php | 4 +- gulpfile.js | 234 + package-lock.json | 9226 ++++++++++++ package.json | 41 + readme.md | 19 +- release.md | 21 +- .../integration/ApprovalStatusIntegration.php | 4 +- web/admin/attendance/lib.js | 317 - web/admin/company_structure/lib.js | 320 - web/admin/dashboard/lib.js | 79 - web/admin/data/lib.js | 177 - web/admin/employees/lib.js | 1950 --- web/admin/fieldnames/lib.js | 49 - web/admin/jobs/lib.js | 139 - web/admin/loans/lib.js | 102 - web/admin/metadata/lib.js | 158 - web/admin/modules/lib.js | 164 - web/admin/overtime/lib.js | 99 - web/admin/payroll/lib.js | 657 - web/admin/permissions/lib.js | 73 - web/admin/projects/lib.js | 172 - web/admin/qualifications/lib.js | 161 - web/admin/reports/lib.js | 396 - web/admin/salary/lib.js | 134 - web/admin/settings/lib.js | 111 - web/admin/travel/lib.js | 195 - web/admin/users/lib.js | 201 - web/api/AdapterBase.js | 2002 +-- web/api/AesCrypt.js | 503 - web/api/Base.js | 2639 ---- web/api/ConversationsAdapter.js | 404 +- web/api/FormValidation.js | 428 +- web/api/Notifications.js | 138 - web/api/SocialShare.js | 74 +- web/api/TimeUtils.js | 163 - .../flag-icon-css/flags/4x3/ar.svg | 33 +- web/css/style.css | 2 +- web/js/app-global.js | 184 - .../css/bootstrap-colorpicker.css | 12 +- web/js/downloadify/images/download.png | Bin 2500 -> 0 bytes web/js/downloadify/js/downloadify.min.js | 3 - web/js/downloadify/js/swfobject.js | 4 - web/js/downloadify/media/downloadify.swf | Bin 2625 -> 0 bytes web/js/select2/select2.css | 42 +- web/modules/attendance/lib.js | 513 - web/modules/dashboard/lib.js | 130 - web/modules/dependents/lib.js | 64 - web/modules/emergency_contact/lib.js | 63 - web/modules/employees/lib.js | 730 - web/modules/loans/lib.js | 91 - web/modules/overtime/lib.js | 120 - web/modules/projects/lib.js | 51 - web/modules/qualifications/lib.js | 200 - web/modules/reports/lib.js | 34 - web/modules/salary/lib.js | 56 - web/modules/src/staffdirectory/index.js | 7 + web/modules/src/staffdirectory/lib.js | 173 + web/modules/time_sheets/lib.js | 966 -- web/modules/travel/lib.js | 241 - web/themecss/AdminLTE.css | 2 +- .../datatables/dataTables.bootstrap.js | 250 - .../plugins/datatables/jquery.dataTables.js | 12129 ---------------- 598 files changed, 74156 insertions(+), 29979 deletions(-) create mode 100644 core/data/payroll/Ghana-Payroll.txt create mode 100644 core/data/payroll/Sample-Country-Payroll.txt create mode 100644 core/data/payroll/SriLanka-Payroll.txt create mode 100644 core/lang/ar.po create mode 100644 core/lang/fi.po create mode 100644 core/lang/nl.po create mode 100644 core/lang/no.po create mode 100644 core/lang/pt.po create mode 100644 core/lang/sr.po create mode 100644 core/lang/sv.po delete mode 120000 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Config.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/ConfigInterface.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/GlobalOptionDefaultValuesInterface.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Inject/ConfigForCommand.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Inject/ConfigForSetters.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigLoader.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigLoaderInterface.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigProcessor.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/YamlConfigLoader.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ArrayUtil.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigFallback.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigGroup.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigMerge.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigOverlay.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/EnvConfig.php delete mode 120000 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigForCommandTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigForSettersTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigGroupTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigLoaderTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigOverlayTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigProcessorTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-1.yml create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-2.yml create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-3.yml create mode 100755 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/install-scenario create mode 100755 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/prep-dependencies create mode 100755 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/scenarios create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/ApplyConfigTestTarget.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/MyFooCommand.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/TestLoader.php delete mode 120000 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Config.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/ConfigInterface.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/GlobalOptionDefaultValuesInterface.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Inject/ConfigForCommand.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Inject/ConfigForSetters.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigLoader.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigLoaderInterface.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigProcessor.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/YamlConfigLoader.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ArrayUtil.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigFallback.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigGroup.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigMerge.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigOverlay.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/EnvConfig.php delete mode 120000 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigForCommandTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigForSettersTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigGroupTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigLoaderTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigOverlayTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigProcessorTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigTest.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-1.yml create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-2.yml create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-3.yml create mode 100755 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/install-scenario create mode 100755 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/prep-dependencies create mode 100755 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/scenarios create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/ApplyConfigTestTarget.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/MyFooCommand.php create mode 100644 core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/TestLoader.php delete mode 120000 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Application.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CallableTask.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Collection.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionBuilder.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionProcessHook.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CompletionWrapper.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Element.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/NestedCollectionInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/TaskForEach.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Temporary.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/BuilderAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/CommandArguments.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/CommandReceiver.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ConfigAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/DynamicParams.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecCommand.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecOneCommand.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/IO.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/InflectionTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/InputAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/OutputAdapter.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/OutputAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProcessExecutor.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProcessUtils.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProgressIndicator.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProgressIndicatorAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ResourceExistenceChecker.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/TaskIO.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/TimeKeeper.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/Timer.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/VerbosityThresholdTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config/Config.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config/GlobalOptionDefaultValuesInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/BuilderAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/CommandInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/CompletionInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/ConfigAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/IOAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/InflectionInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/OutputAdapterInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/OutputAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/PrintedInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/ProgressIndicatorAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/ProgressInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/RollbackInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/SimulatedInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/TaskInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/VerbosityThresholdInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/WrappedTaskInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Exception/TaskException.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Exception/TaskExitException.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/GlobalOptionsEventListener.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/LoadAllTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/ResultPrinter.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogLevel.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogStyle.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogger.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Result.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/ResultData.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Robo.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Runner.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/SelfUpdateCommand.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/Consumer.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/Data.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/StateAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/StateAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/ApiGen/ApiGen.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/ApiGen/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/Extract.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/Pack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/CssPreprocessor.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/ImageMinify.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Less.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Minify.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Scss.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/Exec.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/ExecStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/ParallelExec.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/SymfonyCommand.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/Watch.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/loadShortcuts.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/BaseTask.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Install.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Update.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/CommandStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Config.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/CreateProject.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/DumpAutoload.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Init.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Install.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Remove.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/RequireDependency.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Update.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Validate.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/Changelog.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GenerateMarkdownDoc.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GenerateTask.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GitHub.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GitHubRelease.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/OpenBrowser.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/PackPhar.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/PhpServer.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/SemVer.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Build.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Commit.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Exec.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Pull.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Remove.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Result.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Run.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Start.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Stop.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Concat.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Replace.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/TmpFile.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Write.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/BaseDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/CleanDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/CopyDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/DeleteDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/FilesystemStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/FlattenDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/MirrorDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/TmpDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/WorkDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/loadShortcuts.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/Run.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Install.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Update.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/Rsync.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/Ssh.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Simulator.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/StackBasedTask.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Atoum.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Behat.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Codecept.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/PHPUnit.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Phpspec.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/GitStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/HgStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/SvnStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/loadShortcuts.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/TaskAccessor.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/TaskInfo.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Tasks.php delete mode 120000 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Application.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CallableTask.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Collection.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionBuilder.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionProcessHook.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CompletionWrapper.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Element.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/NestedCollectionInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/TaskForEach.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Temporary.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/BuilderAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/CommandArguments.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/CommandReceiver.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ConfigAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/DynamicParams.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecCommand.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecOneCommand.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/IO.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/InflectionTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/InputAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/OutputAdapter.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/OutputAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProcessExecutor.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProcessUtils.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProgressIndicator.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProgressIndicatorAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ResourceExistenceChecker.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/TaskIO.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/TimeKeeper.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/Timer.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/VerbosityThresholdTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config/Config.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config/GlobalOptionDefaultValuesInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/BuilderAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/CommandInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/CompletionInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/ConfigAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/IOAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/InflectionInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/OutputAdapterInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/OutputAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/PrintedInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/ProgressIndicatorAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/ProgressInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/RollbackInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/SimulatedInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/TaskInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/VerbosityThresholdInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/WrappedTaskInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Exception/TaskException.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Exception/TaskExitException.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/GlobalOptionsEventListener.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/LoadAllTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/ResultPrinter.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogLevel.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogStyle.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogger.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Result.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/ResultData.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Robo.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Runner.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/SelfUpdateCommand.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/Consumer.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/Data.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/StateAwareInterface.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/StateAwareTrait.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/ApiGen/ApiGen.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/ApiGen/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/Extract.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/Pack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/CssPreprocessor.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/ImageMinify.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Less.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Minify.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Scss.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/Exec.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/ExecStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/ParallelExec.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/SymfonyCommand.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/Watch.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/loadShortcuts.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/BaseTask.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Install.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Update.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/CommandStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Config.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/CreateProject.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/DumpAutoload.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Init.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Install.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Remove.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/RequireDependency.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Update.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Validate.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/Changelog.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GenerateMarkdownDoc.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GenerateTask.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GitHub.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GitHubRelease.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/OpenBrowser.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/PackPhar.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/PhpServer.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/SemVer.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Build.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Commit.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Exec.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Pull.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Remove.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Result.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Run.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Start.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Stop.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Concat.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Replace.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/TmpFile.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Write.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/BaseDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/CleanDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/CopyDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/DeleteDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/FilesystemStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/FlattenDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/MirrorDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/TmpDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/WorkDir.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/loadShortcuts.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/Run.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Base.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Install.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Update.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/Rsync.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/Ssh.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Simulator.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/StackBasedTask.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Atoum.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Behat.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Codecept.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/PHPUnit.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Phpspec.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/GitStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/HgStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/SvnStack.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/loadShortcuts.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/loadTasks.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/TaskAccessor.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/TaskInfo.php create mode 100644 core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Tasks.php delete mode 120000 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/src create mode 100644 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/src/Expander.php delete mode 120000 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests create mode 100644 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests/phpunit/ExpanderTest.php create mode 100644 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests/resources/valid.yml delete mode 120000 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/src create mode 100644 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/src/Expander.php delete mode 120000 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests create mode 100644 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests/phpunit/ExpanderTest.php create mode 100644 core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests/resources/valid.yml create mode 100644 core/migrations/v20170621_190401_report_modifications.php create mode 100644 core/migrations/v20180801_240003_asset_management.php create mode 100644 core/migrations/v20180808_250004_add_languages.php create mode 100644 core/migrations/v20180810_250005_performance_review.php create mode 100644 core/migrations/v20180912_250006_remove_null_users.php create mode 100644 core/migrations/v20181025_260001_dept_based_leave_periods.php create mode 100644 core/migrations/v20181106_260002_add_arabic_lang.php create mode 100644 core/migrations/v20190125_260003_attendance_with_map.php create mode 100644 core/modules/staffdirectory/customTemplates/element.html create mode 100644 core/modules/staffdirectory/index.php create mode 100644 core/modules/staffdirectory/meta.json create mode 100644 core/src/Attendance/Rest/AttendanceRestEndPoint.php create mode 100644 core/src/Classes/Cron/Task/DocumentExpiryNotificationTask.php create mode 100644 core/src/Classes/Data/DataReader.php create mode 100644 core/src/Classes/Data/Query/DataQuery.php create mode 100644 core/src/Classes/Data/Query/FieldMapping.php create mode 100644 core/src/Classes/Data/Query/Filter.php create mode 100644 core/src/Classes/PermissionManager.php delete mode 100644 core/src/Expenses/Admin/Api/ExpensesActionManager.php delete mode 100644 core/src/Expenses/Admin/Api/ExpensesAdminManager.php delete mode 100644 core/src/Expenses/Common/Model/EmployeeExpense.php delete mode 100644 core/src/Expenses/Common/Model/EmployeeExpenseApproval.php delete mode 100644 core/src/Expenses/Common/Model/ExpensesCategory.php delete mode 100644 core/src/Expenses/Common/Model/ExpensesPaymentMethod.php delete mode 100644 core/src/Expenses/User/Api/ExpensesActionManager.php delete mode 100644 core/src/Expenses/User/Api/ExpensesModulesManager.php create mode 100644 core/src/Overtime/Admin/Api/OvertimePayrollUtils.php create mode 100644 core/src/Reports/Admin/Reports/AssetUsageReport.php create mode 100644 core/src/Reports/Admin/Reports/EmployeeDetailsReport.php create mode 100644 core/src/StaffDirectory/Common/Model/StaffDirectory.php create mode 100644 core/src/StaffDirectory/Rest/StaffDirectoryRestEndPoint.php create mode 100644 core/src/StaffDirectory/User/Api/StaffDirectoryModulesManager.php create mode 100644 core/src/TimeSheets/User/Api/TimeSheetsPayrollUtils.php create mode 100644 gulpfile.js create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 web/admin/attendance/lib.js delete mode 100644 web/admin/company_structure/lib.js delete mode 100644 web/admin/dashboard/lib.js delete mode 100644 web/admin/data/lib.js delete mode 100644 web/admin/employees/lib.js delete mode 100644 web/admin/fieldnames/lib.js delete mode 100644 web/admin/jobs/lib.js delete mode 100644 web/admin/loans/lib.js delete mode 100644 web/admin/metadata/lib.js delete mode 100644 web/admin/modules/lib.js delete mode 100644 web/admin/overtime/lib.js delete mode 100644 web/admin/payroll/lib.js delete mode 100644 web/admin/permissions/lib.js delete mode 100644 web/admin/projects/lib.js delete mode 100644 web/admin/qualifications/lib.js delete mode 100644 web/admin/reports/lib.js delete mode 100644 web/admin/salary/lib.js delete mode 100644 web/admin/settings/lib.js delete mode 100644 web/admin/travel/lib.js delete mode 100644 web/admin/users/lib.js delete mode 100644 web/api/AesCrypt.js delete mode 100644 web/api/Base.js delete mode 100644 web/api/Notifications.js delete mode 100644 web/api/TimeUtils.js delete mode 100644 web/js/app-global.js delete mode 100755 web/js/downloadify/images/download.png delete mode 100755 web/js/downloadify/js/downloadify.min.js delete mode 100755 web/js/downloadify/js/swfobject.js delete mode 100755 web/js/downloadify/media/downloadify.swf delete mode 100644 web/modules/attendance/lib.js delete mode 100644 web/modules/dashboard/lib.js delete mode 100644 web/modules/dependents/lib.js delete mode 100644 web/modules/emergency_contact/lib.js delete mode 100644 web/modules/employees/lib.js delete mode 100644 web/modules/loans/lib.js delete mode 100644 web/modules/overtime/lib.js delete mode 100644 web/modules/projects/lib.js delete mode 100644 web/modules/qualifications/lib.js delete mode 100644 web/modules/reports/lib.js delete mode 100644 web/modules/salary/lib.js create mode 100644 web/modules/src/staffdirectory/index.js create mode 100644 web/modules/src/staffdirectory/lib.js delete mode 100644 web/modules/time_sheets/lib.js delete mode 100644 web/modules/travel/lib.js delete mode 100644 web/themejs/plugins/datatables/dataTables.bootstrap.js delete mode 100644 web/themejs/plugins/datatables/jquery.dataTables.js diff --git a/.gitignore b/.gitignore index 0be78500..41b3dadc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,17 @@ -/.settings -/.buildpath -/.project -/.idea/ -/build -/deployment/clients/dev/data/ -/deployment/clients/test/data/ -/deployment/clients/local/data/ -/.vagrant -/app/config.php -/app/data/* +.settings +.buildpath +.project +.idea/ +build +deployment/clients/dev/data/ +deployment/clients/test/data/ +deployment/clients/local/data/ +.vagrant +app/config.php +app/data/* +cache.properties +node_modules/* +web/dist/*.map +web/admin/dist/*.map +web/modules/dist/*.map .gitkeep diff --git a/Vagrantfile b/Vagrantfile index 70d78268..269b878d 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -21,9 +21,8 @@ Vagrant.configure(2) do |config| config.vm.hostname = "icehrm.open" config.hostsupdater.aliases = [ - "app.dev", - "app.app.dev", - "clients.app.dev" + "app.icehrm-open.test", + "clients.icehrm-open.test" ] end diff --git a/build.xml b/build.xml index 622aa124..97964395 100644 --- a/build.xml +++ b/build.xml @@ -1,5 +1,5 @@ - + @@ -11,7 +11,7 @@ - @@ -94,7 +93,6 @@ - @@ -145,7 +143,7 @@ - + @@ -181,12 +179,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -196,11 +223,16 @@ - - - - - + + + + + + + + + + @@ -219,6 +251,9 @@ + + + diff --git a/cache.properties b/cache.properties index 8b30eb9b..405e7561 100644 --- a/cache.properties +++ b/cache.properties @@ -1,244 +1,499 @@ -#Sun Apr 29 05:47:35 CEST 2018 -/Users/Thilina/Projects/icehrm/src/Expenses/Common/Model/EmployeeExpenseApproval.php=db8eedd8fb151769acded489e9d616c1 -/Users/Thilina/Projects/icehrm/src/Attendance/Common/Calculations/BasicOvertimeCalculator.php=9c96ae3f71796029d3f93e5c63783f53 -/Users/Thilina/Projects/icehrm/src/Classes/Email/SNSEmailSender.php=fa905e3ab63ea745c591e744d6741b6b -/Users/Thilina/Projects/icehrm/src/Salary/Common/Model/SalaryComponent.php=31e89f1115de7986cd790c8e113ab6d5 -/Users/Thilina/Projects/icehrm/src/Classes/Email/EmailSender.php=03a98d7d1bcc56a77cc5b3bfa46b79fd -/Users/Thilina/Projects/icehrm/test/bootstrap.php=391db040530140c40c84cbbc65645d58 -/Users/Thilina/Projects/icehrm/src/Utils/InputCleaner.php=e86fcb9daf1d32a4328edf40a31152f8 -/Users/Thilina/Projects/icehrm/src/Projects/Common/Model/Project.php=05b1cd967d67cb977558f2567d7f6cb6 -/Users/Thilina/Projects/icehrm/src/Model/DataEntryBackup.php=9ab3a7d48dbdd377a90c505cf692c17e -/Users/Thilina/Projects/icehrm/src/Qualifications/Common/Model/Skill.php=e1441a2526e24a7ada7d20b36ff9e355 -/Users/Thilina/Projects/icehrm/src/Permissions/Admin/Api/PermissionsAdminManager.php=c66e06b926b4006e8a2d7f2e77e0f1fa -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/Province.php=4a718577000772ab7591a2586f7c75c8 -/Users/Thilina/Projects/icehrm/src/Loans/Common/Model/EmployeeCompanyLoan.php=abc8959df2ec0f3e19ff6da12c3163f9 -/Users/Thilina/Projects/icehrm/src/Classes/Approval/ApprovalStatus.php=7a3bc0a73f237eb677254b245887f48f -/Users/Thilina/Projects/icehrm/src/Classes/FileService.php=806ff6c25c7654c30e99b0418e1c1475 -/Users/Thilina/Projects/icehrm/src/Dashboard/User/Api/DashboardActionManager.php=3f797cf4807ad5cd4f881607142df049 -/Users/Thilina/Projects/icehrm/src/Classes/Cron/Task/EmailSenderTask.php=f0c93e7c807706922cb812723e51bd09 -/Users/Thilina/Projects/icehrm/src/Attendance/Admin/Api/AttendanceUtil.php=34fe63a4c0f954451afae6c359ea5b38 -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/Deduction.php=1e49d0fd8d4673e3fd094cfb0e467df4 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/PayrollDataExport.php=83bd6faa73c75667ecf25091c3729abc -/Users/Thilina/Projects/icehrm/src/Employees/Common/Model/Employee.php=f8814257c241892fcf45e1d409d6ab1b -/Users/Thilina/Projects/icehrm/src/Metadata/Admin/Api/MetadataAdminManager.php=9f383f9c34ec98a8e2e701825c548a8a -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/NewHiresEmployeeReport.php=64eab525953538d481dab6052dd76d81 -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/DeductionGroup.php=c35db5b88aa4b0c7d78b8444688931b5 -/Users/Thilina/Projects/icehrm/src/Utils/Math/EvalMathFuncs.php=d6f7c26eab307d205ee8483d87a380cb -/Users/Thilina/Projects/icehrm/src/Classes/ModuleBuilder/ModuleTabGroup.php=d81cfc2b3dcad2f57317b1274c884d95 -/Users/Thilina/Projects/icehrm/src/Model/RestAccessToken.php=77c292675944ff887fc8b4c3f7b6da94 -/Users/Thilina/Projects/icehrm/src/Classes/LDAPManager.php=e88dd0634a6ca372564faa5a1d540796 -/Users/Thilina/Projects/icehrm/src/Expenses/Admin/Api/ExpensesAdminManager.php=ef6961e298a55379ec4dfff8b9db77fc -/Users/Thilina/Projects/icehrm/src/Dashboard/User/Api/DashboardModulesManager.php=2e8968121b445353ee864c76c44483d3 -/Users/Thilina/Projects/icehrm/src/Model/UserReport.php=0a8a8476e3088011cc54fda139567b56 -/Users/Thilina/Projects/icehrm/src/Travel/Common/Model/EmployeeTravelRecordApproval.php=d84b2a1323f3663806cc30545e748cd4 -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/SupportedLanguage.php=3ec1220796f6e33641998a33f036d709 -/Users/Thilina/Projects/icehrm/src/TimeSheets/Common/Model/QTDays.php=32a00e65a966331b776dc37cc0609edf -/Users/Thilina/Projects/icehrm/src/Salary/Common/Model/EmployeeSalary.php=ec80c4e8280d23568df79f59d1b32de8 -/Users/Thilina/Projects/icehrm/src/Classes/SimpleImage.php=fdfb7b2e71e14975ebce16de44ea9dee -/Users/Thilina/Projects/icehrm/src/Expenses/User/Api/ExpensesModulesManager.php=4860a1fbb24f4074a6918b2c0b973e80 -/Users/Thilina/Projects/icehrm/src/Employees/User/Api/EmployeesActionManager.php=7f495266d28737c779e1e9ab3c61e0db -/Users/Thilina/Projects/icehrm/src/Classes/Approval/ApproveAdminActionManager.php=3c26b53f0e5141b8f4a033cbbd4c622e -/Users/Thilina/Projects/icehrm/src/Settings/Admin/Api/SettingsAdminManager.php=5e5df0056db6f9593128720581feca18 -/Users/Thilina/Projects/icehrm/src/Travel/User/Api/TravelModulesManager.php=94c9204a67e99af9133cd2aa371cb6da -/Users/Thilina/Projects/icehrm/test/unit/UserAttendanceActionManagerUnit.php=1d71d366a13f253ef6931aa87202ac42 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/OvertimeRequestReport.php=3cd3bc887da768a32bfc61c152489528 -/Users/Thilina/Projects/icehrm/src/Employees/User/Api/EmployeesModulesManager.php=ad9ab05afd9cf551870352dba82e6d69 -/Users/Thilina/Projects/icehrm/test/helper/EmployeeTestDataHelper.php=65ec2048653c9e4e4359d9b6967a860d -/Users/Thilina/Projects/icehrm/test/integration/ApprovalStatusIntegration.php=8b9243e5cbb302513d906ff9de246acd -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/EmployeeTimeSheetData.php=9d612ee603fdf4e6b710eec725da2656 -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/PayrollData.php=f1a49da4e6e5a91695dd96c9585e1686 -/Users/Thilina/Projects/icehrm/src/TimeSheets/User/Api/TimeSheetsInitialize.php=d47372f12494019c1004a04cbe57013d -/Users/Thilina/Projects/icehrm/src/Modules/Admin/Api/ModulesAdminManager.php=ef70889c3b3b9eae52800ce3a326d540 -/Users/Thilina/Projects/icehrm/src/Modules/Common/Model/Module.php=8f0d1680087f555f5628c53236c7625f -/Users/Thilina/Projects/icehrm/src/Expenses/Common/Model/ExpensesPaymentMethod.php=338ce9cabb90a291e88b940756b06701 -/Users/Thilina/Projects/icehrm/src/Company/Common/Model/Timezone.php=50aff3bc39221658c35041abdc55ad98 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/OvertimeSummaryReport.php=16d9e2f10de82f25d0965e2d327086b9 -/Users/Thilina/Projects/icehrm/src/Data/Common/Model/DataImport.php=a6af4d8acd5585932823889509cca581 -/Users/Thilina/Projects/icehrm/src/FieldNames/Common/Model/FieldNameMapping.php=73bd1da0f6e51329dbe12930bb566ccd -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/ActiveEmployeeReport.php=261180dfbe69ab83d9d63646111695ba -/Users/Thilina/Projects/icehrm/test/unit/LanguageManagerUnit.php=ebb20febce875350bfddd7f0358e6ad0 -/Users/Thilina/Projects/icehrm/src/Utils/LogManager.php=144ebae4d0ff60f0fd21e79a45aa6e6a -/Users/Thilina/Projects/icehrm/src/Dependents/Common/Model/EmployeeDependent.php=1f4b6cd6dfbc14269b53dbbac3730f9e -/Users/Thilina/Projects/icehrm/src/Data/Admin/Import/PayrollDataImporter.php=7350ec94ef8a70ba6c263e53c70c7073 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/ExpenseReport.php=397c8deb446994b64e2b9fef2845bb89 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/OvertimeReport.php=f630ae5402ec7957f42b64fa46cd1923 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/EmployeeLeaveEntitlementReport.php=9be41bfeb88fd0171028203f6513c799 -/Users/Thilina/Projects/icehrm/src/Projects/User/Api/ProjectsModulesManager.php=4fc0463507ca7768a1e493d703ac2581 -/Users/Thilina/Projects/icehrm/src/Permissions/Common/Model/Permission.php=0745dd3786e95cfc5265c32f47f4ee4a -/Users/Thilina/Projects/icehrm/src/Overtime/Admin/Api/OvertimeActionManager.php=0b039c008daf52e64f9ce827eabdd25a -/Users/Thilina/Projects/icehrm/src/Salary/User/Api/SalaryModulesManager.php=050d077e79532353a7d12a7221829b7c -/Users/Thilina/Projects/icehrm/src/Classes/Cron/IceTask.php=cc9b1481e824fd967eb503248eb92e29 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/EmployeeTimesheetReport.php=8661944cf39b10c441841a8af72cb988 -/Users/Thilina/Projects/icehrm/src/EmergencyContacts/User/Api/EmergencyContactModulesManager.php=527888466137dad3da5c6bf5b7bf9b28 -/Users/Thilina/Projects/icehrm/src/Classes/SettingsManager.php=ebed24cde74d7fb33cca4ba156389760 -/Users/Thilina/Projects/icehrm/src/Qualifications/Common/Model/EmployeeLanguage.php=66127455502fb29181324c1cc25f93c4 -/Users/Thilina/Projects/icehrm/src/Classes/Approval/ApproveCommonActionManager.php=c1b7efb8c4f3fe8199c7e0d6fdd1ccce -/Users/Thilina/Projects/icehrm/src/Overtime/Common/Model/EmployeeOvertime.php=50c166318a354b05dc2ae0e442d43a33 -/Users/Thilina/Projects/icehrm/src/Reports/User/Api/ReportsModulesManager.php=1645b61be16b96d0085510f6a2d30b68 -/Users/Thilina/Projects/icehrm/src/Classes/RestApiManager.php=c53180aa40576c5fe8c519b2b0a39e32 -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/Payroll.php=5c7eb622aade003f693275944e041cc7 -/Users/Thilina/Projects/icehrm/src/Attendance/Admin/Api/AttendanceActionManager.php=9045182bc0854647219b0a0418c37ffd -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Api/PDFReportBuilder.php=fbbc196b5ea432671667bcc239d8bf54 -/Users/Thilina/Projects/icehrm/src/Employees/Rest/EmployeeRestEndPoint.php=5a006d8637a05d63f19e130b37bdd97d -/Users/Thilina/Projects/icehrm/src/Model/File.php=8211922ac309e1c3e5fc316a90bc0bf0 -/Users/Thilina/Projects/icehrm/src/Data/Admin/Api/AbstractDataImporter.php=315bf5eec45aa13e174d412014e2237f -/Users/Thilina/Projects/icehrm/src/Classes/NotificationManager.php=a739fd4177892d44e78efed1641072cc -/Users/Thilina/Projects/icehrm/src/Utils/SessionUtils.php=f5c4db2214dfb4d8bf5b9bfe5edb1bac -/Users/Thilina/Projects/icehrm/src/Travel/Admin/Api/TravelActionManager.php=0e2fdd403d3456ebda102d554349e9f4 -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/PayrollColumn.php=0f2e8fd9b44c038f163ae646d3c6f4b6 -/Users/Thilina/Projects/icehrm/src/Travel/Common/Model/EmployeeTravelRecord.php=5366a1927bd94630217ffbc9386ff605 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/TravelRequestReport.php=c4bdd4c88f4a7b15c8091a0dcbb5018a -/Users/Thilina/Projects/icehrm/src/Classes/StatusChangeLogManager.php=b091e855d9800eea9d4190e0c75e3e8c -/Users/Thilina/Projects/icehrm/src/Qualifications/Admin/Api/QualificationsAdminManager.php=3037d64a2344a497ff0ceea52265d2a6 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/EmployeeLeavesReport.php=bd5efb4666ca4103a2e7e98aa24e1c83 -/Users/Thilina/Projects/icehrm/src/TimeSheets/User/Api/TimeSheetsActionManager.php=ef271183cf6e71d8db24b8d3369e19b9 -/Users/Thilina/Projects/icehrm/src/Expenses/Common/Model/ExpensesCategory.php=e9c0e170b950a39994d0a33d5981374f -/Users/Thilina/Projects/icehrm/src/Classes/Email/SwiftMailer.php=eca37dc0add437ae1089c695b5074b90 -/Users/Thilina/Projects/icehrm/src/Data/Admin/Import/AttendanceDataImporter.php=dc4dec4294b9feac08a5f996b85cab85 -/Users/Thilina/Projects/icehrm/src/Salary/Common/Model/PayrollEmployee.php=1a01bd60d1f82fc6f3eeb1875006f659 -/Users/Thilina/Projects/icehrm/src/Classes/Crypt/AesCtr.php=4897c7fe9a510f38eeb91046127d79f7 -/Users/Thilina/Projects/icehrm/src/Classes/AbstractModuleManager.php=5bb9fc5859bdd790753277a47752b0b9 -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/ImmigrationStatus.php=f0dc9a94bcc487df21d53387ae8e89ba -/Users/Thilina/Projects/icehrm/src/Salary/Admin/Api/SalaryAdminManager.php=8bedb5d82608974feedd1c094cac64fa -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Api/ClassBasedReportBuilder.php=fc77219539745bdb6364fc81bdda2516 -/Users/Thilina/Projects/icehrm/src/Classes/BaseService.php=e0de0276b6a8b58a4e318848a45439b6 -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/PayrollColumnTemplate.php=cb69bf4717cfbaf0f395b931296efd9a -/Users/Thilina/Projects/icehrm/src/Expenses/Admin/Api/ExpensesActionManager.php=2997346b4574ccd83e564c338e38b189 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/EmployeeTimeTrackReport.php=eddda882fae0c258e97fb50aafe21061 -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/Nationality.php=0f0cd1d95496f95ac9de08aa15e6b6a4 -/Users/Thilina/Projects/icehrm/src/Classes/ReportHandler.php=80b280cae34fdfbee864b05b07c6789a -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/ExpenseReport.php=7c8d187bc57175a92b8bc0fa33e501f0 -/Users/Thilina/Projects/icehrm/src/Overtime/Admin/Api/OvertimeAdminManager.php=7ae7776e6445429a1f0158a5efd38c04 -/Users/Thilina/Projects/icehrm/src/Salary/Common/Model/SalaryComponentType.php=d96878a0b1547f44731830526306ab56 -/Users/Thilina/Projects/icehrm/src/Travel/Common/Model/EmployeeImmigration.php=1dcb690d0045699a1aa65eda033f9adf -/Users/Thilina/Projects/icehrm/src/Classes/MenuItemTemplate.php=7ad7eb3a874ec729ec1baf0760f0b4ed -/Users/Thilina/Projects/icehrm/src/Employees/Admin/Api/EmployeesAdminManager.php=15e983c78e17191ced1a7eec13be0d3e -/Users/Thilina/Projects/icehrm/src/Classes/Cron/CronUtils.php=b55a1fe1c4ed55dc582e208b341f52b4 -/Users/Thilina/Projects/icehrm/src/Overtime/Common/Model/EmployeeOvertimeApproval.php=edd2eedebb9f62a44f0e588c615654ce -/Users/Thilina/Projects/icehrm/src/Qualifications/Common/Model/EmployeeSkill.php=a02c5ceda0489aba4ed47df010d4892e -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/EmployeeAttendanceReport.php=a20c94c986fa57c52daebbcbf4fa1f3f -/Users/Thilina/Projects/icehrm/src/Overtime/User/Api/OvertimeActionManager.php=f6d2c26500ed9e10b90bb5826d6c124e -/Users/Thilina/Projects/icehrm/src/Projects/Common/Model/Client.php=666b6d5ad575ddd9ccc198f5e98e1211 -/Users/Thilina/Projects/icehrm/src/Dependents/User/Api/DependentsModulesManager.php=409b6ea72b6ce0319bb12df6458d2bef -/Users/Thilina/Projects/icehrm/src/Jobs/Common/Model/JobTitle.php=4765635589eb4cc84cec2e578faa1557 -/Users/Thilina/Projects/icehrm/src/Model/Cron.php=4f3da95d8dd8e6b4642e6a2c6390c5fe -/Users/Thilina/Projects/icehrm/src/Projects/Admin/Api/ProjectsAdminManager.php=8f20c5277a8560a69318263166b804e3 -/Users/Thilina/Projects/icehrm/src/Loans/Common/Model/CompanyLoan.php=6e1e409dd612f22b47c6ffdcda4fe3a0 -/Users/Thilina/Projects/icehrm/src/Classes/Migration/MigrationManager.php=10ce5f1187ed06d2b12820a0d9d7e90a -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Api/ReportsAdminManager.php=be16482fcb8d6714f13618407acf25a5 -/Users/Thilina/Projects/icehrm/src/Utils/CalendarTools.php=9f60bf1aaa928a02163680da60ac255c -/Users/Thilina/Projects/icehrm/src/Data/Admin/Api/DataAdminManager.php=3913dc1f43ae1965956c420d0d9084c8 -/Users/Thilina/Projects/icehrm/src/TimeSheets/Common/Model/EmployeeTimeEntry.php=f69d37222ff6d528b5dde53fcbb5b3a8 -/Users/Thilina/Projects/icehrm/src/Classes/UIManager.php=03b64742f6595dedce18bba1372d4b20 -/Users/Thilina/Projects/icehrm/src/Classes/MemcacheService.php=e07916b1c628686162c19fa26aad93d5 -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/EmployeeTimesheetReport.php=2ec16a7dccb131862f295ad97db9067b -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/Country.php=f772b574b2b1310977a50daf9d2a51ef -/Users/Thilina/Projects/icehrm/src/Model/Audit.php=31e7780e4e210a8c840188d2015d2e01 -/Users/Thilina/Projects/icehrm/src/Classes/Approval/ApproveModuleActionManager.php=834a7aad3a07c194a0a830cc353daec9 -/Users/Thilina/Projects/icehrm/src/Loans/Admin/Api/LoansAdminManager.php=0954d425f553598a6f3a9dbefc19fb45 -/Users/Thilina/Projects/icehrm/src/Classes/SubActionManager.php=7523ec5017da87c8d7d3e4438310d96f -/Users/Thilina/Projects/icehrm/src/Model/ApproveModel.php=7f15abbdae78812f15d65e7a165f6115 -/Users/Thilina/Projects/icehrm/src/Classes/CustomFieldManager.php=7259e4d11e73fdd04984097e00233203 -/Users/Thilina/Projects/icehrm/src/Payroll/Admin/Api/PayrollActionManager.php=177d85ae36ed00f8a42d9bb9e8f9aa1a -/Users/Thilina/Projects/icehrm/src/Loans/User/Api/LoansModulesManager.php=4f0650c7b4ab3ec6c241bd32c680dfca -/Users/Thilina/Projects/icehrm/src/Utils/Math/EvalMathStack.php=4b86e2041c19d8ef8eaf7f4ea630e116 -/Users/Thilina/Projects/icehrm/src/Users/Admin/Api/UsersAdminManager.php=695662b7186616d4379d0a588b5130e6 -/Users/Thilina/Projects/icehrm/src/Qualifications/Common/Model/Language.php=c904c6e3e2e167f5e79afffabf94716a -/Users/Thilina/Projects/icehrm/src/Classes/Macaw.php=5a2f26ffcb41c9f42af776a91c283572 -/Users/Thilina/Projects/icehrm/src/Attendance/Common/Model/AttendanceStatus.php=ad80af2d596e584a3ab60a5fce4aac09 -/Users/Thilina/Projects/icehrm/src/Classes/Email/SMTPEmailSender.php=0df2a519ce3a2d61d486b9527782f72b -/Users/Thilina/Projects/icehrm/src/FieldNames/Admin/Api/FieldNamesAdminManager.php=5eca8c33ccd8d9fc1c4e5b7fa81ed93c -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/PayFrequency.php=9207a551d667bab9734aa041e02a1be1 -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/CurrencyType.php=e9f5f17d4e18a706e4c4068f253c01ac -/Users/Thilina/Projects/icehrm/src/Employees/Common/Model/EmployeeApproval.php=481ddd171d66e644bb442ab02e97b097 -/Users/Thilina/Projects/icehrm/src/Data/Admin/Api/DataImporter.php=ad94e2de98e11c1d3f0f0b32c46f358c -/Users/Thilina/Projects/icehrm/src/Expenses/Common/Model/EmployeeExpense.php=29d2dccb5d009d392c4b8f44c59fcdd8 -/Users/Thilina/Projects/icehrm/test/TestTemplate.php=8e6ff185d587f339892a9a720e2bfa5f -/Users/Thilina/Projects/icehrm/src/Classes/Crypt/Aes.php=d0b15a04faf73b0ff35efc308d09b6e7 -/Users/Thilina/Projects/icehrm/src/Classes/LanguageManager.php=8df5d6d62bae8a5e14ab1cd486325af3 -/Users/Thilina/Projects/icehrm/src/Qualifications/Common/Model/Education.php=6f992ef2bb13951f3c52f5209d73733b -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/EmployeeLeavesReport.php=0bd5801ac4c9803db53198c68904d5f5 -/Users/Thilina/Projects/icehrm/src/TimeSheets/Common/Model/EmployeeTimeSheet.php=2a4e685315485e4933df5d2ba856d8fb -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/ClientProjectTimeReport.php=f860b3cff536b5074bb7d1e193c1c41d -/Users/Thilina/Projects/icehrm/src/Expenses/User/Api/ExpensesActionManager.php=c8ce93f6877fd2cdbc963b5c38708f04 -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/EmployeeAttendanceReport.php=600c1feca3eab6d724ac9661f2f514d5 -/Users/Thilina/Projects/icehrm/src/Utils/Math/EvalMath.php=476cb2ee5306966d7cd7bee2f3202559 -/Users/Thilina/Projects/icehrm/src/Model/Migration.php=3f11c6dfaa18d4a6dcb2caa8d3677121 -/Users/Thilina/Projects/icehrm/src/Data/Common/Model/DataImportFile.php=a0b3f8410e80862ba79aa9d8fed383d7 -/Users/Thilina/Projects/icehrm/src/Travel/User/Api/TravelActionManager.php=e6241358886dc00138506f3bc4d13346 -/Users/Thilina/Projects/icehrm/src/Company/Common/Model/CompanyStructure.php=a1957202858bc093b29e8dfe48955cc6 -/Users/Thilina/Projects/icehrm/src/Classes/Migration/AbstractMigration.php=324fe15e15a0ca2b0f50f4029ae10548 -/Users/Thilina/Projects/icehrm/src/Qualifications/Common/Model/EmployeeCertification.php=96045388cba569f4ea9617dc8fbeded6 -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/PayslipTemplate.php=cc9bf7552cfccd84a0b9b1431f224f1f -/Users/Thilina/Projects/icehrm/test/test.includes.php=d87bcd9386b3271b62818e2b86df6c28 -/Users/Thilina/Projects/icehrm/src/Company/Admin/Api/CompanyAdminManager.php=484a8b669d5fed117f1f40f289f2c6f4 -/Users/Thilina/Projects/icehrm/src/Classes/Email/PHPMailer.php=54789d10177cc5075cb4d50838b05821 -/Users/Thilina/Projects/icehrm/src/Qualifications/Common/Model/EmployeeEducation.php=8ba4cbc034b5ee23d593cc3352cf46a9 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Reports/TerminatedEmployeeReport.php=1b8b58d6e85eb77e45aaf44f426025ea -/Users/Thilina/Projects/icehrm/src/Users/Admin/Api/UsersEmailSender.php=87247955c331115e482aa3e577eca0b4 -/Users/Thilina/Projects/icehrm/src/Classes/IceConstants.php=5f7497997d12c27dab080b6f34640df1 -/Users/Thilina/Projects/icehrm/test/test.config.php=2d82ac9b697f10bb9bd6d760f63d2be4 -/Users/Thilina/Projects/icehrm/src/Travel/Common/Model/ImmigrationDocument.php=c0636d2ce3e7d89d9e4ebb00c8d1450f -/Users/Thilina/Projects/icehrm/src/Classes/ModuleBuilder/ModuleBuilder.php=29fed2a27587032060efc02c7a30a838 -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/PayslipReport.php=a7197be66726cf126c196bf6beccb907 -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/EmployeeTimeTrackReport.php=ce6f2b098845233342c336f837001554 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Api/PDFReportBuilderInterface.php=cc049c4c1b86e5a5e4fd99ddf24e563d -/Users/Thilina/Projects/icehrm/src/Qualifications/User/Api/QualificationsModulesManager.php=e668d64139ecc146af9ebaea2f91e1fe -/Users/Thilina/Projects/icehrm/src/Classes/RestEndPoint.php=86136262a2e2a8f45564d17123dd5812 -/Users/Thilina/Projects/icehrm/src/Classes/S3FileSystem.php=6308aca72380cef1981625946b59652f -/Users/Thilina/Projects/icehrm/src/Classes/Cron/Task/EmailIceTask.php=b754a286061db310b3f18677946d7b43 -/Users/Thilina/Projects/icehrm/src/Data/Admin/Import/EmployeeDataImporter.php=d1b66e2d042335df792fa8913d363d5f -/Users/Thilina/Projects/icehrm/src/Projects/Common/Model/EmployeeProject.php=b0de956de8ec4c423604195b96f57df9 -/Users/Thilina/Projects/icehrm/src/Model/Report.php=498c96015d1be2b31d8cd0bcedea7fab -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/CustomFieldValue.php=a9b7d8db9ee113345298ba49f9354be8 -/Users/Thilina/Projects/icehrm/src/Classes/Cron/IceCron.php=edb023962095493d7daa728793ceaf9c -/Users/Thilina/Projects/icehrm/src/Settings/Admin/Api/SettingsInitialize.php=148bc391f5d101121f915a590f991a6b -/Users/Thilina/Projects/icehrm/src/Dashboard/Admin/Api/DashboardActionManager.php=5e8e996f9f4b77f1fbd10e026a5d1351 -/Users/Thilina/Projects/icehrm/src/Payroll/Admin/Api/PayrollAdminManager.php=9bac9a6ed8406c9eb6fe7ef666aee482 -/Users/Thilina/Projects/icehrm/src/Jobs/Admin/Api/JobsAdminManager.php=12546328edffcc5bda7e84f6a8c56d9e -/Users/Thilina/Projects/icehrm/src/Jobs/Common/Model/PayGrade.php=55f2f83ff22136154b14460b6b37632a -/Users/Thilina/Projects/icehrm/src/EmergencyContacts/Common/Model/EmergencyContact.php=6ec07210d94e695732c6d1a6a0fb34be -/Users/Thilina/Projects/icehrm/src/Employees/Admin/Api/EmployeesActionManager.php=63c6ccf63f54eab8556c893cf47f983c -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/CalculationHook.php=bbfa6f83e4042db9640b67c131274118 -/Users/Thilina/Projects/icehrm/src/Users/Common/Model/User.php=cc9b6c966b40678574fdd35bb1f16cb2 -/Users/Thilina/Projects/icehrm/src/Users/Admin/Api/UsersActionManager.php=b65c97c665190f9fb011cc8d0b97888c -/Users/Thilina/Projects/icehrm/src/Attendance/User/Api/AttendanceModulesManager.php=f1b34fae71cc963e197b41ed2ca032ca -/Users/Thilina/Projects/icehrm/src/Classes/IceResponse.php=bb74495c33fab87e96f72b610cfd5374 -/Users/Thilina/Projects/icehrm/src/Qualifications/Common/Model/Certification.php=e81a7f90a10799d97a918e2cb071c1a9 -/Users/Thilina/Projects/icehrm/src/Model/BaseModel.php=d932a9bb126c174000b9c51a8cb4d2f6 -/Users/Thilina/Projects/icehrm/src/Model/StatusChangeLog.php=0745140bddda3f06915dcfcc6ac97ce8 -/Users/Thilina/Projects/icehrm/src/Classes/AbstractInitialize.php=841a38244ca1d44b008f67a6b45df348 -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/EmployeeTimeSheetData.php=2d6e95947963949b1c5150269d7527f7 -/Users/Thilina/Projects/icehrm/src/Data/Admin/Api/DataActionManager.php=82f3ced08b946ca6e10a83c6e07475db -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/OvertimeReport.php=431965980b2458019398d2ed6d7fc39a -/Users/Thilina/Projects/icehrm/src/Metadata/Common/Model/Ethnicity.php=5f5935cdeab1b41ac0d2db9f6973f6b0 -/Users/Thilina/Projects/icehrm/test/integration/MigrationManagerIntegration.php=f0f5bccf120067b34396f1e61fd6d20a -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Api/CSVReportBuilderInterface.php=6ada9a15e850c09162fc75020d6b00e4 -/Users/Thilina/Projects/icehrm/src/Payroll/Common/Model/PayrollCalculations.php=70d1b733b1adbb6c6a2ea0dcec89efca -/Users/Thilina/Projects/icehrm/src/Travel/Admin/Api/TravelAdminManager.php=9b3c6e369e2264d2bc9fca122e8ed90c -/Users/Thilina/Projects/icehrm/src/Model/ReportFile.php=0a766e94902b5473ef1fa24583cf2481 -/Users/Thilina/Projects/icehrm/src/Modules/Admin/Api/ModulesActionManager.php=c4d592d8930201a883a5d1ea71a037af -/Users/Thilina/Projects/icehrm/src/Model/IceEmail.php=02bd3cd01cb37ab05d763e468cba3835 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Api/ReportBuilderInterface.php=dd7e723c48ec4f97db98ffec0d0f39cb -/Users/Thilina/Projects/icehrm/src/TimeSheets/User/Api/TimeSheetsModulesManager.php=63a8c4364cd579be46b60a2e83f8f87f -/Users/Thilina/Projects/icehrm/src/Employees/Common/Model/ArchivedEmployee.php=6056e5073538c0d7a22dea52b6c25374 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Api/ReportBuilder.php=9b0e8e996157caebcf17a2a342ba0f6e -/Users/Thilina/Projects/icehrm/src/Users/Common/Model/UserRole.php=8d7dbcdf68c2c5a7a4d4f73dbb07d63b -/Users/Thilina/Projects/icehrm/src/Salary/Common/Model/PayFrequency.php=fab16310b7db7bb9aace5a6b038c9d2a -/Users/Thilina/Projects/icehrm/src/Model/Notification.php=0b06b249e456508d5a8ce06b453efe6b -/Users/Thilina/Projects/icehrm/src/Attendance/Admin/Api/AttendanceDashboardManager.php=c08fc7c021dd0c0780851c308225291f -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/TravelRequestReport.php=810d405042307fe9c6ca82e082c3673e -/Users/Thilina/Projects/icehrm/src/Attendance/Common/Model/Attendance.php=aa0945e6fc70e6e3418d0e09f7110082 -/Users/Thilina/Projects/icehrm/src/Employees/Common/Model/EmploymentStatus.php=11365db49528f08847e0dfbf1b31472d -/Users/Thilina/Projects/icehrm/src/Attendance/Admin/Api/AttendanceAdminManager.php=21e4a22a3eb290704181e5a4a7a5df7a -/Users/Thilina/Projects/icehrm/src/Classes/HistoryManager.php=4741dd856bb81ec2e27bd016afb8e042 -/Users/Thilina/Projects/icehrm/src/Dashboard/Admin/Api/DashboardAdminManager.php=800b72969de1b8c311a8e1b7d2940c79 -/Users/Thilina/Projects/icehrm/src/Overtime/User/Api/OvertimeModulesManager.php=b29d52a4e3f021cdd786f41cbf1b9837 -/Users/Thilina/Projects/icehrm/src/Reports/User/Reports/OvertimeSummaryReport.php=3918d7210957040977b8a43c580abae0 -/Users/Thilina/Projects/icehrm/src/Classes/ModuleBuilder/ModuleTab.php=89136363d7520967c2d42e175052f4d5 -/Users/Thilina/Projects/icehrm/src/Reports/Admin/Api/CSVReportBuilder.php=5c5f7175cc2aff776388c3281cea9cf3 -/Users/Thilina/Projects/icehrm/src/Model/Setting.php=5b9440e9211662f5ed69f29794b6054d -/Users/Thilina/Projects/icehrm/src/FieldNames/Common/Model/CustomField.php=88578da07f1f07bae868e17b4a8e4cf7 -/Users/Thilina/Projects/icehrm/src/Attendance/User/Api/AttendanceActionManager.php=feaa97dd192e7faec2045aba7dc03125 -/Users/Thilina/Projects/icehrm/src/Overtime/Common/Model/OvertimeCategory.php=e9c90b23155e3fe1c7d9dd9cef462d1e -/Users/Thilina/Projects/icehrm/src/Attendance/Common/Calculations/CaliforniaOvertimeCalculator.php=a1a5ff46939030747f505710fbd49ffd +#Fri Feb 01 06:41:09 GMT+00:00 2019 +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Admin/Api/AttendanceUtil.php=34fe63a4c0f954451afae6c359ea5b38 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/ClientProjectTimeReport.php=f860b3cff536b5074bb7d1e193c1c41d +/Users/Thilina/Projects/icehrm-open/core/src/Classes/S3FileSystem.php=6308aca72380cef1981625946b59652f +/vagrant/core/src/Classes/AbstractInitialize.php=a6e16a53a0178bc30b27dcf3684fbdad +/vagrant/core/src/Reports/User/Reports/EmployeeTimeSheetData.php=2d6e95947963949b1c5150269d7527f7 +/vagrant/core/src/Classes/ReportHandler.php=80b280cae34fdfbee864b05b07c6789a +/vagrant/core/src/Classes/Migration/AbstractMigration.php=324fe15e15a0ca2b0f50f4029ae10548 +/vagrant/core/src/Classes/Crypt/AesCtr.php=4897c7fe9a510f38eeb91046127d79f7 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Approval/ApproveAdminActionManager.php=01eaf59752e8379205bc52f3278f96fc +/Users/Thilina/Projects/icehrm-open/core/src/Data/Admin/Api/DataActionManager.php=82f3ced08b946ca6e10a83c6e07475db +/Users/Thilina/Projects/icehrm-open/core/src/Utils/CalendarTools.php=9f60bf1aaa928a02163680da60ac255c +/vagrant/core/src/Data/Admin/Api/DataAdminManager.php=3913dc1f43ae1965956c420d0d9084c8 +/vagrant/core/src/Travel/User/Api/TravelActionManager.php=d055895c69bafe0b6855566dc4054699 +/vagrant/core/src/Reports/Admin/Reports/ExpenseReport.php=397c8deb446994b64e2b9fef2845bb89 +/vagrant/core/src/Metadata/Common/Model/CurrencyType.php=0fc8e338a2f0f149ac24757427470971 +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/Nationality.php=639ee9f14c53032ff26e7105c2219593 +/vagrant/core/src/Classes/Migration/MigrationManager.php=b2a6fae32ad9370a4e3375a623330fa7 +/Users/Thilina/Projects/icehrm-open/core/src/Projects/Common/Model/EmployeeProject.php=b0de956de8ec4c423604195b96f57df9 +/vagrant/core/src/Classes/Cron/IceCron.php=217fba4cf5ce69cdf734447f6a45b356 +/Users/Thilina/Projects/icehrm-open/core/src/Dashboard/Admin/Api/DashboardAdminManager.php=800b72969de1b8c311a8e1b7d2940c79 +/Users/Thilina/Projects/icehrm-open/test/bootstrap.php=0e9cfabb3aec1ac52ecf4d27334f2624 +/vagrant/core/src/Reports/Admin/Reports/EmployeeTimesheetReport.php=8661944cf39b10c441841a8af72cb988 +/vagrant/core/src/Company/Admin/Api/CompanyAdminManager.php=484a8b669d5fed117f1f40f289f2c6f4 +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/User/Api/QualificationsModulesManager.php=e668d64139ecc146af9ebaea2f91e1fe +/vagrant/core/src/Loans/Common/Model/EmployeeCompanyLoan.php=abc8959df2ec0f3e19ff6da12c3163f9 +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/Province.php=0ff661394cbcfec7f514f2d5eae7ca25 +/Users/Thilina/Projects/icehrm-open/core/src/Salary/User/Api/SalaryModulesManager.php=050d077e79532353a7d12a7221829b7c +/vagrant/core/src/Utils/Math/EvalMathFuncs.php=d6f7c26eab307d205ee8483d87a380cb +/vagrant/core/src/Metadata/Common/Model/Nationality.php=639ee9f14c53032ff26e7105c2219593 +/vagrant/core/src/Data/Common/Model/DataImport.php=a6af4d8acd5585932823889509cca581 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/EmployeeTimeTrackReport.php=eddda882fae0c258e97fb50aafe21061 +/Users/Thilina/Projects/icehrm-open/core/src/FieldNames/Admin/Api/FieldNamesAdminManager.php=5eca8c33ccd8d9fc1c4e5b7fa81ed93c +/vagrant/core/src/Projects/Common/Model/Project.php=05b1cd967d67cb977558f2567d7f6cb6 +/Users/Thilina/Projects/icehrm-open/test/integration/ApprovalStatusIntegration.php=8b9243e5cbb302513d906ff9de246acd +/Users/Thilina/Projects/icehrm-open/test/TestTemplate.php=8e6ff185d587f339892a9a720e2bfa5f +/Users/Thilina/Projects/icehrm-open/core/src/Employees/Admin/Api/EmployeesAdminManager.php=15e983c78e17191ced1a7eec13be0d3e +/vagrant/core/src/Payroll/Common/Model/PayrollCalculations.php=70d1b733b1adbb6c6a2ea0dcec89efca +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Data/Query/DataQuery.php=eae53f27055f569d43fd2cad06b7beff +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/EmployeeDetailsReport.php=1e415e088afc4fc56e3cbf77af8f84c5 +/vagrant/core/src/Dashboard/Admin/Api/DashboardActionManager.php=5e8e996f9f4b77f1fbd10e026a5d1351 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/BaseService.php=92bd3a9bb4e7eb84e079b0db75d5f752 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Approval/ApprovalStatus.php=7a3bc0a73f237eb677254b245887f48f +/vagrant/core/src/Model/Audit.php=6259d9e1d7e7777bb8cde096bdc742aa +/vagrant/core/src/Utils/Math/EvalMathStack.php=4b86e2041c19d8ef8eaf7f4ea630e116 +/vagrant/core/src/Reports/Admin/Reports/PayrollDataExport.php=83bd6faa73c75667ecf25091c3729abc +/vagrant/test/integration/ApprovalStatusIntegration.php=cff0c3e3e051bf87d6a5313655b741cd +/vagrant/core/src/Employees/Common/Model/EmployeeApproval.php=481ddd171d66e644bb442ab02e97b097 +/Users/Thilina/Projects/icehrm-open/core/src/EmergencyContacts/Common/Model/EmergencyContact.php=6ec07210d94e695732c6d1a6a0fb34be +/vagrant/core/src/Users/Common/Model/User.php=ad497e45b540b026aa80fa58f5055cc1 +/Users/Thilina/Projects/icehrm-open/core/src/Company/Common/Model/CompanyStructure.php=a1957202858bc093b29e8dfe48955cc6 +/Users/Thilina/Projects/icehrm-open/test/test.includes.php=66d627b31f3f6b76f1739a54e7d9fd9f +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Approval/ApproveModuleActionManager.php=834a7aad3a07c194a0a830cc353daec9 +/vagrant/core/src/Reports/User/Reports/TravelRequestReport.php=810d405042307fe9c6ca82e082c3673e +/Users/Thilina/Projects/icehrm-open/core/src/Users/Common/Model/UserRole.php=9f9021a51c94b25e203cc3c0322c80d7 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/Payroll.php=8aa76dfc05183abe955552b15e3c4351 +/vagrant/core/src/Classes/PermissionManager.php=149c16e23f9066538e9c7a0ee3bb397f +/vagrant/core/src/Employees/User/Api/EmployeesActionManager.php=e34f4fe38b3e0eb45cb65232fa6ec359 +/vagrant/core/src/Classes/Email/SwiftMailer.php=eca37dc0add437ae1089c695b5074b90 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/EmployeeLeaveEntitlementReport.php=9be41bfeb88fd0171028203f6513c799 +/vagrant/core/src/Projects/Admin/Api/ProjectsAdminManager.php=8f20c5277a8560a69318263166b804e3 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/EmployeeTimeSheetData.php=2d6e95947963949b1c5150269d7527f7 +/vagrant/core/src/Employees/User/Api/EmployeesModulesManager.php=ad9ab05afd9cf551870352dba82e6d69 +/vagrant/core/src/Reports/Admin/Reports/EmployeeTimeSheetData.php=9d612ee603fdf4e6b710eec725da2656 +/Users/Thilina/Projects/icehrm-open/core/src/Travel/User/Api/TravelActionManager.php=d055895c69bafe0b6855566dc4054699 +/vagrant/core/src/Metadata/Common/Model/ImmigrationStatus.php=f0dc9a94bcc487df21d53387ae8e89ba +/vagrant/test/test.config.php=68587cbb63b8a37dc07fdac177eb23a4 +/Users/Thilina/Projects/icehrm-open/core/src/Employees/Common/Model/Employee.php=1e8f3958597a1d2f138e927115671538 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/IceResponse.php=bb74495c33fab87e96f72b610cfd5374 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/OvertimeSummaryReport.php=3918d7210957040977b8a43c580abae0 +/vagrant/core/src/Travel/Common/Model/ImmigrationDocument.php=c0636d2ce3e7d89d9e4ebb00c8d1450f +/vagrant/core/src/Reports/Admin/Reports/OvertimeSummaryReport.php=16d9e2f10de82f25d0965e2d327086b9 +/vagrant/core/src/Jobs/Common/Model/PayGrade.php=9cc01a86f03deb884884681a73deb27a +/vagrant/core/src/Classes/RestEndPoint.php=48bd6506bb12af195f32d65c0ae635f2 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Admin/Api/PayrollActionManager.php=c95c4e2ae643a16b8e59fa73dc1f0193 +/vagrant/core/src/Data/Admin/Import/EmployeeDataImporter.php=d1b66e2d042335df792fa8913d363d5f +/Users/Thilina/Projects/icehrm-open/core/src/TimeSheets/User/Api/TimeSheetsModulesManager.php=63a8c4364cd579be46b60a2e83f8f87f +/vagrant/test/bootstrap.php=0e9cfabb3aec1ac52ecf4d27334f2624 +/vagrant/core/src/Salary/Common/Model/PayrollEmployee.php=1a01bd60d1f82fc6f3eeb1875006f659 +/vagrant/core/src/Employees/Admin/Api/EmployeesAdminManager.php=15e983c78e17191ced1a7eec13be0d3e +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Common/Model/EmployeeLanguage.php=66127455502fb29181324c1cc25f93c4 +/Users/Thilina/Projects/icehrm-open/core/src/Model/Cron.php=9e638c23f7cb93500a1b1f1ef4edf86f +/Users/Thilina/Projects/icehrm-open/core/src/Utils/SessionUtils.php=cdb9d769cf1f51bab1462ddac2387e81 +/vagrant/core/src/Classes/Cron/Task/EmailIceTask.php=b754a286061db310b3f18677946d7b43 +/Users/Thilina/Projects/icehrm-open/core/src/Overtime/Common/Model/EmployeeOvertime.php=4275d184646684892b289524b33cf9d7 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Macaw.php=5a2f26ffcb41c9f42af776a91c283572 +/Users/Thilina/Projects/icehrm-open/core/src/StaffDirectory/Common/Model/StaffDirectory.php=73f3c132e741460f200be3b3100833f6 +/vagrant/core/src/Jobs/Admin/Api/JobsAdminManager.php=12546328edffcc5bda7e84f6a8c56d9e +/Users/Thilina/Projects/icehrm-open/core/src/Overtime/User/Api/OvertimeModulesManager.php=b29d52a4e3f021cdd786f41cbf1b9837 +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Common/Model/Attendance.php=aa0945e6fc70e6e3418d0e09f7110082 +/Users/Thilina/Projects/icehrm-open/core/src/Employees/Common/Model/EmploymentStatus.php=6e72924fac0cecc49aaf070389f8d73a +/Users/Thilina/Projects/icehrm-open/core/src/Modules/Common/Model/Module.php=6930680c77dfbcd410e1425c76511c16 +/Users/Thilina/Projects/icehrm-open/core/src/Data/Common/Model/DataImport.php=a6af4d8acd5585932823889509cca581 +/vagrant/core/src/Modules/Admin/Api/ModulesActionManager.php=a4f9c92a8f6de83ed72c5f775369b883 +/Users/Thilina/Projects/icehrm-open/core/src/Dependents/User/Api/DependentsModulesManager.php=409b6ea72b6ce0319bb12df6458d2bef +/Users/Thilina/Projects/icehrm-open/core/src/Salary/Common/Model/PayFrequency.php=fab16310b7db7bb9aace5a6b038c9d2a +/Users/Thilina/Projects/icehrm-open/core/src/Classes/FileService.php=b948c3e305263af82269976e01af17c4 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Crypt/AesCtr.php=4897c7fe9a510f38eeb91046127d79f7 +/Users/Thilina/Projects/icehrm-open/core/src/FieldNames/Common/Model/CustomField.php=32400d304e8064e69624311c3c80dffb +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/Country.php=be5371104ea0bbfa7132201d5e31e62f +/vagrant/core/src/EmergencyContacts/Common/Model/EmergencyContact.php=6ec07210d94e695732c6d1a6a0fb34be +/Users/Thilina/Projects/icehrm-open/core/src/Settings/Admin/Api/SettingsAdminManager.php=5e5df0056db6f9593128720581feca18 +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/Ethnicity.php=5f5935cdeab1b41ac0d2db9f6973f6b0 +/vagrant/core/src/TimeSheets/User/Api/TimeSheetsPayrollUtils.php=85db5b3cf330d2010ac14aaff1bccc2a +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/EmployeeLeavesReport.php=bd5efb4666ca4103a2e7e98aa24e1c83 +/Users/Thilina/Projects/icehrm-open/core/src/Employees/User/Api/EmployeesModulesManager.php=ad9ab05afd9cf551870352dba82e6d69 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Cron/IceCron.php=217fba4cf5ce69cdf734447f6a45b356 +/Users/Thilina/Projects/icehrm-open/core/src/Data/Admin/Api/DataImporter.php=ad94e2de98e11c1d3f0f0b32c46f358c +/vagrant/core/src/Loans/User/Api/LoansModulesManager.php=4f0650c7b4ab3ec6c241bd32c680dfca +/Users/Thilina/Projects/icehrm-open/test/unit/UserAttendanceActionManagerUnit.php=1d71d366a13f253ef6931aa87202ac42 +/vagrant/core/src/Attendance/Common/Calculations/BasicOvertimeCalculator.php=9c96ae3f71796029d3f93e5c63783f53 +/vagrant/core/src/Reports/Admin/Api/PDFReportBuilder.php=fbbc196b5ea432671667bcc239d8bf54 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Api/PDFReportBuilderInterface.php=cc049c4c1b86e5a5e4fd99ddf24e563d +/vagrant/core/src/Reports/Admin/Api/CSVReportBuilderInterface.php=6ada9a15e850c09162fc75020d6b00e4 +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Common/Model/AttendanceStatus.php=ad80af2d596e584a3ab60a5fce4aac09 +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/CurrencyType.php=0fc8e338a2f0f149ac24757427470971 +/vagrant/test/integration/MigrationManagerIntegration.php=f0f5bccf120067b34396f1e61fd6d20a +/Users/Thilina/Projects/icehrm-open/core/src/Salary/Common/Model/PayrollEmployee.php=1a01bd60d1f82fc6f3eeb1875006f659 +/vagrant/core/src/Reports/User/Reports/ExpenseReport.php=7c8d187bc57175a92b8bc0fa33e501f0 +/vagrant/core/src/Model/UserReport.php=0a8a8476e3088011cc54fda139567b56 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/LanguageManager.php=e019a01be56a46a93177a50340fc3eea +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Common/Model/Education.php=327f74726fca1a976e2fc6272ffecdea +/vagrant/core/src/TimeSheets/Common/Model/QTDays.php=32a00e65a966331b776dc37cc0609edf +/vagrant/core/src/TimeSheets/User/Api/TimeSheetsInitialize.php=d47372f12494019c1004a04cbe57013d +/Users/Thilina/Projects/icehrm-open/test/helper/EmployeeTestDataHelper.php=65ec2048653c9e4e4359d9b6967a860d +/vagrant/core/src/Classes/Approval/ApprovalStatus.php=7a3bc0a73f237eb677254b245887f48f +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/User/Api/AttendanceModulesManager.php=f1b34fae71cc963e197b41ed2ca032ca +/vagrant/core/src/Reports/User/Reports/OvertimeReport.php=431965980b2458019398d2ed6d7fc39a +/vagrant/core/src/Overtime/User/Api/OvertimeActionManager.php=5ace85f1fdbd23f5adc8d089f2d6b5fa +/vagrant/core/src/Model/File.php=3bc6c71925ad1e20721ffd63567c7783 +/Users/Thilina/Projects/icehrm-open/core/src/Overtime/Admin/Api/OvertimeAdminManager.php=701c52c0bca0b0d89c5bb8e7cbafac8e +/vagrant/core/src/Settings/Admin/Api/SettingsInitialize.php=148bc391f5d101121f915a590f991a6b +/vagrant/core/src/Utils/SessionUtils.php=cdb9d769cf1f51bab1462ddac2387e81 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Cron/CronUtils.php=b55a1fe1c4ed55dc582e208b341f52b4 +/vagrant/core/src/Reports/Admin/Api/CSVReportBuilder.php=5c5f7175cc2aff776388c3281cea9cf3 +/Users/Thilina/Projects/icehrm-open/core/src/Projects/User/Api/ProjectsModulesManager.php=4fc0463507ca7768a1e493d703ac2581 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/PayrollColumn.php=0f2e8fd9b44c038f163ae646d3c6f4b6 +/vagrant/core/src/Classes/SimpleImage.php=fdfb7b2e71e14975ebce16de44ea9dee +/vagrant/core/src/Dashboard/User/Api/DashboardActionManager.php=3f797cf4807ad5cd4f881607142df049 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/SettingsManager.php=ebed24cde74d7fb33cca4ba156389760 +/vagrant/core/src/FieldNames/Common/Model/FieldNameMapping.php=e3e81b3a4e0f6c74cd687038632107d8 +/vagrant/core/src/Reports/Admin/Reports/NewHiresEmployeeReport.php=64eab525953538d481dab6052dd76d81 +/vagrant/core/src/Classes/Email/SNSEmailSender.php=fa905e3ab63ea745c591e744d6741b6b +/Users/Thilina/Projects/icehrm-open/core/src/Model/ApproveModel.php=97c98d153a6cca455cbeb0b637eac098 +/vagrant/core/src/Jobs/Common/Model/JobTitle.php=2f24525e14942c7f284a44c8e416cd34 +/Users/Thilina/Projects/icehrm-open/core/src/Loans/Common/Model/EmployeeCompanyLoan.php=abc8959df2ec0f3e19ff6da12c3163f9 +/vagrant/core/src/Loans/Common/Model/CompanyLoan.php=cca60a4d5fa1189cdbd35146b010a2c7 +/vagrant/core/src/Reports/User/Reports/PayslipReport.php=7582da680dd305d073faf95d268083cd +/vagrant/core/src/Classes/FileService.php=b948c3e305263af82269976e01af17c4 +/Users/Thilina/Projects/icehrm-open/core/src/Employees/Common/Model/ArchivedEmployee.php=6056e5073538c0d7a22dea52b6c25374 +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Common/Model/Skill.php=293e642127ea74960ebd79d81f11b0f9 +/Users/Thilina/Projects/icehrm-open/core/src/Model/Notification.php=fe1cf65671434bc29c8d17a78577e1f3 +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/SupportedLanguage.php=3ec1220796f6e33641998a33f036d709 +/vagrant/core/src/FieldNames/Admin/Api/FieldNamesAdminManager.php=5eca8c33ccd8d9fc1c4e5b7fa81ed93c +/Users/Thilina/Projects/icehrm-open/core/src/TimeSheets/User/Api/TimeSheetsPayrollUtils.php=85db5b3cf330d2010ac14aaff1bccc2a +/vagrant/core/src/Reports/Admin/Reports/EmployeeTimeTrackReport.php=eddda882fae0c258e97fb50aafe21061 +/Users/Thilina/Projects/icehrm-open/core/src/StaffDirectory/Rest/StaffDirectoryRestEndPoint.php=ba417b136c9c65cd5096c3bde7d141c2 +/vagrant/core/src/Classes/Approval/ApproveCommonActionManager.php=c1b7efb8c4f3fe8199c7e0d6fdd1ccce +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Api/ReportBuilderInterface.php=dd7e723c48ec4f97db98ffec0d0f39cb +/vagrant/core/src/Reports/Admin/Reports/EmployeeDetailsReport.php=1e415e088afc4fc56e3cbf77af8f84c5 +/vagrant/core/src/Qualifications/Common/Model/Skill.php=293e642127ea74960ebd79d81f11b0f9 +/Users/Thilina/Projects/icehrm-open/test/integration/MigrationManagerIntegration.php=f0f5bccf120067b34396f1e61fd6d20a +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Common/Model/EmployeeEducation.php=8ba4cbc034b5ee23d593cc3352cf46a9 +/vagrant/core/src/Overtime/Common/Model/OvertimeCategory.php=49198d964e954be3d427e3a7a29a6443 +/vagrant/core/src/Data/Admin/Import/PayrollDataImporter.php=7350ec94ef8a70ba6c263e53c70c7073 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/TravelRequestReport.php=c4bdd4c88f4a7b15c8091a0dcbb5018a +/vagrant/core/src/Classes/Email/SMTPEmailSender.php=0df2a519ce3a2d61d486b9527782f72b +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/EmployeeTimesheetReport.php=2ec16a7dccb131862f295ad97db9067b +/Users/Thilina/Projects/icehrm-open/core/src/Utils/Math/EvalMathFuncs.php=d6f7c26eab307d205ee8483d87a380cb +/vagrant/core/src/Qualifications/Common/Model/EmployeeCertification.php=96045388cba569f4ea9617dc8fbeded6 +/vagrant/core/src/Classes/AbstractModuleManager.php=69d73f9f71155445c32222050528b2e0 +/vagrant/core/src/Classes/Approval/ApproveModuleActionManager.php=834a7aad3a07c194a0a830cc353daec9 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Cron/Task/EmailIceTask.php=b754a286061db310b3f18677946d7b43 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/ActiveEmployeeReport.php=261180dfbe69ab83d9d63646111695ba +/vagrant/core/src/Classes/Macaw.php=5a2f26ffcb41c9f42af776a91c283572 +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Common/Calculations/CaliforniaOvertimeCalculator.php=a1a5ff46939030747f505710fbd49ffd +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Common/Model/EmployeeSkill.php=a02c5ceda0489aba4ed47df010d4892e +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/EmployeeAttendanceReport.php=600c1feca3eab6d724ac9661f2f514d5 +/Users/Thilina/Projects/icehrm-open/core/src/Users/Admin/Api/UsersAdminManager.php=695662b7186616d4379d0a588b5130e6 +/Users/Thilina/Projects/icehrm-open/core/src/Users/Admin/Api/UsersActionManager.php=52c9dc80e7d81e244b5f0ed9a90693cd +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/OvertimeReport.php=431965980b2458019398d2ed6d7fc39a +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Api/ReportsAdminManager.php=be16482fcb8d6714f13618407acf25a5 +/vagrant/core/src/Reports/User/Reports/EmployeeTimeTrackReport.php=ce6f2b098845233342c336f837001554 +/vagrant/core/src/Classes/LDAPManager.php=e88dd0634a6ca372564faa5a1d540796 +/vagrant/core/src/Classes/Email/PHPMailer.php=54789d10177cc5075cb4d50838b05821 +/Users/Thilina/Projects/icehrm-open/core/src/Company/Common/Model/Timezone.php=50aff3bc39221658c35041abdc55ad98 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Data/DataReader.php=b788e0ab03f397f845ee49427f9689da +/vagrant/core/src/Utils/LogManager.php=144ebae4d0ff60f0fd21e79a45aa6e6a +/Users/Thilina/Projects/icehrm-open/core/src/Utils/Math/EvalMathStack.php=4b86e2041c19d8ef8eaf7f4ea630e116 +/Users/Thilina/Projects/icehrm-open/core/src/Model/IceEmail.php=02bd3cd01cb37ab05d763e468cba3835 +/vagrant/core/src/Users/Admin/Api/UsersAdminManager.php=695662b7186616d4379d0a588b5130e6 +/Users/Thilina/Projects/icehrm-open/core/src/Model/UserReport.php=0a8a8476e3088011cc54fda139567b56 +/Users/Thilina/Projects/icehrm-open/core/src/Data/Admin/Import/EmployeeDataImporter.php=d1b66e2d042335df792fa8913d363d5f +/Users/Thilina/Projects/icehrm-open/core/src/Travel/Common/Model/EmployeeImmigration.php=1dcb690d0045699a1aa65eda033f9adf +/vagrant/core/src/Classes/UIManager.php=b43c282c50f732086e6cc07381794cf6 +/Users/Thilina/Projects/icehrm-open/core/src/Overtime/Admin/Api/OvertimePayrollUtils.php=839c6f828000c302512d8d3058286506 +/vagrant/core/src/Model/ApproveModel.php=97c98d153a6cca455cbeb0b637eac098 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Api/ReportBuilder.php=9b0e8e996157caebcf17a2a342ba0f6e +/Users/Thilina/Projects/icehrm-open/core/src/Loans/Admin/Api/LoansAdminManager.php=0954d425f553598a6f3a9dbefc19fb45 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/OvertimeRequestReport.php=3cd3bc887da768a32bfc61c152489528 +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Admin/Api/MetadataAdminManager.php=9f383f9c34ec98a8e2e701825c548a8a +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Data/Query/FieldMapping.php=59bf4b2160b88d4ceb3729588b341b64 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/HistoryManager.php=4741dd856bb81ec2e27bd016afb8e042 +/Users/Thilina/Projects/icehrm-open/core/src/Overtime/Common/Model/EmployeeOvertimeApproval.php=edd2eedebb9f62a44f0e588c615654ce +/vagrant/core/src/Qualifications/Common/Model/Language.php=16759d70f3d52e38cbe81abed9b220d8 +/vagrant/core/src/Attendance/Admin/Api/AttendanceDashboardManager.php=c08fc7c021dd0c0780851c308225291f +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Email/SNSEmailSender.php=fa905e3ab63ea745c591e744d6741b6b +/Users/Thilina/Projects/icehrm-open/core/src/Modules/Admin/Api/ModulesAdminManager.php=e0bc5316cc3c7c6e214761c54e738e9c +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/TerminatedEmployeeReport.php=1b8b58d6e85eb77e45aaf44f426025ea +/vagrant/core/src/Model/Notification.php=fe1cf65671434bc29c8d17a78577e1f3 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Migration/AbstractMigration.php=324fe15e15a0ca2b0f50f4029ae10548 +/vagrant/core/src/Dashboard/User/Api/DashboardModulesManager.php=2e8968121b445353ee864c76c44483d3 +/Users/Thilina/Projects/icehrm-open/core/src/Loans/User/Api/LoansModulesManager.php=4f0650c7b4ab3ec6c241bd32c680dfca +/Users/Thilina/Projects/icehrm-open/core/src/Modules/Admin/Api/ModulesActionManager.php=a4f9c92a8f6de83ed72c5f775369b883 +/vagrant/core/src/Classes/CustomFieldManager.php=ed6fd78e1a485b2dc05e4fe683ec4731 +/vagrant/core/src/Loans/Admin/Api/LoansAdminManager.php=0954d425f553598a6f3a9dbefc19fb45 +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Admin/Api/AttendanceActionManager.php=ebf11e8f9395c7ef272b08c8f1fcd22c +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Common/Model/Certification.php=39426e51081f6385feb4803f6a62e937 +/vagrant/core/src/Reports/Admin/Reports/EmployeeAttendanceReport.php=a20c94c986fa57c52daebbcbf4fa1f3f +/Users/Thilina/Projects/icehrm-open/core/src/TimeSheets/Common/Model/QTDays.php=32a00e65a966331b776dc37cc0609edf +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Api/PDFReportBuilder.php=fbbc196b5ea432671667bcc239d8bf54 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Cron/Task/EmailSenderTask.php=f0c93e7c807706922cb812723e51bd09 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/ExpenseReport.php=397c8deb446994b64e2b9fef2845bb89 +/vagrant/core/src/Dashboard/Admin/Api/DashboardAdminManager.php=800b72969de1b8c311a8e1b7d2940c79 +/vagrant/core/src/Classes/ModuleBuilder/ModuleTab.php=89136363d7520967c2d42e175052f4d5 +/Users/Thilina/Projects/icehrm-open/core/src/Dependents/Common/Model/EmployeeDependent.php=1f4b6cd6dfbc14269b53dbbac3730f9e +/Users/Thilina/Projects/icehrm-open/core/src/Utils/Math/EvalMath.php=bdae5673431ca215e080d3b0aa0f74c8 +/vagrant/core/src/Utils/CalendarTools.php=9f60bf1aaa928a02163680da60ac255c +/Users/Thilina/Projects/icehrm-open/core/src/Jobs/Common/Model/JobTitle.php=2f24525e14942c7f284a44c8e416cd34 +/vagrant/core/src/StaffDirectory/User/Api/StaffDirectoryModulesManager.php=01de49a245a08bcf9a770bcee9331136 +/vagrant/core/src/Classes/Cron/Task/EmailSenderTask.php=f0c93e7c807706922cb812723e51bd09 +/vagrant/core/src/Reports/User/Reports/ClientProjectTimeReport.php=f860b3cff536b5074bb7d1e193c1c41d +/vagrant/core/src/Reports/User/Api/ReportsModulesManager.php=1645b61be16b96d0085510f6a2d30b68 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/AbstractInitialize.php=a6e16a53a0178bc30b27dcf3684fbdad +/vagrant/core/src/Salary/Admin/Api/SalaryAdminManager.php=8bedb5d82608974feedd1c094cac64fa +/vagrant/core/src/Employees/Common/Model/EmploymentStatus.php=6e72924fac0cecc49aaf070389f8d73a +/vagrant/core/src/Classes/HistoryManager.php=4741dd856bb81ec2e27bd016afb8e042 +/Users/Thilina/Projects/icehrm-open/core/src/Loans/Common/Model/CompanyLoan.php=cca60a4d5fa1189cdbd35146b010a2c7 +/vagrant/core/src/Travel/Admin/Api/TravelActionManager.php=3a1057fd319a38ff8eecf55b4879d517 +/vagrant/core/src/Projects/Common/Model/Client.php=e4ee80d40f4bbcd94516d767b639f4e4 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Api/CSVReportBuilder.php=5c5f7175cc2aff776388c3281cea9cf3 +/vagrant/core/src/Reports/Admin/Api/PDFReportBuilderInterface.php=cc049c4c1b86e5a5e4fd99ddf24e563d +/vagrant/core/src/Overtime/User/Api/OvertimeModulesManager.php=b29d52a4e3f021cdd786f41cbf1b9837 +/Users/Thilina/Projects/icehrm-open/core/src/Permissions/Admin/Api/PermissionsAdminManager.php=c66e06b926b4006e8a2d7f2e77e0f1fa +/vagrant/core/src/Attendance/Common/Calculations/CaliforniaOvertimeCalculator.php=a1a5ff46939030747f505710fbd49ffd +/Users/Thilina/Projects/icehrm-open/test/test.config.php=68587cbb63b8a37dc07fdac177eb23a4 +/Users/Thilina/Projects/icehrm-open/core/src/Dashboard/Admin/Api/DashboardActionManager.php=5e8e996f9f4b77f1fbd10e026a5d1351 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/PayslipReport.php=7582da680dd305d073faf95d268083cd +/vagrant/core/src/Salary/Common/Model/EmployeeSalary.php=f7d994ee11b471fff1a6d522d0c62232 +/vagrant/core/src/Classes/BaseService.php=92bd3a9bb4e7eb84e079b0db75d5f752 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/EmployeeTimesheetReport.php=8661944cf39b10c441841a8af72cb988 +/vagrant/core/src/Settings/Admin/Api/SettingsAdminManager.php=5e5df0056db6f9593128720581feca18 +/Users/Thilina/Projects/icehrm-open/core/src/Employees/Common/Model/EmployeeApproval.php=481ddd171d66e644bb442ab02e97b097 +/vagrant/core/src/Permissions/Common/Model/Permission.php=0745dd3786e95cfc5265c32f47f4ee4a +/Users/Thilina/Projects/icehrm-open/core/src/Utils/LogManager.php=144ebae4d0ff60f0fd21e79a45aa6e6a +/Users/Thilina/Projects/icehrm-open/core/src/Dashboard/User/Api/DashboardModulesManager.php=2e8968121b445353ee864c76c44483d3 +/vagrant/core/src/Users/Admin/Api/UsersEmailSender.php=44ef76064fa528f8c88b0cf6b6e9b448 +/Users/Thilina/Projects/icehrm-open/core/src/StaffDirectory/User/Api/StaffDirectoryModulesManager.php=01de49a245a08bcf9a770bcee9331136 +/vagrant/core/src/StaffDirectory/Rest/StaffDirectoryRestEndPoint.php=ba417b136c9c65cd5096c3bde7d141c2 +/vagrant/core/src/Payroll/Common/Model/PayslipTemplate.php=cc9bf7552cfccd84a0b9b1431f224f1f +/vagrant/core/src/Classes/Email/EmailSender.php=7a77f7e9c4622634bddd8ac1ff7b6fa3 +/vagrant/test/test.includes.php=66d627b31f3f6b76f1739a54e7d9fd9f +/vagrant/core/src/Attendance/Common/Model/AttendanceStatus.php=ad80af2d596e584a3ab60a5fce4aac09 +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Admin/Api/QualificationsAdminManager.php=3037d64a2344a497ff0ceea52265d2a6 +/Users/Thilina/Projects/icehrm-open/core/src/EmergencyContacts/User/Api/EmergencyContactModulesManager.php=527888466137dad3da5c6bf5b7bf9b28 +/vagrant/core/src/Classes/MemcacheService.php=e07916b1c628686162c19fa26aad93d5 +/vagrant/core/src/Payroll/Common/Model/PayrollData.php=f1a49da4e6e5a91695dd96c9585e1686 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Migration/MigrationManager.php=b2a6fae32ad9370a4e3375a623330fa7 +/vagrant/core/src/Classes/IceResponse.php=bb74495c33fab87e96f72b610cfd5374 +/vagrant/core/src/Classes/Cron/Task/DocumentExpiryNotificationTask.php=c5f29d1d3ea8b984b442fee8d07d08a1 +/Users/Thilina/Projects/icehrm-open/core/src/Data/Admin/Api/DataAdminManager.php=3913dc1f43ae1965956c420d0d9084c8 +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Rest/AttendanceRestEndPoint.php=98b5f7f6dc8bfe0fb0eddbc8f894837b +/vagrant/core/src/Utils/Math/EvalMath.php=bdae5673431ca215e080d3b0aa0f74c8 +/Users/Thilina/Projects/icehrm-open/core/src/Salary/Admin/Api/SalaryAdminManager.php=8bedb5d82608974feedd1c094cac64fa +/vagrant/core/src/Classes/IceConstants.php=76b653fed16d089de7da45fe4dfd32a0 +/vagrant/core/src/Overtime/Admin/Api/OvertimeAdminManager.php=701c52c0bca0b0d89c5bb8e7cbafac8e +/vagrant/core/src/Classes/ModuleBuilder/ModuleBuilder.php=29fed2a27587032060efc02c7a30a838 +/vagrant/test/unit/LanguageManagerUnit.php=ebb20febce875350bfddd7f0358e6ad0 +/vagrant/core/src/Metadata/Common/Model/CalculationHook.php=14b41df5f777aa74832b359d43d45140 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Cron/Task/DocumentExpiryNotificationTask.php=c5f29d1d3ea8b984b442fee8d07d08a1 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/CustomFieldManager.php=ed6fd78e1a485b2dc05e4fe683ec4731 +/Users/Thilina/Projects/icehrm-open/core/src/Overtime/Admin/Api/OvertimeActionManager.php=63ef6d09e21234f0ee963106c417a196 +/vagrant/core/src/Reports/Admin/Api/ReportBuilder.php=9b0e8e996157caebcf17a2a342ba0f6e +/Users/Thilina/Projects/icehrm-open/core/src/Overtime/Common/Model/OvertimeCategory.php=49198d964e954be3d427e3a7a29a6443 +/vagrant/core/src/Classes/Data/Query/FieldMapping.php=59bf4b2160b88d4ceb3729588b341b64 +/vagrant/core/src/Classes/MenuItemTemplate.php=7ad7eb3a874ec729ec1baf0760f0b4ed +/vagrant/core/src/Projects/User/Api/ProjectsModulesManager.php=4fc0463507ca7768a1e493d703ac2581 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/PermissionManager.php=149c16e23f9066538e9c7a0ee3bb397f +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Admin/Api/AttendanceDashboardManager.php=c08fc7c021dd0c0780851c308225291f +/vagrant/core/src/Payroll/Common/Model/Deduction.php=1e49d0fd8d4673e3fd094cfb0e467df4 +/vagrant/core/src/Employees/Common/Model/ArchivedEmployee.php=6056e5073538c0d7a22dea52b6c25374 +/Users/Thilina/Projects/icehrm-open/core/src/Jobs/Common/Model/PayGrade.php=9cc01a86f03deb884884681a73deb27a +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Email/SwiftMailer.php=eca37dc0add437ae1089c695b5074b90 +/vagrant/core/src/Data/Admin/Api/AbstractDataImporter.php=315bf5eec45aa13e174d412014e2237f +/Users/Thilina/Projects/icehrm-open/core/src/Model/BaseModel.php=18a7c31592c280ad3e6d2fdee42e1514 +/vagrant/core/src/Metadata/Common/Model/SupportedLanguage.php=3ec1220796f6e33641998a33f036d709 +/Users/Thilina/Projects/icehrm-open/core/src/Model/Migration.php=3f11c6dfaa18d4a6dcb2caa8d3677121 +/vagrant/core/src/TimeSheets/User/Api/TimeSheetsModulesManager.php=63a8c4364cd579be46b60a2e83f8f87f +/vagrant/core/src/Classes/SubActionManager.php=efcd05491fde9cd1f19c7baf8d09669a +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Admin/Api/AttendanceAdminManager.php=21e4a22a3eb290704181e5a4a7a5df7a +/vagrant/core/src/Employees/Common/Model/Employee.php=1e8f3958597a1d2f138e927115671538 +/vagrant/core/src/Qualifications/Common/Model/EmployeeLanguage.php=66127455502fb29181324c1cc25f93c4 +/Users/Thilina/Projects/icehrm-open/core/src/Projects/Common/Model/Project.php=05b1cd967d67cb977558f2567d7f6cb6 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/RestEndPoint.php=48bd6506bb12af195f32d65c0ae635f2 +/vagrant/core/src/Reports/Admin/Api/ReportBuilderInterface.php=dd7e723c48ec4f97db98ffec0d0f39cb +/vagrant/core/src/Employees/Admin/Api/EmployeesActionManager.php=422c05fab85d0c9f398a8c71fdef6758 +/vagrant/core/src/Classes/NotificationManager.php=e1bf4227b181f06feed9ed678a80ad2a +/vagrant/core/src/Attendance/Rest/AttendanceRestEndPoint.php=98b5f7f6dc8bfe0fb0eddbc8f894837b +/vagrant/core/src/Model/BaseModel.php=18a7c31592c280ad3e6d2fdee42e1514 +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Common/Model/Language.php=16759d70f3d52e38cbe81abed9b220d8 +/vagrant/core/src/Model/Migration.php=3f11c6dfaa18d4a6dcb2caa8d3677121 +/vagrant/core/src/Employees/Rest/EmployeeRestEndPoint.php=c133d71de94b3c13fac97f9d1061ce06 +/vagrant/core/src/Dependents/User/Api/DependentsModulesManager.php=409b6ea72b6ce0319bb12df6458d2bef +/vagrant/core/src/Salary/Common/Model/PayFrequency.php=fab16310b7db7bb9aace5a6b038c9d2a +/vagrant/core/src/Travel/Admin/Api/TravelAdminManager.php=9b3c6e369e2264d2bc9fca122e8ed90c +/vagrant/core/src/Classes/Cron/CronUtils.php=b55a1fe1c4ed55dc582e208b341f52b4 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/ModuleBuilder/ModuleBuilder.php=29fed2a27587032060efc02c7a30a838 +/Users/Thilina/Projects/icehrm-open/core/src/Company/Admin/Api/CompanyAdminManager.php=484a8b669d5fed117f1f40f289f2c6f4 +/vagrant/core/src/Qualifications/Common/Model/Education.php=327f74726fca1a976e2fc6272ffecdea +/Users/Thilina/Projects/icehrm-open/core/src/Classes/NotificationManager.php=e1bf4227b181f06feed9ed678a80ad2a +/vagrant/core/src/Classes/LanguageManager.php=e019a01be56a46a93177a50340fc3eea +/vagrant/core/src/Classes/Data/Query/Filter.php=3ec1fa1e59c0cbc0955dd3f2f738d1c3 +/vagrant/core/src/Metadata/Common/Model/Country.php=be5371104ea0bbfa7132201d5e31e62f +/Users/Thilina/Projects/icehrm-open/core/src/TimeSheets/Common/Model/EmployeeTimeEntry.php=f69d37222ff6d528b5dde53fcbb5b3a8 +/Users/Thilina/Projects/icehrm-open/core/src/Overtime/User/Api/OvertimeActionManager.php=5ace85f1fdbd23f5adc8d089f2d6b5fa +/vagrant/core/src/Travel/Common/Model/EmployeeImmigration.php=1dcb690d0045699a1aa65eda033f9adf +/vagrant/test/unit/UserAttendanceActionManagerUnit.php=1d71d366a13f253ef6931aa87202ac42 +/Users/Thilina/Projects/icehrm-open/core/src/Model/StatusChangeLog.php=0745140bddda3f06915dcfcc6ac97ce8 +/vagrant/core/src/Reports/Admin/Reports/AssetUsageReport.php=176cc5363c46aee80f4fc1802b0d29c3 +/Users/Thilina/Projects/icehrm-open/core/src/Users/Common/Model/User.php=ad497e45b540b026aa80fa58f5055cc1 +/Users/Thilina/Projects/icehrm-open/core/src/Data/Admin/Api/AbstractDataImporter.php=315bf5eec45aa13e174d412014e2237f +/vagrant/core/src/Metadata/Admin/Api/MetadataAdminManager.php=9f383f9c34ec98a8e2e701825c548a8a +/Users/Thilina/Projects/icehrm-open/core/src/Travel/Admin/Api/TravelActionManager.php=3a1057fd319a38ff8eecf55b4879d517 +/vagrant/core/src/Metadata/Common/Model/Ethnicity.php=5f5935cdeab1b41ac0d2db9f6973f6b0 +/Users/Thilina/Projects/icehrm-open/core/src/Salary/Common/Model/SalaryComponentType.php=d96878a0b1547f44731830526306ab56 +/vagrant/core/src/Metadata/Common/Model/CustomFieldValue.php=a5d9109aa3b465bf98ba0b04ce5d0430 +/vagrant/core/src/Model/Report.php=498c96015d1be2b31d8cd0bcedea7fab +/vagrant/core/src/Classes/SettingsManager.php=ebed24cde74d7fb33cca4ba156389760 +/vagrant/core/src/Payroll/Admin/Api/PayrollAdminManager.php=9bac9a6ed8406c9eb6fe7ef666aee482 +/Users/Thilina/Projects/icehrm-open/core/src/Jobs/Admin/Api/JobsAdminManager.php=12546328edffcc5bda7e84f6a8c56d9e +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Api/ReportsModulesManager.php=1645b61be16b96d0085510f6a2d30b68 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Email/EmailSender.php=7a77f7e9c4622634bddd8ac1ff7b6fa3 +/Users/Thilina/Projects/icehrm-open/core/src/TimeSheets/User/Api/TimeSheetsActionManager.php=ef271183cf6e71d8db24b8d3369e19b9 +/Users/Thilina/Projects/icehrm-open/core/src/Model/Report.php=498c96015d1be2b31d8cd0bcedea7fab +/vagrant/core/src/Classes/Cron/IceTask.php=cc9b1481e824fd967eb503248eb92e29 +/Users/Thilina/Projects/icehrm-open/core/src/Employees/Admin/Api/EmployeesActionManager.php=422c05fab85d0c9f398a8c71fdef6758 +/vagrant/core/src/Model/StatusChangeLog.php=0745140bddda3f06915dcfcc6ac97ce8 +/vagrant/core/src/Attendance/User/Api/AttendanceModulesManager.php=f1b34fae71cc963e197b41ed2ca032ca +/Users/Thilina/Projects/icehrm-open/core/src/Employees/Rest/EmployeeRestEndPoint.php=c133d71de94b3c13fac97f9d1061ce06 +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/User/Api/AttendanceActionManager.php=feaa97dd192e7faec2045aba7dc03125 +/Users/Thilina/Projects/icehrm-open/core/src/Employees/User/Api/EmployeesActionManager.php=e34f4fe38b3e0eb45cb65232fa6ec359 +/vagrant/core/src/Classes/StatusChangeLogManager.php=b091e855d9800eea9d4190e0c75e3e8c +/vagrant/core/src/Reports/Admin/Reports/TravelRequestReport.php=c4bdd4c88f4a7b15c8091a0dcbb5018a +/vagrant/core/src/Permissions/Admin/Api/PermissionsAdminManager.php=c66e06b926b4006e8a2d7f2e77e0f1fa +/Users/Thilina/Projects/icehrm-open/core/src/Travel/Admin/Api/TravelAdminManager.php=9b3c6e369e2264d2bc9fca122e8ed90c +/Users/Thilina/Projects/icehrm-open/core/src/Classes/IceConstants.php=76b653fed16d089de7da45fe4dfd32a0 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Crypt/Aes.php=d0b15a04faf73b0ff35efc308d09b6e7 +/vagrant/core/src/Reports/User/Reports/OvertimeSummaryReport.php=3918d7210957040977b8a43c580abae0 +/Users/Thilina/Projects/icehrm-open/test/unit/LanguageManagerUnit.php=ebb20febce875350bfddd7f0358e6ad0 +/Users/Thilina/Projects/icehrm-open/core/src/Model/Setting.php=f24f377a9590eb8ead2400b186f18a80 +/Users/Thilina/Projects/icehrm-open/core/src/Model/File.php=3bc6c71925ad1e20721ffd63567c7783 +/vagrant/core/src/Reports/Admin/Reports/OvertimeReport.php=f630ae5402ec7957f42b64fa46cd1923 +/vagrant/core/src/Qualifications/Common/Model/EmployeeSkill.php=a02c5ceda0489aba4ed47df010d4892e +/vagrant/core/src/Travel/Common/Model/EmployeeTravelRecordApproval.php=d84b2a1323f3663806cc30545e748cd4 +/vagrant/core/src/Reports/Admin/Reports/EmployeeLeaveEntitlementReport.php=9be41bfeb88fd0171028203f6513c799 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/ExpenseReport.php=7c8d187bc57175a92b8bc0fa33e501f0 +/vagrant/core/src/Data/Common/Model/DataImportFile.php=a0b3f8410e80862ba79aa9d8fed383d7 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/PayslipTemplate.php=cc9bf7552cfccd84a0b9b1431f224f1f +/vagrant/core/src/Payroll/Common/Model/DeductionGroup.php=c35db5b88aa4b0c7d78b8444688931b5 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Api/ClassBasedReportBuilder.php=fc77219539745bdb6364fc81bdda2516 +/vagrant/core/src/TimeSheets/Common/Model/EmployeeTimeEntry.php=f69d37222ff6d528b5dde53fcbb5b3a8 +/vagrant/core/src/Classes/ModuleBuilder/ModuleTabGroup.php=d81cfc2b3dcad2f57317b1274c884d95 +/Users/Thilina/Projects/icehrm-open/core/src/Travel/User/Api/TravelModulesManager.php=94c9204a67e99af9133cd2aa371cb6da +/vagrant/core/src/Projects/Common/Model/EmployeeProject.php=b0de956de8ec4c423604195b96f57df9 +/Users/Thilina/Projects/icehrm-open/core/src/TimeSheets/Common/Model/EmployeeTimeSheet.php=2a4e685315485e4933df5d2ba856d8fb +/Users/Thilina/Projects/icehrm-open/core/src/Users/Admin/Api/UsersEmailSender.php=44ef76064fa528f8c88b0cf6b6e9b448 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/RestApiManager.php=c53180aa40576c5fe8c519b2b0a39e32 +/vagrant/core/src/Travel/Common/Model/EmployeeTravelRecord.php=5366a1927bd94630217ffbc9386ff605 +/Users/Thilina/Projects/icehrm-open/core/src/Travel/Common/Model/EmployeeTravelRecordApproval.php=d84b2a1323f3663806cc30545e748cd4 +/vagrant/core/src/Reports/Admin/Api/ReportsAdminManager.php=be16482fcb8d6714f13618407acf25a5 +/Users/Thilina/Projects/icehrm-open/core/src/Travel/Common/Model/EmployeeTravelRecord.php=5366a1927bd94630217ffbc9386ff605 +/vagrant/core/src/Users/Common/Model/UserRole.php=9f9021a51c94b25e203cc3c0322c80d7 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/Deduction.php=1e49d0fd8d4673e3fd094cfb0e467df4 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Approval/ApproveCommonActionManager.php=c1b7efb8c4f3fe8199c7e0d6fdd1ccce +/vagrant/core/src/Payroll/Common/Model/PayrollColumnTemplate.php=cb69bf4717cfbaf0f395b931296efd9a +/vagrant/core/src/StaffDirectory/Common/Model/StaffDirectory.php=73f3c132e741460f200be3b3100833f6 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/PayrollCalculations.php=70d1b733b1adbb6c6a2ea0dcec89efca +/vagrant/core/src/Classes/Data/DataReader.php=b788e0ab03f397f845ee49427f9689da +/vagrant/core/src/Data/Admin/Api/DataActionManager.php=82f3ced08b946ca6e10a83c6e07475db +/vagrant/test/helper/EmployeeTestDataHelper.php=65ec2048653c9e4e4359d9b6967a860d +/vagrant/core/src/Payroll/Common/Model/PayrollColumn.php=0f2e8fd9b44c038f163ae646d3c6f4b6 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/PayrollData.php=f1a49da4e6e5a91695dd96c9585e1686 +/vagrant/core/src/Reports/User/Reports/EmployeeTimesheetReport.php=2ec16a7dccb131862f295ad97db9067b +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/PayrollDataExport.php=83bd6faa73c75667ecf25091c3729abc +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/TravelRequestReport.php=810d405042307fe9c6ca82e082c3673e +/vagrant/core/src/Modules/Admin/Api/ModulesAdminManager.php=e0bc5316cc3c7c6e214761c54e738e9c +/vagrant/core/src/Company/Common/Model/CompanyStructure.php=a1957202858bc093b29e8dfe48955cc6 +/vagrant/core/src/Qualifications/Common/Model/Certification.php=39426e51081f6385feb4803f6a62e937 +/vagrant/core/src/Reports/Admin/Reports/EmployeeLeavesReport.php=bd5efb4666ca4103a2e7e98aa24e1c83 +/vagrant/core/src/FieldNames/Common/Model/CustomField.php=32400d304e8064e69624311c3c80dffb +/vagrant/core/src/EmergencyContacts/User/Api/EmergencyContactModulesManager.php=527888466137dad3da5c6bf5b7bf9b28 +/vagrant/core/src/Data/Admin/Import/AttendanceDataImporter.php=dc4dec4294b9feac08a5f996b85cab85 +/Users/Thilina/Projects/icehrm-open/core/src/Data/Admin/Import/AttendanceDataImporter.php=dc4dec4294b9feac08a5f996b85cab85 +/vagrant/core/src/Company/Common/Model/Timezone.php=50aff3bc39221658c35041abdc55ad98 +/Users/Thilina/Projects/icehrm-open/core/src/Model/RestAccessToken.php=77c292675944ff887fc8b4c3f7b6da94 +/Users/Thilina/Projects/icehrm-open/core/src/Model/ReportFile.php=0a766e94902b5473ef1fa24583cf2481 +/vagrant/core/src/Classes/RestApiManager.php=c53180aa40576c5fe8c519b2b0a39e32 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/MemcacheService.php=e07916b1c628686162c19fa26aad93d5 +/Users/Thilina/Projects/icehrm-open/core/src/Projects/Admin/Api/ProjectsAdminManager.php=8f20c5277a8560a69318263166b804e3 +/vagrant/core/src/Model/IceEmail.php=02bd3cd01cb37ab05d763e468cba3835 +/vagrant/core/src/Salary/Common/Model/SalaryComponent.php=31e89f1115de7986cd790c8e113ab6d5 +/vagrant/core/src/Dependents/Common/Model/EmployeeDependent.php=1f4b6cd6dfbc14269b53dbbac3730f9e +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/NewHiresEmployeeReport.php=64eab525953538d481dab6052dd76d81 +/vagrant/core/src/Travel/User/Api/TravelModulesManager.php=94c9204a67e99af9133cd2aa371cb6da +/vagrant/core/src/Reports/Admin/Api/ClassBasedReportBuilder.php=fc77219539745bdb6364fc81bdda2516 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/DeductionGroup.php=c35db5b88aa4b0c7d78b8444688931b5 +/vagrant/core/src/Modules/Common/Model/Module.php=6930680c77dfbcd410e1425c76511c16 +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/ImmigrationStatus.php=f0dc9a94bcc487df21d53387ae8e89ba +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Data/Query/Filter.php=3ec1fa1e59c0cbc0955dd3f2f738d1c3 +/vagrant/core/src/TimeSheets/Common/Model/EmployeeTimeSheet.php=2a4e685315485e4933df5d2ba856d8fb +/vagrant/core/src/Classes/S3FileSystem.php=6308aca72380cef1981625946b59652f +/vagrant/core/src/Salary/User/Api/SalaryModulesManager.php=050d077e79532353a7d12a7221829b7c +/Users/Thilina/Projects/icehrm-open/core/src/Attendance/Common/Calculations/BasicOvertimeCalculator.php=9c96ae3f71796029d3f93e5c63783f53 +/Users/Thilina/Projects/icehrm-open/core/src/Travel/Common/Model/ImmigrationDocument.php=c0636d2ce3e7d89d9e4ebb00c8d1450f +/vagrant/core/src/Attendance/Admin/Api/AttendanceAdminManager.php=21e4a22a3eb290704181e5a4a7a5df7a +/vagrant/core/src/Users/Admin/Api/UsersActionManager.php=52c9dc80e7d81e244b5f0ed9a90693cd +/vagrant/core/src/Model/RestAccessToken.php=77c292675944ff887fc8b4c3f7b6da94 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/MenuItemTemplate.php=7ad7eb3a874ec729ec1baf0760f0b4ed +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/CalculationHook.php=14b41df5f777aa74832b359d43d45140 +/vagrant/core/src/Qualifications/Admin/Api/QualificationsAdminManager.php=3037d64a2344a497ff0ceea52265d2a6 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/PayrollColumnTemplate.php=cb69bf4717cfbaf0f395b931296efd9a +/Users/Thilina/Projects/icehrm-open/core/src/Classes/SimpleImage.php=fdfb7b2e71e14975ebce16de44ea9dee +/Users/Thilina/Projects/icehrm-open/core/src/Settings/Admin/Api/SettingsInitialize.php=148bc391f5d101121f915a590f991a6b +/vagrant/core/src/Overtime/Admin/Api/OvertimeActionManager.php=63ef6d09e21234f0ee963106c417a196 +/vagrant/core/src/Attendance/Admin/Api/AttendanceActionManager.php=ebf11e8f9395c7ef272b08c8f1fcd22c +/Users/Thilina/Projects/icehrm-open/core/src/Utils/InputCleaner.php=e86fcb9daf1d32a4328edf40a31152f8 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/EmployeeTimeSheetData.php=9d612ee603fdf4e6b710eec725da2656 +/vagrant/core/src/Data/Admin/Api/DataImporter.php=ad94e2de98e11c1d3f0f0b32c46f358c +/Users/Thilina/Projects/icehrm-open/core/src/Model/Audit.php=6259d9e1d7e7777bb8cde096bdc742aa +/Users/Thilina/Projects/icehrm-open/core/src/Classes/UIManager.php=b43c282c50f732086e6cc07381794cf6 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Email/SMTPEmailSender.php=0df2a519ce3a2d61d486b9527782f72b +/vagrant/core/src/Qualifications/Common/Model/EmployeeEducation.php=8ba4cbc034b5ee23d593cc3352cf46a9 +/vagrant/core/src/Metadata/Common/Model/Province.php=0ff661394cbcfec7f514f2d5eae7ca25 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/SubActionManager.php=efcd05491fde9cd1f19c7baf8d09669a +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Cron/IceTask.php=cc9b1481e824fd967eb503248eb92e29 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/AbstractModuleManager.php=69d73f9f71155445c32222050528b2e0 +/Users/Thilina/Projects/icehrm-open/core/src/Projects/Common/Model/Client.php=e4ee80d40f4bbcd94516d767b639f4e4 +/Users/Thilina/Projects/icehrm-open/core/src/Permissions/Common/Model/Permission.php=0745dd3786e95cfc5265c32f47f4ee4a +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/OvertimeSummaryReport.php=16d9e2f10de82f25d0965e2d327086b9 +/Users/Thilina/Projects/icehrm-open/core/src/Dashboard/User/Api/DashboardActionManager.php=3f797cf4807ad5cd4f881607142df049 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/StatusChangeLogManager.php=b091e855d9800eea9d4190e0c75e3e8c +/vagrant/core/src/Reports/User/Reports/EmployeeAttendanceReport.php=600c1feca3eab6d724ac9661f2f514d5 +/vagrant/core/src/Model/Setting.php=f24f377a9590eb8ead2400b186f18a80 +/vagrant/core/src/Payroll/Admin/Api/PayrollActionManager.php=c95c4e2ae643a16b8e59fa73dc1f0193 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/EmployeeTimeTrackReport.php=ce6f2b098845233342c336f837001554 +/vagrant/core/src/Overtime/Common/Model/EmployeeOvertimeApproval.php=edd2eedebb9f62a44f0e588c615654ce +/Users/Thilina/Projects/icehrm-open/core/src/Reports/User/Reports/EmployeeLeavesReport.php=0bd5801ac4c9803db53198c68904d5f5 +/vagrant/core/src/Reports/Admin/Reports/TerminatedEmployeeReport.php=1b8b58d6e85eb77e45aaf44f426025ea +/Users/Thilina/Projects/icehrm-open/core/src/Salary/Common/Model/SalaryComponent.php=31e89f1115de7986cd790c8e113ab6d5 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/EmployeeAttendanceReport.php=a20c94c986fa57c52daebbcbf4fa1f3f +/vagrant/test/TestTemplate.php=8e6ff185d587f339892a9a720e2bfa5f +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/AssetUsageReport.php=176cc5363c46aee80f4fc1802b0d29c3 +/vagrant/core/src/Attendance/Admin/Api/AttendanceUtil.php=34fe63a4c0f954451afae6c359ea5b38 +/vagrant/core/src/Classes/Approval/ApproveAdminActionManager.php=01eaf59752e8379205bc52f3278f96fc +/Users/Thilina/Projects/icehrm-open/core/src/Metadata/Common/Model/CustomFieldValue.php=a5d9109aa3b465bf98ba0b04ce5d0430 +/Users/Thilina/Projects/icehrm-open/core/src/Data/Admin/Import/PayrollDataImporter.php=7350ec94ef8a70ba6c263e53c70c7073 +/vagrant/core/src/Overtime/Common/Model/EmployeeOvertime.php=4275d184646684892b289524b33cf9d7 +/vagrant/core/src/Classes/Crypt/Aes.php=d0b15a04faf73b0ff35efc308d09b6e7 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/LDAPManager.php=e88dd0634a6ca372564faa5a1d540796 +/vagrant/core/src/Reports/Admin/Reports/OvertimeRequestReport.php=3cd3bc887da768a32bfc61c152489528 +/vagrant/core/src/Reports/Admin/Reports/ActiveEmployeeReport.php=261180dfbe69ab83d9d63646111695ba +/Users/Thilina/Projects/icehrm-open/core/src/Classes/Email/PHPMailer.php=54789d10177cc5075cb4d50838b05821 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/ModuleBuilder/ModuleTab.php=89136363d7520967c2d42e175052f4d5 +/vagrant/core/src/TimeSheets/User/Api/TimeSheetsActionManager.php=ef271183cf6e71d8db24b8d3369e19b9 +/Users/Thilina/Projects/icehrm-open/core/src/TimeSheets/User/Api/TimeSheetsInitialize.php=d47372f12494019c1004a04cbe57013d +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Reports/OvertimeReport.php=f630ae5402ec7957f42b64fa46cd1923 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Common/Model/PayFrequency.php=9207a551d667bab9734aa041e02a1be1 +/vagrant/core/src/Classes/Data/Query/DataQuery.php=eae53f27055f569d43fd2cad06b7beff +/Users/Thilina/Projects/icehrm-open/core/src/Qualifications/Common/Model/EmployeeCertification.php=96045388cba569f4ea9617dc8fbeded6 +/Users/Thilina/Projects/icehrm-open/core/src/Model/DataEntryBackup.php=9ab3a7d48dbdd377a90c505cf692c17e +/vagrant/core/src/Attendance/User/Api/AttendanceActionManager.php=feaa97dd192e7faec2045aba7dc03125 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/ModuleBuilder/ModuleTabGroup.php=d81cfc2b3dcad2f57317b1274c884d95 +/vagrant/core/src/Utils/InputCleaner.php=e86fcb9daf1d32a4328edf40a31152f8 +/vagrant/core/src/Salary/Common/Model/SalaryComponentType.php=d96878a0b1547f44731830526306ab56 +/vagrant/core/src/Payroll/Common/Model/PayFrequency.php=9207a551d667bab9734aa041e02a1be1 +/vagrant/core/src/Overtime/Admin/Api/OvertimePayrollUtils.php=839c6f828000c302512d8d3058286506 +/vagrant/core/src/Attendance/Common/Model/Attendance.php=aa0945e6fc70e6e3418d0e09f7110082 +/Users/Thilina/Projects/icehrm-open/core/src/Classes/ReportHandler.php=80b280cae34fdfbee864b05b07c6789a +/vagrant/core/src/Model/ReportFile.php=0a766e94902b5473ef1fa24583cf2481 +/Users/Thilina/Projects/icehrm-open/core/src/FieldNames/Common/Model/FieldNameMapping.php=e3e81b3a4e0f6c74cd687038632107d8 +/Users/Thilina/Projects/icehrm-open/core/src/Reports/Admin/Api/CSVReportBuilderInterface.php=6ada9a15e850c09162fc75020d6b00e4 +/Users/Thilina/Projects/icehrm-open/core/src/Data/Common/Model/DataImportFile.php=a0b3f8410e80862ba79aa9d8fed383d7 +/vagrant/core/src/Qualifications/User/Api/QualificationsModulesManager.php=e668d64139ecc146af9ebaea2f91e1fe +/vagrant/core/src/Payroll/Common/Model/Payroll.php=8aa76dfc05183abe955552b15e3c4351 +/Users/Thilina/Projects/icehrm-open/core/src/Payroll/Admin/Api/PayrollAdminManager.php=9bac9a6ed8406c9eb6fe7ef666aee482 +/vagrant/core/src/Reports/User/Reports/EmployeeLeavesReport.php=0bd5801ac4c9803db53198c68904d5f5 +/Users/Thilina/Projects/icehrm-open/core/src/Salary/Common/Model/EmployeeSalary.php=f7d994ee11b471fff1a6d522d0c62232 +/vagrant/core/src/Model/Cron.php=9e638c23f7cb93500a1b1f1ef4edf86f +/vagrant/core/src/Model/DataEntryBackup.php=9ab3a7d48dbdd377a90c505cf692c17e diff --git a/core/admin/attendance/index.php b/core/admin/attendance/index.php index ebd47161..d4a38310 100644 --- a/core/admin/attendance/index.php +++ b/core/admin/attendance/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'attendance_monitor'; diff --git a/core/admin/company_structure/index.php b/core/admin/company_structure/index.php index cd468c6a..0d41b4e3 100644 --- a/core/admin/company_structure/index.php +++ b/core/admin/company_structure/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'company_structure'; diff --git a/core/admin/dashboard/index.php b/core/admin/dashboard/index.php index 12fad5b8..dbdbc8f9 100644 --- a/core/admin/dashboard/index.php +++ b/core/admin/dashboard/index.php @@ -1,85 +1,15 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'dashboard'; define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; - -$invoices = []; -$numOfUnpaidInvoices = 0; -if (class_exists('\\Billing\\Admin\\Api\\BillingActionManager')) { - $billingActionManager = new \Billing\Admin\Api\BillingActionManager(); - - $invoices = $billingActionManager->getInvoices(null)->getData(); - if(!empty($invoices)){ - $invoices = json_decode(json_encode($invoices)); - } - - foreach($invoices as $inv){ - if($inv->status == "Sent"){ - $numOfUnpaidInvoices++; - } - } -} - - ?>
- -
-

You have a pending invoice

-

- You have a pending invoice. Please make you complete the payment so we can provide a better service. -
-
- Make a Payment -

-
- 1){?> -
-

You have pending invoices

-

- You have pending invoice. None of your employees are currently allowed to login. Please make sure you complete payments to all the invoices to restore your service. - Please logout and login after completing the payment to get your service restored. -
-
- Make a Payment -

-
- - - -
-

Your Trial Has Expired

-

- Your Icehrm Trial has expired. Please upgrade subscription to continue. If not upgraded your account will be deleted with in few days. -
-
- Upgrade Subscription -

-
- getModuleManagers(); diff --git a/core/admin/fieldnames/index.php b/core/admin/fieldnames/index.php index 92ae663d..8cf6ce94 100644 --- a/core/admin/fieldnames/index.php +++ b/core/admin/fieldnames/index.php @@ -5,7 +5,7 @@ This file is part of Ice Framework. ------------------------------------------------------------------ Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) +Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'fieldnames'; diff --git a/core/admin/jobs/index.php b/core/admin/jobs/index.php index 87ea3c94..db3dff50 100644 --- a/core/admin/jobs/index.php +++ b/core/admin/jobs/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'jobs'; define('MODULE_PATH',dirname(__FILE__)); diff --git a/core/admin/loans/index.php b/core/admin/loans/index.php index dc659f39..644cf7b8 100644 --- a/core/admin/loans/index.php +++ b/core/admin/loans/index.php @@ -1,24 +1,7 @@ -. - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'CompanyLoans'; @@ -26,27 +9,27 @@ define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
- + - +
- +
- +
@@ -61,4 +44,4 @@ modJsList['tabEmployeeCompanyLoan'] = new EmployeeCompanyLoanAdapter('EmployeeCo var modJs = modJsList['tabCompanyLoan']; - + diff --git a/core/admin/metadata/index.php b/core/admin/metadata/index.php index 245d92c1..76b92573 100644 --- a/core/admin/metadata/index.php +++ b/core/admin/metadata/index.php @@ -18,7 +18,7 @@ along with Ice Framework. If not, see . ------------------------------------------------------------------ Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) +Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'metadata'; diff --git a/core/admin/modules/index.php b/core/admin/modules/index.php index 92480d0c..a5f0556d 100644 --- a/core/admin/modules/index.php +++ b/core/admin/modules/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'Modules'; diff --git a/core/admin/overtime/index.php b/core/admin/overtime/index.php index 74580c3a..49709ba3 100644 --- a/core/admin/overtime/index.php +++ b/core/admin/overtime/index.php @@ -1,27 +1,10 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ -$moduleName = 'travel'; +$moduleName = 'overtime'; define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; diff --git a/core/admin/permissions/index.php b/core/admin/permissions/index.php index ba53430a..ea159193 100644 --- a/core/admin/permissions/index.php +++ b/core/admin/permissions/index.php @@ -1,24 +1,7 @@ -. - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'Permissions'; @@ -26,18 +9,18 @@ define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
- + - +
- +
@@ -51,4 +34,4 @@ modJsList['tabPermission'].setShowAddNew(false); var modJs = modJsList['tabPermission']; - + diff --git a/core/admin/projects/index.php b/core/admin/projects/index.php index 304b9333..e333c3a1 100644 --- a/core/admin/projects/index.php +++ b/core/admin/projects/index.php @@ -1,24 +1,7 @@ -. - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'projects'; @@ -26,36 +9,36 @@ define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
- + - +
- +
- +
- +
@@ -110,4 +93,4 @@ modJsList['tabEmployeeProject'].setShowEdit(false); var modJs = modJsList['tabClient']; - + diff --git a/core/admin/qualifications/index.php b/core/admin/qualifications/index.php index 1e425ded..935b05db 100644 --- a/core/admin/qualifications/index.php +++ b/core/admin/qualifications/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'company_structure'; @@ -26,37 +9,37 @@ define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
- + - +
- +
- +
- +
@@ -124,4 +107,4 @@ modJsList['tabLanguage'].setShowEdit(false); var modJs = modJsList['tabSkill']; - + diff --git a/core/admin/settings/index.php b/core/admin/settings/index.php index ce16c9ea..1bcefb35 100644 --- a/core/admin/settings/index.php +++ b/core/admin/settings/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'settings'; diff --git a/core/admin/travel/index.php b/core/admin/travel/index.php index 0ce5216b..5a85b880 100644 --- a/core/admin/travel/index.php +++ b/core/admin/travel/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'travel'; diff --git a/core/admin/users/emailTemplates/welcomeUser.html b/core/admin/users/emailTemplates/welcomeUser.html index d67217b9..d5646a13 100644 --- a/core/admin/users/emailTemplates/welcomeUser.html +++ b/core/admin/users/emailTemplates/welcomeUser.html @@ -4,14 +4,23 @@ Your account in IceHrm has been created on #_url_#< Please find your account information below:

Username: #_username_#
Email: #_email_# (You can use, username or email to login)
-Password: #_password_# (Strongly advised to change this password once logged in)
+Temporary Password: #_password_# (Strongly advised to change this password once logged in)

-To get started, follow this link: #_url_#

+Login to IceHrm here: (#_url_#)
+ + + + +
+ +
THIS IS AN AUTOMATED EMAIL - REPLIES WILL BE SENT TO #_adminEmail_#
-
\ No newline at end of file +
diff --git a/core/admin/users/index.php b/core/admin/users/index.php index 4ffc2b40..e6d910df 100644 --- a/core/admin/users/index.php +++ b/core/admin/users/index.php @@ -1,24 +1,7 @@ -. - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'users'; @@ -31,14 +14,14 @@ $csrf = \Classes\BaseService::getInstance()->generateCsrf('User');
  • - +
    - +
    @@ -63,4 +46,4 @@ modJsList['tabUserRole'] = new UserRoleAdapter('UserRole'); var modJs = modJsList['tabUser']; - + diff --git a/core/config.base.php b/core/config.base.php index 41fc89bc..4c051372 100644 --- a/core/config.base.php +++ b/core/config.base.php @@ -13,10 +13,10 @@ if(!defined('HOME_LINK_OTHERS')){ } //Version -define('VERSION', '24.0.0.OS'); -define('CACHE_VALUE', '24.0.0.OS'); -define('VERSION_NUMBER', '2400'); -define('VERSION_DATE', '26/06/2018'); +define('VERSION', '26.1.0.OS'); +define('CACHE_VALUE', '26.1.0.OS'); +define('VERSION_NUMBER', '2610'); +define('VERSION_DATE', '31/01/2019'); if(!defined('CONTACT_EMAIL')){define('CONTACT_EMAIL','icehrm@gamonoid.com');} if(!defined('KEY_PREFIX')){define('KEY_PREFIX','IceHrm');} diff --git a/core/crons/cron.php b/core/crons/cron.php index 269115ed..27f3ea51 100644 --- a/core/crons/cron.php +++ b/core/crons/cron.php @@ -10,7 +10,6 @@ if(!$crons){ \Utils\LogManager::getInstance()->info(CLIENT_NAME." cron count :".count($crons)); foreach($crons as $cron){ - $count++; $iceCron = new \Classes\Cron\IceCron($cron); \Utils\LogManager::getInstance()->info(CLIENT_NAME." check cron :".$cron->name); if($iceCron->isRunNow()){ diff --git a/core/data/payroll/Ghana-Payroll.txt b/core/data/payroll/Ghana-Payroll.txt new file mode 100644 index 00000000..c1861e30 --- /dev/null +++ b/core/data/payroll/Ghana-Payroll.txt @@ -0,0 +1,312 @@ +{ + "name": "Ghana Payroll Calculation", + "description": "", + "deductions": [ + { + "id": "101", + "name": "Housing Allowance (10%)", + "componentType": "[]", + "component": "[\"1\"]", + "payrollColumn": null, + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":0,\"upperCondition\":\"No Upper Limit\",\"upperLimit\":0,\"amount\":\"X*0.1\",\"id\":\"rangeAmounts_1\"}]" + }, + { + "id": "102", + "name": "Overtime Allowance (10%)", + "componentType": "[]", + "component": "[\"1\"]", + "payrollColumn": null, + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":0,\"upperCondition\":\"No Upper Limit\",\"upperLimit\":0,\"amount\":\"X*0.1\",\"id\":\"rangeAmounts_1\"}]" + }, + { + "id": "103", + "name": "SSNIT", + "componentType": "[]", + "component": "[\"1\"]", + "payrollColumn": null, + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":0,\"upperCondition\":\"No Upper Limit\",\"upperLimit\":0,\"amount\":\"X*0.055\",\"id\":\"rangeAmounts_1\"}]" + }, + { + "id": "104", + "name": "Tax - Ghana", + "componentType": "[]", + "component": "[]", + "payrollColumn": null, + "rangeAmounts": "" + }, + { + "id": "106", + "name": "Next 108 GHC", + "componentType": "[]", + "component": "[]", + "payrollColumn": "112", + "rangeAmounts": "[{\"lowerCondition\":\"gte\",\"lowerLimit\":\"216\",\"upperCondition\":\"lt\",\"upperLimit\":\"324\",\"amount\":\"X*0.05\",\"id\":\"rangeAmounts_1\"},{\"lowerCondition\":\"gte\",\"lowerLimit\":\"324\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":0,\"amount\":\"5.4\",\"id\":\"rangeAmounts_2\"}]" + }, + { + "id": "107", + "name": "Next 151 GHC", + "componentType": "[]", + "component": "[]", + "payrollColumn": "112", + "rangeAmounts": "[{\"lowerCondition\":\"gte\",\"lowerLimit\":\"324\",\"upperCondition\":\"lt\",\"upperLimit\":\"475\",\"amount\":\"(X-324) * 0.1\",\"id\":\"rangeAmounts_1\"},{\"lowerCondition\":\"gte\",\"lowerLimit\":\"259\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":0,\"amount\":\"15.10\",\"id\":\"rangeAmounts_2\"}]" + }, + { + "id": "108", + "name": "Next 2765 GHC", + "componentType": "[]", + "component": "[]", + "payrollColumn": "112", + "rangeAmounts": "[{\"lowerCondition\":\"gte\",\"lowerLimit\":\"475\",\"upperCondition\":\"lt\",\"upperLimit\":\"3240\",\"amount\":\"(X - 475) * 0.175\",\"id\":\"rangeAmounts_1\"},{\"lowerCondition\":\"gte\",\"lowerLimit\":\"3240\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":0,\"amount\":\"483.88\",\"id\":\"rangeAmounts_2\"}]" + }, + { + "id": "111", + "name": "Remaining after 3240 GHC", + "componentType": "[]", + "component": "[]", + "payrollColumn": "112", + "rangeAmounts": "[{\"lowerCondition\":\"gte\",\"lowerLimit\":\"3240\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":0,\"amount\":\"(X-3240)*0.25\",\"id\":\"rangeAmounts_1\"}]" + } + ], + "columns": [ + { + "id": "105", + "name": "GH - Salary (Basic)", + "calculation_hook": null, + "salary_components": "[\"1\"]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "1", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "106", + "name": "GH - Housing Allowance", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"101\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "2", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "107", + "name": "GH - Overtime Allowance", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"102\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "3", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "108", + "name": "GH - Total", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"106\",\"107\",\"105\"]", + "sub_columns": "[]", + "colorder": "4", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "109", + "name": "GH - SSNIT", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"103\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "5", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "112", + "name": "GH - Taxable Income", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"106\",\"105\"]", + "sub_columns": "[\"109\"]", + "colorder": "7", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "113", + "name": "GH - Next 108 GHC", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"106\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "9", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "114", + "name": "GH - Next 151 GHC", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"107\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "10", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "115", + "name": "GH - Next 2765 GHC", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"108\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "11", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "120", + "name": "GH - Remaining after 3240 GHC", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"111\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "12", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "121", + "name": "GH - Overtime Allow. Tax", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "13", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "[{\"name\":\"O\",\"column\":\"107\",\"id\":\"calculation_columns_1\"}]", + "calculation_function": "O*0.05" + }, + { + "id": "122", + "name": "GH - Total (PAYE Tax)", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"113\",\"114\",\"115\",\"121\",\"120\"]", + "sub_columns": "[]", + "colorder": "14", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "123", + "name": "GH - Deductions - Sub Total", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"109\",\"122\"]", + "sub_columns": "[]", + "colorder": "15", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "125", + "name": "GH - Final Total", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"108\"]", + "sub_columns": "[\"123\"]", + "colorder": "16", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + } + ], + "salaryComponents": [ + { + "id": "1", + "name": "Basic Salary", + "componentType": "1", + "details": null + } + ], + "salaryComponentTypes": [ + { + "id": "1", + "code": "B001", + "name": "Basic" + } + ], + "samplePayroll": { + "name": "Germany Payroll Calculation", + "pay_period": "4", + "columns": "[\"126\",\"127\",\"131\",\"129\",\"128\",\"133\",\"130\",\"132\"]", + "date_start": "2017-08-01", + "date_end": "2017-08-31", + "status": "Draft" + }, + "payslipTemplate": { + "name": "Sample Payslip Template", + "data": "[{\"type\":\"Company Logo\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_1\"},{\"type\":\"Company Name\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_2\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_5\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"126\",\"label\":\"Basic Salary\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_3\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"127\",\"label\":\"Car Allowance\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_4\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"130\",\"label\":\"Payment for Hours Worked\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_6\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_7\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"131\",\"label\":\"Gross Pay\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_8\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"132\",\"label\":\"Tax 19%\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_9\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_10\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"133\",\"label\":\"Net Pay\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_11\"}]", + "status": null, + "created": "2017-09-08 21:12:40", + "updated": "2017-09-08 21:12:40" + } +} \ No newline at end of file diff --git a/core/data/payroll/Sample-Country-Payroll.txt b/core/data/payroll/Sample-Country-Payroll.txt new file mode 100644 index 00000000..c2f23526 --- /dev/null +++ b/core/data/payroll/Sample-Country-Payroll.txt @@ -0,0 +1,188 @@ +{ + "name": "Sample Country Payroll", + "description": "", + "deductions": [ + { + "id": "112", + "name": "DE - Tax", + "componentType": "[]", + "component": "[]", + "payrollColumn": "131", + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":0,\"upperCondition\":\"No Upper Limit\",\"upperLimit\":0,\"amount\":\"X * 0.19\",\"id\":\"rangeAmounts_1\"}]" + } + ], + "columns": [ + { + "id": "126", + "name": "DE - Basic Salary", + "calculation_hook": null, + "salary_components": "[\"1\"]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "1", + "editable": "Yes", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "127", + "name": "DE - Car Allowance", + "calculation_hook": null, + "salary_components": "[\"3\"]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "2", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "128", + "name": "DE - Hours Worked per Month", + "calculation_hook": "AttendanceUtil_getTimeWorkedHours", + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "3", + "editable": "No", + "enabled": "Yes", + "default_value": "0", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "129", + "name": "DE - Hourly Pay", + "calculation_hook": null, + "salary_components": "[\"5\"]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "4", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "130", + "name": "DE - Payment for Hours Worked", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "5", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "[{\"name\":\"X\",\"column\":\"128\",\"id\":\"calculation_columns_1\"},{\"name\":\"Y\",\"column\":\"129\",\"id\":\"calculation_columns_2\"}]", + "calculation_function": "X * Y" + }, + { + "id": "131", + "name": "DE - Gross Salary", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"126\",\"127\",\"130\"]", + "sub_columns": "[]", + "colorder": "6", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "132", + "name": "DE - Tax", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"112\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "7", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "133", + "name": "DE - Net Salary", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"131\"]", + "sub_columns": "[\"132\"]", + "colorder": "8", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + } + ], + "salaryComponents": [ + { + "id": "1", + "name": "Basic Salary", + "componentType": "1", + "details": null + }, + { + "id": "3", + "name": "Car Allowance", + "componentType": "2", + "details": null + }, + { + "id": "5", + "name": "Regular Hourly Pay", + "componentType": "3", + "details": null + } + ], + "salaryComponentTypes": [ + { + "id": "1", + "code": "B001", + "name": "Basic" + }, + { + "id": "2", + "code": "B002", + "name": "Allowance" + }, + { + "id": "3", + "code": "B003", + "name": "Hourly" + } + ], + "samplePayroll": { + "name": "Sample Country Payroll", + "pay_period": "4", + "columns": "[\"126\",\"127\",\"131\",\"129\",\"128\",\"133\",\"130\",\"132\"]", + "date_start": "2017-08-01", + "date_end": "2017-08-31", + "status": "Draft" + }, + "payslipTemplate": { + "name": "Sample Payslip Template", + "data": "[{\"type\":\"Company Logo\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_1\"},{\"type\":\"Company Name\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_2\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_5\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"126\",\"label\":\"Basic Salary\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_3\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"127\",\"label\":\"Car Allowance\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_4\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"130\",\"label\":\"Payment for Hours Worked\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_6\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_7\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"131\",\"label\":\"Gross Pay\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_8\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"132\",\"label\":\"Tax 19%\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_9\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_10\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"133\",\"label\":\"Net Pay\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_11\"}]", + "status": null, + "created": "2017-09-08 21:12:40", + "updated": "2017-09-08 21:12:40" + } +} \ No newline at end of file diff --git a/core/data/payroll/SriLanka-Payroll.txt b/core/data/payroll/SriLanka-Payroll.txt new file mode 100644 index 00000000..5d5c39fc --- /dev/null +++ b/core/data/payroll/SriLanka-Payroll.txt @@ -0,0 +1,264 @@ +{ + "name": "Sri Lanka Payroll Calculation", + "description": "", + "deductions": [ + { + "id": "1", + "name": "EPF Employee Contribution", + "componentType": "[]", + "component": "[]", + "payrollColumn": "7", + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":\"0\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":\"0\",\"amount\":\"X*0.08\",\"id\":\"rangeAmounts_1\"}]" + }, + { + "id": "2", + "name": "EPF Employer Contribution", + "componentType": "[]", + "component": "[]", + "payrollColumn": "7", + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":\"0\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":\"0\",\"amount\":\"X*0.12\",\"id\":\"rangeAmounts_1\"}]" + }, + { + "id": "3", + "name": "ETF Employer Contribution", + "componentType": "[]", + "component": "[]", + "payrollColumn": "7", + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":\"0\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":\"0\",\"amount\":\"X*0.03\",\"id\":\"rangeAmounts_1\"}]" + }, + { + "id": "4", + "name": "PAYE Tax", + "componentType": "[]", + "component": "[]", + "payrollColumn": "12", + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":\"0\",\"upperCondition\":\"lte\",\"upperLimit\":\"62500\",\"amount\":\"0\",\"id\":\"rangeAmounts_1\"},{\"lowerCondition\":\"gt\",\"lowerLimit\":\"62500\",\"upperCondition\":\"lte\",\"upperLimit\":\"104167\",\"amount\":\"X*0.04 - 2500\",\"id\":\"rangeAmounts_2\"},{\"lowerCondition\":\"gt\",\"lowerLimit\":\"104167\",\"upperCondition\":\"lte\",\"upperLimit\":\"145833\",\"amount\":\"X*0.08 - 6667\",\"id\":\"rangeAmounts_3\"},{\"lowerCondition\":\"gt\",\"lowerLimit\":\"145833\",\"upperCondition\":\"lte\",\"upperLimit\":\"187500\",\"amount\":\"X*0.12-12500\",\"id\":\"rangeAmounts_4\"},{\"lowerCondition\":\"gt\",\"lowerLimit\":\"187500\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":\"0\",\"amount\":\"X*0.16 - 20000\",\"id\":\"rangeAmounts_5\"}]" + }, + { + "id": "5", + "name": "Stamp Duty", + "componentType": "[]", + "component": "[]", + "payrollColumn": "12", + "rangeAmounts": "[{\"lowerCondition\":\"No Lower Limit\",\"lowerLimit\":\"0\",\"upperCondition\":\"lte\",\"upperLimit\":\"25000\",\"amount\":\"0\",\"id\":\"rangeAmounts_1\"},{\"lowerCondition\":\"gt\",\"lowerLimit\":\"25000\",\"upperCondition\":\"No Upper Limit\",\"upperLimit\":\"0\",\"amount\":\"25\",\"id\":\"rangeAmounts_2\"}]" + } + ], + "columns": [ + { + "id": "5", + "name": "LK - Basic Salary", + "calculation_hook": null, + "salary_components": "[\"1\"]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "5", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "6", + "name": "LK - Fixed Allowance", + "calculation_hook": null, + "salary_components": "[\"2\"]", + "deductions": "[]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "6", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "7", + "name": "LK - Gross Pay", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"5\",\"6\"]", + "sub_columns": "[]", + "colorder": "7", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "8", + "name": "LK - EPF Employee Contribution", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"1\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "8", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "9", + "name": "LK - EPF Employer Contribution", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"2\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "9", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "10", + "name": "LK - ETF Employer Contribution", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"3\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "10", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "11", + "name": "LK - Total EPF 20%", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"8\",\"9\"]", + "sub_columns": "[]", + "colorder": "11", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "12", + "name": "LK - Total for PAYE", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"7\"]", + "sub_columns": "[]", + "colorder": "12", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "13", + "name": "LK - PAYE Tax", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"4\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "13", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "14", + "name": "LK - Stamp Duty", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[\"5\"]", + "add_columns": "[]", + "sub_columns": "[]", + "colorder": "14", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "15", + "name": "LK - Total Deductions", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"8\",\"13\",\"14\"]", + "sub_columns": "[]", + "colorder": "15", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + }, + { + "id": "16", + "name": "LK - Salary to Bank", + "calculation_hook": null, + "salary_components": "[]", + "deductions": "[]", + "add_columns": "[\"7\"]", + "sub_columns": "[\"15\"]", + "colorder": "16", + "editable": "No", + "enabled": "Yes", + "default_value": "0.00", + "calculation_columns": "", + "calculation_function": "" + } + ], + "salaryComponents": [ + { + "id": "1", + "name": "Basic Salary", + "componentType": "1", + "details": null + }, + { + "id": "2", + "name": "Fixed Allowance", + "componentType": "1", + "details": null + } + ], + "salaryComponentTypes": [ + { + "id": "1", + "code": "B001", + "name": "Basic" + } + ], + "samplePayroll": { + "name": "Sri Lanka Payroll Sample", + "pay_period": "4", + "columns": "[\"5\",\"8\",\"9\",\"10\",\"6\",\"7\",\"13\",\"16\",\"14\",\"15\",\"11\",\"12\"]", + "date_start": "2016-03-01", + "date_end": "2016-03-31", + "status": "Draft" + }, + "payslipTemplate": { + "name": "Sri Lanka - Default Payslip", + "data": "[{\"type\":\"Company Logo\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"fontSize\":\"Normal\",\"fontStyle\":\"Normal\",\"fontColor\":\"#000000\",\"status\":\"Show\",\"id\":\"data_1\"},{\"type\":\"Company Name\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"fontSize\":\"Normal\",\"fontStyle\":\"Normal\",\"fontColor\":\"\",\"status\":\"Show\",\"id\":\"data_2\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"fontSize\":\"Normal\",\"fontStyle\":\"Normal\",\"fontColor\":\"\",\"status\":\"Show\",\"id\":\"data_8\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"5\",\"label\":\"Basic Salary\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_3\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"6\",\"label\":\"Fixed Allowance\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_4\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"7\",\"label\":\"Gross Pay\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_11\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"fontSize\":\"Normal\",\"fontStyle\":\"Normal\",\"fontColor\":\"\",\"status\":\"Show\",\"id\":\"data_9\"},{\"type\":\"Text\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"Deductions\",\"status\":\"Show\",\"id\":\"data_13\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"8\",\"label\":\"EPF Employee Contribution\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_6\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"13\",\"label\":\"PAYE Tax\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_14\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"14\",\"label\":\"Stamp Duty\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_15\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"15\",\"label\":\"Total Deductions\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_16\"},{\"type\":\"Separators\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_17\"},{\"type\":\"Text\",\"payrollColumn\":\"NULL\",\"label\":\"\",\"text\":\"Employer Contributions\",\"status\":\"Show\",\"id\":\"data_18\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"9\",\"label\":\"EPF Employer Contribution\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_19\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"7\",\"label\":\"ETF Employer Contribution\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_20\"},{\"type\":\"Separators\",\"payrollColumn\":\"7\",\"label\":\"\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_21\"},{\"type\":\"Text\",\"payrollColumn\":\"7\",\"label\":\"\",\"text\":\"Totals\",\"status\":\"Show\",\"id\":\"data_22\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"11\",\"label\":\"Total EPF 20%\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_23\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"12\",\"label\":\"Total for PAYE\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_24\"},{\"type\":\"Payroll Column\",\"payrollColumn\":\"16\",\"label\":\"Net Salary\",\"text\":\"\",\"status\":\"Show\",\"id\":\"data_25\"}]", + "status": null, + "created": "2016-06-29 22:07:12", + "updated": "2016-06-29 22:07:12" + } +} \ No newline at end of file diff --git a/core/entry_footer.php b/core/entry_footer.php index 4f9421e0..ed1301d6 100644 --- a/core/entry_footer.php +++ b/core/entry_footer.php @@ -30,9 +30,7 @@ modJsList[prop].setNoJSONRequests(''); } } - var timeUtils = new TimeUtils(); - timeUtils.setServerGMToffset(''); - + var clientUrl = ''; diff --git a/core/entry_header.php b/core/entry_header.php index abdbd633..2e1a849f 100644 --- a/core/entry_header.php +++ b/core/entry_header.php @@ -7,11 +7,25 @@ if(!file_exists($logoFileName)){ ?> - - <?=$meta->title?> - - - + + getGAKey())) { ?> + + + + + + + + + + <?=$companyName?> + + + @@ -20,76 +34,20 @@ if(!file_exists($logoFileName)){ - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + diff --git a/core/footer.php b/core/footer.php index 724811d9..11d2f096 100644 --- a/core/footer.php +++ b/core/footer.php @@ -42,13 +42,8 @@ //Other static js objects - - var timeUtils = new TimeUtils(); - timeUtils.setServerGMToffset(''); - - var notificationManager = new NotificationManager(); - notificationManager.setBaseUrl('service.php'); - notificationManager.setTimeUtils(timeUtils); + var timeUtils = setupTimeUtils(''); + var notificationManager = setupNotifications('service.php'); . ------------------------------------------------------------------ Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) +Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ if (!defined('MODULE_NAME')) { define('MODULE_NAME', $moduleName); @@ -94,14 +94,18 @@ $chatUserProfile = \Classes\UIManager::getInstance()->getCurrentProfile(); ?> - - - - + getGAKey())) { ?> + + + + + + + <?=$companyName?> @@ -110,84 +114,20 @@ $chatUserProfile = \Classes\UIManager::getInstance()->getCurrentProfile(); - - - - + + + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -214,6 +154,9 @@ $chatUserProfile = \Classes\UIManager::getInstance()->getCurrentProfile();
    +getCurrentLanguageCode() === 'ar') {?> + +
    db->_connectionID === $db->_connectionID && $db->database == $d->db->database) { + if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database) { $obj = $d; break; } } } - + if ($index == false) $index = sizeof($_ADODB_ACTIVE_DBS); - + if(!isset($obj)) { $obj = new ADODB_Active_DB(); $obj->db = $db; - $obj->tables = array(); + $obj->tables = array(); } - + $_ADODB_ACTIVE_DBS[$index] = $obj; - + return $index; } @@ -82,8 +82,8 @@ function ADODB_SetDatabaseAdapter(&$db, $index=false) class ADODB_Active_Record { static $_changeNames = true; // dynamically pluralize table names static $_quoteNames = false; - - static $_foreignSuffix = '_id'; // + + static $_foreignSuffix = '_id'; // var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat] var $_table; // tablename, if set in class definition then use it as table name var $_tableat; // associative index pointing to ADODB_Active_Table, eg $ADODB_Active_DBS[_dbat]->tables[$this->_tableat] @@ -103,7 +103,7 @@ class ADODB_Active_Record { } // should be static - static function SetDatabaseAdapter(&$db, $index=false) + static function SetDatabaseAdapter(&$db, $index=false) { //error_log("Coming into ".self::_pluralize(get_called_class())."'s SetDatabaseAdapter where ".get_class()); if(!$index || !isset($index)) { @@ -111,19 +111,19 @@ class ADODB_Active_Record { } return ADODB_SetDatabaseAdapter($db, $index); } - - + + public function __set($name, $value) { $name = str_replace(' ', '_', $name); $this->$name = $value; } - + // php5 constructor function __construct($table = false, $pkeyarr=false, $db=false) { global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS; - + if ($db == false && is_object($pkeyarr)) { $db = $pkeyarr; $pkeyarr = false; @@ -143,9 +143,9 @@ class ADODB_Active_Record { if(isset($_ADODB_ACTIVE_DBS[self::_pluralize(get_called_class())])) { $this->_dbat = self::_pluralize(get_called_class()); } else { - $this->_dbat = key($_ADODB_ACTIVE_DBS); + $this->_dbat = key($_ADODB_ACTIVE_DBS); } - + } $this->_table = $table; @@ -153,13 +153,13 @@ class ADODB_Active_Record { $this->UpdateActiveTable($pkeyarr); } - + function __wakeup() { $class = get_class($this); new $class; } - + static function _pluralize($table) { if (!ADODB_Active_Record::$_changeNames) return $table; @@ -170,26 +170,26 @@ class ADODB_Active_Record { $lastc2 = substr($ut,$len-2); switch ($lastc) { case 'S': - return $table.'es'; + return $table.'es'; case 'Y': return substr($table,0,$len-1).'ies'; - case 'X': + case 'X': return $table.'es'; - case 'H': + case 'H': if ($lastc2 == 'CH' || $lastc2 == 'SH') return $table.'es'; default: return $table.'s'; } } - + // CFR Lamest singular inflector ever - @todo Make it real! // Note: There is an assumption here...and it is that the argument's length >= 4 function _singularize($tables) { - + if (!ADODB_Active_Record::$_changeNames) return $table; - + $ut = strtoupper($tables); $len = strlen($tables); if($ut[$len-1] != 'S') @@ -221,14 +221,14 @@ class ADODB_Active_Record { $table->_hasMany[$foreignRef] = $ar; # $this->$foreignRef = $this->_hasMany[$foreignRef]; // WATCHME Removed assignment by ref. to please __get() } - + // use when you don't want ADOdb to auto-pluralize tablename static function TableHasMany($table, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record') { $ar = new ADODB_Active_Record($table); $ar->hasMany($foreignRef, $foreignKey, $foreignClass); } - + // use when you don't want ADOdb to auto-pluralize tablename static function TableKeyHasMany($table, $tablePKey, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record') { @@ -236,8 +236,8 @@ class ADODB_Active_Record { $ar = new ADODB_Active_Record($table,$tablePKey); $ar->hasMany($foreignRef, $foreignKey, $foreignClass); } - - + + // use when you want ADOdb to auto-pluralize tablename for you. Note that the class must already be defined. // e.g. class Person will generate relationship for table Persons static function ClassHasMany($parentclass, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record') @@ -245,7 +245,7 @@ class ADODB_Active_Record { $ar = new $parentclass(); $ar->hasMany($foreignRef, $foreignKey, $foreignClass); } - + function belongsTo($foreignRef,$foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record') { @@ -256,24 +256,24 @@ class ADODB_Active_Record { $ar->parentKey = $parentKey; $ar->UpdateActiveTable(); $ar->foreignKey = ($foreignKey) ? $foreignKey : $foreignRef.ADODB_Active_Record::$_foreignSuffix; - + $table =& $this->TableInfo(); $table->_belongsTo[$foreignRef] = $ar; # $this->$foreignRef = $this->_belongsTo[$foreignRef]; } - + static function ClassBelongsTo($class, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record') { $ar = new $class(); $ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass); } - + static function TableBelongsTo($table, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record') { $ar = new ADOdb_Active_Record($table); $ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass); } - + static function TableKeyBelongsTo($table, $tablePKey, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record') { if (!is_array($tablePKey)) $tablePKey = array($tablePKey); @@ -284,8 +284,8 @@ class ADODB_Active_Record { /** * __get Access properties - used for lazy loading - * - * @param mixed $name + * + * @param mixed $name * @access protected * @return mixed */ @@ -293,9 +293,9 @@ class ADODB_Active_Record { { return $this->LoadRelations($name, '', -1, -1); } - + /** - * @param string $name + * @param string $name * @param string $whereOrderBy : eg. ' AND field1 = value ORDER BY field2' * @param offset * @param limit @@ -307,12 +307,12 @@ class ADODB_Active_Record { $table = $this->TableInfo(); if ($limit >= 0) $extras['limit'] = $limit; if ($offset >= 0) $extras['offset'] = $offset; - - if (strlen($whereOrderBy)) + + if (strlen($whereOrderBy)) if (!preg_match('/^[ \n\r]*AND/i',$whereOrderBy)) if (!preg_match('/^[ \n\r]*ORDER[ \n\r]/i',$whereOrderBy)) $whereOrderBy = 'AND '.$whereOrderBy; - + if(!empty($table->_belongsTo[$name])) { $obj = $table->_belongsTo[$name]; @@ -323,7 +323,7 @@ class ADODB_Active_Record { { if ($obj->parentKey) $key = $obj->parentKey; else $key = reset($table->keys); - + $arrayOfOne = $obj->Find($key.'='.$this->$columnName.' '.$whereOrderBy,false,false,$extras); if ($arrayOfOne) { $this->$name = $arrayOfOne[0]; @@ -332,7 +332,7 @@ class ADODB_Active_Record { } } if(!empty($table->_hasMany[$name])) - { + { $obj = $table->_hasMany[$name]; $key = reset($table->keys); $id = @$this->$key; @@ -345,11 +345,11 @@ class ADODB_Active_Record { $this->$name = $objs; return $objs; } - + return array(); } ////////////////////////////////// - + // update metadata function UpdateActiveTable($pkeys=false,$forceUpdate=false) { @@ -365,7 +365,7 @@ class ADODB_Active_Record { $acttab = $tables[$tableat]; foreach($acttab->flds as $name => $fld) { - if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) + if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) $this->$name = $fld->default_value; else $this->$name = null; @@ -379,19 +379,19 @@ class ADODB_Active_Record { @flock($fp, LOCK_SH); $acttab = unserialize(fread($fp,100000)); fclose($fp); - if ($acttab->_created + $ADODB_ACTIVE_CACHESECS - (abs(rand()) % 16) > time()) { + if ($acttab->_created + $ADODB_ACTIVE_CACHESECS - (abs(rand()) % 16) > time()) { // abs(rand()) randomizes deletion, reducing contention to delete/refresh file // ideally, you should cache at least 32 secs - + foreach($acttab->flds as $name => $fld) { - if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) + if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) $this->$name = $fld->default_value; else $this->$name = null; } - + $activedb->tables[$table] = $acttab; - + //if ($db->debug) ADOConnection::outp("Reading cached active record file: $fname"); return; } else if ($db->debug) { @@ -400,18 +400,18 @@ class ADODB_Active_Record { } $activetab = new ADODB_Active_Table(); $activetab->name = $table; - + $save = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; if ($db->fetchMode !== false) $savem = $db->SetFetchMode(false); - + $cols = $db->MetaColumns($table); - + if (isset($savem)) $db->SetFetchMode($savem); $ADODB_FETCH_MODE = $save; - + if (!$cols) { - $this->Error("Invalid table name: $table",'UpdateActiveTable'); + $this->Error("Invalid table name: $table",'UpdateActiveTable'); return false; } $fld = reset($cols); @@ -421,14 +421,14 @@ class ADODB_Active_Record { foreach($cols as $name => $fld) { if (!empty($fld->primary_key)) $pkeys[] = $name; } - } else + } else $pkeys = $this->GetPrimaryKeys($db, $table); } if (empty($pkeys)) { $this->Error("No primary key found for table $table",'UpdateActiveTable'); return false; } - + $attr = array(); $keys = array(); $ADODB_ASSOC_CASE = 2; @@ -446,18 +446,18 @@ class ADODB_Active_Record { $keys[strtolower($name)] = strtolower($name); } break; - - case 1: + + case 1: foreach($cols as $name => $fldobj) { $name = strtoupper($name); - + if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) $this->$name = $fldobj->default_value; else $this->$name = null; $attr[$name] = $fldobj; } - + foreach($pkeys as $k => $name) { $keys[strtoupper($name)] = strtoupper($name); } @@ -465,7 +465,7 @@ class ADODB_Active_Record { default: foreach($cols as $name => $fldobj) { $name = ($fldobj->name); - + if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) $this->$name = $fldobj->default_value; else @@ -477,7 +477,7 @@ class ADODB_Active_Record { } break; } - + $activetab->keys = $keys; $activetab->flds = $attr; @@ -489,58 +489,58 @@ class ADODB_Active_Record { } if (isset($activedb->tables[$table])) { $oldtab = $activedb->tables[$table]; - + if ($oldtab) $activetab->_belongsTo = $oldtab->_belongsTo; if ($oldtab) $activetab->_hasMany = $oldtab->_hasMany; } $activedb->tables[$table] = $activetab; } - + function GetPrimaryKeys(&$db, $table) { return $db->MetaPrimaryKeys($table); } - - // error handler for both PHP4+5. + + // error handler for both PHP4+5. function Error($err,$fn) { global $_ADODB_ACTIVE_DBS; - + $fn = get_class($this).'::'.$fn; $this->_lasterr = $fn.': '.$err; - + if ($this->_dbat < 0) $db = false; else { $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat]; $db = $activedb->db; } - - if (function_exists('adodb_throw')) { + + if (function_exists('adodb_throw')) { if (!$db) adodb_throw('ADOdb_Active_Record', $fn, -1, $err, 0, 0, false); else adodb_throw($db->databaseType, $fn, -1, $err, 0, 0, $db); } else if (!$db || $db->debug) ADOConnection::outp($this->_lasterr); - + } - + // return last error message function ErrorMsg() { if (!function_exists('adodb_throw')) { if ($this->_dbat < 0) $db = false; else $db = $this->DB(); - + // last error could be database error too if ($db && $db->ErrorMsg()) return $db->ErrorMsg(); } return $this->_lasterr; } - - function ErrorNo() + + function ErrorNo() { if ($this->_dbat < 0) return -9999; // no database connection... $db = $this->DB(); - + return (int) $db->ErrorNo(); } @@ -549,7 +549,7 @@ class ADODB_Active_Record { function DB() { global $_ADODB_ACTIVE_DBS; - + if ($this->_dbat < 0) { $false = false; $this->Error("No database connection set: use ADOdb_Active_Record::SetDatabaseAdaptor(\$db)", "DB"); @@ -559,7 +559,7 @@ class ADODB_Active_Record { $db = $activedb->db; return $db; } - + // retrieve ADODB_Active_Table function &TableInfo() { @@ -568,8 +568,8 @@ class ADODB_Active_Record { $table = $activedb->tables[$this->_tableat]; return $table; } - - + + // I have an ON INSERT trigger on a table that sets other columns in the table. // So, I find that for myTable, I want to reload an active record after saving it. -- Malcolm Cook function Reload() @@ -580,21 +580,21 @@ class ADODB_Active_Record { return($this->Load($where)); } - + // set a numeric array (using natural table field ordering) as object properties function Set(&$row) { global $ACTIVE_RECORD_SAFETY; - + $db = $this->DB(); - + if (!$row) { - $this->_saved = false; + $this->_saved = false; return false; } - + $this->_saved = true; - + $table = $this->TableInfo(); if ($ACTIVE_RECORD_SAFETY && sizeof($table->flds) != sizeof($row)) { # @@ -613,7 +613,7 @@ class ADODB_Active_Record { } else $keys = array_keys($row); - + # reset($keys); $this->_original = array(); @@ -627,7 +627,7 @@ class ADODB_Active_Record { # return true; } - + // get last inserted id for INSERT function LastInsertID(&$db,$fieldname) { @@ -635,32 +635,32 @@ class ADODB_Active_Record { $val = $db->Insert_ID($this->_table,$fieldname); else $val = false; - + if (is_null($val) || $val === false) { // this might not work reliably in multi-user environment return $db->GetOne("select max(".$fieldname.") from ".$this->_table); } return $val; } - + // quote data in where clause function doquote(&$db, $val,$t) { switch($t) { case 'L': if (strpos($db->databaseType,'postgres') !== false) return $db->qstr($val); - case 'D': + case 'D': case 'T': if (empty($val)) return 'null'; - - case 'B': + + case 'B': case 'N': case 'C': case 'X': if (is_null($val)) return 'null'; - - if (strlen($val)>1 && - (strncmp($val,"'",1) != 0 || substr($val,strlen($val)-1,1) != "'")) { + + if (strlen($val)>1 && + (strncmp($val,"'",1) != 0 || substr($val,strlen($val)-1,1) != "'")) { return $db->qstr($val); break; } @@ -669,13 +669,13 @@ class ADODB_Active_Record { break; } } - + // generate where clause for an UPDATE/SELECT function GenWhere(&$db, &$table) { $keys = $table->keys; $parr = array(); - + foreach($keys as $k) { $f = $table->flds[$k]; if ($f) { @@ -684,17 +684,17 @@ class ADODB_Active_Record { } return implode(' and ', $parr); } - - + + function _QName($n,$db=false) { if (!ADODB_Active_Record::$_quoteNames) return $n; if (!$db) $db = $this->DB(); if (!$db) return false; return $db->nameQuote.$n.$db->nameQuote; } - + //------------------------------------------------------------ Public functions below - + function Load($where=null,$bindarr=false) { $this->_where = $where; @@ -705,31 +705,31 @@ class ADODB_Active_Record { } return $this->LoadFromRawQuery($qry, $bindarr); } - + function LoadFromRawQuery($qry, $bindarr=false) { global $ADODB_FETCH_MODE; - + $db = $this->DB(); if (!$db) return false; - + $save = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; if ($db->fetchMode !== false) $savem = $db->SetFetchMode(false); - + $row = $db->GetRow($qry,$bindarr); - + if (isset($savem)) $db->SetFetchMode($savem); $ADODB_FETCH_MODE = $save; - + return $this->Set($row); } - + # useful for multiple record inserts # see http://phplens.com/lens/lensforum/msgs.php?id=17795 function Reset() { $this->_where=null; - $this->_saved = false; - $this->_lasterr = false; + $this->_saved = false; + $this->_lasterr = false; $this->_original = false; $vars=get_object_vars($this); foreach($vars as $k=>$v){ @@ -740,24 +740,24 @@ class ADODB_Active_Record { $this->foreignName=strtolower(get_class($this)); return true; } - + // false on error function Save() { if ($this->_saved) $ok = $this->Update(); else $ok = $this->Insert(); - + return $ok; } - - + + // false on error function Insert() { $db = $this->DB(); if (!$db) return false; $cnt = 0; $table = $this->TableInfo(); - + $valarr = array(); $names = array(); $valstr = array(); @@ -771,7 +771,7 @@ class ADODB_Active_Record { $cnt += 1; } } - + if (empty($names)){ foreach($table->flds as $name=>$fld) { $valarr[] = null; @@ -782,7 +782,7 @@ class ADODB_Active_Record { } $sql = 'INSERT INTO '.$this->_table."(".implode(',',$names).') VALUES ('.implode(',',$valstr).')'; $ok = $db->Execute($sql,$valarr); - + if ($ok) { $this->_saved = true; $autoinc = false; @@ -797,32 +797,32 @@ class ADODB_Active_Record { $this->$k = $this->LastInsertID($db,$k); } } - + $this->_original = $valarr; return !empty($ok); } - + function Delete() { $db = $this->DB(); if (!$db) return false; $table = $this->TableInfo(); - + $where = $this->GenWhere($db,$table); $sql = 'DELETE FROM '.$this->_table.' WHERE '.$where; $ok = $db->Execute($sql); - + return $ok ? true : false; } - + protected function intify($ret) { if(is_numeric($ret)) { return intval($ret); } else { - return $ret; + return $ret; } - + } - + function Aggregate($function, $column, $whereGroupBy, $bindarr=false) { if(!in_array($function, ADODB_Active_Record::$_supportedAggregateFunctions)) { throw new InvalidArgumentException("Unknown Aggregate Function $function"); @@ -833,11 +833,11 @@ class ADODB_Active_Record { $db = $this->DB(); if (!$db || empty($this->_table)) return false; return $db->GetOne("select $function($column) from ".$this->_table." where ". $whereGroupBy, $bindarr); } - + function Count($whereGroupBy, $bindarr=false) { return $this->intify( $this->Aggregate("count", "*", $whereGroupBy, $bindarr) ); } - + function CountDistinct($column, $whereGroupBy, $bindarr=false) { if(!in_array($column, $this->GetAttributeNames())) { throw new InvalidArgumentException("Unknown Column for CountDistinct $column"); @@ -845,7 +845,7 @@ class ADODB_Active_Record { $db = $this->DB(); if (!$db || empty($this->_table)) return false; return $this->intify( $db->GetOne("select count(distinct($column)) from ".$this->_table." where ". $whereGroupBy, $bindarr) ); } - + // returns an array of active record objects function Find($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array()) { @@ -853,7 +853,7 @@ class ADODB_Active_Record { $arr = $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr,$extra); return $arr; } - + // returns an array of active record objects function FindFromRawQuery($query,$bindarr=false,$pkeysArr=false,$extra=array()) { @@ -861,17 +861,17 @@ class ADODB_Active_Record { $arr = $db->GetActiveRecordsClass2(get_class($this),$this->_table, $query,$bindarr,$pkeysArr,$extra); return $arr; } - + // returns 0 on error, 1 on update, 2 on insert function Replace() { global $ADODB_ASSOC_CASE; - + $db = $this->DB(); if (!$db) return false; $table = $this->TableInfo(); - + $pkey = $table->keys; - + foreach($table->flds as $name=>$fld) { $val = $this->$name; /* @@ -887,24 +887,24 @@ class ADODB_Active_Record { if (is_null($val) && !empty($fld->auto_increment)) { continue; } - + if (is_array($val)) continue; - + $t = $db->MetaType($fld->type); $arr[$name] = $this->doquote($db,$val,$t); $valarr[] = $val; } - + if (!is_array($pkey)) $pkey = array($pkey); - - - if ($ADODB_ASSOC_CASE == 0) + + + if ($ADODB_ASSOC_CASE == 0) foreach($pkey as $k => $v) $pkey[$k] = strtolower($v); - elseif ($ADODB_ASSOC_CASE == 1) + elseif ($ADODB_ASSOC_CASE == 1) foreach($pkey as $k => $v) $pkey[$k] = strtoupper($v); - + $ok = $db->Replace($this->_table,$arr,$pkey); if ($ok) { $this->_saved = true; // 1= update 2=insert @@ -921,9 +921,9 @@ class ADODB_Active_Record { $this->$k = $this->LastInsertID($db,$k); } } - + $this->_original = $valarr; - } + } return $ok; } @@ -932,14 +932,14 @@ class ADODB_Active_Record { { $db = $this->DB(); if (!$db) return false; $table = $this->TableInfo(); - + $where = $this->GenWhere($db, $table); - + if (!$where) { $this->error("Where missing for table $table", "Update"); return false; } - $valarr = array(); + $valarr = array(); $neworig = array(); $pairs = array(); $i = -1; @@ -948,10 +948,10 @@ class ADODB_Active_Record { $i += 1; $val = $this->$name; $neworig[] = $val; - - if (isset($table->keys[$name]) || is_array($val)) + + if (isset($table->keys[$name]) || is_array($val)) continue; - + if (is_null($val)) { if (isset($fld->not_null) && $fld->not_null) { if (isset($fld->default_value) && strlen($fld->default_value)) continue; @@ -969,8 +969,8 @@ class ADODB_Active_Record { $pairs[] = $this->_QName($name,$db).'='.$db->Param($cnt); $cnt += 1; } - - + + if (!$cnt) return -1; $sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where; $ok = $db->Execute($sql,$valarr); @@ -980,21 +980,21 @@ class ADODB_Active_Record { } return 0; } - + function GetAttributeNames() { $table = $this->TableInfo(); if (!$table) return false; return array_keys($table->flds); } - + }; function adodb_GetActiveRecordsClass(&$db, $class, $table,$whereOrderBy,$bindarr, $primkeyArr, $extra) { $qry = "select * from ".$table; - + if (!empty($whereOrderBy)) { $qry .= ' WHERE '.$whereOrderBy; } @@ -1006,7 +1006,7 @@ function adodb_GetActiveRecordsClass2(&$db, $class, $table, $qry, $bindarr, $pri { global $_ADODB_ACTIVE_DBS; - + $save = $db->SetFetchMode(ADODB_FETCH_NUM); if(isset($extra['limit'])) { @@ -1027,13 +1027,13 @@ function adodb_GetActiveRecordsClass2(&$db, $class, $table, $qry, $bindarr, $pri } $db->SetFetchMode($save); - + $false = false; - - if ($rows === false) { + + if ($rows === false) { return $false; } - + if (!class_exists($class)) { $db->outp_throw("Unknown class $class in GetActiveRecordsClass()",'GetActiveRecordsClass'); @@ -1047,7 +1047,7 @@ function adodb_GetActiveRecordsClass2(&$db, $class, $table, $qry, $bindarr, $pri $arrRef = array(); $bTos = array(); // Will store belongTo's indices if any foreach($rows as $row) { - + $obj = new $class($table,$primkeyArr,$db); if ($obj->ErrorNo()){ $db->_errorMsg = $obj->ErrorMsg(); @@ -1055,7 +1055,7 @@ function adodb_GetActiveRecordsClass2(&$db, $class, $table, $qry, $bindarr, $pri } $obj->Set($row); $arr[] = $obj; - } // foreach($rows as $row) + } // foreach($rows as $row) return $arr; } diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src deleted file mode 120000 index 929cb3dc..00000000 --- a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src +++ /dev/null @@ -1 +0,0 @@ -../../src \ No newline at end of file diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Config.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Config.php new file mode 100644 index 00000000..25f714f2 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Config.php @@ -0,0 +1,157 @@ +config = new Data($data); + $this->setDefaults(new Data()); + } + + /** + * {@inheritdoc} + */ + public function has($key) + { + return ($this->config->has($key)); + } + + /** + * {@inheritdoc} + */ + public function get($key, $defaultFallback = null) + { + if ($this->has($key)) { + return $this->config->get($key); + } + return $this->getDefault($key, $defaultFallback); + } + + /** + * {@inheritdoc} + */ + public function set($key, $value) + { + $this->config->set($key, $value); + return $this; + } + + /** + * {@inheritdoc} + */ + public function import($data) + { + return $this->replace($data); + } + + /** + * {@inheritdoc} + */ + public function replace($data) + { + $this->config = new Data($data); + return $this; + } + + /** + * {@inheritdoc} + */ + public function combine($data) + { + if (!empty($data)) { + $this->config->import($data, true); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function export() + { + return $this->config->export(); + } + + /** + * {@inheritdoc} + */ + public function hasDefault($key) + { + return $this->getDefaults()->has($key); + } + + /** + * {@inheritdoc} + */ + public function getDefault($key, $defaultFallback = null) + { + return $this->hasDefault($key) ? $this->getDefaults()->get($key) : $defaultFallback; + } + + /** + * {@inheritdoc} + */ + public function setDefault($key, $value) + { + $this->getDefaults()->set($key, $value); + return $this; + } + + /** + * Return the class $defaults property and ensure it's a Data object + * TODO: remove Data object validation in 2.0 + * + * @return Data + */ + protected function getDefaults() + { + // Ensure $this->defaults is a Data object (not an array) + if (!$this->defaults instanceof Data) { + $this->setDefaults($this->defaults); + } + return $this->defaults; + } + + /** + * Sets the $defaults class parameter + * TODO: remove support for array in 2.0 as this would currently break backward compatibility + * + * @param Data|array $defaults + * + * @throws \Exception + */ + protected function setDefaults($defaults) + { + if (is_array($defaults)) { + $this->defaults = new Data($defaults); + } elseif ($defaults instanceof Data) { + $this->defaults = $defaults; + } else { + throw new \Exception("Unknown type provided for \$defaults"); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/ConfigInterface.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/ConfigInterface.php new file mode 100644 index 00000000..5124ea1f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/ConfigInterface.php @@ -0,0 +1,105 @@ + default-value + */ + public function getGlobalOptionDefaultValues(); +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Inject/ConfigForCommand.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Inject/ConfigForCommand.php new file mode 100644 index 00000000..ce2646e1 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Inject/ConfigForCommand.php @@ -0,0 +1,127 @@ +config = $config; + } + + public function setApplication(Application $application) + { + $this->application = $application; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return [ConsoleEvents::COMMAND => 'injectConfiguration']; + } + + /** + * Before a Console command runs, inject configuration settings + * for this command into the default value of the options of + * this command. + * + * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event + */ + public function injectConfiguration(ConsoleCommandEvent $event) + { + $command = $event->getCommand(); + $this->injectConfigurationForGlobalOptions($event->getInput()); + $this->injectConfigurationForCommand($command, $event->getInput()); + + $targetOfHelpCommand = $this->getHelpCommandTarget($command, $event->getInput()); + if ($targetOfHelpCommand) { + $this->injectConfigurationForCommand($targetOfHelpCommand, $event->getInput()); + } + } + + protected function injectConfigurationForGlobalOptions($input) + { + if (!$this->application) { + return; + } + + $configGroup = new ConfigFallback($this->config, 'options'); + + $definition = $this->application->getDefinition(); + $options = $definition->getOptions(); + + return $this->injectConfigGroupIntoOptions($configGroup, $options, $input); + } + + protected function injectConfigurationForCommand($command, $input) + { + $commandName = $command->getName(); + $commandName = str_replace(':', '.', $commandName); + $configGroup = new ConfigFallback($this->config, $commandName, 'command.', '.options.'); + + $definition = $command->getDefinition(); + $options = $definition->getOptions(); + + return $this->injectConfigGroupIntoOptions($configGroup, $options, $input); + } + + protected function injectConfigGroupIntoOptions($configGroup, $options, $input) + { + foreach ($options as $option => $inputOption) { + $key = str_replace('.', '-', $option); + $value = $configGroup->get($key); + if ($value !== null) { + if (is_bool($value) && ($value == true)) { + $input->setOption($key, $value); + } elseif ($inputOption->acceptValue()) { + $inputOption->setDefault($value); + } + } + } + } + + protected function getHelpCommandTarget($command, $input) + { + if (($command->getName() != 'help') || (!isset($this->application))) { + return false; + } + + $this->fixInputForSymfony2($command, $input); + + // Symfony Console helpfully swaps 'command_name' and 'command' + // depending on whether the user entered `help foo` or `--help foo`. + // One of these is always `help`, and the other is the command we + // are actually interested in. + $nameOfCommandToDescribe = $input->getArgument('command_name'); + if ($nameOfCommandToDescribe == 'help') { + $nameOfCommandToDescribe = $input->getArgument('command'); + } + return $this->application->find($nameOfCommandToDescribe); + } + + protected function fixInputForSymfony2($command, $input) + { + // Symfony 3.x prepares $input for us; Symfony 2.x, on the other + // hand, passes it in prior to binding with the command definition, + // so we have to go to a little extra work. It may be inadvisable + // to do these steps for commands other than 'help'. + if (!$input->hasArgument('command_name')) { + $command->ignoreValidationErrors(); + $command->mergeApplicationDefinition(); + $input->bind($command->getDefinition()); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Inject/ConfigForSetters.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Inject/ConfigForSetters.php new file mode 100644 index 00000000..5ec87042 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Inject/ConfigForSetters.php @@ -0,0 +1,47 @@ +config = new ConfigMerge($config, $group, $prefix, $postfix); + } + + public function apply($object, $configurationKey) + { + $settings = $this->config->get($configurationKey); + foreach ($settings as $setterMethod => $args) { + $fn = [$object, $setterMethod]; + if (is_callable($fn)) { + $result = call_user_func_array($fn, (array)$args); + + // We require that $fn must only be used with setter methods. + // Setter methods are required to always return $this so that + // they may be chained. We will therefore throw an exception + // for any setter that returns something else. + if ($result != $object) { + $methodDescription = get_class($object) . "::$setterMethod"; + $propertyDescription = $this->config->describe($configurationKey); + throw new \Exception("$methodDescription did not return '\$this' when processing $propertyDescription."); + } + } + } + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigLoader.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigLoader.php new file mode 100644 index 00000000..ecc6f64f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigLoader.php @@ -0,0 +1,35 @@ +source; + } + + protected function setSourceName($source) + { + $this->source = $source; + return $this; + } + + public function export() + { + return $this->config; + } + + public function keys() + { + return array_keys($this->config); + } + + abstract public function load($path); +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigLoaderInterface.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigLoaderInterface.php new file mode 100644 index 00000000..9b155c1b --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/ConfigLoaderInterface.php @@ -0,0 +1,29 @@ +expander = $expander ?: new Expander(); + } + + /** + * Extend the configuration to be processed with the + * configuration provided by the specified loader. + * + * @param ConfigLoaderInterface $loader + */ + public function extend(ConfigLoaderInterface $loader) + { + return $this->addFromSource($loader->export(), $loader->getSourceName()); + } + + /** + * Extend the configuration to be processed with + * the provided nested array. + * + * @param array $data + */ + public function add($data) + { + $this->unprocessedConfig[] = $data; + return $this; + } + + /** + * Extend the configuration to be processed with + * the provided nested array. Also record the name + * of the data source, if applicable. + * + * @param array $data + * @param string $source + */ + protected function addFromSource($data, $source = '') + { + if (empty($source)) { + return $this->add($data); + } + $this->unprocessedConfig[$source] = $data; + return $this; + } + + /** + * Process all of the configuration that has been collected, + * and return a nested array. + * + * @return array + */ + public function export($referenceArray = []) + { + if (!empty($this->unprocessedConfig)) { + $this->processedConfig = $this->process( + $this->processedConfig, + $this->fetchUnprocessed(), + $referenceArray + ); + } + return $this->processedConfig; + } + + /** + * To aid in debugging: return the source of each configuration item. + * n.b. Must call this function *before* export and save the result + * if persistence is desired. + */ + public function sources() + { + $sources = []; + foreach ($this->unprocessedConfig as $sourceName => $config) { + if (!empty($sourceName)) { + $configSources = ArrayUtil::fillRecursive($config, $sourceName); + $sources = ArrayUtil::mergeRecursiveDistinct($sources, $configSources); + } + } + return $sources; + } + + /** + * Get the configuration to be processed, and clear out the + * 'unprocessed' list. + * + * @return array + */ + protected function fetchUnprocessed() + { + $toBeProcessed = $this->unprocessedConfig; + $this->unprocessedConfig = []; + return $toBeProcessed; + } + + /** + * Use a map-reduce to evaluate the items to be processed, + * and merge them into the processed array. + * + * @param array $processed + * @param array $toBeProcessed + * @return array + */ + protected function process(array $processed, array $toBeProcessed, $referenceArray = []) + { + $toBeReduced = array_map([$this, 'preprocess'], $toBeProcessed); + $reduced = array_reduce($toBeReduced, [$this, 'reduceOne'], $processed); + return $this->evaluate($reduced, $referenceArray); + } + + /** + * Process a single configuration file from the 'to be processed' + * list. By default this is a no-op. Override this method to + * provide any desired configuration preprocessing, e.g. dot-notation + * expansion of the configuration keys, etc. + * + * @param array $config + * @return array + */ + protected function preprocess(array $config) + { + return $config; + } + + /** + * Evaluate one item in the 'to be evaluated' list, and then + * merge it into the processed configuration (the 'carry'). + * + * @param array $processed + * @param array $config + * @return array + */ + protected function reduceOne(array $processed, array $config) + { + return ArrayUtil::mergeRecursiveDistinct($processed, $config); + } + + /** + * Evaluate one configuration item. + * + * @param array $processed + * @param array $config + * @return array + */ + protected function evaluate(array $config, $referenceArray = []) + { + return $this->expander->expandArrayProperties( + $config, + $referenceArray + ); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/YamlConfigLoader.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/YamlConfigLoader.php new file mode 100644 index 00000000..45705662 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Loader/YamlConfigLoader.php @@ -0,0 +1,26 @@ +setSourceName($path); + + // We silently skip any nonexistent config files, so that + // clients may simply `load` all of their candidates. + if (!file_exists($path)) { + $this->config = []; + return $this; + } + $this->config = (array) Yaml::parse(file_get_contents($path)); + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ArrayUtil.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ArrayUtil.php new file mode 100644 index 00000000..a23f854e --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ArrayUtil.php @@ -0,0 +1,75 @@ + &$value) { + $merged[$key] = self::mergeRecursiveValue($merged, $key, $value); + } + return $merged; + } + + /** + * Process the value in an mergeRecursiveDistinct - make a recursive + * call if needed. + */ + protected static function mergeRecursiveValue(&$merged, $key, $value) + { + if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) { + return self::mergeRecursiveDistinct($merged[$key], $value); + } + return $value; + } + + /** + * Fills all of the leaf-node values of a nested array with the + * provided replacement value. + */ + public static function fillRecursive(array $data, $fill) + { + $result = []; + foreach ($data as $key => $value) { + $result[$key] = $fill; + if (self::isAssociative($value)) { + $result[$key] = self::fillRecursive($value, $fill); + } + } + return $result; + } + + /** + * Return true if the provided parameter is an array, and at least + * one key is non-numeric. + */ + public static function isAssociative($testArray) + { + if (!is_array($testArray)) { + return false; + } + foreach (array_keys($testArray) as $key) { + if (!is_numeric($key)) { + return true; + } + } + return false; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigFallback.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigFallback.php new file mode 100644 index 00000000..9f9972f6 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigFallback.php @@ -0,0 +1,51 @@ +getWithFallback($key, $this->group, $this->prefix, $this->postfix); + } + + /** + * Fetch an option value from a given key, or, if that specific key does + * not contain a value, then consult various fallback options until a + * value is found. + * + */ + protected function getWithFallback($key, $group, $prefix = '', $postfix = '.') + { + $configKey = "{$prefix}{$group}${postfix}{$key}"; + if ($this->config->has($configKey)) { + return $this->config->get($configKey); + } + if ($this->config->hasDefault($configKey)) { + return $this->config->getDefault($configKey); + } + $moreGeneralGroupname = $this->moreGeneralGroupName($group); + if ($moreGeneralGroupname) { + return $this->getWithFallback($key, $moreGeneralGroupname, $prefix, $postfix); + } + return null; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigGroup.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigGroup.php new file mode 100644 index 00000000..24b29dd8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigGroup.php @@ -0,0 +1,61 @@ +config = $config; + $this->group = $group; + $this->prefix = $prefix; + $this->postfix = $postfix; + } + + /** + * Return a description of the configuration group (with prefix and postfix). + */ + public function describe($property) + { + return $this->prefix . $this->group . $this->postfix . $property; + } + + /** + * Get the requested configuration key from the most specific configuration + * group that contains it. + */ + abstract public function get($key); + + /** + * Given a group name, such as "foo.bar.baz", return the next configuration + * group in the fallback hierarchy, e.g. "foo.bar". + */ + protected function moreGeneralGroupName($group) + { + $result = preg_replace('#\.[^.]*$#', '', $group); + if ($result != $group) { + return $result; + } + return false; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigMerge.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigMerge.php new file mode 100644 index 00000000..65fccf72 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigMerge.php @@ -0,0 +1,34 @@ +getWithMerge($key, $this->group, $this->prefix, $this->postfix); + } + + /** + * Merge available configuration from each configuration group. + */ + public function getWithMerge($key, $group, $prefix = '', $postfix = '.') + { + $configKey = "{$prefix}{$group}${postfix}{$key}"; + $result = $this->config->get($configKey, []); + if (!is_array($result)) { + throw new \UnexpectedValueException($configKey . ' must be a list of settings to apply.'); + } + $moreGeneralGroupname = $this->moreGeneralGroupName($group); + if ($moreGeneralGroupname) { + $result += $this->getWithMerge($key, $moreGeneralGroupname, $prefix, $postfix); + } + return $result; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigOverlay.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigOverlay.php new file mode 100644 index 00000000..d1f12697 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/ConfigOverlay.php @@ -0,0 +1,203 @@ +contexts[self::DEFAULT_CONTEXT] = new Config(); + $this->contexts[self::PROCESS_CONTEXT] = new Config(); + } + + /** + * Add a named configuration object to the configuration overlay. + * Configuration objects added LAST have HIGHEST priority, with the + * exception of the fact that the process context always has the + * highest priority. + * + * If a context has already been added, its priority will not change. + */ + public function addContext($name, ConfigInterface $config) + { + $process = $this->contexts[self::PROCESS_CONTEXT]; + unset($this->contexts[self::PROCESS_CONTEXT]); + $this->contexts[$name] = $config; + $this->contexts[self::PROCESS_CONTEXT] = $process; + + return $this; + } + + /** + * Add a placeholder context that will be prioritized higher than + * existing contexts. This is done to ensure that contexts added + * later will maintain a higher priority if the placeholder context + * is later relaced with a different configuration set via addContext(). + * + * @param string $name + * @return $this + */ + public function addPlaceholder($name) + { + return $this->addContext($name, new Config()); + } + + /** + * Increase the priority of the named context such that it is higher + * in priority than any existing context except for the 'process' + * context. + * + * @param string $name + * @return $this + */ + public function increasePriority($name) + { + $config = $this->getContext($name); + unset($this->contexts[$name]); + return $this->addContext($name, $config); + } + + public function hasContext($name) + { + return isset($this->contexts[$name]); + } + + public function getContext($name) + { + if ($this->hasContext($name)) { + return $this->contexts[$name]; + } + return new Config(); + } + + public function removeContext($name) + { + unset($this->contexts[$name]); + } + + /** + * Determine if a non-default config value exists. + */ + public function findContext($key) + { + foreach (array_reverse($this->contexts) as $name => $config) { + if ($config->has($key)) { + return $config; + } + } + return false; + } + + /** + * @inheritdoc + */ + public function has($key) + { + return $this->findContext($key) != false; + } + + /** + * @inheritdoc + */ + public function get($key, $default = null) + { + $context = $this->findContext($key); + if ($context) { + return $context->get($key, $default); + } + return $default; + } + + /** + * @inheritdoc + */ + public function set($key, $value) + { + $this->contexts[self::PROCESS_CONTEXT]->set($key, $value); + return $this; + } + + /** + * @inheritdoc + */ + public function import($data) + { + $this->unsupported(__FUNCTION__); + } + + /** + * @inheritdoc + */ + public function replace($data) + { + $this->unsupported(__FUNCTION__); + } + + /** + * @inheritdoc + */ + public function combine($data) + { + $this->unsupported(__FUNCTION__); + } + + /** + * @inheritdoc + */ + protected function unsupported($fn) + { + throw new \Exception("The method '$fn' is not supported for the ConfigOverlay class."); + } + + /** + * @inheritdoc + */ + public function export() + { + $export = []; + foreach ($this->contexts as $name => $config) { + $export = array_merge_recursive($export, $config->export()); + } + return $export; + } + + /** + * @inheritdoc + */ + public function hasDefault($key) + { + return $this->contexts[self::DEFAULT_CONTEXT]->has($key); + } + + /** + * @inheritdoc + */ + public function getDefault($key, $default = null) + { + return $this->contexts[self::DEFAULT_CONTEXT]->get($key, $default); + } + + /** + * @inheritdoc + */ + public function setDefault($key, $value) + { + $this->contexts[self::DEFAULT_CONTEXT]->set($key, $value); + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/EnvConfig.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/EnvConfig.php new file mode 100644 index 00000000..05f8d2a8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/src/Util/EnvConfig.php @@ -0,0 +1,96 @@ +prefix = strtoupper(rtrim($prefix, '_')) . '_'; + } + + /** + * @inheritdoc + */ + public function has($key) + { + return $this->get($key) !== null; + } + + /** + * @inheritdoc + */ + public function get($key, $defaultFallback = null) + { + $envKey = $this->prefix . strtoupper(strtr($key, '.-', '__')); + $envKey = str_replace($this->prefix . $this->prefix, $this->prefix, $envKey); + return getenv($envKey) ?: $defaultFallback; + } + + /** + * @inheritdoc + */ + public function set($key, $value) + { + throw new \Exception('Cannot call "set" on environmental configuration.'); + } + + /** + * @inheritdoc + */ + public function import($data) + { + // no-op + } + + /** + * @inheritdoc + */ + public function export() + { + return []; + } + + /** + * @inheritdoc + */ + public function hasDefault($key) + { + return false; + } + + /** + * @inheritdoc + */ + public function getDefault($key, $defaultFallback = null) + { + return $defaultFallback; + } + + /** + * @inheritdoc + */ + public function setDefault($key, $value) + { + throw new \Exception('Cannot call "setDefault" on environmental configuration.'); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests deleted file mode 120000 index c2ebfe53..00000000 --- a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests +++ /dev/null @@ -1 +0,0 @@ -../../tests \ No newline at end of file diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigForCommandTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigForCommandTest.php new file mode 100644 index 00000000..41da3076 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigForCommandTest.php @@ -0,0 +1,130 @@ + [ + 'global' => 'from-config', + ], + // Define some configuration settings for the options for + // the commands my:foo and my:bar. + 'command' => [ + 'my' => [ + // commands.my.options.* apply to all my:* commands. + 'options' => [ + 'dir' => '/etc/common', + 'priority' => 'normal', + ], + 'foo' => [ + // commands.my.foo.options.* apply only to the my:foo command. + 'options' => [ + 'name' => 'baz', + ], + ], + ], + ], + ]; + + $this->config = new Config($data); + } + + public function testInjection() + { + $command = new MyFooCommand(); + $input = new StringInput('my:foo'); + + list($status, $output) = $this->runCommandViaApplication($command, $input); + + $expectedOutput = <<< EOT +Enter my:foo +dir: /etc/common +name: baz +other: fish +EOT; + + $this->assertEquals(0, $status); + $this->assertEquals($expectedOutput, $output); + } + + public function testInjectionWithOverride() + { + $command = new MyFooCommand(); + $input = new StringInput('my:foo --name=Fred'); + + list($status, $output) = $this->runCommandViaApplication($command, $input); + + $expectedOutput = <<< EOT +Enter my:foo +dir: /etc/common +name: Fred +other: fish +EOT; + + $this->assertEquals(0, $status); + $this->assertEquals($expectedOutput, $output); + } + + public function testHelpDefaultInjection() + { + $command = new MyFooCommand(); + $input = new StringInput('help my:foo'); + + list($status, $output) = $this->runCommandViaApplication($command, $input); + + $expectedOutput = <<< EOT +What is the name of the thing we are naming [default: "baz"] +EOT; + + $this->assertEquals(0, $status); + $this->assertContains($expectedOutput, $output); + + $expectedOutput = <<< EOT +A certain global option. [default: "from-config"] +EOT; + + $this->assertContains($expectedOutput, $output); + } + + protected function runCommandViaApplication($command, $input) + { + $application = new Application('TestApplication', '0.0.0'); + $application->getDefinition() + ->addOption( + new InputOption('--global', null, InputOption::VALUE_REQUIRED, 'A certain global option.', 'hardcoded') + ); + + $output = new BufferedOutput(); + + $configInjector = new ConfigForCommand($this->config); + $configInjector->setApplication($application); + + $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher(); + $eventDispatcher->addSubscriber($configInjector); + $application->setDispatcher($eventDispatcher); + + $application->setAutoExit(false); + $application->add($command); + + $statusCode = $application->run($input, $output); + $commandOutput = trim($output->fetch()); + + return [$statusCode, $commandOutput]; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigForSettersTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigForSettersTest.php new file mode 100644 index 00000000..422b0a00 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigForSettersTest.php @@ -0,0 +1,87 @@ + [ + 'Operations' => [ + // task.Operations.settings apply to all tasks in + // any *.Tass.Operations namespace. + 'settings' => [ + 'dir' => '/base/dir', + ], + 'Frobulate' => [ + // task.Operations.Frobulate.settings applies only + // the Frobulate task. + 'settings' => [ + 'dir' => '/override/dir', + ], + ], + ], + ], + ]; + $config = new Config($data); + + $applicator = new ConfigForSetters($config, 'Operations.Frobulate', 'task.'); + + $testTarget = new ApplyConfigTestTarget(); + + $applicator->apply($testTarget, 'settings'); + + $this->assertEquals('/override/dir', $testTarget->getDir()); + $this->assertEquals(null, $testTarget->getBad()); + } + + public function testApplyBadConfig() + { + $data = [ + // Define some configuration settings for the configuration + // of some task \My\Tasks\Operations\Frobulate. + 'task' => [ + 'Operations' => [ + // task.Operations.settings apply to all tasks in + // any *.Tass.Operations namespace. + 'settings' => [ + 'dir' => '/base/dir', + ], + 'Frobulate' => [ + // task.Operations.Frobulate.settings applies only + // the Frobulate task. + 'settings' => [ + 'bad' => 'fire truck', + ], + ], + ], + ], + ]; + $config = new Config($data); + + $applicator = new ConfigForSetters($config, 'Operations.Frobulate', 'task.'); + + $testTarget = new ApplyConfigTestTarget(); + + $exceptionMessage = ''; + try + { + $applicator->apply($testTarget, 'settings'); + } + catch (\Exception $e) + { + $exceptionMessage = $e->getMessage(); + } + // We would prefer it if bad methods were never called; unfortunately, + // declaring the return type of a method cannot be done in a reliable + // way (via reflection) until php 7, so we allow these methods to be + // called for now. + $this->assertEquals('fire truck', $testTarget->getBad()); + $this->assertEquals('Consolidation\\TestUtils\\ApplyConfigTestTarget::bad did not return \'$this\' when processing task.Operations.Frobulate.settings.', $exceptionMessage); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigGroupTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigGroupTest.php new file mode 100644 index 00000000..21e470e5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigGroupTest.php @@ -0,0 +1,91 @@ + [ + 'my' => [ + // commands.my.options.* apply to all my:* commands. + 'options' => [ + 'path' => '/etc/common', + 'priority' => 'normal', + ], + 'foo' => [ + // commands.my.foo.options.* apply only to the my:foo command. + 'options' => [ + 'name' => 'baz', + ], + ], + 'bar' => [ + // Similarly, commands.my.bar.options is for the my:bar command. + 'options' => [ + 'priority' => 'high', + ], + ], + ], + ], + // Define some configuration settings for the configuration + // of some task \My\Tasks\Operations\Frobulate. + 'task' => [ + 'Operations' => [ + // task.Operations.settings apply to all tasks in + // any *.Tass.Operations namespace. + 'settings' => [ + 'dir' => '/base/dir', + ], + 'Frobulate' => [ + // task.Operations.Frobulate.settings applies only + // the Frobulate task. + 'settings' => [ + 'object' => 'fire truck', + ], + ], + ], + ], + ]; + + $this->config = new Config($data); + } + + public function testDotNotation() + { + // Test the test + $this->assertEquals('baz', $this->config->get('command.my.foo.options.name')); + } + + public function testFallback() + { + $fooFallback = new ConfigFallback($this->config, 'my.foo', 'command.', '.options.'); + $barFallback = new ConfigFallback($this->config, 'my.bar', 'command.', '.options.'); + + $this->assertEquals(null, $barFallback->get('name')); + $this->assertEquals('baz', $fooFallback->get('name')); + $this->assertEquals('high', $barFallback->get('priority')); + + $this->assertEquals('normal', $fooFallback->get('priority')); + $this->assertEquals('/etc/common', $barFallback->get('path')); + $this->assertEquals('/etc/common', $fooFallback->get('path')); + } + + public function testMerge() + { + $frobulateMerge = new ConfigMerge($this->config, 'Operations.Frobulate', 'task.'); + + $settings = $frobulateMerge->get('settings'); + $this->assertEquals('fire truck', $settings['object']); + $this->assertEquals('/base/dir', $settings['dir']); + $keys = array_keys($settings); + sort($keys); + $this->assertEquals('dir,object', implode(',', $keys)); + } +} + diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigLoaderTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigLoaderTest.php new file mode 100644 index 00000000..6dedb1f3 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigLoaderTest.php @@ -0,0 +1,29 @@ +assertTrue(file_exists($path)); + + $loader->load($path); + + $configFile = basename($loader->getSourceName()); + $this->assertEquals('config-1.yml', $configFile); + + // Make sure that the data we loaded contained the expected keys + $keys = $loader->keys(); + sort($keys); + $keysString = implode(',', $keys); + $this->assertEquals('c,m', $keysString); + + $configData = $loader->export(); + $this->assertEquals('foo', $configData['c']); + $this->assertEquals('1', $configData['m'][0]); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigOverlayTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigOverlayTest.php new file mode 100644 index 00000000..f7faf748 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigOverlayTest.php @@ -0,0 +1,168 @@ +import([ + 'hidden-by-a' => 'alias hidden-by-a', + 'hidden-by-process' => 'alias hidden-by-process', + 'options' =>[ + 'a-a' => 'alias-a', + ], + 'command' => [ + 'foo' => [ + 'bar' => [ + 'command' => [ + 'options' => [ + 'a-b' => 'alias-b', + ], + ], + ], + ], + ], + ]); + + $configFileContext = new Config(); + $configFileContext->import([ + 'hidden-by-cf' => 'config-file hidden-by-cf', + 'hidden-by-a' => 'config-file hidden-by-a', + 'hidden-by-process' => 'config-file hidden-by-process', + 'options' =>[ + 'cf-a' => 'config-file-a', + ], + 'command' => [ + 'foo' => [ + 'bar' => [ + 'command' => [ + 'options' => [ + 'cf-b' => 'config-file-b', + ], + ], + ], + ], + ], + ]); + + $this->overlay = new ConfigOverlay(); + $this->overlay->set('hidden-by-process', 'process-h'); + $this->overlay->addContext('cf', $configFileContext); + $this->overlay->addContext('a', $aliasContext); + $this->overlay->setDefault('df-a', 'default'); + $this->overlay->setDefault('hidden-by-a', 'default hidden-by-a'); + $this->overlay->setDefault('hidden-by-cf', 'default hidden-by-cf'); + $this->overlay->setDefault('hidden-by-process', 'default hidden-by-process'); + } + + public function testGetPriority() + { + $this->assertEquals('process-h', $this->overlay->get('hidden-by-process')); + $this->assertEquals('config-file hidden-by-cf', $this->overlay->get('hidden-by-cf')); + $this->assertEquals('alias hidden-by-a', $this->overlay->get('hidden-by-a')); + } + + public function testDefault() + { + $this->assertEquals('alias-a', $this->overlay->get('options.a-a')); + $this->assertEquals('alias-a', $this->overlay->get('options.a-a', 'ignored')); + $this->assertEquals('default', $this->overlay->getDefault('df-a', 'ignored')); + $this->assertEquals('nsv', $this->overlay->getDefault('a-a', 'nsv')); + + $this->overlay->setDefault('df-a', 'new value'); + $this->assertEquals('new value', $this->overlay->getDefault('df-a', 'ignored')); + } + + public function testExport() + { + $data = $this->overlay->export(); + + $this->assertEquals('config-file-a', $data['options']['cf-a']); + $this->assertEquals('alias-a', $data['options']['a-a']); + } + + /** + * @expectedException Exception + */ + public function testImport() + { + $data = $this->overlay->import(['a' => 'value']); + } + + public function testMaintainPriority() + { + // Get and re-add the 'cf' context. Its priority should not change. + $configFileContext = $this->overlay->getContext('cf'); + $this->overlay->addContext('cf', $configFileContext); + + // These asserts are the same as in testGetPriority + $this->assertEquals('process-h', $this->overlay->get('hidden-by-process')); + $this->assertEquals('config-file hidden-by-cf', $this->overlay->get('hidden-by-cf')); + $this->assertEquals('alias hidden-by-a', $this->overlay->get('hidden-by-a')); + } + + public function testChangePriority() + { + // Increase the priority of the 'cf' context. Now, it should have a higher + // priority than the 'alias' context, but should still have a lower + // priority than the 'process' context. + $this->overlay->increasePriority('cf'); + + // These asserts are the same as in testGetPriority + $this->assertEquals('process-h', $this->overlay->get('hidden-by-process')); + $this->assertEquals('config-file hidden-by-cf', $this->overlay->get('hidden-by-cf')); + + // This one has changed: the config-file value is now found instead + // of the alias value. + $this->assertEquals('config-file hidden-by-a', $this->overlay->get('hidden-by-a')); + } + + public function testPlaceholder() + { + $this->overlay->addPlaceholder('lower'); + + $higherContext = new Config(); + $higherContext->import(['priority-test' => 'higher']); + + $lowerContext = new Config(); + $lowerContext->import(['priority-test' => 'lower']); + + // Usually 'lower' would have the highest priority, since it is + // added last. However, our earlier call to 'addPlaceholder' reserves + // a spot for it, so the 'higher' context will end up with a higher + // priority. + $this->overlay->addContext('higher', $higherContext); + $this->overlay->addContext('lower', $lowerContext); + $this->assertEquals('higher', $this->overlay->get('priority-test', 'neither')); + + // Test to see that we can change the value of the 'higher' context, + // and the change will be reflected in the overlay. + $higherContext->set('priority-test', 'changed'); + $this->assertEquals('changed', $this->overlay->get('priority-test', 'neither')); + + // Test to see that the 'process' context still has the highest priority. + $this->overlay->set('priority-test', 'process'); + $higherContext->set('priority-test', 'ignored'); + $this->assertEquals('process', $this->overlay->get('priority-test', 'neither')); + } + + public function testDoesNotHave() + { + $context = $this->overlay->getContext('no-such-context'); + $data = $context->export(); + $this->assertEquals('[]', json_encode($data)); + + $this->assertTrue(!$this->overlay->has('no-such-key')); + $this->assertTrue(!$this->overlay->hasDefault('no-such-default')); + + $this->assertEquals('no-such-value', $this->overlay->get('no-such-key', 'no-such-value')); + + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigProcessorTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigProcessorTest.php new file mode 100644 index 00000000..ac645a28 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigProcessorTest.php @@ -0,0 +1,152 @@ + 'foo', + 'm' => [1], + ]; + $config2 = [ + 'b' => '${c}bar', + 'm' => [2], + ]; + $config3 = [ + 'a' => '${b}baz', + 'm' => [3], + ]; + + $processor = new ConfigProcessor(); + $processor->add($config1); + $processor->add($config2); + $processor->add($config3); + + $data = $processor->export(); + $this->assertEquals('foo', $data['c']); + $this->assertEquals('foobar', $data['b']); + $this->assertEquals('foobarbaz', $data['a']); + } + + public function processorForConfigMergeTest($provideSourceNames) + { + $config1 = [ + 'm' => [ + 'x' => 'x-1', + 'y' => [ + 'r' => 'r-1', + 's' => 's-1', + 't' => 't-1', + ], + 'z' => 'z-1', + ], + ]; + $config2 = [ + 'm' => [ + 'w' => 'w-2', + 'y' => [ + 'q' => 'q-2', + 's' => 's-2', + ], + 'z' => 'z-2', + ], + ]; + $config3 = [ + 'm' => [ + 'v' => 'v-3', + 'y' => [ + 't' => 't-3', + 'u' => 'u-3', + ], + 'z' => 'z-3', + ], + ]; + + $processor = new ConfigProcessor(); + $testLoader = new TestLoader(); + + $testLoader->set($config1); + $testLoader->setSourceName($provideSourceNames ? 'c-1' : ''); + $processor->extend($testLoader); + + $testLoader->set($config2); + $testLoader->setSourceName($provideSourceNames ? 'c-2' : ''); + $processor->extend($testLoader); + + $testLoader->set($config3); + $testLoader->setSourceName($provideSourceNames ? 'c-3' : ''); + $processor->extend($testLoader); + + return $processor; + } + + public function testConfigProcessorMergeAssociative() + { + $processor = $this->processorForConfigMergeTest(false); + $data = $processor->export(); + $this->assertEquals('{"m":{"x":"x-1","y":{"r":"r-1","s":"s-2","t":"t-3","q":"q-2","u":"u-3"},"z":"z-3","w":"w-2","v":"v-3"}}', json_encode($data)); + } + + public function testConfigProcessorMergeAssociativeWithSourceNames() + { + $processor = $this->processorForConfigMergeTest(true); + $sources = $processor->sources(); + $data = $processor->export(); + $this->assertEquals('{"m":{"x":"x-1","y":{"r":"r-1","s":"s-2","t":"t-3","q":"q-2","u":"u-3"},"z":"z-3","w":"w-2","v":"v-3"}}', json_encode($data)); + $this->assertEquals('c-1', $sources['m']['x']); + $this->assertEquals('c-1', $sources['m']['y']['r']); + $this->assertEquals('c-2', $sources['m']['w']); + $this->assertEquals('c-2', $sources['m']['y']['s']); + $this->assertEquals('c-3', $sources['m']['z']); + $this->assertEquals('c-3', $sources['m']['y']['u']); + } + + public function testConfiProcessorSources() + { + $processor = new ConfigProcessor(); + $loader = new YamlConfigLoader(); + $processor->extend($loader->load(__DIR__ . '/data/config-1.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-2.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-3.yml')); + + $sources = $processor->sources(); + + $data = $processor->export(); + $this->assertEquals('foo', $data['c']); + $this->assertEquals('foobar', $data['b']); + $this->assertEquals('foobarbaz', $data['a']); + + $this->assertEquals('3', $data['m'][0]); + + $this->assertEquals( __DIR__ . '/data/config-3.yml', $sources['a']); + $this->assertEquals( __DIR__ . '/data/config-2.yml', $sources['b']); + $this->assertEquals( __DIR__ . '/data/config-1.yml', $sources['c']); + $this->assertEquals( __DIR__ . '/data/config-3.yml', $sources['m']); + } + + public function testConfiProcessorSourcesLoadInReverseOrder() + { + $processor = new ConfigProcessor(); + $loader = new YamlConfigLoader(); + $processor->extend($loader->load(__DIR__ . '/data/config-3.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-2.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-1.yml')); + + $sources = $processor->sources(); + + $data = $processor->export(); + $this->assertEquals('foo', $data['c']); + $this->assertEquals('foobar', $data['b']); + $this->assertEquals('foobarbaz', $data['a']); + + $this->assertEquals('1', $data['m'][0]); + + $this->assertEquals( __DIR__ . '/data/config-3.yml', $sources['a']); + $this->assertEquals( __DIR__ . '/data/config-2.yml', $sources['b']); + $this->assertEquals( __DIR__ . '/data/config-1.yml', $sources['c']); + $this->assertEquals( __DIR__ . '/data/config-1.yml', $sources['m']); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigTest.php new file mode 100644 index 00000000..f2ace0ce --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/ConfigTest.php @@ -0,0 +1,140 @@ +set('foo', 'bar'); + $data = $config->export(); + $this->assertEquals('{"foo":"bar"}', json_encode($data)); + } + + public function testCombine() + { + // Pointless tests just to ensure everything is covered. + $config = new Config(); + $config->set('foo', 'bar'); + $config->set('baz', 'boz'); + $config2 = new Config(); + $config2->set('foo', 'fu'); + $config2->set('new', 'blue'); + $config->combine($config2->export()); + $this->assertEquals('fu', $config->get('foo')); + $this->assertEquals('boz', $config->get('baz')); + $this->assertEquals('blue', $config->get('new')); + } + + public function testDefault() + { + $data = [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'boz', + ]; + + $foo = ["foo" => "bar"]; + + $config = new Config($data); + + $config->setDefault('c', 'other'); + $config->setDefault('d', 'other'); + $config->setDefault('f', $foo); + + $this->assertEquals('foo', $config->get('a')); + $this->assertEquals('boz', $config->get('c')); + $this->assertEquals('other', $config->get('d')); + $this->assertEquals('other', $config->getDefault('c')); + $this->assertEquals('', $config->get('e')); + $this->assertEquals('bar', $config->get('f.foo')); + $this->assertEquals('{"foo":"bar"}', json_encode($config->get('f'))); + } + + public function testDefaultsArray() + { + $data = ['a' => 'foo', 'b' => 'bar', 'c' => 'boz',]; + $defaults = ['d' => 'foo', 'e' => 'bar', 'f' => 'boz',]; + + // Create reflection class to test private methods + $configClass = new \ReflectionClass("Consolidation\Config\Config"); + + // $defaults + $defaultsProperty = $configClass->getProperty("defaults"); + $defaultsProperty->setAccessible(true); + + // $getDefaults + $getDefaultsMethod = $configClass->getMethod("getDefaults"); + $getDefaultsMethod->setAccessible(true); + + // Test the config class + $config = new Config($data); + + // Set $config::defaults to an array to test getter and setter + $defaultsProperty->setValue($config, $defaults); + $this->assertTrue(is_array($defaultsProperty->getValue($config))); + $this->assertInstanceOf('Dflydev\DotAccessData\Data', + $getDefaultsMethod->invoke($config)); + + // Set $config::defaults to a string to test exception + $defaultsProperty->setValue($config, "foo.bar"); + $this->setExpectedException("Exception"); + $getDefaultsMethod->invoke($config); + } + + public function testConfigurationWithCrossFileReferences() + { + $config = new Config(); + $processor = new ConfigProcessor(); + $loader = new YamlConfigLoader(); + $processor->extend($loader->load(__DIR__ . '/data/config-1.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-2.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-3.yml')); + + // Does not fail if configuration file cannot be found + $processor->extend($loader->load(__DIR__ . '/data/no-such-file.yml')); + + // We must capture the sources before exporting, as export + // dumps this information. + $sources = $processor->sources(); + + $config->import($processor->export()); + + $this->assertEquals(implode(',', $config->get('m')), '3'); + $this->assertEquals($config->get('a'), 'foobarbaz'); + + $this->assertEquals($sources['a'], __DIR__ . '/data/config-3.yml'); + $this->assertEquals($sources['b'], __DIR__ . '/data/config-2.yml'); + $this->assertEquals($sources['c'], __DIR__ . '/data/config-1.yml'); + } + + public function testConfigurationWithReverseOrderCrossFileReferences() + { + $config = new Config(); + $processor = new ConfigProcessor(); + $loader = new YamlConfigLoader(); + $processor->extend($loader->load(__DIR__ . '/data/config-3.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-2.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-1.yml')); + + $sources = $processor->sources(); + $config->import($processor->export()); + + $this->assertEquals(implode(',', $config->get('m')), '1'); + + if (strpos($config->get('a'), '$') !== false) { + throw new \PHPUnit_Framework_SkippedTestError( + 'Evaluation of cross-file references in reverse order not supported.' + ); + } + $this->assertEquals($config->get('a'), 'foobarbaz'); + + $this->assertEquals($sources['a'], __DIR__ . '/data/config-3.yml'); + $this->assertEquals($sources['b'], __DIR__ . '/data/config-2.yml'); + $this->assertEquals($sources['c'], __DIR__ . '/data/config-1.yml'); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-1.yml b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-1.yml new file mode 100644 index 00000000..e8f55a9d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-1.yml @@ -0,0 +1,3 @@ +c: foo +m: + - 1 diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-2.yml b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-2.yml new file mode 100644 index 00000000..baa7e63f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-2.yml @@ -0,0 +1,3 @@ +b: ${c}bar +m: + - 2 diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-3.yml b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-3.yml new file mode 100644 index 00000000..d5895642 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/data/config-3.yml @@ -0,0 +1,3 @@ +a: ${b}baz +m: + - 3 diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/install-scenario b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/install-scenario new file mode 100755 index 00000000..d77d57d0 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/install-scenario @@ -0,0 +1,23 @@ +#!/bin/bash + +SCENARIO=$1 +ACTION=${2-install} + +dir=dependencies/${SCENARIO} +if [ -z "$SCENARIO" ] ; then + SCENARIO=default + dir=. +fi + + +if [ ! -d "$dir" ] ; then + echo "Requested scenario '${SCENARIO}' does not exist." + exit 1 +fi + +echo "Switch to ${SCENARIO} scenario" + +set -ex + +composer -n --working-dir=$dir ${ACTION} --prefer-dist --no-scripts +composer -n --working-dir=$dir info diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/prep-dependencies b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/prep-dependencies new file mode 100755 index 00000000..d1898440 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/prep-dependencies @@ -0,0 +1,66 @@ +#!/bin/bash + +# +# This script is called automatically on every `composer update`. +# See "post-update-cmd" in the "scripts" section of composer.json. +# +# This script will create a derived composer.json / composer.lock +# pair for every test scenario. Test scenarios are defined in the +# "scenarios" file, which should be customized to suit the needs +# of the project. +# + +SELF_DIRNAME="`dirname -- "$0"`" +source ${SELF_DIRNAME}/scenarios + +echo +echo "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" +echo "::" +echo ":: Update dependencies for the following scenarios:" +echo "::" +echo ":: ${SCENARIOS}" +echo "::" +echo "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" +echo + +set -ex + +for SCENARIO in ${SCENARIOS} ; do + + dir=dependencies/${SCENARIO} + + # Define indirect variable names + stability_variable="stability_${SCENARIO}" + requirement_variable="requirement_${SCENARIO}" + platform_php_variable="platform_php_${SCENARIO}" + + echo "### Create $dir/composer.json for ${SCENARIO} scenario" + mkdir -p $dir + cp composer.json $dir + + # Then set our own platform php version if applicable (otherwise unset it) + composer -n --working-dir=$dir config platform.php "${!platform_php_variable---unset}" + + # Temporarily set our vendor directory to 'vendor' + composer -n --working-dir=$dir config vendor-dir vendor + + # Set an appropriate minimum stability for this version of Symfony + composer -n --working-dir=$dir config minimum-stability "${!stability_variable-stable}" + + # Add a constraint to limit the Symfony version + composer -n --working-dir=$dir require --dev --no-update "${!requirement_variable}" + + # Create the composer.lock file. Ignore the vendor directory created. + composer -n --working-dir=$dir update --no-scripts + + # Set the vendor directory to its final desired location. + composer -n --working-dir=$dir config vendor-dir '../../vendor' + + # The 'autoload' section specifies directory paths that are relative + # to the composer.json file. We will drop in some symlinks so that + # these paths will resolve as if the composer.json were in the root. + for target in $AUTOLOAD_DIRECTORIES ; do + ln -s -f ../../$target $dir + done + +done diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/scenarios b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/scenarios new file mode 100755 index 00000000..6a8f81b2 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/scripts/scenarios @@ -0,0 +1,12 @@ +#!/bin/bash + +SCENARIOS="symfony2 symfony3 symfony4" + +AUTOLOAD_DIRECTORIES='src tests' + +platform_php_symfony2='5.4' +platform_php_symfony3='5.6' + +requirement_symfony2='symfony/console:^2.8' +requirement_symfony3='symfony/console:^3' +requirement_symfony4='symfony/console:^4' diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/ApplyConfigTestTarget.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/ApplyConfigTestTarget.php new file mode 100644 index 00000000..6dace2be --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/ApplyConfigTestTarget.php @@ -0,0 +1,43 @@ +dir = $dir; + return $this; + } + + /** + * A getter for the 'dir' property that we will use to + * determine if the setter was called. + */ + public function getDir() + { + return $this->dir; + } + + /** + * A bad setter that does not return $this. + */ + public function bad($value) + { + $this->value = $value; + } + + /** + * A getter for the bad setter. + */ + public function getBad() + { + return $this->value; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/MyFooCommand.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/MyFooCommand.php new file mode 100644 index 00000000..0487a024 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/MyFooCommand.php @@ -0,0 +1,47 @@ +setName('my:foo') + ->setDescription('My foo command.') + ->setHelp('This command tests command option injection by echoing its options') + ->addOption( + 'other', + null, + InputOption::VALUE_REQUIRED, + 'Some other option', + 'fish' + ) + ->addOption( + 'name', + null, + InputOption::VALUE_REQUIRED, + 'What is the name of the thing we are naming', + 'George' + ) + ->addOption( + 'dir', + null, + InputOption::VALUE_REQUIRED, + 'What is the base directory to use for this command', + '/default/path' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->writeln('Enter my:foo'); + $output->writeln('dir: ' . $input->getOption('dir')); + $output->writeln('name: ' . $input->getOption('name')); + $output->writeln('other: ' . $input->getOption('other')); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/TestLoader.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/TestLoader.php new file mode 100644 index 00000000..241e5120 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony2/tests/src/TestLoader.php @@ -0,0 +1,36 @@ +data = $data; + } + + public function setSourceName($name) + { + $this->sourceName = $name; + } + + public function export() + { + return $this->data; + } + + public function keys() + { + return array_keys($this->data); + } + + public function getSourceName() + { + return $this->sourceName; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src deleted file mode 120000 index 929cb3dc..00000000 --- a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src +++ /dev/null @@ -1 +0,0 @@ -../../src \ No newline at end of file diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Config.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Config.php new file mode 100644 index 00000000..25f714f2 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Config.php @@ -0,0 +1,157 @@ +config = new Data($data); + $this->setDefaults(new Data()); + } + + /** + * {@inheritdoc} + */ + public function has($key) + { + return ($this->config->has($key)); + } + + /** + * {@inheritdoc} + */ + public function get($key, $defaultFallback = null) + { + if ($this->has($key)) { + return $this->config->get($key); + } + return $this->getDefault($key, $defaultFallback); + } + + /** + * {@inheritdoc} + */ + public function set($key, $value) + { + $this->config->set($key, $value); + return $this; + } + + /** + * {@inheritdoc} + */ + public function import($data) + { + return $this->replace($data); + } + + /** + * {@inheritdoc} + */ + public function replace($data) + { + $this->config = new Data($data); + return $this; + } + + /** + * {@inheritdoc} + */ + public function combine($data) + { + if (!empty($data)) { + $this->config->import($data, true); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function export() + { + return $this->config->export(); + } + + /** + * {@inheritdoc} + */ + public function hasDefault($key) + { + return $this->getDefaults()->has($key); + } + + /** + * {@inheritdoc} + */ + public function getDefault($key, $defaultFallback = null) + { + return $this->hasDefault($key) ? $this->getDefaults()->get($key) : $defaultFallback; + } + + /** + * {@inheritdoc} + */ + public function setDefault($key, $value) + { + $this->getDefaults()->set($key, $value); + return $this; + } + + /** + * Return the class $defaults property and ensure it's a Data object + * TODO: remove Data object validation in 2.0 + * + * @return Data + */ + protected function getDefaults() + { + // Ensure $this->defaults is a Data object (not an array) + if (!$this->defaults instanceof Data) { + $this->setDefaults($this->defaults); + } + return $this->defaults; + } + + /** + * Sets the $defaults class parameter + * TODO: remove support for array in 2.0 as this would currently break backward compatibility + * + * @param Data|array $defaults + * + * @throws \Exception + */ + protected function setDefaults($defaults) + { + if (is_array($defaults)) { + $this->defaults = new Data($defaults); + } elseif ($defaults instanceof Data) { + $this->defaults = $defaults; + } else { + throw new \Exception("Unknown type provided for \$defaults"); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/ConfigInterface.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/ConfigInterface.php new file mode 100644 index 00000000..5124ea1f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/ConfigInterface.php @@ -0,0 +1,105 @@ + default-value + */ + public function getGlobalOptionDefaultValues(); +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Inject/ConfigForCommand.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Inject/ConfigForCommand.php new file mode 100644 index 00000000..ce2646e1 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Inject/ConfigForCommand.php @@ -0,0 +1,127 @@ +config = $config; + } + + public function setApplication(Application $application) + { + $this->application = $application; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return [ConsoleEvents::COMMAND => 'injectConfiguration']; + } + + /** + * Before a Console command runs, inject configuration settings + * for this command into the default value of the options of + * this command. + * + * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event + */ + public function injectConfiguration(ConsoleCommandEvent $event) + { + $command = $event->getCommand(); + $this->injectConfigurationForGlobalOptions($event->getInput()); + $this->injectConfigurationForCommand($command, $event->getInput()); + + $targetOfHelpCommand = $this->getHelpCommandTarget($command, $event->getInput()); + if ($targetOfHelpCommand) { + $this->injectConfigurationForCommand($targetOfHelpCommand, $event->getInput()); + } + } + + protected function injectConfigurationForGlobalOptions($input) + { + if (!$this->application) { + return; + } + + $configGroup = new ConfigFallback($this->config, 'options'); + + $definition = $this->application->getDefinition(); + $options = $definition->getOptions(); + + return $this->injectConfigGroupIntoOptions($configGroup, $options, $input); + } + + protected function injectConfigurationForCommand($command, $input) + { + $commandName = $command->getName(); + $commandName = str_replace(':', '.', $commandName); + $configGroup = new ConfigFallback($this->config, $commandName, 'command.', '.options.'); + + $definition = $command->getDefinition(); + $options = $definition->getOptions(); + + return $this->injectConfigGroupIntoOptions($configGroup, $options, $input); + } + + protected function injectConfigGroupIntoOptions($configGroup, $options, $input) + { + foreach ($options as $option => $inputOption) { + $key = str_replace('.', '-', $option); + $value = $configGroup->get($key); + if ($value !== null) { + if (is_bool($value) && ($value == true)) { + $input->setOption($key, $value); + } elseif ($inputOption->acceptValue()) { + $inputOption->setDefault($value); + } + } + } + } + + protected function getHelpCommandTarget($command, $input) + { + if (($command->getName() != 'help') || (!isset($this->application))) { + return false; + } + + $this->fixInputForSymfony2($command, $input); + + // Symfony Console helpfully swaps 'command_name' and 'command' + // depending on whether the user entered `help foo` or `--help foo`. + // One of these is always `help`, and the other is the command we + // are actually interested in. + $nameOfCommandToDescribe = $input->getArgument('command_name'); + if ($nameOfCommandToDescribe == 'help') { + $nameOfCommandToDescribe = $input->getArgument('command'); + } + return $this->application->find($nameOfCommandToDescribe); + } + + protected function fixInputForSymfony2($command, $input) + { + // Symfony 3.x prepares $input for us; Symfony 2.x, on the other + // hand, passes it in prior to binding with the command definition, + // so we have to go to a little extra work. It may be inadvisable + // to do these steps for commands other than 'help'. + if (!$input->hasArgument('command_name')) { + $command->ignoreValidationErrors(); + $command->mergeApplicationDefinition(); + $input->bind($command->getDefinition()); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Inject/ConfigForSetters.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Inject/ConfigForSetters.php new file mode 100644 index 00000000..5ec87042 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Inject/ConfigForSetters.php @@ -0,0 +1,47 @@ +config = new ConfigMerge($config, $group, $prefix, $postfix); + } + + public function apply($object, $configurationKey) + { + $settings = $this->config->get($configurationKey); + foreach ($settings as $setterMethod => $args) { + $fn = [$object, $setterMethod]; + if (is_callable($fn)) { + $result = call_user_func_array($fn, (array)$args); + + // We require that $fn must only be used with setter methods. + // Setter methods are required to always return $this so that + // they may be chained. We will therefore throw an exception + // for any setter that returns something else. + if ($result != $object) { + $methodDescription = get_class($object) . "::$setterMethod"; + $propertyDescription = $this->config->describe($configurationKey); + throw new \Exception("$methodDescription did not return '\$this' when processing $propertyDescription."); + } + } + } + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigLoader.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigLoader.php new file mode 100644 index 00000000..ecc6f64f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigLoader.php @@ -0,0 +1,35 @@ +source; + } + + protected function setSourceName($source) + { + $this->source = $source; + return $this; + } + + public function export() + { + return $this->config; + } + + public function keys() + { + return array_keys($this->config); + } + + abstract public function load($path); +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigLoaderInterface.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigLoaderInterface.php new file mode 100644 index 00000000..9b155c1b --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/ConfigLoaderInterface.php @@ -0,0 +1,29 @@ +expander = $expander ?: new Expander(); + } + + /** + * Extend the configuration to be processed with the + * configuration provided by the specified loader. + * + * @param ConfigLoaderInterface $loader + */ + public function extend(ConfigLoaderInterface $loader) + { + return $this->addFromSource($loader->export(), $loader->getSourceName()); + } + + /** + * Extend the configuration to be processed with + * the provided nested array. + * + * @param array $data + */ + public function add($data) + { + $this->unprocessedConfig[] = $data; + return $this; + } + + /** + * Extend the configuration to be processed with + * the provided nested array. Also record the name + * of the data source, if applicable. + * + * @param array $data + * @param string $source + */ + protected function addFromSource($data, $source = '') + { + if (empty($source)) { + return $this->add($data); + } + $this->unprocessedConfig[$source] = $data; + return $this; + } + + /** + * Process all of the configuration that has been collected, + * and return a nested array. + * + * @return array + */ + public function export($referenceArray = []) + { + if (!empty($this->unprocessedConfig)) { + $this->processedConfig = $this->process( + $this->processedConfig, + $this->fetchUnprocessed(), + $referenceArray + ); + } + return $this->processedConfig; + } + + /** + * To aid in debugging: return the source of each configuration item. + * n.b. Must call this function *before* export and save the result + * if persistence is desired. + */ + public function sources() + { + $sources = []; + foreach ($this->unprocessedConfig as $sourceName => $config) { + if (!empty($sourceName)) { + $configSources = ArrayUtil::fillRecursive($config, $sourceName); + $sources = ArrayUtil::mergeRecursiveDistinct($sources, $configSources); + } + } + return $sources; + } + + /** + * Get the configuration to be processed, and clear out the + * 'unprocessed' list. + * + * @return array + */ + protected function fetchUnprocessed() + { + $toBeProcessed = $this->unprocessedConfig; + $this->unprocessedConfig = []; + return $toBeProcessed; + } + + /** + * Use a map-reduce to evaluate the items to be processed, + * and merge them into the processed array. + * + * @param array $processed + * @param array $toBeProcessed + * @return array + */ + protected function process(array $processed, array $toBeProcessed, $referenceArray = []) + { + $toBeReduced = array_map([$this, 'preprocess'], $toBeProcessed); + $reduced = array_reduce($toBeReduced, [$this, 'reduceOne'], $processed); + return $this->evaluate($reduced, $referenceArray); + } + + /** + * Process a single configuration file from the 'to be processed' + * list. By default this is a no-op. Override this method to + * provide any desired configuration preprocessing, e.g. dot-notation + * expansion of the configuration keys, etc. + * + * @param array $config + * @return array + */ + protected function preprocess(array $config) + { + return $config; + } + + /** + * Evaluate one item in the 'to be evaluated' list, and then + * merge it into the processed configuration (the 'carry'). + * + * @param array $processed + * @param array $config + * @return array + */ + protected function reduceOne(array $processed, array $config) + { + return ArrayUtil::mergeRecursiveDistinct($processed, $config); + } + + /** + * Evaluate one configuration item. + * + * @param array $processed + * @param array $config + * @return array + */ + protected function evaluate(array $config, $referenceArray = []) + { + return $this->expander->expandArrayProperties( + $config, + $referenceArray + ); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/YamlConfigLoader.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/YamlConfigLoader.php new file mode 100644 index 00000000..45705662 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Loader/YamlConfigLoader.php @@ -0,0 +1,26 @@ +setSourceName($path); + + // We silently skip any nonexistent config files, so that + // clients may simply `load` all of their candidates. + if (!file_exists($path)) { + $this->config = []; + return $this; + } + $this->config = (array) Yaml::parse(file_get_contents($path)); + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ArrayUtil.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ArrayUtil.php new file mode 100644 index 00000000..a23f854e --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ArrayUtil.php @@ -0,0 +1,75 @@ + &$value) { + $merged[$key] = self::mergeRecursiveValue($merged, $key, $value); + } + return $merged; + } + + /** + * Process the value in an mergeRecursiveDistinct - make a recursive + * call if needed. + */ + protected static function mergeRecursiveValue(&$merged, $key, $value) + { + if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) { + return self::mergeRecursiveDistinct($merged[$key], $value); + } + return $value; + } + + /** + * Fills all of the leaf-node values of a nested array with the + * provided replacement value. + */ + public static function fillRecursive(array $data, $fill) + { + $result = []; + foreach ($data as $key => $value) { + $result[$key] = $fill; + if (self::isAssociative($value)) { + $result[$key] = self::fillRecursive($value, $fill); + } + } + return $result; + } + + /** + * Return true if the provided parameter is an array, and at least + * one key is non-numeric. + */ + public static function isAssociative($testArray) + { + if (!is_array($testArray)) { + return false; + } + foreach (array_keys($testArray) as $key) { + if (!is_numeric($key)) { + return true; + } + } + return false; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigFallback.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigFallback.php new file mode 100644 index 00000000..9f9972f6 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigFallback.php @@ -0,0 +1,51 @@ +getWithFallback($key, $this->group, $this->prefix, $this->postfix); + } + + /** + * Fetch an option value from a given key, or, if that specific key does + * not contain a value, then consult various fallback options until a + * value is found. + * + */ + protected function getWithFallback($key, $group, $prefix = '', $postfix = '.') + { + $configKey = "{$prefix}{$group}${postfix}{$key}"; + if ($this->config->has($configKey)) { + return $this->config->get($configKey); + } + if ($this->config->hasDefault($configKey)) { + return $this->config->getDefault($configKey); + } + $moreGeneralGroupname = $this->moreGeneralGroupName($group); + if ($moreGeneralGroupname) { + return $this->getWithFallback($key, $moreGeneralGroupname, $prefix, $postfix); + } + return null; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigGroup.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigGroup.php new file mode 100644 index 00000000..24b29dd8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigGroup.php @@ -0,0 +1,61 @@ +config = $config; + $this->group = $group; + $this->prefix = $prefix; + $this->postfix = $postfix; + } + + /** + * Return a description of the configuration group (with prefix and postfix). + */ + public function describe($property) + { + return $this->prefix . $this->group . $this->postfix . $property; + } + + /** + * Get the requested configuration key from the most specific configuration + * group that contains it. + */ + abstract public function get($key); + + /** + * Given a group name, such as "foo.bar.baz", return the next configuration + * group in the fallback hierarchy, e.g. "foo.bar". + */ + protected function moreGeneralGroupName($group) + { + $result = preg_replace('#\.[^.]*$#', '', $group); + if ($result != $group) { + return $result; + } + return false; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigMerge.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigMerge.php new file mode 100644 index 00000000..65fccf72 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigMerge.php @@ -0,0 +1,34 @@ +getWithMerge($key, $this->group, $this->prefix, $this->postfix); + } + + /** + * Merge available configuration from each configuration group. + */ + public function getWithMerge($key, $group, $prefix = '', $postfix = '.') + { + $configKey = "{$prefix}{$group}${postfix}{$key}"; + $result = $this->config->get($configKey, []); + if (!is_array($result)) { + throw new \UnexpectedValueException($configKey . ' must be a list of settings to apply.'); + } + $moreGeneralGroupname = $this->moreGeneralGroupName($group); + if ($moreGeneralGroupname) { + $result += $this->getWithMerge($key, $moreGeneralGroupname, $prefix, $postfix); + } + return $result; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigOverlay.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigOverlay.php new file mode 100644 index 00000000..d1f12697 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/ConfigOverlay.php @@ -0,0 +1,203 @@ +contexts[self::DEFAULT_CONTEXT] = new Config(); + $this->contexts[self::PROCESS_CONTEXT] = new Config(); + } + + /** + * Add a named configuration object to the configuration overlay. + * Configuration objects added LAST have HIGHEST priority, with the + * exception of the fact that the process context always has the + * highest priority. + * + * If a context has already been added, its priority will not change. + */ + public function addContext($name, ConfigInterface $config) + { + $process = $this->contexts[self::PROCESS_CONTEXT]; + unset($this->contexts[self::PROCESS_CONTEXT]); + $this->contexts[$name] = $config; + $this->contexts[self::PROCESS_CONTEXT] = $process; + + return $this; + } + + /** + * Add a placeholder context that will be prioritized higher than + * existing contexts. This is done to ensure that contexts added + * later will maintain a higher priority if the placeholder context + * is later relaced with a different configuration set via addContext(). + * + * @param string $name + * @return $this + */ + public function addPlaceholder($name) + { + return $this->addContext($name, new Config()); + } + + /** + * Increase the priority of the named context such that it is higher + * in priority than any existing context except for the 'process' + * context. + * + * @param string $name + * @return $this + */ + public function increasePriority($name) + { + $config = $this->getContext($name); + unset($this->contexts[$name]); + return $this->addContext($name, $config); + } + + public function hasContext($name) + { + return isset($this->contexts[$name]); + } + + public function getContext($name) + { + if ($this->hasContext($name)) { + return $this->contexts[$name]; + } + return new Config(); + } + + public function removeContext($name) + { + unset($this->contexts[$name]); + } + + /** + * Determine if a non-default config value exists. + */ + public function findContext($key) + { + foreach (array_reverse($this->contexts) as $name => $config) { + if ($config->has($key)) { + return $config; + } + } + return false; + } + + /** + * @inheritdoc + */ + public function has($key) + { + return $this->findContext($key) != false; + } + + /** + * @inheritdoc + */ + public function get($key, $default = null) + { + $context = $this->findContext($key); + if ($context) { + return $context->get($key, $default); + } + return $default; + } + + /** + * @inheritdoc + */ + public function set($key, $value) + { + $this->contexts[self::PROCESS_CONTEXT]->set($key, $value); + return $this; + } + + /** + * @inheritdoc + */ + public function import($data) + { + $this->unsupported(__FUNCTION__); + } + + /** + * @inheritdoc + */ + public function replace($data) + { + $this->unsupported(__FUNCTION__); + } + + /** + * @inheritdoc + */ + public function combine($data) + { + $this->unsupported(__FUNCTION__); + } + + /** + * @inheritdoc + */ + protected function unsupported($fn) + { + throw new \Exception("The method '$fn' is not supported for the ConfigOverlay class."); + } + + /** + * @inheritdoc + */ + public function export() + { + $export = []; + foreach ($this->contexts as $name => $config) { + $export = array_merge_recursive($export, $config->export()); + } + return $export; + } + + /** + * @inheritdoc + */ + public function hasDefault($key) + { + return $this->contexts[self::DEFAULT_CONTEXT]->has($key); + } + + /** + * @inheritdoc + */ + public function getDefault($key, $default = null) + { + return $this->contexts[self::DEFAULT_CONTEXT]->get($key, $default); + } + + /** + * @inheritdoc + */ + public function setDefault($key, $value) + { + $this->contexts[self::DEFAULT_CONTEXT]->set($key, $value); + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/EnvConfig.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/EnvConfig.php new file mode 100644 index 00000000..05f8d2a8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/src/Util/EnvConfig.php @@ -0,0 +1,96 @@ +prefix = strtoupper(rtrim($prefix, '_')) . '_'; + } + + /** + * @inheritdoc + */ + public function has($key) + { + return $this->get($key) !== null; + } + + /** + * @inheritdoc + */ + public function get($key, $defaultFallback = null) + { + $envKey = $this->prefix . strtoupper(strtr($key, '.-', '__')); + $envKey = str_replace($this->prefix . $this->prefix, $this->prefix, $envKey); + return getenv($envKey) ?: $defaultFallback; + } + + /** + * @inheritdoc + */ + public function set($key, $value) + { + throw new \Exception('Cannot call "set" on environmental configuration.'); + } + + /** + * @inheritdoc + */ + public function import($data) + { + // no-op + } + + /** + * @inheritdoc + */ + public function export() + { + return []; + } + + /** + * @inheritdoc + */ + public function hasDefault($key) + { + return false; + } + + /** + * @inheritdoc + */ + public function getDefault($key, $defaultFallback = null) + { + return $defaultFallback; + } + + /** + * @inheritdoc + */ + public function setDefault($key, $value) + { + throw new \Exception('Cannot call "setDefault" on environmental configuration.'); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests deleted file mode 120000 index c2ebfe53..00000000 --- a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests +++ /dev/null @@ -1 +0,0 @@ -../../tests \ No newline at end of file diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigForCommandTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigForCommandTest.php new file mode 100644 index 00000000..41da3076 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigForCommandTest.php @@ -0,0 +1,130 @@ + [ + 'global' => 'from-config', + ], + // Define some configuration settings for the options for + // the commands my:foo and my:bar. + 'command' => [ + 'my' => [ + // commands.my.options.* apply to all my:* commands. + 'options' => [ + 'dir' => '/etc/common', + 'priority' => 'normal', + ], + 'foo' => [ + // commands.my.foo.options.* apply only to the my:foo command. + 'options' => [ + 'name' => 'baz', + ], + ], + ], + ], + ]; + + $this->config = new Config($data); + } + + public function testInjection() + { + $command = new MyFooCommand(); + $input = new StringInput('my:foo'); + + list($status, $output) = $this->runCommandViaApplication($command, $input); + + $expectedOutput = <<< EOT +Enter my:foo +dir: /etc/common +name: baz +other: fish +EOT; + + $this->assertEquals(0, $status); + $this->assertEquals($expectedOutput, $output); + } + + public function testInjectionWithOverride() + { + $command = new MyFooCommand(); + $input = new StringInput('my:foo --name=Fred'); + + list($status, $output) = $this->runCommandViaApplication($command, $input); + + $expectedOutput = <<< EOT +Enter my:foo +dir: /etc/common +name: Fred +other: fish +EOT; + + $this->assertEquals(0, $status); + $this->assertEquals($expectedOutput, $output); + } + + public function testHelpDefaultInjection() + { + $command = new MyFooCommand(); + $input = new StringInput('help my:foo'); + + list($status, $output) = $this->runCommandViaApplication($command, $input); + + $expectedOutput = <<< EOT +What is the name of the thing we are naming [default: "baz"] +EOT; + + $this->assertEquals(0, $status); + $this->assertContains($expectedOutput, $output); + + $expectedOutput = <<< EOT +A certain global option. [default: "from-config"] +EOT; + + $this->assertContains($expectedOutput, $output); + } + + protected function runCommandViaApplication($command, $input) + { + $application = new Application('TestApplication', '0.0.0'); + $application->getDefinition() + ->addOption( + new InputOption('--global', null, InputOption::VALUE_REQUIRED, 'A certain global option.', 'hardcoded') + ); + + $output = new BufferedOutput(); + + $configInjector = new ConfigForCommand($this->config); + $configInjector->setApplication($application); + + $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher(); + $eventDispatcher->addSubscriber($configInjector); + $application->setDispatcher($eventDispatcher); + + $application->setAutoExit(false); + $application->add($command); + + $statusCode = $application->run($input, $output); + $commandOutput = trim($output->fetch()); + + return [$statusCode, $commandOutput]; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigForSettersTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigForSettersTest.php new file mode 100644 index 00000000..422b0a00 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigForSettersTest.php @@ -0,0 +1,87 @@ + [ + 'Operations' => [ + // task.Operations.settings apply to all tasks in + // any *.Tass.Operations namespace. + 'settings' => [ + 'dir' => '/base/dir', + ], + 'Frobulate' => [ + // task.Operations.Frobulate.settings applies only + // the Frobulate task. + 'settings' => [ + 'dir' => '/override/dir', + ], + ], + ], + ], + ]; + $config = new Config($data); + + $applicator = new ConfigForSetters($config, 'Operations.Frobulate', 'task.'); + + $testTarget = new ApplyConfigTestTarget(); + + $applicator->apply($testTarget, 'settings'); + + $this->assertEquals('/override/dir', $testTarget->getDir()); + $this->assertEquals(null, $testTarget->getBad()); + } + + public function testApplyBadConfig() + { + $data = [ + // Define some configuration settings for the configuration + // of some task \My\Tasks\Operations\Frobulate. + 'task' => [ + 'Operations' => [ + // task.Operations.settings apply to all tasks in + // any *.Tass.Operations namespace. + 'settings' => [ + 'dir' => '/base/dir', + ], + 'Frobulate' => [ + // task.Operations.Frobulate.settings applies only + // the Frobulate task. + 'settings' => [ + 'bad' => 'fire truck', + ], + ], + ], + ], + ]; + $config = new Config($data); + + $applicator = new ConfigForSetters($config, 'Operations.Frobulate', 'task.'); + + $testTarget = new ApplyConfigTestTarget(); + + $exceptionMessage = ''; + try + { + $applicator->apply($testTarget, 'settings'); + } + catch (\Exception $e) + { + $exceptionMessage = $e->getMessage(); + } + // We would prefer it if bad methods were never called; unfortunately, + // declaring the return type of a method cannot be done in a reliable + // way (via reflection) until php 7, so we allow these methods to be + // called for now. + $this->assertEquals('fire truck', $testTarget->getBad()); + $this->assertEquals('Consolidation\\TestUtils\\ApplyConfigTestTarget::bad did not return \'$this\' when processing task.Operations.Frobulate.settings.', $exceptionMessage); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigGroupTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigGroupTest.php new file mode 100644 index 00000000..21e470e5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigGroupTest.php @@ -0,0 +1,91 @@ + [ + 'my' => [ + // commands.my.options.* apply to all my:* commands. + 'options' => [ + 'path' => '/etc/common', + 'priority' => 'normal', + ], + 'foo' => [ + // commands.my.foo.options.* apply only to the my:foo command. + 'options' => [ + 'name' => 'baz', + ], + ], + 'bar' => [ + // Similarly, commands.my.bar.options is for the my:bar command. + 'options' => [ + 'priority' => 'high', + ], + ], + ], + ], + // Define some configuration settings for the configuration + // of some task \My\Tasks\Operations\Frobulate. + 'task' => [ + 'Operations' => [ + // task.Operations.settings apply to all tasks in + // any *.Tass.Operations namespace. + 'settings' => [ + 'dir' => '/base/dir', + ], + 'Frobulate' => [ + // task.Operations.Frobulate.settings applies only + // the Frobulate task. + 'settings' => [ + 'object' => 'fire truck', + ], + ], + ], + ], + ]; + + $this->config = new Config($data); + } + + public function testDotNotation() + { + // Test the test + $this->assertEquals('baz', $this->config->get('command.my.foo.options.name')); + } + + public function testFallback() + { + $fooFallback = new ConfigFallback($this->config, 'my.foo', 'command.', '.options.'); + $barFallback = new ConfigFallback($this->config, 'my.bar', 'command.', '.options.'); + + $this->assertEquals(null, $barFallback->get('name')); + $this->assertEquals('baz', $fooFallback->get('name')); + $this->assertEquals('high', $barFallback->get('priority')); + + $this->assertEquals('normal', $fooFallback->get('priority')); + $this->assertEquals('/etc/common', $barFallback->get('path')); + $this->assertEquals('/etc/common', $fooFallback->get('path')); + } + + public function testMerge() + { + $frobulateMerge = new ConfigMerge($this->config, 'Operations.Frobulate', 'task.'); + + $settings = $frobulateMerge->get('settings'); + $this->assertEquals('fire truck', $settings['object']); + $this->assertEquals('/base/dir', $settings['dir']); + $keys = array_keys($settings); + sort($keys); + $this->assertEquals('dir,object', implode(',', $keys)); + } +} + diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigLoaderTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigLoaderTest.php new file mode 100644 index 00000000..6dedb1f3 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigLoaderTest.php @@ -0,0 +1,29 @@ +assertTrue(file_exists($path)); + + $loader->load($path); + + $configFile = basename($loader->getSourceName()); + $this->assertEquals('config-1.yml', $configFile); + + // Make sure that the data we loaded contained the expected keys + $keys = $loader->keys(); + sort($keys); + $keysString = implode(',', $keys); + $this->assertEquals('c,m', $keysString); + + $configData = $loader->export(); + $this->assertEquals('foo', $configData['c']); + $this->assertEquals('1', $configData['m'][0]); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigOverlayTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigOverlayTest.php new file mode 100644 index 00000000..f7faf748 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigOverlayTest.php @@ -0,0 +1,168 @@ +import([ + 'hidden-by-a' => 'alias hidden-by-a', + 'hidden-by-process' => 'alias hidden-by-process', + 'options' =>[ + 'a-a' => 'alias-a', + ], + 'command' => [ + 'foo' => [ + 'bar' => [ + 'command' => [ + 'options' => [ + 'a-b' => 'alias-b', + ], + ], + ], + ], + ], + ]); + + $configFileContext = new Config(); + $configFileContext->import([ + 'hidden-by-cf' => 'config-file hidden-by-cf', + 'hidden-by-a' => 'config-file hidden-by-a', + 'hidden-by-process' => 'config-file hidden-by-process', + 'options' =>[ + 'cf-a' => 'config-file-a', + ], + 'command' => [ + 'foo' => [ + 'bar' => [ + 'command' => [ + 'options' => [ + 'cf-b' => 'config-file-b', + ], + ], + ], + ], + ], + ]); + + $this->overlay = new ConfigOverlay(); + $this->overlay->set('hidden-by-process', 'process-h'); + $this->overlay->addContext('cf', $configFileContext); + $this->overlay->addContext('a', $aliasContext); + $this->overlay->setDefault('df-a', 'default'); + $this->overlay->setDefault('hidden-by-a', 'default hidden-by-a'); + $this->overlay->setDefault('hidden-by-cf', 'default hidden-by-cf'); + $this->overlay->setDefault('hidden-by-process', 'default hidden-by-process'); + } + + public function testGetPriority() + { + $this->assertEquals('process-h', $this->overlay->get('hidden-by-process')); + $this->assertEquals('config-file hidden-by-cf', $this->overlay->get('hidden-by-cf')); + $this->assertEquals('alias hidden-by-a', $this->overlay->get('hidden-by-a')); + } + + public function testDefault() + { + $this->assertEquals('alias-a', $this->overlay->get('options.a-a')); + $this->assertEquals('alias-a', $this->overlay->get('options.a-a', 'ignored')); + $this->assertEquals('default', $this->overlay->getDefault('df-a', 'ignored')); + $this->assertEquals('nsv', $this->overlay->getDefault('a-a', 'nsv')); + + $this->overlay->setDefault('df-a', 'new value'); + $this->assertEquals('new value', $this->overlay->getDefault('df-a', 'ignored')); + } + + public function testExport() + { + $data = $this->overlay->export(); + + $this->assertEquals('config-file-a', $data['options']['cf-a']); + $this->assertEquals('alias-a', $data['options']['a-a']); + } + + /** + * @expectedException Exception + */ + public function testImport() + { + $data = $this->overlay->import(['a' => 'value']); + } + + public function testMaintainPriority() + { + // Get and re-add the 'cf' context. Its priority should not change. + $configFileContext = $this->overlay->getContext('cf'); + $this->overlay->addContext('cf', $configFileContext); + + // These asserts are the same as in testGetPriority + $this->assertEquals('process-h', $this->overlay->get('hidden-by-process')); + $this->assertEquals('config-file hidden-by-cf', $this->overlay->get('hidden-by-cf')); + $this->assertEquals('alias hidden-by-a', $this->overlay->get('hidden-by-a')); + } + + public function testChangePriority() + { + // Increase the priority of the 'cf' context. Now, it should have a higher + // priority than the 'alias' context, but should still have a lower + // priority than the 'process' context. + $this->overlay->increasePriority('cf'); + + // These asserts are the same as in testGetPriority + $this->assertEquals('process-h', $this->overlay->get('hidden-by-process')); + $this->assertEquals('config-file hidden-by-cf', $this->overlay->get('hidden-by-cf')); + + // This one has changed: the config-file value is now found instead + // of the alias value. + $this->assertEquals('config-file hidden-by-a', $this->overlay->get('hidden-by-a')); + } + + public function testPlaceholder() + { + $this->overlay->addPlaceholder('lower'); + + $higherContext = new Config(); + $higherContext->import(['priority-test' => 'higher']); + + $lowerContext = new Config(); + $lowerContext->import(['priority-test' => 'lower']); + + // Usually 'lower' would have the highest priority, since it is + // added last. However, our earlier call to 'addPlaceholder' reserves + // a spot for it, so the 'higher' context will end up with a higher + // priority. + $this->overlay->addContext('higher', $higherContext); + $this->overlay->addContext('lower', $lowerContext); + $this->assertEquals('higher', $this->overlay->get('priority-test', 'neither')); + + // Test to see that we can change the value of the 'higher' context, + // and the change will be reflected in the overlay. + $higherContext->set('priority-test', 'changed'); + $this->assertEquals('changed', $this->overlay->get('priority-test', 'neither')); + + // Test to see that the 'process' context still has the highest priority. + $this->overlay->set('priority-test', 'process'); + $higherContext->set('priority-test', 'ignored'); + $this->assertEquals('process', $this->overlay->get('priority-test', 'neither')); + } + + public function testDoesNotHave() + { + $context = $this->overlay->getContext('no-such-context'); + $data = $context->export(); + $this->assertEquals('[]', json_encode($data)); + + $this->assertTrue(!$this->overlay->has('no-such-key')); + $this->assertTrue(!$this->overlay->hasDefault('no-such-default')); + + $this->assertEquals('no-such-value', $this->overlay->get('no-such-key', 'no-such-value')); + + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigProcessorTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigProcessorTest.php new file mode 100644 index 00000000..ac645a28 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigProcessorTest.php @@ -0,0 +1,152 @@ + 'foo', + 'm' => [1], + ]; + $config2 = [ + 'b' => '${c}bar', + 'm' => [2], + ]; + $config3 = [ + 'a' => '${b}baz', + 'm' => [3], + ]; + + $processor = new ConfigProcessor(); + $processor->add($config1); + $processor->add($config2); + $processor->add($config3); + + $data = $processor->export(); + $this->assertEquals('foo', $data['c']); + $this->assertEquals('foobar', $data['b']); + $this->assertEquals('foobarbaz', $data['a']); + } + + public function processorForConfigMergeTest($provideSourceNames) + { + $config1 = [ + 'm' => [ + 'x' => 'x-1', + 'y' => [ + 'r' => 'r-1', + 's' => 's-1', + 't' => 't-1', + ], + 'z' => 'z-1', + ], + ]; + $config2 = [ + 'm' => [ + 'w' => 'w-2', + 'y' => [ + 'q' => 'q-2', + 's' => 's-2', + ], + 'z' => 'z-2', + ], + ]; + $config3 = [ + 'm' => [ + 'v' => 'v-3', + 'y' => [ + 't' => 't-3', + 'u' => 'u-3', + ], + 'z' => 'z-3', + ], + ]; + + $processor = new ConfigProcessor(); + $testLoader = new TestLoader(); + + $testLoader->set($config1); + $testLoader->setSourceName($provideSourceNames ? 'c-1' : ''); + $processor->extend($testLoader); + + $testLoader->set($config2); + $testLoader->setSourceName($provideSourceNames ? 'c-2' : ''); + $processor->extend($testLoader); + + $testLoader->set($config3); + $testLoader->setSourceName($provideSourceNames ? 'c-3' : ''); + $processor->extend($testLoader); + + return $processor; + } + + public function testConfigProcessorMergeAssociative() + { + $processor = $this->processorForConfigMergeTest(false); + $data = $processor->export(); + $this->assertEquals('{"m":{"x":"x-1","y":{"r":"r-1","s":"s-2","t":"t-3","q":"q-2","u":"u-3"},"z":"z-3","w":"w-2","v":"v-3"}}', json_encode($data)); + } + + public function testConfigProcessorMergeAssociativeWithSourceNames() + { + $processor = $this->processorForConfigMergeTest(true); + $sources = $processor->sources(); + $data = $processor->export(); + $this->assertEquals('{"m":{"x":"x-1","y":{"r":"r-1","s":"s-2","t":"t-3","q":"q-2","u":"u-3"},"z":"z-3","w":"w-2","v":"v-3"}}', json_encode($data)); + $this->assertEquals('c-1', $sources['m']['x']); + $this->assertEquals('c-1', $sources['m']['y']['r']); + $this->assertEquals('c-2', $sources['m']['w']); + $this->assertEquals('c-2', $sources['m']['y']['s']); + $this->assertEquals('c-3', $sources['m']['z']); + $this->assertEquals('c-3', $sources['m']['y']['u']); + } + + public function testConfiProcessorSources() + { + $processor = new ConfigProcessor(); + $loader = new YamlConfigLoader(); + $processor->extend($loader->load(__DIR__ . '/data/config-1.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-2.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-3.yml')); + + $sources = $processor->sources(); + + $data = $processor->export(); + $this->assertEquals('foo', $data['c']); + $this->assertEquals('foobar', $data['b']); + $this->assertEquals('foobarbaz', $data['a']); + + $this->assertEquals('3', $data['m'][0]); + + $this->assertEquals( __DIR__ . '/data/config-3.yml', $sources['a']); + $this->assertEquals( __DIR__ . '/data/config-2.yml', $sources['b']); + $this->assertEquals( __DIR__ . '/data/config-1.yml', $sources['c']); + $this->assertEquals( __DIR__ . '/data/config-3.yml', $sources['m']); + } + + public function testConfiProcessorSourcesLoadInReverseOrder() + { + $processor = new ConfigProcessor(); + $loader = new YamlConfigLoader(); + $processor->extend($loader->load(__DIR__ . '/data/config-3.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-2.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-1.yml')); + + $sources = $processor->sources(); + + $data = $processor->export(); + $this->assertEquals('foo', $data['c']); + $this->assertEquals('foobar', $data['b']); + $this->assertEquals('foobarbaz', $data['a']); + + $this->assertEquals('1', $data['m'][0]); + + $this->assertEquals( __DIR__ . '/data/config-3.yml', $sources['a']); + $this->assertEquals( __DIR__ . '/data/config-2.yml', $sources['b']); + $this->assertEquals( __DIR__ . '/data/config-1.yml', $sources['c']); + $this->assertEquals( __DIR__ . '/data/config-1.yml', $sources['m']); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigTest.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigTest.php new file mode 100644 index 00000000..f2ace0ce --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/ConfigTest.php @@ -0,0 +1,140 @@ +set('foo', 'bar'); + $data = $config->export(); + $this->assertEquals('{"foo":"bar"}', json_encode($data)); + } + + public function testCombine() + { + // Pointless tests just to ensure everything is covered. + $config = new Config(); + $config->set('foo', 'bar'); + $config->set('baz', 'boz'); + $config2 = new Config(); + $config2->set('foo', 'fu'); + $config2->set('new', 'blue'); + $config->combine($config2->export()); + $this->assertEquals('fu', $config->get('foo')); + $this->assertEquals('boz', $config->get('baz')); + $this->assertEquals('blue', $config->get('new')); + } + + public function testDefault() + { + $data = [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'boz', + ]; + + $foo = ["foo" => "bar"]; + + $config = new Config($data); + + $config->setDefault('c', 'other'); + $config->setDefault('d', 'other'); + $config->setDefault('f', $foo); + + $this->assertEquals('foo', $config->get('a')); + $this->assertEquals('boz', $config->get('c')); + $this->assertEquals('other', $config->get('d')); + $this->assertEquals('other', $config->getDefault('c')); + $this->assertEquals('', $config->get('e')); + $this->assertEquals('bar', $config->get('f.foo')); + $this->assertEquals('{"foo":"bar"}', json_encode($config->get('f'))); + } + + public function testDefaultsArray() + { + $data = ['a' => 'foo', 'b' => 'bar', 'c' => 'boz',]; + $defaults = ['d' => 'foo', 'e' => 'bar', 'f' => 'boz',]; + + // Create reflection class to test private methods + $configClass = new \ReflectionClass("Consolidation\Config\Config"); + + // $defaults + $defaultsProperty = $configClass->getProperty("defaults"); + $defaultsProperty->setAccessible(true); + + // $getDefaults + $getDefaultsMethod = $configClass->getMethod("getDefaults"); + $getDefaultsMethod->setAccessible(true); + + // Test the config class + $config = new Config($data); + + // Set $config::defaults to an array to test getter and setter + $defaultsProperty->setValue($config, $defaults); + $this->assertTrue(is_array($defaultsProperty->getValue($config))); + $this->assertInstanceOf('Dflydev\DotAccessData\Data', + $getDefaultsMethod->invoke($config)); + + // Set $config::defaults to a string to test exception + $defaultsProperty->setValue($config, "foo.bar"); + $this->setExpectedException("Exception"); + $getDefaultsMethod->invoke($config); + } + + public function testConfigurationWithCrossFileReferences() + { + $config = new Config(); + $processor = new ConfigProcessor(); + $loader = new YamlConfigLoader(); + $processor->extend($loader->load(__DIR__ . '/data/config-1.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-2.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-3.yml')); + + // Does not fail if configuration file cannot be found + $processor->extend($loader->load(__DIR__ . '/data/no-such-file.yml')); + + // We must capture the sources before exporting, as export + // dumps this information. + $sources = $processor->sources(); + + $config->import($processor->export()); + + $this->assertEquals(implode(',', $config->get('m')), '3'); + $this->assertEquals($config->get('a'), 'foobarbaz'); + + $this->assertEquals($sources['a'], __DIR__ . '/data/config-3.yml'); + $this->assertEquals($sources['b'], __DIR__ . '/data/config-2.yml'); + $this->assertEquals($sources['c'], __DIR__ . '/data/config-1.yml'); + } + + public function testConfigurationWithReverseOrderCrossFileReferences() + { + $config = new Config(); + $processor = new ConfigProcessor(); + $loader = new YamlConfigLoader(); + $processor->extend($loader->load(__DIR__ . '/data/config-3.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-2.yml')); + $processor->extend($loader->load(__DIR__ . '/data/config-1.yml')); + + $sources = $processor->sources(); + $config->import($processor->export()); + + $this->assertEquals(implode(',', $config->get('m')), '1'); + + if (strpos($config->get('a'), '$') !== false) { + throw new \PHPUnit_Framework_SkippedTestError( + 'Evaluation of cross-file references in reverse order not supported.' + ); + } + $this->assertEquals($config->get('a'), 'foobarbaz'); + + $this->assertEquals($sources['a'], __DIR__ . '/data/config-3.yml'); + $this->assertEquals($sources['b'], __DIR__ . '/data/config-2.yml'); + $this->assertEquals($sources['c'], __DIR__ . '/data/config-1.yml'); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-1.yml b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-1.yml new file mode 100644 index 00000000..e8f55a9d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-1.yml @@ -0,0 +1,3 @@ +c: foo +m: + - 1 diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-2.yml b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-2.yml new file mode 100644 index 00000000..baa7e63f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-2.yml @@ -0,0 +1,3 @@ +b: ${c}bar +m: + - 2 diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-3.yml b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-3.yml new file mode 100644 index 00000000..d5895642 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/data/config-3.yml @@ -0,0 +1,3 @@ +a: ${b}baz +m: + - 3 diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/install-scenario b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/install-scenario new file mode 100755 index 00000000..d77d57d0 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/install-scenario @@ -0,0 +1,23 @@ +#!/bin/bash + +SCENARIO=$1 +ACTION=${2-install} + +dir=dependencies/${SCENARIO} +if [ -z "$SCENARIO" ] ; then + SCENARIO=default + dir=. +fi + + +if [ ! -d "$dir" ] ; then + echo "Requested scenario '${SCENARIO}' does not exist." + exit 1 +fi + +echo "Switch to ${SCENARIO} scenario" + +set -ex + +composer -n --working-dir=$dir ${ACTION} --prefer-dist --no-scripts +composer -n --working-dir=$dir info diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/prep-dependencies b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/prep-dependencies new file mode 100755 index 00000000..d1898440 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/prep-dependencies @@ -0,0 +1,66 @@ +#!/bin/bash + +# +# This script is called automatically on every `composer update`. +# See "post-update-cmd" in the "scripts" section of composer.json. +# +# This script will create a derived composer.json / composer.lock +# pair for every test scenario. Test scenarios are defined in the +# "scenarios" file, which should be customized to suit the needs +# of the project. +# + +SELF_DIRNAME="`dirname -- "$0"`" +source ${SELF_DIRNAME}/scenarios + +echo +echo "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" +echo "::" +echo ":: Update dependencies for the following scenarios:" +echo "::" +echo ":: ${SCENARIOS}" +echo "::" +echo "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" +echo + +set -ex + +for SCENARIO in ${SCENARIOS} ; do + + dir=dependencies/${SCENARIO} + + # Define indirect variable names + stability_variable="stability_${SCENARIO}" + requirement_variable="requirement_${SCENARIO}" + platform_php_variable="platform_php_${SCENARIO}" + + echo "### Create $dir/composer.json for ${SCENARIO} scenario" + mkdir -p $dir + cp composer.json $dir + + # Then set our own platform php version if applicable (otherwise unset it) + composer -n --working-dir=$dir config platform.php "${!platform_php_variable---unset}" + + # Temporarily set our vendor directory to 'vendor' + composer -n --working-dir=$dir config vendor-dir vendor + + # Set an appropriate minimum stability for this version of Symfony + composer -n --working-dir=$dir config minimum-stability "${!stability_variable-stable}" + + # Add a constraint to limit the Symfony version + composer -n --working-dir=$dir require --dev --no-update "${!requirement_variable}" + + # Create the composer.lock file. Ignore the vendor directory created. + composer -n --working-dir=$dir update --no-scripts + + # Set the vendor directory to its final desired location. + composer -n --working-dir=$dir config vendor-dir '../../vendor' + + # The 'autoload' section specifies directory paths that are relative + # to the composer.json file. We will drop in some symlinks so that + # these paths will resolve as if the composer.json were in the root. + for target in $AUTOLOAD_DIRECTORIES ; do + ln -s -f ../../$target $dir + done + +done diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/scenarios b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/scenarios new file mode 100755 index 00000000..6a8f81b2 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/scripts/scenarios @@ -0,0 +1,12 @@ +#!/bin/bash + +SCENARIOS="symfony2 symfony3 symfony4" + +AUTOLOAD_DIRECTORIES='src tests' + +platform_php_symfony2='5.4' +platform_php_symfony3='5.6' + +requirement_symfony2='symfony/console:^2.8' +requirement_symfony3='symfony/console:^3' +requirement_symfony4='symfony/console:^4' diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/ApplyConfigTestTarget.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/ApplyConfigTestTarget.php new file mode 100644 index 00000000..6dace2be --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/ApplyConfigTestTarget.php @@ -0,0 +1,43 @@ +dir = $dir; + return $this; + } + + /** + * A getter for the 'dir' property that we will use to + * determine if the setter was called. + */ + public function getDir() + { + return $this->dir; + } + + /** + * A bad setter that does not return $this. + */ + public function bad($value) + { + $this->value = $value; + } + + /** + * A getter for the bad setter. + */ + public function getBad() + { + return $this->value; + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/MyFooCommand.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/MyFooCommand.php new file mode 100644 index 00000000..0487a024 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/MyFooCommand.php @@ -0,0 +1,47 @@ +setName('my:foo') + ->setDescription('My foo command.') + ->setHelp('This command tests command option injection by echoing its options') + ->addOption( + 'other', + null, + InputOption::VALUE_REQUIRED, + 'Some other option', + 'fish' + ) + ->addOption( + 'name', + null, + InputOption::VALUE_REQUIRED, + 'What is the name of the thing we are naming', + 'George' + ) + ->addOption( + 'dir', + null, + InputOption::VALUE_REQUIRED, + 'What is the base directory to use for this command', + '/default/path' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->writeln('Enter my:foo'); + $output->writeln('dir: ' . $input->getOption('dir')); + $output->writeln('name: ' . $input->getOption('name')); + $output->writeln('other: ' . $input->getOption('other')); + } +} diff --git a/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/TestLoader.php b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/TestLoader.php new file mode 100644 index 00000000..241e5120 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/config/scenarios/symfony4/tests/src/TestLoader.php @@ -0,0 +1,36 @@ +data = $data; + } + + public function setSourceName($name) + { + $this->sourceName = $name; + } + + public function export() + { + return $this->data; + } + + public function keys() + { + return array_keys($this->data); + } + + public function getSourceName() + { + return $this->sourceName; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src deleted file mode 120000 index 929cb3dc..00000000 --- a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src +++ /dev/null @@ -1 +0,0 @@ -../../src \ No newline at end of file diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Application.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Application.php new file mode 100644 index 00000000..19d4725f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Application.php @@ -0,0 +1,73 @@ +getDefinition() + ->addOption( + new InputOption('--simulate', null, InputOption::VALUE_NONE, 'Run in simulated mode (show what would have happened).') + ); + $this->getDefinition() + ->addOption( + new InputOption('--progress-delay', null, InputOption::VALUE_REQUIRED, 'Number of seconds before progress bar is displayed in long-running task collections. Default: 2s.', Config::DEFAULT_PROGRESS_DELAY) + ); + + $this->getDefinition() + ->addOption( + new InputOption('--define', '-D', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Define a configuration item value.', []) + ); + } + + /** + * @param string $roboFile + * @param string $roboClass + */ + public function addInitRoboFileCommand($roboFile, $roboClass) + { + $createRoboFile = new Command('init'); + $createRoboFile->setDescription("Intitalizes basic RoboFile in current dir"); + $createRoboFile->setCode(function () use ($roboClass, $roboFile) { + $output = Robo::output(); + $output->writeln(" ~~~ Welcome to Robo! ~~~~ "); + $output->writeln(" ". basename($roboFile) ." will be created in the current directory "); + file_put_contents( + $roboFile, + 'writeln(" Edit this file to add your commands! "); + }); + $this->add($createRoboFile); + } + + /** + * Add self update command, do nothing if null is provided + * + * @param string $repository GitHub Repository for self update + */ + public function addSelfUpdateCommand($repository = null) + { + if (!$repository) { + return; + } + $selfUpdateCommand = new SelfUpdateCommand($this->getName(), $this->getVersion(), $repository); + $this->add($selfUpdateCommand); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CallableTask.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CallableTask.php new file mode 100644 index 00000000..ae9c54fc --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CallableTask.php @@ -0,0 +1,62 @@ +fn = $fn; + $this->reference = $reference; + } + + /** + * @return \Robo\Result + */ + public function run() + { + $result = call_user_func($this->fn, $this->getState()); + // If the function returns no result, then count it + // as a success. + if (!isset($result)) { + $result = Result::success($this->reference); + } + // If the function returns a result, it must either return + // a \Robo\Result or an exit code. In the later case, we + // convert it to a \Robo\Result. + if (!$result instanceof Result) { + $result = new Result($this->reference, $result); + } + + return $result; + } + + public function getState() + { + if ($this->reference instanceof StateAwareInterface) { + return $this->reference->getState(); + } + return new Data(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Collection.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Collection.php new file mode 100644 index 00000000..607435a4 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Collection.php @@ -0,0 +1,769 @@ +resetState(); + } + + public function setProgressBarAutoDisplayInterval($interval) + { + if (!$this->progressIndicator) { + return; + } + return $this->progressIndicator->setProgressBarAutoDisplayInterval($interval); + } + + /** + * {@inheritdoc} + */ + public function add(TaskInterface $task, $name = self::UNNAMEDTASK) + { + $task = new CompletionWrapper($this, $task); + $this->addToTaskList($name, $task); + return $this; + } + + /** + * {@inheritdoc} + */ + public function addCode(callable $code, $name = self::UNNAMEDTASK) + { + return $this->add(new CallableTask($code, $this), $name); + } + + /** + * {@inheritdoc} + */ + public function addIterable($iterable, callable $code) + { + $callbackTask = (new IterationTask($iterable, $code, $this))->inflect($this); + return $this->add($callbackTask); + } + + /** + * {@inheritdoc} + */ + public function rollback(TaskInterface $rollbackTask) + { + // Rollback tasks always try as hard as they can, and never report failures. + $rollbackTask = $this->ignoreErrorsTaskWrapper($rollbackTask); + return $this->wrapAndRegisterRollback($rollbackTask); + } + + /** + * {@inheritdoc} + */ + public function rollbackCode(callable $rollbackCode) + { + // Rollback tasks always try as hard as they can, and never report failures. + $rollbackTask = $this->ignoreErrorsCodeWrapper($rollbackCode); + return $this->wrapAndRegisterRollback($rollbackTask); + } + + /** + * {@inheritdoc} + */ + public function completion(TaskInterface $completionTask) + { + $collection = $this; + $completionRegistrationTask = new CallableTask( + function () use ($collection, $completionTask) { + + $collection->registerCompletion($completionTask); + }, + $this + ); + $this->addToTaskList(self::UNNAMEDTASK, $completionRegistrationTask); + return $this; + } + + /** + * {@inheritdoc} + */ + public function completionCode(callable $completionTask) + { + $completionTask = new CallableTask($completionTask, $this); + return $this->completion($completionTask); + } + + /** + * {@inheritdoc} + */ + public function before($name, $task, $nameOfTaskToAdd = self::UNNAMEDTASK) + { + return $this->addBeforeOrAfter(__FUNCTION__, $name, $task, $nameOfTaskToAdd); + } + + /** + * {@inheritdoc} + */ + public function after($name, $task, $nameOfTaskToAdd = self::UNNAMEDTASK) + { + return $this->addBeforeOrAfter(__FUNCTION__, $name, $task, $nameOfTaskToAdd); + } + + /** + * {@inheritdoc} + */ + public function progressMessage($text, $context = [], $level = LogLevel::NOTICE) + { + $context += ['name' => 'Progress']; + $context += TaskInfo::getTaskContext($this); + return $this->addCode( + function () use ($level, $text, $context) { + $context += $this->getState()->getData(); + $this->printTaskOutput($level, $text, $context); + } + ); + } + + /** + * @param \Robo\Contract\TaskInterface $rollbackTask + * + * @return $this + */ + protected function wrapAndRegisterRollback(TaskInterface $rollbackTask) + { + $collection = $this; + $rollbackRegistrationTask = new CallableTask( + function () use ($collection, $rollbackTask) { + $collection->registerRollback($rollbackTask); + }, + $this + ); + $this->addToTaskList(self::UNNAMEDTASK, $rollbackRegistrationTask); + return $this; + } + + /** + * Add either a 'before' or 'after' function or task. + * + * @param string $method + * @param string $name + * @param callable|TaskInterface $task + * @param string $nameOfTaskToAdd + * + * @return $this + */ + protected function addBeforeOrAfter($method, $name, $task, $nameOfTaskToAdd) + { + if (is_callable($task)) { + $task = new CallableTask($task, $this); + } + $existingTask = $this->namedTask($name); + $fn = [$existingTask, $method]; + call_user_func($fn, $task, $nameOfTaskToAdd); + return $this; + } + + /** + * Wrap the provided task in a wrapper that will ignore + * any errors or exceptions that may be produced. This + * is useful, for example, in adding optional cleanup tasks + * at the beginning of a task collection, to remove previous + * results which may or may not exist. + * + * TODO: Provide some way to specify which sort of errors + * are ignored, so that 'file not found' may be ignored, + * but 'permission denied' reported? + * + * @param \Robo\Contract\TaskInterface $task + * + * @return \Robo\Collection\CallableTask + */ + public function ignoreErrorsTaskWrapper(TaskInterface $task) + { + // If the task is a stack-based task, then tell it + // to try to run all of its operations, even if some + // of them fail. + if ($task instanceof StackBasedTask) { + $task->stopOnFail(false); + } + $ignoreErrorsInTask = function () use ($task) { + $data = []; + try { + $result = $this->runSubtask($task); + $message = $result->getMessage(); + $data = $result->getData(); + $data['exitcode'] = $result->getExitCode(); + } catch (\Exception $e) { + $message = $e->getMessage(); + } + + return Result::success($task, $message, $data); + }; + // Wrap our ignore errors callable in a task. + return new CallableTask($ignoreErrorsInTask, $this); + } + + /** + * @param callable $task + * + * @return \Robo\Collection\CallableTask + */ + public function ignoreErrorsCodeWrapper(callable $task) + { + return $this->ignoreErrorsTaskWrapper(new CallableTask($task, $this)); + } + + /** + * Return the list of task names added to this collection. + * + * @return array + */ + public function taskNames() + { + return array_keys($this->taskList); + } + + /** + * Test to see if a specified task name exists. + * n.b. before() and after() require that the named + * task exist; use this function to test first, if + * unsure. + * + * @param string $name + * + * @return bool + */ + public function hasTask($name) + { + return array_key_exists($name, $this->taskList); + } + + /** + * Find an existing named task. + * + * @param string $name + * The name of the task to insert before. The named task MUST exist. + * + * @return Element + * The task group for the named task. Generally this is only + * used to call 'before()' and 'after()'. + */ + protected function namedTask($name) + { + if (!$this->hasTask($name)) { + throw new \RuntimeException("Could not find task named $name"); + } + return $this->taskList[$name]; + } + + /** + * Add a list of tasks to our task collection. + * + * @param TaskInterface[] $tasks + * An array of tasks to run with rollback protection + * + * @return $this + */ + public function addTaskList(array $tasks) + { + foreach ($tasks as $name => $task) { + $this->add($task, $name); + } + return $this; + } + + /** + * Add the provided task to our task list. + * + * @param string $name + * @param \Robo\Contract\TaskInterface $task + * + * @return \Robo\Collection\Collection + */ + protected function addToTaskList($name, TaskInterface $task) + { + // All tasks are stored in a task group so that we have a place + // to hang 'before' and 'after' tasks. + $taskGroup = new Element($task); + return $this->addCollectionElementToTaskList($name, $taskGroup); + } + + /** + * @param int|string $name + * @param \Robo\Collection\Element $taskGroup + * + * @return $this + */ + protected function addCollectionElementToTaskList($name, Element $taskGroup) + { + // If a task name is not provided, then we'll let php pick + // the array index. + if (Result::isUnnamed($name)) { + $this->taskList[] = $taskGroup; + return $this; + } + // If we are replacing an existing task with the + // same name, ensure that our new task is added to + // the end. + $this->taskList[$name] = $taskGroup; + return $this; + } + + /** + * Set the parent collection. This is necessary so that nested + * collections' rollback and completion tasks can be added to the + * top-level collection, ensuring that the rollbacks for a collection + * will run if any later task fails. + * + * @param \Robo\Collection\NestedCollectionInterface $parentCollection + * + * @return $this + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->parentCollection = $parentCollection; + return $this; + } + + /** + * Get the appropriate parent collection to use + * + * @return CollectionInterface + */ + public function getParentCollection() + { + return $this->parentCollection ? $this->parentCollection : $this; + } + + /** + * Register a rollback task to run if there is any failure. + * + * Clients are free to add tasks to the rollback stack as + * desired; however, usually it is preferable to call + * Collection::rollback() instead. With that function, + * the rollback function will only be called if all of the + * tasks added before it complete successfully, AND some later + * task fails. + * + * One example of a good use-case for registering a callback + * function directly is to add a task that sends notification + * when a task fails. + * + * @param TaskInterface $rollbackTask + * The rollback task to run on failure. + */ + public function registerRollback(TaskInterface $rollbackTask) + { + if ($this->parentCollection) { + return $this->parentCollection->registerRollback($rollbackTask); + } + if ($rollbackTask) { + $this->rollbackStack[] = $rollbackTask; + } + } + + /** + * Register a completion task to run once all other tasks finish. + * Completion tasks run whether or not a rollback operation was + * triggered. They do not trigger rollbacks if they fail. + * + * The typical use-case for a completion function is to clean up + * temporary objects (e.g. temporary folders). The preferred + * way to do that, though, is to use Temporary::wrap(). + * + * On failures, completion tasks will run after all rollback tasks. + * If one task collection is nested inside another task collection, + * then the nested collection's completion tasks will run as soon as + * the nested task completes; they are not deferred to the end of + * the containing collection's execution. + * + * @param TaskInterface $completionTask + * The completion task to run at the end of all other operations. + */ + public function registerCompletion(TaskInterface $completionTask) + { + if ($this->parentCollection) { + return $this->parentCollection->registerCompletion($completionTask); + } + if ($completionTask) { + // Completion tasks always try as hard as they can, and never report failures. + $completionTask = $this->ignoreErrorsTaskWrapper($completionTask); + $this->completionStack[] = $completionTask; + } + } + + /** + * Return the count of steps in this collection + * + * @return int + */ + public function progressIndicatorSteps() + { + $steps = 0; + foreach ($this->taskList as $name => $taskGroup) { + $steps += $taskGroup->progressIndicatorSteps(); + } + return $steps; + } + + /** + * A Collection of tasks can provide a command via `getCommand()` + * if it contains a single task, and that task implements CommandInterface. + * + * @return string + * + * @throws \Robo\Exception\TaskException + */ + public function getCommand() + { + if (empty($this->taskList)) { + return ''; + } + + if (count($this->taskList) > 1) { + // TODO: We could potentially iterate over the items in the collection + // and concatenate the result of getCommand() from each one, and fail + // only if we encounter a command that is not a CommandInterface. + throw new TaskException($this, "getCommand() does not work on arbitrary collections of tasks."); + } + + $taskElement = reset($this->taskList); + $task = $taskElement->getTask(); + $task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + if ($task instanceof CommandInterface) { + return $task->getCommand(); + } + + throw new TaskException($task, get_class($task) . " does not implement CommandInterface, so can't be used to provide a command"); + } + + /** + * Run our tasks, and roll back if necessary. + * + * @return \Robo\Result + */ + public function run() + { + $result = $this->runWithoutCompletion(); + $this->complete(); + return $result; + } + + /** + * @return \Robo\Result + */ + private function runWithoutCompletion() + { + $result = Result::success($this); + + if (empty($this->taskList)) { + return $result; + } + + $this->startProgressIndicator(); + if ($result->wasSuccessful()) { + foreach ($this->taskList as $name => $taskGroup) { + $taskList = $taskGroup->getTaskList(); + $result = $this->runTaskList($name, $taskList, $result); + if (!$result->wasSuccessful()) { + $this->fail(); + return $result; + } + } + $this->taskList = []; + } + $this->stopProgressIndicator(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * Run every task in a list, but only up to the first failure. + * Return the failing result, or success if all tasks run. + * + * @param string $name + * @param TaskInterface[] $taskList + * @param \Robo\Result $result + * + * @return \Robo\Result + * + * @throws \Robo\Exception\TaskExitException + */ + private function runTaskList($name, array $taskList, Result $result) + { + try { + foreach ($taskList as $taskName => $task) { + $taskResult = $this->runSubtask($task); + $this->advanceProgressIndicator(); + // If the current task returns an error code, then stop + // execution and signal a rollback. + if (!$taskResult->wasSuccessful()) { + return $taskResult; + } + // We accumulate our results into a field so that tasks that + // have a reference to the collection may examine and modify + // the incremental results, if they wish. + $key = Result::isUnnamed($taskName) ? $name : $taskName; + $result->accumulate($key, $taskResult); + // The result message will be the message of the last task executed. + $result->setMessage($taskResult->getMessage()); + } + } catch (TaskExitException $exitException) { + $this->fail(); + throw $exitException; + } catch (\Exception $e) { + // Tasks typically should not throw, but if one does, we will + // convert it into an error and roll back. + return Result::fromException($task, $e, $result->getData()); + } + return $result; + } + + /** + * Force the rollback functions to run + * + * @return $this + */ + public function fail() + { + $this->disableProgressIndicator(); + $this->runRollbackTasks(); + $this->complete(); + return $this; + } + + /** + * Force the completion functions to run + * + * @return $this + */ + public function complete() + { + $this->detatchProgressIndicator(); + $this->runTaskListIgnoringFailures($this->completionStack); + $this->reset(); + return $this; + } + + /** + * Reset this collection, removing all tasks. + * + * @return $this + */ + public function reset() + { + $this->taskList = []; + $this->completionStack = []; + $this->rollbackStack = []; + return $this; + } + + /** + * Run all of our rollback tasks. + * + * Note that Collection does not implement RollbackInterface, but + * it may still be used as a task inside another task collection + * (i.e. you can nest task collections, if desired). + */ + protected function runRollbackTasks() + { + $this->runTaskListIgnoringFailures($this->rollbackStack); + // Erase our rollback stack once we have finished rolling + // everything back. This will allow us to potentially use + // a command collection more than once (e.g. to retry a + // failed operation after doing some error recovery). + $this->rollbackStack = []; + } + + /** + * @param TaskInterface|NestedCollectionInterface|WrappedTaskInterface $task + * + * @return \Robo\Result + */ + protected function runSubtask($task) + { + $original = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->setParentCollectionForTask($original, $this->getParentCollection()); + if ($original instanceof InflectionInterface) { + $original->inflect($this); + } + if ($original instanceof StateAwareInterface) { + $original->setState($this->getState()); + } + $this->doDeferredInitialization($original); + $taskResult = $task->run(); + $taskResult = Result::ensureResult($task, $taskResult); + $this->doStateUpdates($original, $taskResult); + return $taskResult; + } + + protected function doStateUpdates($task, Data $taskResult) + { + $this->updateState($taskResult); + $key = spl_object_hash($task); + if (array_key_exists($key, $this->messageStoreKeys)) { + $state = $this->getState(); + list($stateKey, $sourceKey) = $this->messageStoreKeys[$key]; + $value = empty($sourceKey) ? $taskResult->getMessage() : $taskResult[$sourceKey]; + $state[$stateKey] = $value; + } + } + + public function storeState($task, $key, $source = '') + { + $this->messageStoreKeys[spl_object_hash($task)] = [$key, $source]; + + return $this; + } + + public function deferTaskConfiguration($task, $functionName, $stateKey) + { + return $this->defer( + $task, + function ($task, $state) use ($functionName, $stateKey) { + $fn = [$task, $functionName]; + $value = $state[$stateKey]; + $fn($value); + } + ); + } + + /** + * Defer execution of a callback function until just before a task + * runs. Use this time to provide more settings for the task, e.g. from + * the collection's shared state, which is populated with the results + * of previous test runs. + */ + public function defer($task, $callback) + { + $this->deferredCallbacks[spl_object_hash($task)][] = $callback; + + return $this; + } + + protected function doDeferredInitialization($task) + { + // If the task is a state consumer, then call its receiveState method + if ($task instanceof \Robo\State\Consumer) { + $task->receiveState($this->getState()); + } + + // Check and see if there are any deferred callbacks for this task. + $key = spl_object_hash($task); + if (!array_key_exists($key, $this->deferredCallbacks)) { + return; + } + + // Call all of the deferred callbacks + foreach ($this->deferredCallbacks[$key] as $fn) { + $fn($task, $this->getState()); + } + } + + /** + * @param TaskInterface|NestedCollectionInterface|WrappedTaskInterface $task + * @param $parentCollection + */ + protected function setParentCollectionForTask($task, $parentCollection) + { + if ($task instanceof NestedCollectionInterface) { + $task->setParentCollection($parentCollection); + } + } + + /** + * Run all of the tasks in a provided list, ignoring failures. + * This is used to roll back or complete. + * + * @param TaskInterface[] $taskList + */ + protected function runTaskListIgnoringFailures(array $taskList) + { + foreach ($taskList as $task) { + try { + $this->runSubtask($task); + } catch (\Exception $e) { + // Ignore rollback failures. + } + } + } + + /** + * Give all of our tasks to the provided collection builder. + * + * @param CollectionBuilder $builder + */ + public function transferTasks($builder) + { + foreach ($this->taskList as $name => $taskGroup) { + // TODO: We are abandoning all of our before and after tasks here. + // At the moment, transferTasks is only called under conditions where + // there will be none of these, but care should be taken if that changes. + $task = $taskGroup->getTask(); + $builder->addTaskToCollection($task); + } + $this->reset(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionBuilder.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionBuilder.php new file mode 100644 index 00000000..3e037b01 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionBuilder.php @@ -0,0 +1,571 @@ +collectionBuilder() + * ->taskFilesystemStack() + * ->mkdir('g') + * ->touch('g/g.txt') + * ->rollback( + * $this->taskDeleteDir('g') + * ) + * ->taskFilesystemStack() + * ->mkdir('g/h') + * ->touch('g/h/h.txt') + * ->taskFilesystemStack() + * ->mkdir('g/h/i/c') + * ->touch('g/h/i/i.txt') + * ->run() + * ?> + * + * In the example above, the `taskDeleteDir` will be called if + * ``` + */ +class CollectionBuilder extends BaseTask implements NestedCollectionInterface, WrappedTaskInterface, CommandInterface, StateAwareInterface +{ + use StateAwareTrait; + + /** + * @var \Robo\Tasks + */ + protected $commandFile; + + /** + * @var CollectionInterface + */ + protected $collection; + + /** + * @var TaskInterface + */ + protected $currentTask; + + /** + * @var bool + */ + protected $simulated; + + /** + * @param \Robo\Tasks $commandFile + */ + public function __construct($commandFile) + { + $this->commandFile = $commandFile; + $this->resetState(); + } + + public static function create($container, $commandFile) + { + $builder = new self($commandFile); + + $builder->setLogger($container->get('logger')); + $builder->setProgressIndicator($container->get('progressIndicator')); + $builder->setConfig($container->get('config')); + $builder->setOutputAdapter($container->get('outputAdapter')); + + return $builder; + } + + /** + * @param bool $simulated + * + * @return $this + */ + public function simulated($simulated = true) + { + $this->simulated = $simulated; + return $this; + } + + /** + * @return bool + */ + public function isSimulated() + { + if (!isset($this->simulated)) { + $this->simulated = $this->getConfig()->get(Config::SIMULATE); + } + return $this->simulated; + } + + /** + * Create a temporary directory to work in. When the collection + * completes or rolls back, the temporary directory will be deleted. + * Returns the path to the location where the directory will be + * created. + * + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return string + */ + public function tmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + // n.b. Any task that the builder is asked to create is + // automatically added to the builder's collection, and + // wrapped in the builder object. Therefore, the result + // of any call to `taskFoo()` from within the builder will + // always be `$this`. + return $this->taskTmpDir($prefix, $base, $includeRandomPart)->getPath(); + } + + /** + * Create a working directory to hold results. A temporary directory + * is first created to hold the intermediate results. After the + * builder finishes, the work directory is moved into its final location; + * any results already in place will be moved out of the way and + * then deleted. + * + * @param string $finalDestination The path where the working directory + * will be moved once the task collection completes. + * + * @return string + */ + public function workDir($finalDestination) + { + // Creating the work dir task in this context adds it to our task collection. + return $this->taskWorkDir($finalDestination)->getPath(); + } + + public function addTask(TaskInterface $task) + { + $this->getCollection()->add($task); + return $this; + } + + /** + * Add arbitrary code to execute as a task. + * + * @see \Robo\Collection\CollectionInterface::addCode + * + * @param callable $code + * @param int|string $name + * @return $this + */ + public function addCode(callable $code, $name = \Robo\Collection\CollectionInterface::UNNAMEDTASK) + { + $this->getCollection()->addCode($code, $name); + return $this; + } + + /** + * Add a list of tasks to our task collection. + * + * @param TaskInterface[] $tasks + * An array of tasks to run with rollback protection + * + * @return $this + */ + public function addTaskList(array $tasks) + { + $this->getCollection()->addTaskList($tasks); + return $this; + } + + public function rollback(TaskInterface $task) + { + // Ensure that we have a collection if we are going to add + // a rollback function. + $this->getCollection()->rollback($task); + return $this; + } + + public function rollbackCode(callable $rollbackCode) + { + $this->getCollection()->rollbackCode($rollbackCode); + return $this; + } + + public function completion(TaskInterface $task) + { + $this->getCollection()->completion($task); + return $this; + } + + public function completionCode(callable $completionCode) + { + $this->getCollection()->completionCode($completionCode); + return $this; + } + + /** + * @param string $text + * @param array $context + * @param string $level + * + * @return $this + */ + public function progressMessage($text, $context = [], $level = LogLevel::NOTICE) + { + $this->getCollection()->progressMessage($text, $context, $level); + return $this; + } + + /** + * @param \Robo\Collection\NestedCollectionInterface $parentCollection + * + * @return $this + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->getCollection()->setParentCollection($parentCollection); + return $this; + } + + /** + * Called by the factory method of each task; adds the current + * task to the task builder. + * + * TODO: protected + * + * @param TaskInterface $task + * + * @return $this + */ + public function addTaskToCollection($task) + { + // Postpone creation of the collection until the second time + // we are called. At that time, $this->currentTask will already + // be populated. We call 'getCollection()' so that it will + // create the collection and add the current task to it. + // Note, however, that if our only tasks implements NestedCollectionInterface, + // then we should force this builder to use a collection. + if (!$this->collection && (isset($this->currentTask) || ($task instanceof NestedCollectionInterface))) { + $this->getCollection(); + } + $this->currentTask = $task; + if ($this->collection) { + $this->collection->add($task); + } + return $this; + } + + public function getState() + { + $collection = $this->getCollection(); + return $collection->getState(); + } + + public function storeState($key, $source = '') + { + return $this->callCollectionStateFuntion(__FUNCTION__, func_get_args()); + } + + public function deferTaskConfiguration($functionName, $stateKey) + { + return $this->callCollectionStateFuntion(__FUNCTION__, func_get_args()); + } + + public function defer($callback) + { + return $this->callCollectionStateFuntion(__FUNCTION__, func_get_args()); + } + + protected function callCollectionStateFuntion($functionName, $args) + { + $currentTask = ($this->currentTask instanceof WrappedTaskInterface) ? $this->currentTask->original() : $this->currentTask; + + array_unshift($args, $currentTask); + $collection = $this->getCollection(); + $fn = [$collection, $functionName]; + + call_user_func_array($fn, $args); + return $this; + } + + public function setVerbosityThreshold($verbosityThreshold) + { + $currentTask = ($this->currentTask instanceof WrappedTaskInterface) ? $this->currentTask->original() : $this->currentTask; + if ($currentTask) { + $currentTask->setVerbosityThreshold($verbosityThreshold); + return $this; + } + parent::setVerbosityThreshold($verbosityThreshold); + return $this; + } + + + /** + * Return the current task for this collection builder. + * TODO: Not needed? + * + * @return \Robo\Contract\TaskInterface + */ + public function getCollectionBuilderCurrentTask() + { + return $this->currentTask; + } + + /** + * Create a new builder with its own task collection + * + * @return CollectionBuilder + */ + public function newBuilder() + { + $collectionBuilder = new self($this->commandFile); + $collectionBuilder->inflect($this); + $collectionBuilder->simulated($this->isSimulated()); + $collectionBuilder->setVerbosityThreshold($this->verbosityThreshold()); + $collectionBuilder->setState($this->getState()); + + return $collectionBuilder; + } + + /** + * Calling the task builder with methods of the current + * task calls through to that method of the task. + * + * There is extra complexity in this function that could be + * simplified if we attached the 'LoadAllTasks' and custom tasks + * to the collection builder instead of the RoboFile. While that + * change would be a better design overall, it would require that + * the user do a lot more work to set up and use custom tasks. + * We therefore take on some additional complexity here in order + * to allow users to maintain their tasks in their RoboFile, which + * is much more convenient. + * + * Calls to $this->collectionBuilder()->taskFoo() cannot be made + * directly because all of the task methods are protected. These + * calls will therefore end up here. If the method name begins + * with 'task', then it is eligible to be used with the builder. + * + * When we call getBuiltTask, below, it will use the builder attached + * to the commandfile to build the task. However, this is not what we + * want: the task needs to be built from THIS collection builder, so that + * it will be affected by whatever state is active in this builder. + * To do this, we have two choices: 1) save and restore the builder + * in the commandfile, or 2) clone the commandfile and set this builder + * on the copy. 1) is vulnerable to failure in multithreaded environments + * (currently not supported), while 2) might cause confusion if there + * is shared state maintained in the commandfile, which is in the + * domain of the user. + * + * Note that even though we are setting up the commandFile to + * use this builder, getBuiltTask always creates a new builder + * (which is constructed using all of the settings from the + * commandFile's builder), and the new task is added to that. + * We therefore need to transfer the newly built task into this + * builder. The temporary builder is discarded. + * + * @param string $fn + * @param array $args + * + * @return $this|mixed + */ + public function __call($fn, $args) + { + if (preg_match('#^task[A-Z]#', $fn) && (method_exists($this->commandFile, 'getBuiltTask'))) { + $saveBuilder = $this->commandFile->getBuilder(); + $this->commandFile->setBuilder($this); + $temporaryBuilder = $this->commandFile->getBuiltTask($fn, $args); + $this->commandFile->setBuilder($saveBuilder); + if (!$temporaryBuilder) { + throw new \BadMethodCallException("No such method $fn: task does not exist in " . get_class($this->commandFile)); + } + $temporaryBuilder->getCollection()->transferTasks($this); + return $this; + } + if (!isset($this->currentTask)) { + throw new \BadMethodCallException("No such method $fn: current task undefined in collection builder."); + } + // If the method called is a method of the current task, + // then call through to the current task's setter method. + $result = call_user_func_array([$this->currentTask, $fn], $args); + + // If something other than a setter method is called, then return its result. + $currentTask = ($this->currentTask instanceof WrappedTaskInterface) ? $this->currentTask->original() : $this->currentTask; + if (isset($result) && ($result !== $currentTask)) { + return $result; + } + + return $this; + } + + /** + * Construct the desired task and add it to this builder. + * + * @param string|object $name + * @param array $args + * + * @return \Robo\Collection\CollectionBuilder + */ + public function build($name, $args) + { + $reflection = new ReflectionClass($name); + $task = $reflection->newInstanceArgs($args); + if (!$task) { + throw new RuntimeException("Can not construct task $name"); + } + $task = $this->fixTask($task, $args); + $this->configureTask($name, $task); + return $this->addTaskToCollection($task); + } + + /** + * @param InflectionInterface $task + * @param array $args + * + * @return \Robo\Collection\CompletionWrapper|\Robo\Task\Simulator + */ + protected function fixTask($task, $args) + { + if ($task instanceof InflectionInterface) { + $task->inflect($this); + } + if ($task instanceof BuilderAwareInterface) { + $task->setBuilder($this); + } + if ($task instanceof VerbosityThresholdInterface) { + $task->setVerbosityThreshold($this->verbosityThreshold()); + } + + // Do not wrap our wrappers. + if ($task instanceof CompletionWrapper || $task instanceof Simulator) { + return $task; + } + + // Remember whether or not this is a task before + // it gets wrapped in any decorator. + $isTask = $task instanceof TaskInterface; + $isCollection = $task instanceof NestedCollectionInterface; + + // If the task implements CompletionInterface, ensure + // that its 'complete' method is called when the application + // terminates -- but only if its 'run' method is called + // first. If the task is added to a collection, then the + // task will be unwrapped via its `original` method, and + // it will be re-wrapped with a new completion wrapper for + // its new collection. + if ($task instanceof CompletionInterface) { + $task = new CompletionWrapper(Temporary::getCollection(), $task); + } + + // If we are in simulated mode, then wrap any task in + // a TaskSimulator. + if ($isTask && !$isCollection && ($this->isSimulated())) { + $task = new \Robo\Task\Simulator($task, $args); + $task->inflect($this); + } + + return $task; + } + + /** + * Check to see if there are any setter methods defined in configuration + * for this task. + */ + protected function configureTask($taskClass, $task) + { + $taskClass = static::configClassIdentifier($taskClass); + $configurationApplier = new ConfigForSetters($this->getConfig(), $taskClass, 'task.'); + $configurationApplier->apply($task, 'settings'); + + // TODO: If we counted each instance of $taskClass that was called from + // this builder, then we could also apply configuration from + // "task.{$taskClass}[$N].settings" + + // TODO: If the builder knew what the current command name was, + // then we could also search for task configuration under + // command-specific keys such as "command.{$commandname}.task.{$taskClass}.settings". + } + + /** + * When we run the collection builder, run everything in the collection. + * + * @return \Robo\Result + */ + public function run() + { + $this->startTimer(); + $result = $this->runTasks(); + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + $result->mergeData($this->getState()->getData()); + return $result; + } + + /** + * If there is a single task, run it; if there is a collection, run + * all of its tasks. + * + * @return \Robo\Result + */ + protected function runTasks() + { + if (!$this->collection && $this->currentTask) { + $result = $this->currentTask->run(); + return Result::ensureResult($this->currentTask, $result); + } + return $this->getCollection()->run(); + } + + /** + * @return string + */ + public function getCommand() + { + if (!$this->collection && $this->currentTask) { + $task = $this->currentTask; + $task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + if ($task instanceof CommandInterface) { + return $task->getCommand(); + } + } + + return $this->getCollection()->getCommand(); + } + + /** + * @return \Robo\Collection\Collection + */ + public function original() + { + return $this->getCollection(); + } + + /** + * Return the collection of tasks associated with this builder. + * + * @return CollectionInterface + */ + public function getCollection() + { + if (!isset($this->collection)) { + $this->collection = new Collection(); + $this->collection->inflect($this); + $this->collection->setState($this->getState()); + $this->collection->setProgressBarAutoDisplayInterval($this->getConfig()->get(Config::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL)); + + if (isset($this->currentTask)) { + $this->collection->add($this->currentTask); + } + } + return $this->collection; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionInterface.php new file mode 100644 index 00000000..173ca169 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CollectionInterface.php @@ -0,0 +1,151 @@ +run(); + } catch (\Exception $e) { + return Result::fromException($result, $e); + } + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CompletionWrapper.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CompletionWrapper.php new file mode 100644 index 00000000..3e81bd91 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/CompletionWrapper.php @@ -0,0 +1,106 @@ +collection = $collection; + $this->task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->rollbackTask = $rollbackTask; + } + + /** + * {@inheritdoc} + */ + public function original() + { + return $this->task; + } + + /** + * Before running this task, register its rollback and completion + * handlers on its collection. The reason this class exists is to + * defer registration of rollback and completion tasks until 'run()' time. + * + * @return \Robo\Result + */ + public function run() + { + if ($this->rollbackTask) { + $this->collection->registerRollback($this->rollbackTask); + } + if ($this->task instanceof RollbackInterface) { + $this->collection->registerRollback(new CallableTask([$this->task, 'rollback'], $this->task)); + } + if ($this->task instanceof CompletionInterface) { + $this->collection->registerCompletion(new CallableTask([$this->task, 'complete'], $this->task)); + } + + return $this->task->run(); + } + + /** + * Make this wrapper object act like the class it wraps. + * + * @param string $function + * @param array $args + * + * @return mixed + */ + public function __call($function, $args) + { + return call_user_func_array(array($this->task, $function), $args); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Element.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Element.php new file mode 100644 index 00000000..b67b56bb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Element.php @@ -0,0 +1,116 @@ +task = $task; + } + + /** + * @param mixed $before + * @param string $name + */ + public function before($before, $name) + { + if ($name) { + $this->before[$name] = $before; + } else { + $this->before[] = $before; + } + } + + /** + * @param mixed $after + * @param string $name + */ + public function after($after, $name) + { + if ($name) { + $this->after[$name] = $after; + } else { + $this->after[] = $after; + } + } + + /** + * @return array + */ + public function getBefore() + { + return $this->before; + } + + /** + * @return array + */ + public function getAfter() + { + return $this->after; + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function getTask() + { + return $this->task; + } + + /** + * @return array + */ + public function getTaskList() + { + return array_merge($this->getBefore(), [$this->getTask()], $this->getAfter()); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + $steps = 0; + foreach ($this->getTaskList() as $task) { + if ($task instanceof WrappedTaskInterface) { + $task = $task->original(); + } + // If the task is a ProgressIndicatorAwareInterface, then it + // will advance the progress indicator a number of times. + if ($task instanceof ProgressIndicatorAwareInterface) { + $steps += $task->progressIndicatorSteps(); + } + // We also advance the progress indicator once regardless + // of whether it is progress-indicator aware or not. + $steps++; + } + return $steps; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/NestedCollectionInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/NestedCollectionInterface.php new file mode 100644 index 00000000..5e32cf37 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/NestedCollectionInterface.php @@ -0,0 +1,12 @@ +iterable = $iterable; + } + + /** + * @param string $message + * @param array $context + * + * @return $this + */ + public function iterationMessage($message, $context = []) + { + $this->message = $message; + $this->context = $context + ['name' => 'Progress']; + return $this; + } + + /** + * @param int|string $key + * @param mixed $value + */ + protected function showIterationMessage($key, $value) + { + if ($this->message) { + $context = ['key' => $key, 'value' => $value]; + $context += $this->context; + $context += TaskInfo::getTaskContext($this); + $this->printTaskInfo($this->message, $context); + } + } + + /** + * @param callable $fn + * + * @return $this + */ + public function withEachKeyValueCall(callable $fn) + { + $this->functionStack[] = $fn; + return $this; + } + + /** + * @param callable $fn + * + * @return \Robo\Collection\TaskForEach + */ + public function call(callable $fn) + { + return $this->withEachKeyValueCall( + function ($key, $value) use ($fn) { + return call_user_func($fn, $value); + } + ); + } + + /** + * @param callable $fn + * + * @return \Robo\Collection\TaskForEach + */ + public function withBuilder(callable $fn) + { + $this->countingStack[] = + function ($key, $value) use ($fn) { + // Create a new builder for every iteration + $builder = $this->collectionBuilder(); + // The user function should build task operations using + // the $key / $value parameters; we will call run() on + // the builder thus constructed. + call_user_func($fn, $builder, $key, $value); + return $builder->getCollection()->progressIndicatorSteps(); + }; + return $this->withEachKeyValueCall( + function ($key, $value) use ($fn) { + // Create a new builder for every iteration + $builder = $this->collectionBuilder() + ->setParentCollection($this->parentCollection); + // The user function should build task operations using + // the $key / $value parameters; we will call run() on + // the builder thus constructed. + call_user_func($fn, $builder, $key, $value); + return $builder->run(); + } + ); + } + + /** + * {@inheritdoc} + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->parentCollection = $parentCollection; + return $this; + } + + /** + * {@inheritdoc} + */ + public function progressIndicatorSteps() + { + $multiplier = count($this->functionStack); + if (!empty($this->countingStack)) { + $value = reset($this->iterable); + $key = key($this->iterable); + foreach ($this->countingStack as $fn) { + $multiplier += call_user_func($fn, $key, $value); + } + } + return count($this->iterable) * $multiplier; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $finalResult = Result::success($this); + $this->startProgressIndicator(); + foreach ($this->iterable as $key => $value) { + $this->showIterationMessage($key, $value); + try { + foreach ($this->functionStack as $fn) { + $result = call_user_func($fn, $key, $value); + $this->advanceProgressIndicator(); + if (!isset($result)) { + $result = Result::success($this); + } + // If the function returns a result, it must either return + // a \Robo\Result or an exit code. In the later case, we + // convert it to a \Robo\Result. + if (!$result instanceof Result) { + $result = new Result($this, $result); + } + if (!$result->wasSuccessful()) { + return $result; + } + $finalResult = $result->merge($finalResult); + } + } catch (\Exception $e) { + return Result::fromException($result, $e); + } + } + $this->stopProgressIndicator(); + return $finalResult; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Temporary.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Temporary.php new file mode 100644 index 00000000..dad25e34 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/Temporary.php @@ -0,0 +1,57 @@ +get('collection'); + register_shutdown_function(function () { + static::complete(); + }); + } + + return static::$collection; + } + + /** + * Call the complete method of all of the registered objects. + */ + public static function complete() + { + // Run the collection of tasks. This will also run the + // completion tasks. + $collection = static::getCollection(); + $collection->run(); + // Make sure that our completion functions do not run twice. + $collection->reset(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/loadTasks.php new file mode 100644 index 00000000..03f68823 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Collection/loadTasks.php @@ -0,0 +1,17 @@ +task(TaskForEach::class, $collection); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/BuilderAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/BuilderAwareTrait.php new file mode 100644 index 00000000..915ff008 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/BuilderAwareTrait.php @@ -0,0 +1,45 @@ +builder = $builder; + + return $this; + } + + /** + * @see \Robo\Contract\BuilderAwareInterface::getBuilder() + * + * @return \Robo\Collection\CollectionBuilder + */ + public function getBuilder() + { + return $this->builder; + } + + /** + * @return \Robo\Collection\CollectionBuilder + */ + protected function collectionBuilder() + { + return $this->getBuilder()->newBuilder(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/CommandArguments.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/CommandArguments.php new file mode 100644 index 00000000..12c2e89f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/CommandArguments.php @@ -0,0 +1,130 @@ +args($arg); + } + + /** + * Pass methods parameters as arguments to executable. Argument values + * are automatically escaped. + * + * @param string|string[] $args + * + * @return $this + */ + public function args($args) + { + if (!is_array($args)) { + $args = func_get_args(); + } + $this->arguments .= ' ' . implode(' ', array_map('static::escape', $args)); + return $this; + } + + /** + * Pass the provided string in its raw (as provided) form as an argument to executable. + * + * @param string $arg + * + * @return $this + */ + public function rawArg($arg) + { + $this->arguments .= " $arg"; + + return $this; + } + + /** + * Escape the provided value, unless it contains only alphanumeric + * plus a few other basic characters. + * + * @param string $value + * + * @return string + */ + public static function escape($value) + { + if (preg_match('/^[a-zA-Z0-9\/\.@~_-]+$/', $value)) { + return $value; + } + return ProcessUtils::escapeArgument($value); + } + + /** + * Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. + * Option values are automatically escaped. + * + * @param string $option + * @param string $value + * @param string $separator + * + * @return $this + */ + public function option($option, $value = null, $separator = ' ') + { + if ($option !== null and strpos($option, '-') !== 0) { + $option = "--$option"; + } + $this->arguments .= null == $option ? '' : " " . $option; + $this->arguments .= null == $value ? '' : $separator . static::escape($value); + return $this; + } + + /** + * Pass multiple options to executable. The associative array contains + * the key:value pairs that become `--key value`, for each item in the array. + * Values are automatically escaped. + */ + public function options(array $options, $separator = ' ') + { + foreach ($options as $option => $value) { + $this->option($option, $value, $separator); + } + return $this; + } + + /** + * Pass an option with multiple values to executable. Value can be a string or array. + * Option values are automatically escaped. + * + * @param string $option + * @param string|array $value + * @param string $separator + * + * @return $this + */ + public function optionList($option, $value = array(), $separator = ' ') + { + if (is_array($value)) { + foreach ($value as $item) { + $this->optionList($option, $item, $separator); + } + } else { + $this->option($option, $value, $separator); + } + + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/CommandReceiver.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/CommandReceiver.php new file mode 100644 index 00000000..03b20fce --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/CommandReceiver.php @@ -0,0 +1,30 @@ +getCommand(); + } else { + throw new TaskException($this, get_class($command) . " does not implement CommandInterface, so can't be passed into this task"); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ConfigAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ConfigAwareTrait.php new file mode 100644 index 00000000..d6d45788 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ConfigAwareTrait.php @@ -0,0 +1,109 @@ +config = $config; + + return $this; + } + + /** + * Get the config management object. + * + * @return ConfigInterface + * + * @see \Robo\Contract\ConfigAwareInterface::getConfig() + */ + public function getConfig() + { + return $this->config; + } + + /** + * Any class that uses ConfigAwareTrait SHOULD override this method + * , and define a prefix for its configuration items. This is usually + * done in a base class. When used, this method should return a string + * that ends with a "."; see BaseTask::configPrefix(). + * + * @return string + */ + protected static function configPrefix() + { + return ''; + } + + protected static function configClassIdentifier($classname) + { + $configIdentifier = strtr($classname, '\\', '.'); + $configIdentifier = preg_replace('#^(.*\.Task\.|\.)#', '', $configIdentifier); + + return $configIdentifier; + } + + protected static function configPostfix() + { + return ''; + } + + /** + * @param string $key + * + * @return string + */ + private static function getClassKey($key) + { + $configPrefix = static::configPrefix(); // task. + $configClass = static::configClassIdentifier(get_called_class()); // PARTIAL_NAMESPACE.CLASSNAME + $configPostFix = static::configPostfix(); // .settings + + return sprintf('%s%s%s.%s', $configPrefix, $configClass, $configPostFix, $key); + } + + /** + * @param string $key + * @param mixed $value + * @param Config|null $config + */ + public static function configure($key, $value, $config = null) + { + if (!$config) { + $config = Robo::config(); + } + $config->setDefault(static::getClassKey($key), $value); + } + + /** + * @param string $key + * @param mixed|null $default + * + * @return mixed|null + */ + protected function getConfigValue($key, $default = null) + { + if (!$this->getConfig()) { + return $default; + } + return $this->getConfig()->get(static::getClassKey($key), $default); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/DynamicParams.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/DynamicParams.php new file mode 100644 index 00000000..28a1d150 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/DynamicParams.php @@ -0,0 +1,45 @@ +$property))) { + $this->$property = !$this->$property; + return $this; + } + + // append item to array + if (is_array($this->$property)) { + if (is_array($args[0])) { + $this->$property = $args[0]; + } else { + array_push($this->$property, $args[0]); + } + return $this; + } + + $this->$property = $args[0]; + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecCommand.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecCommand.php new file mode 100644 index 00000000..c3e6c3af --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecCommand.php @@ -0,0 +1,148 @@ +execTimer)) { + $this->execTimer = new TimeKeeper(); + } + return $this->execTimer; + } + + /** + * Look for a "{$cmd}.phar" in the current working + * directory; return a string to exec it if it is + * found. Otherwise, look for an executable command + * of the same name via findExecutable. + * + * @param string $cmd + * + * @return bool|string + */ + protected function findExecutablePhar($cmd) + { + if (file_exists("{$cmd}.phar")) { + return "php {$cmd}.phar"; + } + return $this->findExecutable($cmd); + } + + /** + * Return the best path to the executable program + * with the provided name. Favor vendor/bin in the + * current project. If not found there, use + * whatever is on the $PATH. + * + * @param string $cmd + * + * @return bool|string + */ + protected function findExecutable($cmd) + { + $pathToCmd = $this->searchForExecutable($cmd); + if ($pathToCmd) { + return $this->useCallOnWindows($pathToCmd); + } + return false; + } + + /** + * @param string $cmd + * + * @return string + */ + private function searchForExecutable($cmd) + { + $projectBin = $this->findProjectBin(); + + $localComposerInstallation = $projectBin . DIRECTORY_SEPARATOR . $cmd; + if (file_exists($localComposerInstallation)) { + return $localComposerInstallation; + } + $finder = new ExecutableFinder(); + return $finder->find($cmd, null, []); + } + + /** + * @return bool|string + */ + protected function findProjectBin() + { + $cwd = getcwd(); + $candidates = [ __DIR__ . '/../../vendor/bin', __DIR__ . '/../../bin', $cwd . '/vendor/bin' ]; + + // If this project is inside a vendor directory, give highest priority + // to that directory. + $vendorDirContainingUs = realpath(__DIR__ . '/../../../..'); + if (is_dir($vendorDirContainingUs) && (basename($vendorDirContainingUs) == 'vendor')) { + array_unshift($candidates, $vendorDirContainingUs . '/bin'); + } + + foreach ($candidates as $dir) { + if (is_dir("$dir")) { + return realpath($dir); + } + } + return false; + } + + /** + * Wrap Windows executables in 'call' per 7a88757d + * + * @param string $cmd + * + * @return string + */ + protected function useCallOnWindows($cmd) + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + if (file_exists("{$cmd}.bat")) { + $cmd = "{$cmd}.bat"; + } + return "call $cmd"; + } + return $cmd; + } + + protected function getCommandDescription() + { + return $this->process->getCommandLine(); + } + + /** + * @param string $command + * + * @return \Robo\Result + */ + protected function executeCommand($command) + { + // TODO: Symfony 4 requires that we supply the working directory. + $result_data = $this->execute(new Process($command, getcwd())); + return new Result( + $this, + $result_data->getExitCode(), + $result_data->getMessage(), + $result_data->getData() + ); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecOneCommand.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecOneCommand.php new file mode 100644 index 00000000..60137514 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ExecOneCommand.php @@ -0,0 +1,12 @@ +interactive() based on posix_isatty(). + * + * @return $this + */ + public function detectInteractive() + { + // If the caller did not explicity set the 'interactive' mode, + // and output should be produced by this task (verbosityMeetsThreshold), + // then we will automatically set interactive mode based on whether + // or not output was redirected when robo was executed. + if (!isset($this->interactive) && function_exists('posix_isatty') && $this->verbosityMeetsThreshold()) { + $this->interactive = posix_isatty(STDOUT); + } + + return $this; + } + + /** + * Executes command in background mode (asynchronously) + * + * @return $this + */ + public function background($arg = true) + { + $this->background = $arg; + return $this; + } + + /** + * Stop command if it runs longer then $timeout in seconds + * + * @param int $timeout + * + * @return $this + */ + public function timeout($timeout) + { + $this->timeout = $timeout; + return $this; + } + + /** + * Stops command if it does not output something for a while + * + * @param int $timeout + * + * @return $this + */ + public function idleTimeout($timeout) + { + $this->idleTimeout = $timeout; + return $this; + } + + /** + * Set a single environment variable, or multiple. + */ + public function env($env, $value = null) + { + if (!is_array($env)) { + $env = [$env => ($value ? $value : true)]; + } + return $this->envVars($env); + } + + /** + * Sets the environment variables for the command + * + * @param array $env + * + * @return $this + */ + public function envVars(array $env) + { + $this->env = $env; + return $this; + } + + /** + * Pass an input to the process. Can be resource created with fopen() or string + * + * @param resource|string $input + * + * @return $this + */ + public function setInput($input) + { + $this->input = $input; + return $this; + } + + /** + * Attach tty to process for interactive input + * + * @param $interactive bool + * + * @return $this + */ + public function interactive($interactive = true) + { + $this->interactive = $interactive; + return $this; + } + + + /** + * Is command printing its output to screen + * + * @return bool + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * Changes working directory of command + * + * @param string $dir + * + * @return $this + */ + public function dir($dir) + { + $this->workingDirectory = $dir; + return $this; + } + + /** + * Shortcut for setting isPrinted() and isMetadataPrinted() to false. + * + * @param bool $arg + * + * @return $this + */ + public function silent($arg) + { + if (is_bool($arg)) { + $this->isPrinted = !$arg; + $this->isMetadataPrinted = !$arg; + } + return $this; + } + + /** + * Should command output be printed + * + * @param bool $arg + * + * @return $this + * + * @deprecated + */ + public function printed($arg) + { + $this->logger->warning("printed() is deprecated. Please use printOutput()."); + return $this->printOutput($arg); + } + + /** + * Should command output be printed + * + * @param bool $arg + * + * @return $this + */ + public function printOutput($arg) + { + if (is_bool($arg)) { + $this->isPrinted = $arg; + } + return $this; + } + + /** + * Should command metadata be printed. I,e., command and timer. + * + * @param bool $arg + * + * @return $this + */ + public function printMetadata($arg) + { + if (is_bool($arg)) { + $this->isMetadataPrinted = $arg; + } + return $this; + } + + /** + * @param Process $process + * @param callable $output_callback + * + * @return \Robo\ResultData + */ + protected function execute($process, $output_callback = null) + { + $this->process = $process; + + if (!$output_callback) { + $output_callback = function ($type, $buffer) { + $progressWasVisible = $this->hideTaskProgress(); + $this->writeMessage($buffer); + $this->showTaskProgress($progressWasVisible); + }; + } + + $this->detectInteractive(); + + if ($this->isMetadataPrinted) { + $this->printAction(); + } + $this->process->setTimeout($this->timeout); + $this->process->setIdleTimeout($this->idleTimeout); + if ($this->workingDirectory) { + $this->process->setWorkingDirectory($this->workingDirectory); + } + if ($this->input) { + $this->process->setInput($this->input); + } + + if ($this->interactive && $this->isPrinted) { + $this->process->setTty(true); + } + + if (isset($this->env)) { + $this->process->setEnv($this->env); + } + + if (!$this->background && !$this->isPrinted) { + $this->startTimer(); + $this->process->run(); + $this->stopTimer(); + $output = rtrim($this->process->getOutput()); + return new ResultData( + $this->process->getExitCode(), + $output, + $this->getResultData() + ); + } + + if (!$this->background && $this->isPrinted) { + $this->startTimer(); + $this->process->run($output_callback); + $this->stopTimer(); + return new ResultData( + $this->process->getExitCode(), + $this->process->getOutput(), + $this->getResultData() + ); + } + + try { + $this->process->start(); + } catch (\Exception $e) { + return new ResultData( + $this->process->getExitCode(), + $e->getMessage(), + $this->getResultData() + ); + } + return new ResultData($this->process->getExitCode()); + } + + /** + * + */ + protected function stop() + { + if ($this->background && isset($this->process) && $this->process->isRunning()) { + $this->process->stop(); + $this->printTaskInfo( + "Stopped {command}", + ['command' => $this->getCommandDescription()] + ); + } + } + + /** + * @param array $context + */ + protected function printAction($context = []) + { + $command = $this->getCommandDescription(); + $formatted_command = $this->formatCommandDisplay($command); + + $dir = $this->workingDirectory ? " in {dir}" : ""; + $this->printTaskInfo("Running {command}$dir", [ + 'command' => $formatted_command, + 'dir' => $this->workingDirectory + ] + $context); + } + + /** + * @param $command + * + * @return mixed + */ + protected function formatCommandDisplay($command) + { + $formatted_command = str_replace("&&", "&&\n", $command); + $formatted_command = str_replace("||", "||\n", $formatted_command); + + return $formatted_command; + } + + /** + * Gets the data array to be passed to Result(). + * + * @return array + * The data array passed to Result(). + */ + protected function getResultData() + { + if ($this->isMetadataPrinted) { + return ['time' => $this->getExecutionTime()]; + } + + return []; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/IO.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/IO.php new file mode 100644 index 00000000..d6c77bff --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/IO.php @@ -0,0 +1,171 @@ +io) { + $this->io = new SymfonyStyle($this->input(), $this->output()); + } + return $this->io; + } + + /** + * @param string $nonDecorated + * @param string $decorated + * + * @return string + */ + protected function decorationCharacter($nonDecorated, $decorated) + { + if (!$this->output()->isDecorated() || (strncasecmp(PHP_OS, 'WIN', 3) == 0)) { + return $nonDecorated; + } + return $decorated; + } + + /** + * @param string $text + */ + protected function say($text) + { + $char = $this->decorationCharacter('>', '➜'); + $this->writeln("$char $text"); + } + + /** + * @param string $text + * @param int $length + * @param string $color + */ + protected function yell($text, $length = 40, $color = 'green') + { + $char = $this->decorationCharacter(' ', '➜'); + $format = "$char %s"; + $this->formattedOutput($text, $length, $format); + } + + /** + * @param string $text + * @param int $length + * @param string $format + */ + protected function formattedOutput($text, $length, $format) + { + $lines = explode("\n", trim($text, "\n")); + $maxLineLength = array_reduce(array_map('strlen', $lines), 'max'); + $length = max($length, $maxLineLength); + $len = $length + 2; + $space = str_repeat(' ', $len); + $this->writeln(sprintf($format, $space)); + foreach ($lines as $line) { + $line = str_pad($line, $length, ' ', STR_PAD_BOTH); + $this->writeln(sprintf($format, " $line ")); + } + $this->writeln(sprintf($format, $space)); + } + + /** + * @param string $question + * @param bool $hideAnswer + * + * @return string + */ + protected function ask($question, $hideAnswer = false) + { + if ($hideAnswer) { + return $this->askHidden($question); + } + return $this->doAsk(new Question($this->formatQuestion($question))); + } + + /** + * @param string $question + * + * @return string + */ + protected function askHidden($question) + { + $question = new Question($this->formatQuestion($question)); + $question->setHidden(true); + return $this->doAsk($question); + } + + /** + * @param string $question + * @param string $default + * + * @return string + */ + protected function askDefault($question, $default) + { + return $this->doAsk(new Question($this->formatQuestion("$question [$default]"), $default)); + } + + /** + * @param string $question + * + * @return string + */ + protected function confirm($question) + { + return $this->doAsk(new ConfirmationQuestion($this->formatQuestion($question . ' (y/n)'), false)); + } + + /** + * @param \Symfony\Component\Console\Question\Question $question + * + * @return string + */ + protected function doAsk(Question $question) + { + return $this->getDialog()->ask($this->input(), $this->output(), $question); + } + + /** + * @param string $message + * + * @return string + */ + protected function formatQuestion($message) + { + return "? $message "; + } + + /** + * @return \Symfony\Component\Console\Helper\QuestionHelper + */ + protected function getDialog() + { + return new QuestionHelper(); + } + + /** + * @param $text + */ + protected function writeln($text) + { + $this->output()->writeln($text); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/InflectionTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/InflectionTrait.php new file mode 100644 index 00000000..8bc4e831 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/InflectionTrait.php @@ -0,0 +1,21 @@ +injectDependencies($this); + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/InputAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/InputAwareTrait.php new file mode 100644 index 00000000..bae58c17 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/InputAwareTrait.php @@ -0,0 +1,51 @@ +input = $input; + + return $this; + } + + /** + * @return \Symfony\Component\Console\Input\InputInterface + */ + protected function input() + { + if (!isset($this->input)) { + $this->setInput(new ArgvInput()); + } + return $this->input; + } + + /** + * Backwards compatibility. + * + * @return \Symfony\Component\Console\Input\InputInterface + * + * @deprecated + */ + protected function getInput() + { + return $this->input(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/OutputAdapter.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/OutputAdapter.php new file mode 100644 index 00000000..b8e795f2 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/OutputAdapter.php @@ -0,0 +1,38 @@ + OutputInterface::VERBOSITY_NORMAL, + VerbosityThresholdInterface::VERBOSITY_VERBOSE => OutputInterface::VERBOSITY_VERBOSE, + VerbosityThresholdInterface::VERBOSITY_VERY_VERBOSE => OutputInterface::VERBOSITY_VERY_VERBOSE, + VerbosityThresholdInterface::VERBOSITY_DEBUG => OutputInterface::VERBOSITY_DEBUG, + ]; + + public function verbosityMeetsThreshold($verbosityThreshold) + { + if (!isset($this->verbosityMap[$verbosityThreshold])) { + return true; + } + $verbosityThreshold = $this->verbosityMap[$verbosityThreshold]; + $verbosity = $this->output()->getVerbosity(); + + return $verbosity >= $verbosityThreshold; + } + + public function writeMessage($message) + { + $this->output()->write($message); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/OutputAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/OutputAwareTrait.php new file mode 100644 index 00000000..48082cb3 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/OutputAwareTrait.php @@ -0,0 +1,51 @@ +output = $output; + + return $this; + } + + /** + * @return \Symfony\Component\Console\Output\OutputInterface + */ + protected function output() + { + if (!isset($this->output)) { + $this->setOutput(new NullOutput()); + } + return $this->output; + } + + /** + * Backwards compatibility + * + * @return \Symfony\Component\Console\Output\OutputInterface + * + * @deprecated + */ + protected function getOutput() + { + return $this->output(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProcessExecutor.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProcessExecutor.php new file mode 100644 index 00000000..f78a4775 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProcessExecutor.php @@ -0,0 +1,51 @@ +process = $process; + } + + public static function create($container, $process) + { + $processExecutor = new self($process); + + $processExecutor->setLogger($container->get('logger')); + $processExecutor->setProgressIndicator($container->get('progressIndicator')); + $processExecutor->setConfig($container->get('config')); + $processExecutor->setOutputAdapter($container->get('outputAdapter')); + + return $processExecutor; + } + + /** + * @return string + */ + protected function getCommandDescription() + { + return $this->process->getCommandLine(); + } + + public function run() + { + return $this->execute($this->process); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProcessUtils.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProcessUtils.php new file mode 100644 index 00000000..7dc4e553 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProcessUtils.php @@ -0,0 +1,79 @@ + + */ + +namespace Robo\Common; + +use Symfony\Component\Process\Exception\InvalidArgumentException; + +/** + * ProcessUtils is a bunch of utility methods. We want to allow Robo 1.x + * to work with Symfony 4.x while remaining backwards compatibility. This + * requires us to replace some deprecated functionality removed in Symfony. + */ +class ProcessUtils +{ + /** + * This class should not be instantiated. + */ + private function __construct() + { + } + + /** + * Escapes a string to be used as a shell argument. + * + * @param string $argument The argument that will be escaped + * + * @return string The escaped argument + * + * @deprecated since version 3.3, to be removed in 4.0. Use a command line array or give env vars to the `Process::start/run()` method instead. + */ + public static function escapeArgument($argument) + { + @trigger_error('The '.__METHOD__.'() method is a copy of a method that was deprecated by Symfony 3.3 and removed in Symfony 4; it will be removed in Robo 2.0.', E_USER_DEPRECATED); + + //Fix for PHP bug #43784 escapeshellarg removes % from given string + //Fix for PHP bug #49446 escapeshellarg doesn't work on Windows + //@see https://bugs.php.net/bug.php?id=43784 + //@see https://bugs.php.net/bug.php?id=49446 + if ('\\' === DIRECTORY_SEPARATOR) { + if ('' === $argument) { + return escapeshellarg($argument); + } + + $escapedArgument = ''; + $quote = false; + foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) { + if ('"' === $part) { + $escapedArgument .= '\\"'; + } elseif (self::isSurroundedBy($part, '%')) { + // Avoid environment variable expansion + $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%'; + } else { + // escape trailing backslash + if ('\\' === substr($part, -1)) { + $part .= '\\'; + } + $quote = true; + $escapedArgument .= $part; + } + } + if ($quote) { + $escapedArgument = '"'.$escapedArgument.'"'; + } + + return $escapedArgument; + } + + return "'".str_replace("'", "'\\''", $argument)."'"; + } + + private static function isSurroundedBy($arg, $char) + { + return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1]; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProgressIndicator.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProgressIndicator.php new file mode 100644 index 00000000..050250e5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProgressIndicator.php @@ -0,0 +1,201 @@ +progressBar = $progressBar; + $this->output = $output; + } + + /** + * @param int $interval + */ + public function setProgressBarAutoDisplayInterval($interval) + { + if ($this->progressIndicatorRunning) { + return; + } + $this->autoDisplayInterval = $interval; + } + + /** + * @return bool + */ + public function hideProgressIndicator() + { + $result = $this->progressBarDisplayed; + if ($this->progressIndicatorRunning && $this->progressBarDisplayed) { + $this->progressBar->clear(); + // Hack: progress indicator does not reset cursor to beginning of line on 'clear' + $this->output->write("\x0D"); + $this->progressBarDisplayed = false; + } + return $result; + } + + public function showProgressIndicator() + { + if ($this->progressIndicatorRunning && !$this->progressBarDisplayed && isset($this->progressBar)) { + $this->progressBar->display(); + $this->progressBarDisplayed = true; + $this->advanceProgressIndicatorCachedSteps(); + } + } + + /** + * @param bool $visible + */ + public function restoreProgressIndicator($visible) + { + if ($visible) { + $this->showProgressIndicator(); + } + } + + /** + * @param int $totalSteps + * @param \Robo\Contract\TaskInterface $owner + */ + public function startProgressIndicator($totalSteps, $owner) + { + if (!isset($this->progressBar)) { + return; + } + + $this->progressIndicatorRunning = true; + if (!isset($this->owner)) { + $this->owner = $owner; + $this->startTimer(); + $this->totalSteps = $totalSteps; + $this->autoShowProgressIndicator(); + } + } + + public function autoShowProgressIndicator() + { + if (($this->autoDisplayInterval < 0) || !isset($this->progressBar) || !$this->output->isDecorated()) { + return; + } + if ($this->autoDisplayInterval <= $this->getExecutionTime()) { + $this->autoDisplayInterval = -1; + $this->progressBar->start($this->totalSteps); + $this->showProgressIndicator(); + } + } + + /** + * @return bool + */ + public function inProgress() + { + return $this->progressIndicatorRunning; + } + + /** + * @param \Robo\Contract\TaskInterface $owner + */ + public function stopProgressIndicator($owner) + { + if ($this->progressIndicatorRunning && ($this->owner === $owner)) { + $this->cleanup(); + } + } + + protected function cleanup() + { + $this->progressIndicatorRunning = false; + $this->owner = null; + if ($this->progressBarDisplayed) { + $this->progressBar->finish(); + // Hack: progress indicator does not always finish cleanly + $this->output->writeln(''); + $this->progressBarDisplayed = false; + } + $this->stopTimer(); + } + + /** + * Erase progress indicator and ensure it never returns. Used + * only during error handlers. + */ + public function disableProgressIndicator() + { + $this->cleanup(); + // ProgressIndicator is shared, so this permanently removes + // the program's ability to display progress bars. + $this->progressBar = null; + } + + /** + * @param int $steps + */ + public function advanceProgressIndicator($steps = 1) + { + $this->cachedSteps += $steps; + if ($this->progressIndicatorRunning) { + $this->autoShowProgressIndicator(); + // We only want to call `advance` if the progress bar is visible, + // because it always displays itself when it is advanced. + if ($this->progressBarDisplayed) { + return $this->advanceProgressIndicatorCachedSteps(); + } + } + } + + protected function advanceProgressIndicatorCachedSteps() + { + $this->progressBar->advance($this->cachedSteps); + $this->cachedSteps = 0; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProgressIndicatorAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProgressIndicatorAwareTrait.php new file mode 100644 index 00000000..060e039a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ProgressIndicatorAwareTrait.php @@ -0,0 +1,135 @@ +progressIndicator = $progressIndicator; + + return $this; + } + + /** + * @return null|bool + */ + protected function hideProgressIndicator() + { + if (!$this->progressIndicator) { + return; + } + return $this->progressIndicator->hideProgressIndicator(); + } + + protected function showProgressIndicator() + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->showProgressIndicator(); + } + + /** + * @param bool $visible + */ + protected function restoreProgressIndicator($visible) + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->restoreProgressIndicator($visible); + } + + /** + * @return int + */ + protected function getTotalExecutionTime() + { + if (!$this->progressIndicator) { + return 0; + } + return $this->progressIndicator->getExecutionTime(); + } + + protected function startProgressIndicator() + { + $this->startTimer(); + if ($this instanceof VerbosityThresholdInterface + && !$this->verbosityMeetsThreshold()) { + return; + } + if (!$this->progressIndicator) { + return; + } + $totalSteps = $this->progressIndicatorSteps(); + $this->progressIndicator->startProgressIndicator($totalSteps, $this); + } + + /** + * @return bool + */ + protected function inProgress() + { + if (!$this->progressIndicator) { + return false; + } + return $this->progressIndicator->inProgress(); + } + + protected function stopProgressIndicator() + { + $this->stopTimer(); + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->stopProgressIndicator($this); + } + + protected function disableProgressIndicator() + { + $this->stopTimer(); + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->disableProgressIndicator(); + } + + protected function detatchProgressIndicator() + { + $this->setProgressIndicator(null); + } + + /** + * @param int $steps + */ + protected function advanceProgressIndicator($steps = 1) + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->advanceProgressIndicator($steps); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ResourceExistenceChecker.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ResourceExistenceChecker.php new file mode 100644 index 00000000..233f90a9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/ResourceExistenceChecker.php @@ -0,0 +1,116 @@ +printTaskError(sprintf('Invalid glob "%s"!', $resource), $this); + $success = false; + continue; + } + foreach ($glob as $resource) { + if (!$this->checkResource($resource, $type)) { + $success = false; + } + } + } + return $success; + } + + /** + * Checks a single resource, file or directory. + * + * It will print an error as well on the console. + * + * @param string $resource File or folder. + * @param string $type "file", "dir", "fileAndDir" + * + * @return bool + */ + protected function checkResource($resource, $type) + { + switch ($type) { + case 'file': + if (!$this->isFile($resource)) { + $this->printTaskError(sprintf('File "%s" does not exist!', $resource), $this); + return false; + } + return true; + case 'dir': + if (!$this->isDir($resource)) { + $this->printTaskError(sprintf('Directory "%s" does not exist!', $resource), $this); + return false; + } + return true; + case 'fileAndDir': + if (!$this->isDir($resource) && !$this->isFile($resource)) { + $this->printTaskError(sprintf('File or directory "%s" does not exist!', $resource), $this); + return false; + } + return true; + } + } + + /** + * Convenience method to check the often uses "source => target" file / folder arrays. + * + * @param string|array $resources + */ + protected function checkSourceAndTargetResource($resources) + { + if (is_string($resources)) { + $resources = [$resources]; + } + $sources = []; + $targets = []; + foreach ($resources as $source => $target) { + $sources[] = $source; + $target[] = $target; + } + $this->checkResources($sources); + $this->checkResources($targets); + } + + /** + * Wrapper method around phps is_dir() + * + * @param string $directory + * + * @return bool + */ + protected function isDir($directory) + { + return is_dir($directory); + } + + /** + * Wrapper method around phps file_exists() + * + * @param string $file + * + * @return bool + */ + protected function isFile($file) + { + return file_exists($file); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/TaskIO.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/TaskIO.php new file mode 100644 index 00000000..49b5ccd8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/TaskIO.php @@ -0,0 +1,237 @@ +logger should always be set in Robo core tasks. + if ($this->logger) { + return $this->logger; + } + + // TODO: Remove call to Robo::logger() once maintaining backwards + // compatibility with legacy external Robo tasks is no longer desired. + if (!Robo::logger()) { + return null; + } + + static $gaveDeprecationWarning = false; + if (!$gaveDeprecationWarning) { + trigger_error('No logger set for ' . get_class($this) . '. Use $this->task(Foo::class) rather than new Foo() in loadTasks to ensure the builder can initialize task the task, or use $this->collectionBuilder()->taskFoo() if creating one task from within another.', E_USER_DEPRECATED); + $gaveDeprecationWarning = true; + } + return Robo::logger(); + } + + /** + * Print information about a task in progress. + * + * With the Symfony Console logger, NOTICE is displayed at VERBOSITY_VERBOSE + * and INFO is displayed at VERBOSITY_VERY_VERBOSE. + * + * Robo overrides the default such that NOTICE is displayed at + * VERBOSITY_NORMAL and INFO is displayed at VERBOSITY_VERBOSE. + * + * n.b. We should probably have printTaskNotice for our ordinary + * output, and use printTaskInfo for less interesting messages. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskInfo($text, $context = null) + { + // The 'note' style is used for both 'notice' and 'info' log levels; + // However, 'notice' is printed at VERBOSITY_NORMAL, whereas 'info' + // is only printed at VERBOSITY_VERBOSE. + $this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that some part of the task succeeded. + * + * With the Symfony Console logger, success messages are remapped to NOTICE, + * and displayed in VERBOSITY_VERBOSE. When used with the Robo logger, + * success messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskSuccess($text, $context = null) + { + // Not all loggers will recognize ConsoleLogLevel::SUCCESS. + // We therefore log as LogLevel::NOTICE, and apply a '_level' + // override in the context so that this message will be + // logged as SUCCESS if that log level is recognized. + $context['_level'] = ConsoleLogLevel::SUCCESS; + $this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that there is something wrong, but + * execution can continue. + * + * Warning messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskWarning($text, $context = null) + { + $this->printTaskOutput(LogLevel::WARNING, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that some operation in the task failed, + * and the task cannot continue. + * + * Error messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskError($text, $context = null) + { + $this->printTaskOutput(LogLevel::ERROR, $text, $this->getTaskContext($context)); + } + + /** + * Provide debugging notification. These messages are only + * displayed if the log level is VERBOSITY_DEBUG. + * + * @param string$text + * @param null|array $context + */ + protected function printTaskDebug($text, $context = null) + { + $this->printTaskOutput(LogLevel::DEBUG, $text, $this->getTaskContext($context)); + } + + /** + * @param string $level + * One of the \Psr\Log\LogLevel constant + * @param string $text + * @param null|array $context + */ + protected function printTaskOutput($level, $text, $context) + { + if (!$this->verbosityMeetsThreshold()) { + return; + } + $logger = $this->logger(); + if (!$logger) { + return; + } + // Hide the progress indicator, if it is visible. + $inProgress = $this->hideTaskProgress(); + $logger->log($level, $text, $this->getTaskContext($context)); + // After we have printed our log message, redraw the progress indicator. + $this->showTaskProgress($inProgress); + } + + /** + * @return bool + */ + protected function hideTaskProgress() + { + $inProgress = false; + if ($this instanceof ProgressIndicatorAwareInterface) { + $inProgress = $this->inProgress(); + } + + // If a progress indicator is running on this task, then we mush + // hide it before we print anything, or its display will be overwritten. + if ($inProgress) { + $inProgress = $this->hideProgressIndicator(); + } + return $inProgress; + } + + /** + * @param $inProgress + */ + protected function showTaskProgress($inProgress) + { + if ($inProgress) { + $this->restoreProgressIndicator($inProgress); + } + } + + /** + * Format a quantity of bytes. + * + * @param int $size + * @param int $precision + * + * @return string + */ + protected function formatBytes($size, $precision = 2) + { + if ($size === 0) { + return 0; + } + $base = log($size, 1024); + $suffixes = array('', 'k', 'M', 'G', 'T'); + return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)]; + } + + /** + * Get the formatted task name for use in task output. + * This is placed in the task context under 'name', and + * used as the log label by Robo\Common\RoboLogStyle, + * which is inserted at the head of log messages by + * Robo\Common\CustomLogStyle::formatMessage(). + * + * @param null|object $task + * + * @return string + */ + protected function getPrintedTaskName($task = null) + { + if (!$task) { + $task = $this; + } + return TaskInfo::formatTaskName($task); + } + + /** + * @param null|array $context + * + * @return array with context information + */ + protected function getTaskContext($context = null) + { + if (!$context) { + $context = []; + } + if (!is_array($context)) { + $context = ['task' => $context]; + } + if (!array_key_exists('task', $context)) { + $context['task'] = $this; + } + + return $context + TaskInfo::getTaskContext($context['task']); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/TimeKeeper.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/TimeKeeper.php new file mode 100644 index 00000000..1cd3e334 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/TimeKeeper.php @@ -0,0 +1,69 @@ +startedAt) { + return; + } + // Get time in seconds as a float, accurate to the microsecond. + $this->startedAt = microtime(true); + } + + public function stop() + { + $this->finishedAt = microtime(true); + } + + /** + * @return float|null + */ + public function elapsed() + { + $finished = $this->finishedAt ? $this->finishedAt : microtime(true); + if ($finished - $this->startedAt <= 0) { + return null; + } + return $finished - $this->startedAt; + } + + /** + * Format a duration into a human-readable time + * + * @param float $duration Duration in seconds, with fractional component + * + * @return string + */ + public static function formatDuration($duration) + { + if ($duration >= self::DAY * 2) { + return gmdate('z \d\a\y\s H:i:s', $duration); + } + if ($duration > self::DAY) { + return gmdate('\1 \d\a\y H:i:s', $duration); + } + if ($duration > self::HOUR) { + return gmdate("H:i:s", $duration); + } + if ($duration > self::MINUTE) { + return gmdate("i:s", $duration); + } + return round($duration, 3).'s'; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/Timer.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/Timer.php new file mode 100644 index 00000000..955eb5bb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/Timer.php @@ -0,0 +1,37 @@ +timer)) { + $this->timer = new TimeKeeper(); + } + $this->timer->start(); + } + + protected function stopTimer() + { + if (!isset($this->timer)) { + return; + } + $this->timer->stop(); + } + + /** + * @return float|null + */ + protected function getExecutionTime() + { + if (!isset($this->timer)) { + return null; + } + return $this->timer->elapsed(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/VerbosityThresholdTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/VerbosityThresholdTrait.php new file mode 100644 index 00000000..2fc51c22 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Common/VerbosityThresholdTrait.php @@ -0,0 +1,79 @@ +verbosityThreshold = $verbosityThreshold; + return $this; + } + + public function verbosityThreshold() + { + return $this->verbosityThreshold; + } + + public function setOutputAdapter(OutputAdapterInterface $outputAdapter) + { + $this->outputAdapter = $outputAdapter; + } + + /** + * @return OutputAdapterInterface + */ + public function outputAdapter() + { + return $this->outputAdapter; + } + + public function hasOutputAdapter() + { + return isset($this->outputAdapter); + } + + public function verbosityMeetsThreshold() + { + if ($this->hasOutputAdapter()) { + return $this->outputAdapter()->verbosityMeetsThreshold($this->verbosityThreshold()); + } + return true; + } + + /** + * Print a message if the selected verbosity level is over this task's + * verbosity threshhold. + */ + public function writeMessage($message) + { + if (!$this->verbosityMeetsThreshold()) { + return; + } + $this->outputAdapter()->writeMessage($message); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config.php new file mode 100644 index 00000000..9e9370d8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config.php @@ -0,0 +1,9 @@ +defaults = $this->getGlobalOptionDefaultValues(); + } + + /** + * Return an associative array containing all of the global configuration + * options and their default values. + * + * @return array + */ + public function getGlobalOptionDefaultValues() + { + $globalOptions = + [ + self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL => self::DEFAULT_PROGRESS_DELAY, + self::SIMULATE => false, + ]; + return $this->trimPrefixFromGlobalOptions($globalOptions); + } + + /** + * Remove the 'options.' prefix from the global options list. + */ + protected function trimPrefixFromGlobalOptions($globalOptions) + { + $result = []; + foreach ($globalOptions as $option => $value) { + $option = str_replace('options.', '', $option); + $result[$option] = $value; + } + return $result; + } + + /** + * @deprecated Use $config->get(Config::SIMULATE) + * + * @return bool + */ + public function isSimulated() + { + return $this->get(self::SIMULATE); + } + + /** + * @deprecated Use $config->set(Config::SIMULATE, true) + * + * @param bool $simulated + * + * @return $this + */ + public function setSimulated($simulated = true) + { + return $this->set(self::SIMULATE, $simulated); + } + + /** + * @deprecated Use $config->get(Config::INTERACTIVE) + * + * @return bool + */ + public function isInteractive() + { + return $this->get(self::INTERACTIVE); + } + + /** + * @deprecated Use $config->set(Config::INTERACTIVE, true) + * + * @param bool $interactive + * + * @return $this + */ + public function setInteractive($interactive = true) + { + return $this->set(self::INTERACTIVE, $interactive); + } + + /** + * @deprecated Use $config->get(Config::DECORATED) + * + * @return bool + */ + public function isDecorated() + { + return $this->get(self::DECORATED); + } + + /** + * @deprecated Use $config->set(Config::DECORATED, true) + * + * @param bool $decorated + * + * @return $this + */ + public function setDecorated($decorated = true) + { + return $this->set(self::DECORATED, $decorated); + } + + /** + * @deprecated Use $config->set(Config::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL, $interval) + * + * @param int $interval + * + * @return $this + */ + public function setProgressBarAutoDisplayInterval($interval) + { + return $this->set(self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL, $interval); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config/GlobalOptionDefaultValuesInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config/GlobalOptionDefaultValuesInterface.php new file mode 100644 index 00000000..f7639455 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Config/GlobalOptionDefaultValuesInterface.php @@ -0,0 +1,17 @@ +inflect($this) + * ->initializer() + * ->... + * + * Instead of: + * + * (new SomeTask($args)) + * ->setLogger($this->logger) + * ->initializer() + * ->... + * + * The reason `inflect` is better than the more explicit alternative is + * that subclasses of BaseTask that implement a new FooAwareInterface + * can override injectDependencies() as explained below, and add more + * dependencies that can be injected as needed. + * + * @param \Robo\Contract\InflectionInterface $parent + */ + public function inflect(InflectionInterface $parent); + + /** + * Take all dependencies availble to this task and inject any that are + * needed into the provided task. The general pattern is that, for every + * FooAwareInterface that this class implements, it should test to see + * if the child also implements the same interface, and if so, should call + * $child->setFoo($this->foo). + * + * The benefits of this are pretty large. Any time an object that implements + * InflectionInterface is created, just call `$child->inflect($this)`, and + * any available optional dependencies will be hooked up via setter injection. + * + * The required dependencies of an object should be provided via constructor + * injection, not inflection. + * + * @param InflectionInterface $child An object created by this class that + * should have its dependencies injected. + * + * @see https://mwop.net/blog/2016-04-26-on-locators.html + */ + public function injectDependencies(InflectionInterface $child); +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/OutputAdapterInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/OutputAdapterInterface.php new file mode 100644 index 00000000..948d384c --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Contract/OutputAdapterInterface.php @@ -0,0 +1,11 @@ +prefix = 'options'; + } + + /** + * Add a reference to the Symfony Console application object. + */ + public function setApplication($application) + { + $this->application = $application; + return $this; + } + + /** + * Stipulate the prefix to use for option injection. + * @param string $prefix + */ + public function setGlobalOptionsPrefix($prefix) + { + $this->prefix = $prefix; + return $this; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return [ConsoleEvents::COMMAND => 'handleCommandEvent']; + } + + /** + * Run all of our individual operations when a command event is received. + */ + public function handleCommandEvent(ConsoleCommandEvent $event) + { + $this->setGlobalOptions($event); + $this->setConfigurationValues($event); + } + + /** + * Before a Console command runs, examine the global + * commandline options from the event Input, and set + * configuration values as appropriate. + * + * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event + */ + public function setGlobalOptions(ConsoleCommandEvent $event) + { + $config = $this->getConfig(); + $input = $event->getInput(); + + $globalOptions = $config->get($this->prefix, []); + if ($config instanceof \Consolidation\Config\GlobalOptionDefaultValuesInterface) { + $globalOptions += $config->getGlobalOptionDefaultValues(); + } + + $globalOptions += $this->applicationOptionDefaultValues(); + + // Set any config value that has a defined global option (e.g. --simulate) + foreach ($globalOptions as $option => $default) { + $value = $input->hasOption($option) ? $input->getOption($option) : null; + // Unfortunately, the `?:` operator does not differentate between `0` and `null` + if (!isset($value)) { + $value = $default; + } + $config->set($this->prefix . '.' . $option, $value); + } + } + + /** + * Examine the commandline --define / -D options, and apply the provided + * values to the active configuration. + * + * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event + */ + public function setConfigurationValues(ConsoleCommandEvent $event) + { + $config = $this->getConfig(); + $input = $event->getInput(); + + // Also set any `-D config.key=value` options from the commandline. + if ($input->hasOption('define')) { + $configDefinitions = $input->getOption('define'); + foreach ($configDefinitions as $value) { + list($key, $value) = $this->splitConfigKeyValue($value); + $config->set($key, $value); + } + } + } + + /** + * Split up the key=value config setting into its component parts. If + * the input string contains no '=' character, then the value will be 'true'. + * + * @param string $value + * @return array + */ + protected function splitConfigKeyValue($value) + { + $parts = explode('=', $value, 2); + $parts[] = true; + return $parts; + } + + /** + * Get default option values from the Symfony Console application, if + * it is available. + */ + protected function applicationOptionDefaultValues() + { + if (!$this->application) { + return []; + } + + $result = []; + foreach ($this->application->getDefinition()->getOptions() as $key => $option) { + $result[$key] = $option->acceptValue() ? $option->getDefault() : null; + } + return $result; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/LoadAllTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/LoadAllTasks.php new file mode 100644 index 00000000..3183d5b6 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/LoadAllTasks.php @@ -0,0 +1,39 @@ +getTask(); + if ($task instanceof VerbosityThresholdInterface && !$task->verbosityMeetsThreshold()) { + return; + } + if (!$result->wasSuccessful()) { + return $this->printError($result); + } else { + return $this->printSuccess($result); + } + } + + /** + * Log that we are about to abort due to an error being encountered + * in 'stop on fail' mode. + * + * @param \Robo\Result $result + */ + public function printStopOnFail($result) + { + $this->printMessage(LogLevel::NOTICE, 'Stopping on fail. Exiting....'); + $this->printMessage(LogLevel::ERROR, 'Exit Code: {code}', ['code' => $result->getExitCode()]); + } + + /** + * Log the result of a Robo task that returned an error. + * + * @param \Robo\Result $result + * + * @return bool + */ + protected function printError(Result $result) + { + $task = $result->getTask(); + $context = $result->getContext() + ['timer-label' => 'Time', '_style' => []]; + $context['_style']['message'] = ''; + + $printOutput = true; + if ($task instanceof PrintedInterface) { + $printOutput = !$task->getPrinted(); + } + if ($printOutput) { + $this->printMessage(LogLevel::ERROR, "{message}", $context); + } + $this->printMessage(LogLevel::ERROR, 'Exit code {code}', $context); + return true; + } + + /** + * Log the result of a Robo task that was successful. + * + * @param \Robo\Result $result + * + * @return bool + */ + protected function printSuccess(Result $result) + { + $task = $result->getTask(); + $context = $result->getContext() + ['timer-label' => 'in']; + $time = $result->getExecutionTime(); + if ($time) { + $this->printMessage(ConsoleLogLevel::SUCCESS, 'Done', $context); + } + return false; + } + + /** + * @param string $level + * @param string $message + * @param array $context + */ + protected function printMessage($level, $message, $context = []) + { + $inProgress = $this->hideProgressIndicator(); + $this->logger->log($level, $message, $context); + if ($inProgress) { + $this->restoreProgressIndicator($inProgress); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogLevel.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogLevel.php new file mode 100644 index 00000000..d7d5eb0a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogLevel.php @@ -0,0 +1,11 @@ +labelStyles += [ + RoboLogLevel::SIMULATED_ACTION => self::TASK_STYLE_SIMULATED, + ]; + $this->messageStyles += [ + RoboLogLevel::SIMULATED_ACTION => '', + ]; + } + + /** + * Log style customization for Robo: replace the log level with + * the task name. + * + * @param string $level + * @param string $message + * @param array $context + * + * @return string + */ + protected function formatMessageByLevel($level, $message, $context) + { + $label = $level; + if (array_key_exists('name', $context)) { + $label = $context['name']; + } + return $this->formatMessage($label, $message, $context, $this->labelStyles[$level], $this->messageStyles[$level]); + } + + /** + * Log style customization for Robo: add the time indicator to the + * end of the log message if it exists in the context. + * + * @param string $label + * @param string $message + * @param array $context + * @param string $taskNameStyle + * @param string $messageStyle + * + * @return string + */ + protected function formatMessage($label, $message, $context, $taskNameStyle, $messageStyle = '') + { + $message = parent::formatMessage($label, $message, $context, $taskNameStyle, $messageStyle); + + if (array_key_exists('time', $context) && !empty($context['time']) && array_key_exists('timer-label', $context)) { + $duration = TimeKeeper::formatDuration($context['time']); + $message .= ' ' . $context['timer-label'] . ' ' . $this->wrapFormatString($duration, 'fg=yellow'); + } + + return $message; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogger.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogger.php new file mode 100644 index 00000000..75cf23f7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Log/RoboLogger.php @@ -0,0 +1,29 @@ + OutputInterface::VERBOSITY_NORMAL, // Default is "verbose" + LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL, // Default is "verbose" + LogLevel::INFO => OutputInterface::VERBOSITY_VERBOSE, // Default is "very verbose" + ]; + parent::__construct($output, $roboVerbosityOverrides); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Result.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Result.php new file mode 100644 index 00000000..7d779352 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Result.php @@ -0,0 +1,258 @@ +task = $task; + $this->printResult(); + + if (self::$stopOnFail) { + $this->stopOnFail(); + } + } + + /** + * Tasks should always return a Result. However, they are also + * allowed to return NULL or an array to indicate success. + */ + public static function ensureResult($task, $result) + { + if ($result instanceof Result) { + return $result; + } + if (!isset($result)) { + return static::success($task); + } + if ($result instanceof Data) { + return static::success($task, $result->getMessage(), $result->getData()); + } + if ($result instanceof ResultData) { + return new Result($task, $result->getExitCode(), $result->getMessage(), $result->getData()); + } + if (is_array($result)) { + return static::success($task, '', $result); + } + throw new \Exception(sprintf('Task %s returned a %s instead of a \Robo\Result.', get_class($task), get_class($result))); + } + + protected function printResult() + { + // For historic reasons, the Result constructor is responsible + // for printing task results. + // TODO: Make IO the responsibility of some other class. Maintaining + // existing behavior for backwards compatibility. This is undesirable + // in the long run, though, as it can result in unwanted repeated input + // in task collections et. al. + $resultPrinter = Robo::resultPrinter(); + if ($resultPrinter) { + if ($resultPrinter->printResult($this)) { + $this->alreadyPrinted(); + } + } + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $extension + * @param string $service + * + * @return \Robo\Result + */ + public static function errorMissingExtension(TaskInterface $task, $extension, $service) + { + $messageTpl = 'PHP extension required for %s. Please enable %s'; + $message = sprintf($messageTpl, $service, $extension); + + return self::error($task, $message); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $class + * @param string $package + * + * @return \Robo\Result + */ + public static function errorMissingPackage(TaskInterface $task, $class, $package) + { + $messageTpl = 'Class %s not found. Please install %s Composer package'; + $message = sprintf($messageTpl, $class, $package); + + return self::error($task, $message); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $message + * @param array $data + * + * @return \Robo\Result + */ + public static function error(TaskInterface $task, $message, $data = []) + { + return new self($task, self::EXITCODE_ERROR, $message, $data); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param \Exception $e + * @param array $data + * + * @return \Robo\Result + */ + public static function fromException(TaskInterface $task, \Exception $e, $data = []) + { + $exitCode = $e->getCode(); + if (!$exitCode) { + $exitCode = self::EXITCODE_ERROR; + } + return new self($task, $exitCode, $e->getMessage(), $data); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $message + * @param array $data + * + * @return \Robo\Result + */ + public static function success(TaskInterface $task, $message = '', $data = []) + { + return new self($task, self::EXITCODE_OK, $message, $data); + } + + /** + * Return a context useful for logging messages. + * + * @return array + */ + public function getContext() + { + $task = $this->getTask(); + + return TaskInfo::getTaskContext($task) + [ + 'code' => $this->getExitCode(), + 'data' => $this->getArrayCopy(), + 'time' => $this->getExecutionTime(), + 'message' => $this->getMessage(), + ]; + } + + /** + * Add the results from the most recent task to the accumulated + * results from all tasks that have run so far, merging data + * as necessary. + * + * @param int|string $key + * @param \Robo\Result $taskResult + */ + public function accumulate($key, Result $taskResult) + { + // If the task is unnamed, then all of its data elements + // just get merged in at the top-level of the final Result object. + if (static::isUnnamed($key)) { + $this->merge($taskResult); + } elseif (isset($this[$key])) { + // There can only be one task with a given name; however, if + // there are tasks added 'before' or 'after' the named task, + // then the results from these will be stored under the same + // name unless they are given a name of their own when added. + $current = $this[$key]; + $this[$key] = $taskResult->merge($current); + } else { + $this[$key] = $taskResult; + } + } + + /** + * We assume that named values (e.g. for associative array keys) + * are non-numeric; numeric keys are presumed to simply be the + * index of an array, and therefore insignificant. + * + * @param int|string $key + * + * @return bool + */ + public static function isUnnamed($key) + { + return is_numeric($key); + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function getTask() + { + return $this->task; + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function cloneTask() + { + $reflect = new \ReflectionClass(get_class($this->task)); + return $reflect->newInstanceArgs(func_get_args()); + } + + /** + * @return bool + * + * @deprecated since 1.0. + * + * @see wasSuccessful() + */ + public function __invoke() + { + trigger_error(__METHOD__ . ' is deprecated: use wasSuccessful() instead.', E_USER_DEPRECATED); + return $this->wasSuccessful(); + } + + /** + * @return $this + */ + public function stopOnFail() + { + if (!$this->wasSuccessful()) { + $resultPrinter = Robo::resultPrinter(); + if ($resultPrinter) { + $resultPrinter->printStopOnFail($this); + } + $this->exitEarly($this->getExitCode()); + } + return $this; + } + + /** + * @param int $status + * + * @throws \Robo\Exception\TaskExitException + */ + private function exitEarly($status) + { + throw new TaskExitException($this->getTask(), $this->getMessage(), $status); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/ResultData.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/ResultData.php new file mode 100644 index 00000000..90baf6e9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/ResultData.php @@ -0,0 +1,110 @@ +exitCode = $exitCode; + parent::__construct($message, $data); + } + + /** + * @param string $message + * @param array $data + * + * @return \Robo\ResultData + */ + public static function message($message, $data = []) + { + return new self(self::EXITCODE_OK, $message, $data); + } + + /** + * @param string $message + * @param array $data + * + * @return \Robo\ResultData + */ + public static function cancelled($message = '', $data = []) + { + return new ResultData(self::EXITCODE_USER_CANCEL, $message, $data); + } + + /** + * @return int + */ + public function getExitCode() + { + return $this->exitCode; + } + + /** + * @return null|string + */ + public function getOutputData() + { + if (!empty($this->message) && !isset($this['already-printed']) && isset($this['provide-outputdata'])) { + return $this->message; + } + } + + /** + * Indicate that the message in this data has already been displayed. + */ + public function alreadyPrinted() + { + $this['already-printed'] = true; + } + + /** + * Opt-in to providing the result message as the output data + */ + public function provideOutputdata() + { + $this['provide-outputdata'] = true; + } + + /** + * @return bool + */ + public function wasSuccessful() + { + return $this->exitCode === self::EXITCODE_OK; + } + + /** + * @return bool + */ + public function wasCancelled() + { + return $this->exitCode == self::EXITCODE_USER_CANCEL; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Robo.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Robo.php new file mode 100644 index 00000000..0f427707 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Robo.php @@ -0,0 +1,394 @@ +setSelfUpdateRepository($repository); + $statusCode = $runner->execute($argv, $appName, $appVersion, $output); + return $statusCode; + } + + /** + * Sets a new global container. + * + * @param ContainerInterface $container + * A new container instance to replace the current. + */ + public static function setContainer(ContainerInterface $container) + { + static::$container = $container; + } + + /** + * Unsets the global container. + */ + public static function unsetContainer() + { + static::$container = null; + } + + /** + * Returns the currently active global container. + * + * @return \League\Container\ContainerInterface + * + * @throws \RuntimeException + */ + public static function getContainer() + { + if (static::$container === null) { + throw new \RuntimeException('container is not initialized yet. \Robo\Robo::setContainer() must be called with a real container.'); + } + return static::$container; + } + + /** + * Returns TRUE if the container has been initialized, FALSE otherwise. + * + * @return bool + */ + public static function hasContainer() + { + return static::$container !== null; + } + + /** + * Create a config object and load it from the provided paths. + */ + public static function createConfiguration($paths) + { + $config = new \Robo\Config\Config(); + static::loadConfiguration($paths, $config); + return $config; + } + + /** + * Use a simple config loader to load configuration values from specified paths + */ + public static function loadConfiguration($paths, $config = null) + { + if ($config == null) { + $config = static::config(); + } + $loader = new YamlConfigLoader(); + $processor = new ConfigProcessor(); + $processor->add($config->export()); + foreach ($paths as $path) { + $processor->extend($loader->load($path)); + } + $config->import($processor->export()); + } + + /** + * Create a container and initiailze it. If you wish to *change* + * anything defined in the container, then you should call + * \Robo::configureContainer() instead of this function. + * + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * @param null|\Robo\Application $app + * @param null|ConfigInterface $config + * + * @return \League\Container\Container|\League\Container\ContainerInterface + */ + public static function createDefaultContainer($input = null, $output = null, $app = null, $config = null) + { + // Do not allow this function to be called more than once. + if (static::hasContainer()) { + return static::getContainer(); + } + + if (!$app) { + $app = static::createDefaultApplication(); + } + + if (!$config) { + $config = new \Robo\Config\Config(); + } + + // Set up our dependency injection container. + $container = new Container(); + static::configureContainer($container, $app, $config, $input, $output); + + // Set the application dispatcher + $app->setDispatcher($container->get('eventDispatcher')); + + return $container; + } + + /** + * Initialize a container with all of the default Robo services. + * IMPORTANT: after calling this method, clients MUST call: + * + * $dispatcher = $container->get('eventDispatcher'); + * $app->setDispatcher($dispatcher); + * + * Any modification to the container should be done prior to fetching + * objects from it. + * + * It is recommended to use \Robo::createDefaultContainer() + * instead, which does all required setup for the caller, but has + * the limitation that the container it creates can only be + * extended, not modified. + * + * @param \League\Container\ContainerInterface $container + * @param \Symfony\Component\Console\Application $app + * @param ConfigInterface $config + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + */ + public static function configureContainer(ContainerInterface $container, SymfonyApplication $app, ConfigInterface $config, $input = null, $output = null) + { + // Self-referential container refernce for the inflector + $container->add('container', $container); + static::setContainer($container); + + // Create default input and output objects if they were not provided + if (!$input) { + $input = new StringInput(''); + } + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + $config->set(Config::DECORATED, $output->isDecorated()); + $config->set(Config::INTERACTIVE, $input->isInteractive()); + + $container->share('application', $app); + $container->share('config', $config); + $container->share('input', $input); + $container->share('output', $output); + $container->share('outputAdapter', \Robo\Common\OutputAdapter::class); + + // Register logging and related services. + $container->share('logStyler', \Robo\Log\RoboLogStyle::class); + $container->share('logger', \Robo\Log\RoboLogger::class) + ->withArgument('output') + ->withMethodCall('setLogOutputStyler', ['logStyler']); + $container->add('progressBar', \Symfony\Component\Console\Helper\ProgressBar::class) + ->withArgument('output'); + $container->share('progressIndicator', \Robo\Common\ProgressIndicator::class) + ->withArgument('progressBar') + ->withArgument('output'); + $container->share('resultPrinter', \Robo\Log\ResultPrinter::class); + $container->add('simulator', \Robo\Task\Simulator::class); + $container->share('globalOptionsEventListener', \Robo\GlobalOptionsEventListener::class) + ->withMethodCall('setApplication', ['application']); + $container->share('injectConfigEventListener', \Consolidation\Config\Inject\ConfigForCommand::class) + ->withArgument('config') + ->withMethodCall('setApplication', ['application']); + $container->share('collectionProcessHook', \Robo\Collection\CollectionProcessHook::class); + $container->share('alterOptionsCommandEvent', \Consolidation\AnnotatedCommand\Options\AlterOptionsCommandEvent::class) + ->withArgument('application'); + $container->share('hookManager', \Consolidation\AnnotatedCommand\Hooks\HookManager::class) + ->withMethodCall('addCommandEvent', ['alterOptionsCommandEvent']) + ->withMethodCall('addCommandEvent', ['injectConfigEventListener']) + ->withMethodCall('addCommandEvent', ['globalOptionsEventListener']) + ->withMethodCall('addResultProcessor', ['collectionProcessHook', '*']); + $container->share('eventDispatcher', \Symfony\Component\EventDispatcher\EventDispatcher::class) + ->withMethodCall('addSubscriber', ['hookManager']); + $container->share('formatterManager', \Consolidation\OutputFormatters\FormatterManager::class) + ->withMethodCall('addDefaultFormatters', []) + ->withMethodCall('addDefaultSimplifiers', []); + $container->share('prepareTerminalWidthOption', \Consolidation\AnnotatedCommand\Options\PrepareTerminalWidthOption::class) + ->withMethodCall('setApplication', ['application']); + $container->share('commandProcessor', \Consolidation\AnnotatedCommand\CommandProcessor::class) + ->withArgument('hookManager') + ->withMethodCall('setFormatterManager', ['formatterManager']) + ->withMethodCall('addPrepareFormatter', ['prepareTerminalWidthOption']) + ->withMethodCall( + 'setDisplayErrorFunction', + [ + function ($output, $message) use ($container) { + $logger = $container->get('logger'); + $logger->error($message); + } + ] + ); + $container->share('commandFactory', \Consolidation\AnnotatedCommand\AnnotatedCommandFactory::class) + ->withMethodCall('setCommandProcessor', ['commandProcessor']); + + // Deprecated: favor using collection builders to direct use of collections. + $container->add('collection', \Robo\Collection\Collection::class); + // Deprecated: use CollectionBuilder::create() instead -- or, better + // yet, BuilderAwareInterface::collectionBuilder() if available. + $container->add('collectionBuilder', \Robo\Collection\CollectionBuilder::class); + + static::addInflectors($container); + + // Make sure the application is appropriately initialized. + $app->setAutoExit(false); + } + + /** + * @param null|string $appName + * @param null|string $appVersion + * + * @return \Robo\Application + */ + public static function createDefaultApplication($appName = null, $appVersion = null) + { + $appName = $appName ?: self::APPLICATION_NAME; + $appVersion = $appVersion ?: self::VERSION; + + $app = new \Robo\Application($appName, $appVersion); + $app->setAutoExit(false); + return $app; + } + + /** + * Add the Robo League\Container inflectors to the container + * + * @param \League\Container\ContainerInterface $container + */ + public static function addInflectors($container) + { + // Register our various inflectors. + $container->inflector(\Robo\Contract\ConfigAwareInterface::class) + ->invokeMethod('setConfig', ['config']); + $container->inflector(\Psr\Log\LoggerAwareInterface::class) + ->invokeMethod('setLogger', ['logger']); + $container->inflector(\League\Container\ContainerAwareInterface::class) + ->invokeMethod('setContainer', ['container']); + $container->inflector(\Symfony\Component\Console\Input\InputAwareInterface::class) + ->invokeMethod('setInput', ['input']); + $container->inflector(\Robo\Contract\OutputAwareInterface::class) + ->invokeMethod('setOutput', ['output']); + $container->inflector(\Robo\Contract\ProgressIndicatorAwareInterface::class) + ->invokeMethod('setProgressIndicator', ['progressIndicator']); + $container->inflector(\Consolidation\AnnotatedCommand\Events\CustomEventAwareInterface::class) + ->invokeMethod('setHookManager', ['hookManager']); + $container->inflector(\Robo\Contract\VerbosityThresholdInterface::class) + ->invokeMethod('setOutputAdapter', ['outputAdapter']); + } + + /** + * Retrieves a service from the container. + * + * Use this method if the desired service is not one of those with a dedicated + * accessor method below. If it is listed below, those methods are preferred + * as they can return useful type hints. + * + * @param string $id + * The ID of the service to retrieve. + * + * @return mixed + * The specified service. + */ + public static function service($id) + { + return static::getContainer()->get($id); + } + + /** + * Indicates if a service is defined in the container. + * + * @param string $id + * The ID of the service to check. + * + * @return bool + * TRUE if the specified service exists, FALSE otherwise. + */ + public static function hasService($id) + { + // Check hasContainer() first in order to always return a Boolean. + return static::hasContainer() && static::getContainer()->has($id); + } + + /** + * Return the result printer object. + * + * @return \Robo\Log\ResultPrinter + */ + public static function resultPrinter() + { + return static::service('resultPrinter'); + } + + /** + * @return ConfigInterface + */ + public static function config() + { + return static::service('config'); + } + + /** + * @return \Consolidation\Log\Logger + */ + public static function logger() + { + return static::service('logger'); + } + + /** + * @return \Robo\Application + */ + public static function application() + { + return static::service('application'); + } + + /** + * Return the output object. + * + * @return \Symfony\Component\Console\Output\OutputInterface + */ + public static function output() + { + return static::service('output'); + } + + /** + * Return the input object. + * + * @return \Symfony\Component\Console\Input\InputInterface + */ + public static function input() + { + return static::service('input'); + } + + public static function process(Process $process) + { + return ProcessExecutor::create(static::getContainer(), $process); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Runner.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Runner.php new file mode 100644 index 00000000..800ad281 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Runner.php @@ -0,0 +1,465 @@ +roboClass = $roboClass ? $roboClass : self::ROBOCLASS ; + $this->roboFile = $roboFile ? $roboFile : self::ROBOFILE; + $this->dir = getcwd(); + } + + protected function errorCondtion($msg, $errorType) + { + $this->errorConditions[$msg] = $errorType; + } + + /** + * @param \Symfony\Component\Console\Output\OutputInterface $output + * + * @return bool + */ + protected function loadRoboFile($output) + { + // If we have not been provided an output object, make a temporary one. + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + + // If $this->roboClass is a single class that has not already + // been loaded, then we will try to obtain it from $this->roboFile. + // If $this->roboClass is an array, we presume all classes requested + // are available via the autoloader. + if (is_array($this->roboClass) || class_exists($this->roboClass)) { + return true; + } + if (!file_exists($this->dir)) { + $this->errorCondtion("Path `{$this->dir}` is invalid; please provide a valid absolute path to the Robofile to load.", 'red'); + return false; + } + + $realDir = realpath($this->dir); + + $roboFilePath = $realDir . DIRECTORY_SEPARATOR . $this->roboFile; + if (!file_exists($roboFilePath)) { + $requestedRoboFilePath = $this->dir . DIRECTORY_SEPARATOR . $this->roboFile; + $this->errorCondtion("Requested RoboFile `$requestedRoboFilePath` is invalid, please provide valid absolute path to load Robofile.", 'red'); + return false; + } + require_once $roboFilePath; + + if (!class_exists($this->roboClass)) { + $this->errorCondtion("Class {$this->roboClass} was not loaded.", 'red'); + return false; + } + return true; + } + + /** + * @param array $argv + * @param null|string $appName + * @param null|string $appVersion + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * + * @return int + */ + public function execute($argv, $appName = null, $appVersion = null, $output = null) + { + $argv = $this->shebang($argv); + $argv = $this->processRoboOptions($argv); + $app = null; + if ($appName && $appVersion) { + $app = Robo::createDefaultApplication($appName, $appVersion); + } + $commandFiles = $this->getRoboFileCommands($output); + return $this->run($argv, $output, $app, $commandFiles); + } + + /** + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * @param null|\Robo\Application $app + * @param array[] $commandFiles + * + * @return int + */ + public function run($input = null, $output = null, $app = null, $commandFiles = []) + { + // Create default input and output objects if they were not provided + if (!$input) { + $input = new StringInput(''); + } + if (is_array($input)) { + $input = new ArgvInput($input); + } + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + $this->setInput($input); + $this->setOutput($output); + + // If we were not provided a container, then create one + if (!$this->getContainer()) { + $userConfig = 'robo.yml'; + $roboAppConfig = dirname(__DIR__) . '/robo.yml'; + $config = Robo::createConfiguration([$userConfig, $roboAppConfig]); + $container = Robo::createDefaultContainer($input, $output, $app, $config); + $this->setContainer($container); + // Automatically register a shutdown function and + // an error handler when we provide the container. + $this->installRoboHandlers(); + } + + if (!$app) { + $app = Robo::application(); + } + if ($app instanceof \Robo\Application) { + $app->addSelfUpdateCommand($this->getSelfUpdateRepository()); + if (!isset($commandFiles)) { + $this->errorCondtion("Robo is not initialized here. Please run `robo init` to create a new RoboFile.", 'yellow'); + $app->addInitRoboFileCommand($this->roboFile, $this->roboClass); + $commandFiles = []; + } + } + $this->registerCommandClasses($app, $commandFiles); + + try { + $statusCode = $app->run($input, $output); + } catch (TaskExitException $e) { + $statusCode = $e->getCode() ?: 1; + } + + // If there were any error conditions in bootstrapping Robo, + // print them only if the requested command did not complete + // successfully. + if ($statusCode) { + foreach ($this->errorConditions as $msg => $color) { + $this->yell($msg, 40, $color); + } + } + return $statusCode; + } + + /** + * @param \Symfony\Component\Console\Output\OutputInterface $output + * + * @return null|string + */ + protected function getRoboFileCommands($output) + { + if (!$this->loadRoboFile($output)) { + return; + } + return $this->roboClass; + } + + /** + * @param \Robo\Application $app + * @param array $commandClasses + */ + public function registerCommandClasses($app, $commandClasses) + { + foreach ((array)$commandClasses as $commandClass) { + $this->registerCommandClass($app, $commandClass); + } + } + + /** + * @param \Robo\Application $app + * @param string|BuilderAwareInterface|ContainerAwareInterface $commandClass + * + * @return mixed|void + */ + public function registerCommandClass($app, $commandClass) + { + $container = Robo::getContainer(); + $roboCommandFileInstance = $this->instantiateCommandClass($commandClass); + if (!$roboCommandFileInstance) { + return; + } + + // Register commands for all of the public methods in the RoboFile. + $commandFactory = $container->get('commandFactory'); + $commandList = $commandFactory->createCommandsFromClass($roboCommandFileInstance); + foreach ($commandList as $command) { + $app->add($command); + } + return $roboCommandFileInstance; + } + + /** + * @param string|BuilderAwareInterface|ContainerAwareInterface $commandClass + * + * @return null|object + */ + protected function instantiateCommandClass($commandClass) + { + $container = Robo::getContainer(); + + // Register the RoboFile with the container and then immediately + // fetch it; this ensures that all of the inflectors will run. + // If the command class is already an instantiated object, then + // just use it exactly as it was provided to us. + if (is_string($commandClass)) { + if (!class_exists($commandClass)) { + return; + } + $reflectionClass = new \ReflectionClass($commandClass); + if ($reflectionClass->isAbstract()) { + return; + } + + $commandFileName = "{$commandClass}Commands"; + $container->share($commandFileName, $commandClass); + $commandClass = $container->get($commandFileName); + } + // If the command class is a Builder Aware Interface, then + // ensure that it has a builder. Every command class needs + // its own collection builder, as they have references to each other. + if ($commandClass instanceof BuilderAwareInterface) { + $builder = CollectionBuilder::create($container, $commandClass); + $commandClass->setBuilder($builder); + } + if ($commandClass instanceof ContainerAwareInterface) { + $commandClass->setContainer($container); + } + return $commandClass; + } + + public function installRoboHandlers() + { + register_shutdown_function(array($this, 'shutdown')); + set_error_handler(array($this, 'handleError')); + } + + /** + * Process a shebang script, if one was used to launch this Runner. + * + * @param array $args + * + * @return array $args with shebang script removed + */ + protected function shebang($args) + { + // Option 1: Shebang line names Robo, but includes no parameters. + // #!/bin/env robo + // The robo class may contain multiple commands; the user may + // select which one to run, or even get a list of commands or + // run 'help' on any of the available commands as usual. + if ((count($args) > 1) && $this->isShebangFile($args[1])) { + return array_merge([$args[0]], array_slice($args, 2)); + } + // Option 2: Shebang line stipulates which command to run. + // #!/bin/env robo mycommand + // The robo class must contain a public method named 'mycommand'. + // This command will be executed every time. Arguments and options + // may be provided on the commandline as usual. + if ((count($args) > 2) && $this->isShebangFile($args[2])) { + return array_merge([$args[0]], explode(' ', $args[1]), array_slice($args, 3)); + } + return $args; + } + + /** + * Determine if the specified argument is a path to a shebang script. + * If so, load it. + * + * @param string $filepath file to check + * + * @return bool Returns TRUE if shebang script was processed + */ + protected function isShebangFile($filepath) + { + if (!is_file($filepath)) { + return false; + } + $fp = fopen($filepath, "r"); + if ($fp === false) { + return false; + } + $line = fgets($fp); + $result = $this->isShebangLine($line); + if ($result) { + while ($line = fgets($fp)) { + $line = trim($line); + if ($line == 'roboClass = $matches[1]; + eval($script); + $result = true; + } + } + } + } + fclose($fp); + + return $result; + } + + /** + * Test to see if the provided line is a robo 'shebang' line. + * + * @param string $line + * + * @return bool + */ + protected function isShebangLine($line) + { + return ((substr($line, 0, 2) == '#!') && (strstr($line, 'robo') !== false)); + } + + /** + * Check for Robo-specific arguments such as --load-from, process them, + * and remove them from the array. We have to process --load-from before + * we set up Symfony Console. + * + * @param array $argv + * + * @return array + */ + protected function processRoboOptions($argv) + { + // loading from other directory + $pos = $this->arraySearchBeginsWith('--load-from', $argv) ?: array_search('-f', $argv); + if ($pos === false) { + return $argv; + } + + $passThru = array_search('--', $argv); + if (($passThru !== false) && ($passThru < $pos)) { + return $argv; + } + + if (substr($argv[$pos], 0, 12) == '--load-from=') { + $this->dir = substr($argv[$pos], 12); + } elseif (isset($argv[$pos +1])) { + $this->dir = $argv[$pos +1]; + unset($argv[$pos +1]); + } + unset($argv[$pos]); + // Make adjustments if '--load-from' points at a file. + if (is_file($this->dir) || (substr($this->dir, -4) == '.php')) { + $this->roboFile = basename($this->dir); + $this->dir = dirname($this->dir); + $className = basename($this->roboFile, '.php'); + if ($className != $this->roboFile) { + $this->roboClass = $className; + } + } + // Convert directory to a real path, but only if the + // path exists. We do not want to lose the original + // directory if the user supplied a bad value. + $realDir = realpath($this->dir); + if ($realDir) { + chdir($realDir); + $this->dir = $realDir; + } + + return $argv; + } + + /** + * @param string $needle + * @param string[] $haystack + * + * @return bool|int + */ + protected function arraySearchBeginsWith($needle, $haystack) + { + for ($i = 0; $i < count($haystack); ++$i) { + if (substr($haystack[$i], 0, strlen($needle)) == $needle) { + return $i; + } + } + return false; + } + + public function shutdown() + { + $error = error_get_last(); + if (!is_array($error)) { + return; + } + $this->writeln(sprintf("ERROR: %s \nin %s:%d\n", $error['message'], $error['file'], $error['line'])); + } + + /** + * This is just a proxy error handler that checks the current error_reporting level. + * In case error_reporting is disabled the error is marked as handled, otherwise + * the normal internal error handling resumes. + * + * @return bool + */ + public function handleError() + { + if (error_reporting() === 0) { + return true; + } + return false; + } + + /** + * @return string + */ + public function getSelfUpdateRepository() + { + return $this->selfUpdateRepository; + } + + /** + * @param string $selfUpdateRepository + */ + public function setSelfUpdateRepository($selfUpdateRepository) + { + $this->selfUpdateRepository = $selfUpdateRepository; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/SelfUpdateCommand.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/SelfUpdateCommand.php new file mode 100644 index 00000000..d07ee71f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/SelfUpdateCommand.php @@ -0,0 +1,152 @@ + + */ +class SelfUpdateCommand extends Command +{ + const SELF_UPDATE_COMMAND_NAME = 'self:update'; + + protected $gitHubRepository; + + protected $currentVersion; + + protected $applicationName; + + public function __construct($applicationName = null, $currentVersion = null, $gitHubRepository = null) + { + parent::__construct(self::SELF_UPDATE_COMMAND_NAME); + + $this->applicationName = $applicationName; + $this->currentVersion = $currentVersion; + $this->gitHubRepository = $gitHubRepository; + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setAliases(array('update')) + ->setDescription('Updates the robo.phar to the latest version.') + ->setHelp( + <<self-update command checks github for newer +versions of robo and if found, installs the latest. +EOT + ); + } + + protected function getLatestReleaseFromGithub() + { + $opts = [ + 'http' => [ + 'method' => 'GET', + 'header' => [ + 'User-Agent: ' . $this->applicationName . ' (' . $this->gitHubRepository . ')' . ' Self-Update (PHP)' + ] + ] + ]; + + $context = stream_context_create($opts); + + $releases = file_get_contents('https://api.github.com/repos/' . $this->gitHubRepository . '/releases', false, $context); + $releases = json_decode($releases); + + if (! isset($releases[0])) { + throw new \Exception('API error - no release found at GitHub repository ' . $this->gitHubRepository); + } + + $version = $releases[0]->tag_name; + $url = $releases[0]->assets[0]->browser_download_url; + + return [ $version, $url ]; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + if (empty(\Phar::running())) { + throw new \Exception(self::SELF_UPDATE_COMMAND_NAME . ' only works when running the phar version of ' . $this->applicationName . '.'); + } + + $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0]; + $programName = basename($localFilename); + $tempFilename = dirname($localFilename) . '/' . basename($localFilename, '.phar') . '-temp.phar'; + + // check for permissions in local filesystem before start connection process + if (! is_writable($tempDirectory = dirname($tempFilename))) { + throw new \Exception( + $programName . ' update failed: the "' . $tempDirectory . + '" directory used to download the temp file could not be written' + ); + } + + if (! is_writable($localFilename)) { + throw new \Exception( + $programName . ' update failed: the "' . $localFilename . '" file could not be written (execute with sudo)' + ); + } + + list( $latest, $downloadUrl ) = $this->getLatestReleaseFromGithub(); + + + if ($this->currentVersion == $latest) { + $output->writeln('No update available'); + return; + } + + $fs = new sfFilesystem(); + + $output->writeln('Downloading ' . $this->applicationName . ' (' . $this->gitHubRepository . ') ' . $latest); + + $fs->copy($downloadUrl, $tempFilename); + + $output->writeln('Download finished'); + + try { + \error_reporting(E_ALL); // supress notices + + @chmod($tempFilename, 0777 & ~umask()); + // test the phar validity + $phar = new \Phar($tempFilename); + // free the variable to unlock the file + unset($phar); + @rename($tempFilename, $localFilename); + $output->writeln('Successfully updated ' . $programName . ''); + $this->_exit(); + } catch (\Exception $e) { + @unlink($tempFilename); + if (! $e instanceof \UnexpectedValueException && ! $e instanceof \PharException) { + throw $e; + } + $output->writeln('The download is corrupted (' . $e->getMessage() . ').'); + $output->writeln('Please re-run the self-update command to try again.'); + } + } + + /** + * Stop execution + * + * This is a workaround to prevent warning of dispatcher after replacing + * the phar file. + * + * @return void + */ + protected function _exit() + { + exit; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/Consumer.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/Consumer.php new file mode 100644 index 00000000..ab9c0e27 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/Consumer.php @@ -0,0 +1,12 @@ +message = $message; + parent::__construct($data); + } + + /** + * @return array + */ + public function getData() + { + return $this->getArrayCopy(); + } + + /** + * @return string + */ + public function getMessage() + { + return $this->message; + } + + /** + * @param string message + */ + public function setMessage($message) + { + $this->message = $message; + } + + /** + * Merge another result into this result. Data already + * existing in this result takes precedence over the + * data in the Result being merged. + * + * @param \Robo\ResultData $result + * + * @return $this + */ + public function merge(Data $result) + { + $mergedData = $this->getArrayCopy() + $result->getArrayCopy(); + $this->exchangeArray($mergedData); + return $this; + } + + /** + * Update the current data with the data provided in the parameter. + * Provided data takes precedence. + * + * @param \ArrayObject $update + * + * @return $this + */ + public function update(\ArrayObject $update) + { + $iterator = $update->getIterator(); + + while ($iterator->valid()) { + $this[$iterator->key()] = $iterator->current(); + $iterator->next(); + } + + return $this; + } + + /** + * Merge another result into this result. Data already + * existing in this result takes precedence over the + * data in the Result being merged. + * + * $data['message'] is handled specially, and is appended + * to $this->message if set. + * + * @param array $data + * + * @return array + */ + public function mergeData(array $data) + { + $mergedData = $this->getArrayCopy() + $data; + $this->exchangeArray($mergedData); + return $mergedData; + } + + /** + * @return bool + */ + public function hasExecutionTime() + { + return isset($this['time']); + } + + /** + * @return null|float + */ + public function getExecutionTime() + { + if (!$this->hasExecutionTime()) { + return null; + } + return $this['time']; + } + + /** + * Accumulate execution time + */ + public function accumulateExecutionTime($duration) + { + // Convert data arrays to scalar + if (is_array($duration)) { + $duration = isset($duration['time']) ? $duration['time'] : 0; + } + $this['time'] = $this->getExecutionTime() + $duration; + return $this->getExecutionTime(); + } + + /** + * Accumulate the message. + */ + public function accumulateMessage($message) + { + if (!empty($this->message)) { + $this->message .= "\n"; + } + $this->message .= $message; + return $this->getMessage(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/StateAwareInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/StateAwareInterface.php new file mode 100644 index 00000000..f86bccb8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/State/StateAwareInterface.php @@ -0,0 +1,30 @@ +state; + } + + /** + * {@inheritdoc} + */ + public function setState(Data $state) + { + $this->state = $state; + } + + /** + * {@inheritdoc} + */ + public function setStateValue($key, $value) + { + $this->state[$key] = $value; + } + + /** + * {@inheritdoc} + */ + public function updateState(Data $update) + { + $this->state->update($update); + } + + /** + * {@inheritdoc} + */ + public function resetState() + { + $this->state = new Data(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/ApiGen/ApiGen.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/ApiGen/ApiGen.php new file mode 100644 index 00000000..11ff764c --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/ApiGen/ApiGen.php @@ -0,0 +1,518 @@ +taskApiGen('./vendor/apigen/apigen.phar') + * ->config('./apigen.neon') + * ->templateConfig('vendor/apigen/apigen/templates/bootstrap/config.neon') + * ->wipeout(true) + * ->run(); + * ?> + * ``` + */ +class ApiGen extends BaseTask implements CommandInterface +{ + use \Robo\Common\ExecOneCommand; + + const BOOL_NO = 'no'; + const BOOL_YES = 'yes'; + + /** + * @var string + */ + protected $command; + protected $operation = 'generate'; + + /** + * @param null|string $pathToApiGen + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToApiGen = null) + { + $this->command = $pathToApiGen; + $command_parts = []; + preg_match('/((?:.+)?apigen(?:\.phar)?) ?( \w+)? ?(.+)?/', $this->command, $command_parts); + if (count($command_parts) === 3) { + list(, $this->command, $this->operation) = $command_parts; + } + if (count($command_parts) === 4) { + list(, $this->command, $this->operation, $arg) = $command_parts; + $this->arg($arg); + } + if (!$this->command) { + $this->command = $this->findExecutablePhar('apigen'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "No apigen installation found"); + } + } + + /** + * Pass methods parameters as arguments to executable. Argument values + * are automatically escaped. + * + * @param string|string[] $args + * + * @return $this + */ + public function args($args) + { + if (!is_array($args)) { + $args = func_get_args(); + } + $args = array_map(function ($arg) { + if (preg_match('/^\w+$/', trim($arg)) === 1) { + $this->operation = $arg; + return null; + } + return $arg; + }, $args); + $args = array_filter($args); + $this->arguments .= ' ' . implode(' ', array_map('static::escape', $args)); + return $this; + } + + /** + * @param array|Traversable|string $arg a single object or something traversable + * + * @return array|Traversable the provided argument if it was already traversable, or the given + * argument returned as a one-element array + */ + protected static function forceTraversable($arg) + { + $traversable = $arg; + if (!is_array($traversable) && !($traversable instanceof \Traversable)) { + $traversable = array($traversable); + } + return $traversable; + } + + /** + * @param array|string $arg a single argument or an array of multiple string values + * + * @return string a comma-separated string of all of the provided arguments, suitable + * as a command-line "list" type argument for ApiGen + */ + protected static function asList($arg) + { + $normalized = is_array($arg) ? $arg : array($arg); + return implode(',', $normalized); + } + + /** + * @param bool|string $val an argument to be normalized + * @param string $default one of self::BOOL_YES or self::BOOK_NO if the provided + * value could not deterministically be converted to a + * yes or no value + * + * @return string the given value as a command-line "yes|no" type of argument for ApiGen, + * or the default value if none could be determined + */ + protected static function asTextBool($val, $default) + { + if ($val === self::BOOL_YES || $val === self::BOOL_NO) { + return $val; + } + if (!$val) { + return self::BOOL_NO; + } + if ($val === true) { + return self::BOOL_YES; + } + if (is_numeric($val) && $val != 0) { + return self::BOOL_YES; + } + if (strcasecmp($val[0], 'y') === 0) { + return self::BOOL_YES; + } + if (strcasecmp($val[0], 'n') === 0) { + return self::BOOL_NO; + } + // meh, good enough, let apigen sort it out + return $default; + } + + /** + * @param string $config + * + * @return $this + */ + public function config($config) + { + $this->option('config', $config); + return $this; + } + + /** + * @param array|string|Traversable $src one or more source values + * + * @return $this + */ + public function source($src) + { + foreach (self::forceTraversable($src) as $source) { + $this->option('source', $source); + } + return $this; + } + + /** + * @param string $dest + * + * @return $this + */ + public function destination($dest) + { + $this->option('destination', $dest); + return $this; + } + + /** + * @param array|string $exts one or more extensions + * + * @return $this + */ + public function extensions($exts) + { + $this->option('extensions', self::asList($exts)); + return $this; + } + + /** + * @param array|string $exclude one or more exclusions + * + * @return $this + */ + public function exclude($exclude) + { + foreach (self::forceTraversable($exclude) as $excl) { + $this->option('exclude', $excl); + } + return $this; + } + + /** + * @param array|string|Traversable $path one or more skip-doc-path values + * + * @return $this + */ + public function skipDocPath($path) + { + foreach (self::forceTraversable($path) as $skip) { + $this->option('skip-doc-path', $skip); + } + return $this; + } + + /** + * @param array|string|Traversable $prefix one or more skip-doc-prefix values + * + * @return $this + */ + public function skipDocPrefix($prefix) + { + foreach (self::forceTraversable($prefix) as $skip) { + $this->option('skip-doc-prefix', $skip); + } + return $this; + } + + /** + * @param array|string $charset one or more charsets + * + * @return $this + */ + public function charset($charset) + { + $this->option('charset', self::asList($charset)); + return $this; + } + + /** + * @param string $name + * + * @return $this + */ + public function mainProjectNamePrefix($name) + { + $this->option('main', $name); + return $this; + } + + /** + * @param string $title + * + * @return $this + */ + public function title($title) + { + $this->option('title', $title); + return $this; + } + + /** + * @param string $baseUrl + * + * @return $this + */ + public function baseUrl($baseUrl) + { + $this->option('base-url', $baseUrl); + return $this; + } + + /** + * @param string $id + * + * @return $this + */ + public function googleCseId($id) + { + $this->option('google-cse-id', $id); + return $this; + } + + /** + * @param string $trackingCode + * + * @return $this + */ + public function googleAnalytics($trackingCode) + { + $this->option('google-analytics', $trackingCode); + return $this; + } + + /** + * @param mixed $templateConfig + * + * @return $this + */ + public function templateConfig($templateConfig) + { + $this->option('template-config', $templateConfig); + return $this; + } + + /** + * @param array|string $tags one or more supported html tags + * + * @return $this + */ + public function allowedHtml($tags) + { + $this->option('allowed-html', self::asList($tags)); + return $this; + } + + /** + * @param string $groups + * + * @return $this + */ + public function groups($groups) + { + $this->option('groups', $groups); + return $this; + } + + /** + * @param array|string $types or more supported autocomplete types + * + * @return $this + */ + public function autocomplete($types) + { + $this->option('autocomplete', self::asList($types)); + return $this; + } + + /** + * @param array|string $levels one or more access levels + * + * @return $this + */ + public function accessLevels($levels) + { + $this->option('access-levels', self::asList($levels)); + return $this; + } + + /** + * @param boolean|string $internal 'yes' or true if internal, 'no' or false if not + * + * @return $this + */ + public function internal($internal) + { + $this->option('internal', self::asTextBool($internal, self::BOOL_NO)); + return $this; + } + + /** + * @param boolean|string $php 'yes' or true to generate documentation for internal php classes, + * 'no' or false otherwise + * + * @return $this + */ + public function php($php) + { + $this->option('php', self::asTextBool($php, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $tree 'yes' or true to generate a tree view of classes, 'no' or false otherwise + * + * @return $this + */ + public function tree($tree) + { + $this->option('tree', self::asTextBool($tree, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $dep 'yes' or true to generate documentation for deprecated classes, 'no' or false otherwise + * + * @return $this + */ + public function deprecated($dep) + { + $this->option('deprecated', self::asTextBool($dep, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $todo 'yes' or true to document tasks, 'no' or false otherwise + * + * @return $this + */ + public function todo($todo) + { + $this->option('todo', self::asTextBool($todo, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $src 'yes' or true to generate highlighted source code, 'no' or false otherwise + * + * @return $this + */ + public function sourceCode($src) + { + $this->option('source-code', self::asTextBool($src, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $zipped 'yes' or true to generate downloadable documentation, 'no' or false otherwise + * + * @return $this + */ + public function download($zipped) + { + $this->option('download', self::asTextBool($zipped, self::BOOL_NO)); + return $this; + } + + public function report($path) + { + $this->option('report', $path); + return $this; + } + + /** + * @param bool|string $wipeout 'yes' or true to clear out the destination directory, 'no' or false otherwise + * + * @return $this + */ + public function wipeout($wipeout) + { + $this->option('wipeout', self::asTextBool($wipeout, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $quiet 'yes' or true for quiet, 'no' or false otherwise + * + * @return $this + */ + public function quiet($quiet) + { + $this->option('quiet', self::asTextBool($quiet, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $bar 'yes' or true to display a progress bar, 'no' or false otherwise + * + * @return $this + */ + public function progressbar($bar) + { + $this->option('progressbar', self::asTextBool($bar, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $colors 'yes' or true colorize the output, 'no' or false otherwise + * + * @return $this + */ + public function colors($colors) + { + $this->option('colors', self::asTextBool($colors, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $check 'yes' or true to check for updates, 'no' or false otherwise + * + * @return $this + */ + public function updateCheck($check) + { + $this->option('update-check', self::asTextBool($check, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $debug 'yes' or true to enable debug mode, 'no' or false otherwise + * + * @return $this + */ + public function debug($debug) + { + $this->option('debug', self::asTextBool($debug, self::BOOL_NO)); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return "$this->command $this->operation$this->arguments"; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running ApiGen {args}', ['args' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/ApiGen/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/ApiGen/loadTasks.php new file mode 100644 index 00000000..e8cd372a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/ApiGen/loadTasks.php @@ -0,0 +1,15 @@ +task(ApiGen::class, $pathToApiGen); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/Extract.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/Extract.php new file mode 100644 index 00000000..a00a0baf --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/Extract.php @@ -0,0 +1,279 @@ +taskExtract($archivePath) + * ->to($destination) + * ->preserveTopDirectory(false) // the default + * ->run(); + * ?> + * ``` + */ +class Extract extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $filename; + + /** + * @var string + */ + protected $to; + + /** + * @var bool + */ + private $preserveTopDirectory = false; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * Location to store extracted files. + * + * @param string $to + * + * @return $this + */ + public function to($to) + { + $this->to = $to; + return $this; + } + + /** + * @param bool $preserve + * + * @return $this + */ + public function preserveTopDirectory($preserve = true) + { + $this->preserveTopDirectory = $preserve; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!file_exists($this->filename)) { + $this->printTaskError("File {filename} does not exist", ['filename' => $this->filename]); + + return false; + } + if (!($mimetype = static::archiveType($this->filename))) { + $this->printTaskError("Could not determine type of archive for {filename}", ['filename' => $this->filename]); + + return false; + } + + // We will first extract to $extractLocation and then move to $this->to + $extractLocation = static::getTmpDir(); + @mkdir($extractLocation); + @mkdir(dirname($this->to)); + + $this->startTimer(); + + $this->printTaskInfo("Extracting {filename}", ['filename' => $this->filename]); + + $result = $this->extractAppropriateType($mimetype, $extractLocation); + if ($result->wasSuccessful()) { + $this->printTaskInfo("{filename} extracted", ['filename' => $this->filename]); + // Now, we want to move the extracted files to $this->to. There + // are two possibilities that we must consider: + // + // (1) Archived files were encapsulated in a folder with an arbitrary name + // (2) There was no encapsulating folder, and all the files in the archive + // were extracted into $extractLocation + // + // In the case of (1), we want to move and rename the encapsulating folder + // to $this->to. + // + // In the case of (2), we will just move and rename $extractLocation. + $filesInExtractLocation = glob("$extractLocation/*"); + $hasEncapsulatingFolder = ((count($filesInExtractLocation) == 1) && is_dir($filesInExtractLocation[0])); + if ($hasEncapsulatingFolder && !$this->preserveTopDirectory) { + $result = (new FilesystemStack()) + ->inflect($this) + ->rename($filesInExtractLocation[0], $this->to) + ->run(); + (new DeleteDir($extractLocation)) + ->inflect($this) + ->run(); + } else { + $result = (new FilesystemStack()) + ->inflect($this) + ->rename($extractLocation, $this->to) + ->run(); + } + } + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * @param string $mimetype + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractAppropriateType($mimetype, $extractLocation) + { + // Perform the extraction of a zip file. + if (($mimetype == 'application/zip') || ($mimetype == 'application/x-zip')) { + return $this->extractZip($extractLocation); + } + return $this->extractTar($extractLocation); + } + + /** + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractZip($extractLocation) + { + if (!extension_loaded('zlib')) { + return Result::errorMissingExtension($this, 'zlib', 'zip extracting'); + } + + $zip = new \ZipArchive(); + if (($status = $zip->open($this->filename)) !== true) { + return Result::error($this, "Could not open zip archive {$this->filename}"); + } + if (!$zip->extractTo($extractLocation)) { + return Result::error($this, "Could not extract zip archive {$this->filename}"); + } + $zip->close(); + + return Result::success($this); + } + + /** + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractTar($extractLocation) + { + if (!class_exists('Archive_Tar')) { + return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar'); + } + $tar_object = new \Archive_Tar($this->filename); + if (!$tar_object->extract($extractLocation)) { + return Result::error($this, "Could not extract tar archive {$this->filename}"); + } + + return Result::success($this); + } + + /** + * @param string $filename + * + * @return bool|string + */ + protected static function archiveType($filename) + { + $content_type = false; + if (class_exists('finfo')) { + $finfo = new \finfo(FILEINFO_MIME_TYPE); + $content_type = $finfo->file($filename); + // If finfo cannot determine the content type, then we will try other methods + if ($content_type == 'application/octet-stream') { + $content_type = false; + } + } + // Examing the file's magic header bytes. + if (!$content_type) { + if ($file = fopen($filename, 'rb')) { + $first = fread($file, 2); + fclose($file); + if ($first !== false) { + // Interpret the two bytes as a little endian 16-bit unsigned int. + $data = unpack('v', $first); + switch ($data[1]) { + case 0x8b1f: + // First two bytes of gzip files are 0x1f, 0x8b (little-endian). + // See http://www.gzip.org/zlib/rfc-gzip.html#header-trailer + $content_type = 'application/x-gzip'; + break; + + case 0x4b50: + // First two bytes of zip files are 0x50, 0x4b ('PK') (little-endian). + // See http://en.wikipedia.org/wiki/Zip_(file_format)#File_headers + $content_type = 'application/zip'; + break; + + case 0x5a42: + // First two bytes of bzip2 files are 0x5a, 0x42 ('BZ') (big-endian). + // See http://en.wikipedia.org/wiki/Bzip2#File_format + $content_type = 'application/x-bzip2'; + break; + } + } + } + } + // 3. Lastly if above methods didn't work, try to guess the mime type from + // the file extension. This is useful if the file has no identificable magic + // header bytes (for example tarballs). + if (!$content_type) { + // Remove querystring from the filename, if present. + $filename = basename(current(explode('?', $filename, 2))); + $extension_mimetype = array( + '.tar.gz' => 'application/x-gzip', + '.tgz' => 'application/x-gzip', + '.tar' => 'application/x-tar', + ); + foreach ($extension_mimetype as $extension => $ct) { + if (substr($filename, -strlen($extension)) === $extension) { + $content_type = $ct; + break; + } + } + } + + return $content_type; + } + + /** + * @return string + */ + protected static function getTmpDir() + { + return getcwd().'/tmp'.rand().time(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/Pack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/Pack.php new file mode 100644 index 00000000..0970f8e8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/Pack.php @@ -0,0 +1,257 @@ +taskPack( + * ) + * ->add('README') // Puts file 'README' in archive at the root + * ->add('project') // Puts entire contents of directory 'project' in archinve inside 'project' + * ->addFile('dir/file.txt', 'file.txt') // Takes 'file.txt' from cwd and puts it in archive inside 'dir'. + * ->run(); + * ?> + * ``` + */ +class Pack extends BaseTask implements PrintedInterface +{ + /** + * The list of items to be packed into the archive. + * + * @var array + */ + private $items = []; + + /** + * The full path to the archive to be created. + * + * @var string + */ + private $archiveFile; + + /** + * Construct the class. + * + * @param string $archiveFile The full path and name of the archive file to create. + * + * @since 1.0 + */ + public function __construct($archiveFile) + { + $this->archiveFile = $archiveFile; + } + + /** + * Satisfy the parent requirement. + * + * @return bool Always returns true. + * + * @since 1.0 + */ + public function getPrinted() + { + return true; + } + + /** + * @param string $archiveFile + * + * @return $this + */ + public function archiveFile($archiveFile) + { + $this->archiveFile = $archiveFile; + return $this; + } + + /** + * Add an item to the archive. Like file_exists(), the parameter + * may be a file or a directory. + * + * @var string + * Relative path and name of item to store in archive + * @var string + * Absolute or relative path to file or directory's location in filesystem + * + * @return $this + */ + public function addFile($placementLocation, $filesystemLocation) + { + $this->items[$placementLocation] = $filesystemLocation; + + return $this; + } + + /** + * Alias for addFile, in case anyone has angst about using + * addFile with a directory. + * + * @var string + * Relative path and name of directory to store in archive + * @var string + * Absolute or relative path to directory or directory's location in filesystem + * + * @return $this + */ + public function addDir($placementLocation, $filesystemLocation) + { + $this->addFile($placementLocation, $filesystemLocation); + + return $this; + } + + /** + * Add a file or directory, or list of same to the archive. + * + * @var string|array + * If given a string, should contain the relative filesystem path to the + * the item to store in archive; this will also be used as the item's + * path in the archive, so absolute paths should not be used here. + * If given an array, the key of each item should be the path to store + * in the archive, and the value should be the filesystem path to the + * item to store. + * @return $this + */ + public function add($item) + { + if (is_array($item)) { + $this->items = array_merge($this->items, $item); + } else { + $this->addFile($item, $item); + } + + return $this; + } + + /** + * Create a zip archive for distribution. + * + * @return \Robo\Result + * + * @since 1.0 + */ + public function run() + { + $this->startTimer(); + + // Use the file extension to determine what kind of archive to create. + $fileInfo = new \SplFileInfo($this->archiveFile); + $extension = strtolower($fileInfo->getExtension()); + if (empty($extension)) { + return Result::error($this, "Archive filename must use an extension (e.g. '.zip') to specify the kind of archive to create."); + } + + try { + // Inform the user which archive we are creating + $this->printTaskInfo("Creating archive {filename}", ['filename' => $this->archiveFile]); + if ($extension == 'zip') { + $result = $this->archiveZip($this->archiveFile, $this->items); + } else { + $result = $this->archiveTar($this->archiveFile, $this->items); + } + $this->printTaskSuccess("{filename} created.", ['filename' => $this->archiveFile]); + } catch (\Exception $e) { + $this->printTaskError("Could not create {filename}. {exception}", ['filename' => $this->archiveFile, 'exception' => $e->getMessage(), '_style' => ['exception' => '']]); + $result = Result::error($this, sprintf('Could not create %s. %s', $this->archiveFile, $e->getMessage())); + } + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * @param string $archiveFile + * @param array $items + * + * @return \Robo\Result + */ + protected function archiveTar($archiveFile, $items) + { + if (!class_exists('Archive_Tar')) { + return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar'); + } + + $tar_object = new \Archive_Tar($archiveFile); + foreach ($items as $placementLocation => $filesystemLocation) { + $p_remove_dir = $filesystemLocation; + $p_add_dir = $placementLocation; + if (is_file($filesystemLocation)) { + $p_remove_dir = dirname($filesystemLocation); + $p_add_dir = dirname($placementLocation); + if (basename($filesystemLocation) != basename($placementLocation)) { + return Result::error($this, "Tar archiver does not support renaming files during extraction; could not add $filesystemLocation as $placementLocation."); + } + } + + if (!$tar_object->addModify([$filesystemLocation], $p_add_dir, $p_remove_dir)) { + return Result::error($this, "Could not add $filesystemLocation to the archive."); + } + } + + return Result::success($this); + } + + /** + * @param string $archiveFile + * @param array $items + * + * @return \Robo\Result + */ + protected function archiveZip($archiveFile, $items) + { + if (!extension_loaded('zlib')) { + return Result::errorMissingExtension($this, 'zlib', 'zip packing'); + } + + $zip = new \ZipArchive($archiveFile, \ZipArchive::CREATE); + if (!$zip->open($archiveFile, \ZipArchive::CREATE)) { + return Result::error($this, "Could not create zip archive {$archiveFile}"); + } + $result = $this->addItemsToZip($zip, $items); + $zip->close(); + + return $result; + } + + /** + * @param \ZipArchive $zip + * @param array $items + * + * @return \Robo\Result + */ + protected function addItemsToZip($zip, $items) + { + foreach ($items as $placementLocation => $filesystemLocation) { + if (is_dir($filesystemLocation)) { + $finder = new Finder(); + $finder->files()->in($filesystemLocation)->ignoreDotFiles(false); + + foreach ($finder as $file) { + // Replace Windows slashes or resulting zip will have issues on *nixes. + $relativePathname = str_replace('\\', '/', $file->getRelativePathname()); + + if (!$zip->addFile($file->getRealpath(), "{$placementLocation}/{$relativePathname}")) { + return Result::error($this, "Could not add directory $filesystemLocation to the archive; error adding {$file->getRealpath()}."); + } + } + } elseif (is_file($filesystemLocation)) { + if (!$zip->addFile($filesystemLocation, $placementLocation)) { + return Result::error($this, "Could not add file $filesystemLocation to the archive."); + } + } else { + return Result::error($this, "Could not find $filesystemLocation for the archive."); + } + } + + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/loadTasks.php new file mode 100644 index 00000000..cf846fdf --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Archive/loadTasks.php @@ -0,0 +1,25 @@ +task(Pack::class, $filename); + } + + /** + * @param $filename + * + * @return Extract + */ + protected function taskExtract($filename) + { + return $this->task(Extract::class, $filename); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/CssPreprocessor.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/CssPreprocessor.php new file mode 100644 index 00000000..a15d2078 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/CssPreprocessor.php @@ -0,0 +1,214 @@ +files = $input; + + $this->setDefaultCompiler(); + } + + protected function setDefaultCompiler() + { + if (isset($this->compilers[0])) { + //set first compiler as default + $this->compiler = $this->compilers[0]; + } + } + + /** + * Sets import directories + * Alias for setImportPaths + * @see CssPreprocessor::setImportPaths + * + * @param array|string $dirs + * + * @return $this + */ + public function importDir($dirs) + { + return $this->setImportPaths($dirs); + } + + /** + * Adds import directory + * + * @param string $dir + * + * @return $this + */ + public function addImportPath($dir) + { + if (!isset($this->compilerOptions['importDirs'])) { + $this->compilerOptions['importDirs'] = []; + } + + if (!in_array($dir, $this->compilerOptions['importDirs'], true)) { + $this->compilerOptions['importDirs'][] = $dir; + } + + return $this; + } + + /** + * Sets import directories + * + * @param array|string $dirs + * + * @return $this + */ + public function setImportPaths($dirs) + { + if (!is_array($dirs)) { + $dirs = [$dirs]; + } + + $this->compilerOptions['importDirs'] = $dirs; + + return $this; + } + + /** + * @param string $formatterName + * + * @return $this + */ + public function setFormatter($formatterName) + { + $this->compilerOptions['formatter'] = $formatterName; + + return $this; + } + + /** + * Sets the compiler. + * + * @param string $compiler + * @param array $options + * + * @return $this + */ + public function compiler($compiler, array $options = []) + { + $this->compiler = $compiler; + $this->compilerOptions = array_merge($this->compilerOptions, $options); + + return $this; + } + + /** + * Compiles file + * + * @param $file + * + * @return bool|mixed + */ + protected function compile($file) + { + if (is_callable($this->compiler)) { + return call_user_func($this->compiler, $file, $this->compilerOptions); + } + + if (method_exists($this, $this->compiler)) { + return $this->{$this->compiler}($file); + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!in_array($this->compiler, $this->compilers, true) + && !is_callable($this->compiler) + ) { + $message = sprintf('Invalid ' . static::FORMAT_NAME . ' compiler %s!', $this->compiler); + + return Result::error($this, $message); + } + + foreach ($this->files as $in => $out) { + if (!file_exists($in)) { + $message = sprintf('File %s not found.', $in); + + return Result::error($this, $message); + } + if (file_exists($out) && !is_writable($out)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + } + + foreach ($this->files as $in => $out) { + $css = $this->compile($in); + + if ($css instanceof Result) { + return $css; + } elseif (false === $css) { + $message = sprintf( + ucfirst(static::FORMAT_NAME) . ' compilation failed for %s.', + $in + ); + + return Result::error($this, $message); + } + + $dst = $out . '.part'; + $write_result = file_put_contents($dst, $css); + + if (false === $write_result) { + $message = sprintf('File write failed: %s', $out); + + @unlink($dst); + return Result::error($this, $message); + } + + // Cannot be cross-volume: should always succeed + @rename($dst, $out); + + $this->printTaskSuccess('Wrote CSS to {filename}', ['filename' => $out]); + } + + return Result::success($this, 'All ' . static::FORMAT_NAME . ' files compiled.'); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/ImageMinify.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/ImageMinify.php new file mode 100644 index 00000000..1aa62593 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/ImageMinify.php @@ -0,0 +1,716 @@ +taskImageMinify('assets/images/*') + * ->to('dist/images/') + * ->run(); + * ``` + * + * This will use the following minifiers: + * + * - PNG: optipng + * - GIF: gifsicle + * - JPG, JPEG: jpegtran + * - SVG: svgo + * + * When the minifier is specified the task will use that for all the input files. In that case + * it is useful to filter the files with the extension: + * + * ```php + * $this->taskImageMinify('assets/images/*.png') + * ->to('dist/images/') + * ->minifier('pngcrush'); + * ->run(); + * ``` + * + * The task supports the following minifiers: + * + * - optipng + * - pngquant + * - advpng + * - pngout + * - zopflipng + * - pngcrush + * - gifsicle + * - jpegoptim + * - jpeg-recompress + * - jpegtran + * - svgo (only minification, no downloading) + * + * You can also specifiy extra options for the minifiers: + * + * ```php + * $this->taskImageMinify('assets/images/*.jpg') + * ->to('dist/images/') + * ->minifier('jpegtran', ['-progressive' => null, '-copy' => 'none']) + * ->run(); + * ``` + * + * This will execute as: + * `jpegtran -copy none -progressive -optimize -outfile "dist/images/test.jpg" "/var/www/test/assets/images/test.jpg"` + */ +class ImageMinify extends BaseTask +{ + /** + * Destination directory for the minified images. + * + * @var string + */ + protected $to; + + /** + * Array of the source files. + * + * @var array + */ + protected $dirs = []; + + /** + * Symfony 2 filesystem. + * + * @var sfFilesystem + */ + protected $fs; + + /** + * Target directory for the downloaded binary executables. + * + * @var string + */ + protected $executableTargetDir; + + /** + * Array for the downloaded binary executables. + * + * @var array + */ + protected $executablePaths = []; + + /** + * Array for the individual results of all the files. + * + * @var array + */ + protected $results = []; + + /** + * Default minifier to use. + * + * @var string + */ + protected $minifier; + + /** + * Array for minifier options. + * + * @var array + */ + protected $minifierOptions = []; + + /** + * Supported minifiers. + * + * @var array + */ + protected $minifiers = [ + // Default 4 + 'optipng', + 'gifsicle', + 'jpegtran', + 'svgo', + // PNG + 'pngquant', + 'advpng', + 'pngout', + 'zopflipng', + 'pngcrush', + // JPG + 'jpegoptim', + 'jpeg-recompress', + ]; + + /** + * Binary repositories of Imagemin. + * + * @link https://github.com/imagemin + * + * @var array + */ + protected $imageminRepos = [ + // PNG + 'optipng' => 'https://github.com/imagemin/optipng-bin', + 'pngquant' => 'https://github.com/imagemin/pngquant-bin', + 'advpng' => 'https://github.com/imagemin/advpng-bin', + 'pngout' => 'https://github.com/imagemin/pngout-bin', + 'zopflipng' => 'https://github.com/imagemin/zopflipng-bin', + 'pngcrush' => 'https://github.com/imagemin/pngcrush-bin', + // Gif + 'gifsicle' => 'https://github.com/imagemin/gifsicle-bin', + // JPG + 'jpegtran' => 'https://github.com/imagemin/jpegtran-bin', + 'jpegoptim' => 'https://github.com/imagemin/jpegoptim-bin', + 'cjpeg' => 'https://github.com/imagemin/mozjpeg-bin', // note: we do not support this minifier because it creates JPG from non-JPG files + 'jpeg-recompress' => 'https://github.com/imagemin/jpeg-recompress-bin', + // WebP + 'cwebp' => 'https://github.com/imagemin/cwebp-bin', // note: we do not support this minifier because it creates WebP from non-WebP files + ]; + + public function __construct($dirs) + { + is_array($dirs) + ? $this->dirs = $dirs + : $this->dirs[] = $dirs; + + $this->fs = new sfFilesystem(); + + // guess the best path for the executables based on __DIR__ + if (($pos = strpos(__DIR__, 'consolidation/robo')) !== false) { + // the executables should be stored in vendor/bin + $this->executableTargetDir = substr(__DIR__, 0, $pos).'bin'; + } + + // check if the executables are already available + foreach ($this->imageminRepos as $exec => $url) { + $path = $this->executableTargetDir.'/'.$exec; + // if this is Windows add a .exe extension + if (substr($this->getOS(), 0, 3) == 'win') { + $path .= '.exe'; + } + if (is_file($path)) { + $this->executablePaths[$exec] = $path; + } + } + } + + /** + * {@inheritdoc} + */ + public function run() + { + // find the files + $files = $this->findFiles($this->dirs); + + // minify the files + $result = $this->minify($files); + // check if there was an error + if ($result instanceof Result) { + return $result; + } + + $amount = (count($files) == 1 ? 'image' : 'images'); + $message = "Minified {filecount} out of {filetotal} $amount into {destination}"; + $context = ['filecount' => count($this->results['success']), 'filetotal' => count($files), 'destination' => $this->to]; + + if (count($this->results['success']) == count($files)) { + $this->printTaskSuccess($message, $context); + + return Result::success($this, $message, $context); + } else { + return Result::error($this, $message, $context); + } + } + + /** + * Sets the target directory where the files will be copied to. + * + * @param string $target + * + * @return $this + */ + public function to($target) + { + $this->to = rtrim($target, '/'); + + return $this; + } + + /** + * Sets the minifier. + * + * @param string $minifier + * @param array $options + * + * @return $this + */ + public function minifier($minifier, array $options = []) + { + $this->minifier = $minifier; + $this->minifierOptions = array_merge($this->minifierOptions, $options); + + return $this; + } + + /** + * @param array $dirs + * + * @return array|\Robo\Result + * + * @throws \Robo\Exception\TaskException + */ + protected function findFiles($dirs) + { + $files = array(); + + // find the files + foreach ($dirs as $k => $v) { + // reset finder + $finder = new Finder(); + + $dir = $k; + $to = $v; + // check if target was given with the to() method instead of key/value pairs + if (is_int($k)) { + $dir = $v; + if (isset($this->to)) { + $to = $this->to; + } else { + throw new TaskException($this, 'target directory is not defined'); + } + } + + try { + $finder->files()->in($dir); + } catch (\InvalidArgumentException $e) { + // if finder cannot handle it, try with in()->name() + if (strpos($dir, '/') === false) { + $dir = './'.$dir; + } + $parts = explode('/', $dir); + $new_dir = implode('/', array_slice($parts, 0, -1)); + try { + $finder->files()->in($new_dir)->name(array_pop($parts)); + } catch (\InvalidArgumentException $e) { + return Result::fromException($this, $e); + } + } + + foreach ($finder as $file) { + // store the absolute path as key and target as value in the files array + $files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to); + } + $fileNoun = count($finder) == 1 ? ' file' : ' files'; + $this->printTaskInfo("Found {filecount} $fileNoun in {dir}", ['filecount' => count($finder), 'dir' => $dir]); + } + + return $files; + } + + /** + * @param string $file + * @param string $to + * + * @return string + */ + protected function getTarget($file, $to) + { + $target = $to.'/'.basename($file); + + return $target; + } + + /** + * @param array $files + * + * @return \Robo\Result + */ + protected function minify($files) + { + // store the individual results into the results array + $this->results = [ + 'success' => [], + 'error' => [], + ]; + + // loop through the files + foreach ($files as $from => $to) { + if (!isset($this->minifier)) { + // check filetype based on the extension + $extension = strtolower(pathinfo($from, PATHINFO_EXTENSION)); + + // set the default minifiers based on the extension + switch ($extension) { + case 'png': + $minifier = 'optipng'; + break; + case 'jpg': + case 'jpeg': + $minifier = 'jpegtran'; + break; + case 'gif': + $minifier = 'gifsicle'; + break; + case 'svg': + $minifier = 'svgo'; + break; + } + } else { + if (!in_array($this->minifier, $this->minifiers, true) + && !is_callable(strtr($this->minifier, '-', '_')) + ) { + $message = sprintf('Invalid minifier %s!', $this->minifier); + + return Result::error($this, $message); + } + $minifier = $this->minifier; + } + + // Convert minifier name to camelCase (e.g. jpeg-recompress) + $funcMinifier = $this->camelCase($minifier); + + // call the minifier method which prepares the command + if (is_callable($funcMinifier)) { + $command = call_user_func($funcMinifier, $from, $to, $this->minifierOptions); + } elseif (method_exists($this, $funcMinifier)) { + $command = $this->{$funcMinifier}($from, $to); + } else { + $message = sprintf('Minifier method %s cannot be found!', $funcMinifier); + + return Result::error($this, $message); + } + + // launch the command + $this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]); + $result = $this->executeCommand($command); + + // check the return code + if ($result->getExitCode() == 127) { + $this->printTaskError('The {minifier} executable cannot be found', ['minifier' => $minifier]); + // try to install from imagemin repository + if (array_key_exists($minifier, $this->imageminRepos)) { + $result = $this->installFromImagemin($minifier); + if ($result instanceof Result) { + if ($result->wasSuccessful()) { + $this->printTaskSuccess($result->getMessage()); + // retry the conversion with the downloaded executable + if (is_callable($minifier)) { + $command = call_user_func($minifier, $from, $to, $minifierOptions); + } elseif (method_exists($this, $minifier)) { + $command = $this->{$minifier}($from, $to); + } + // launch the command + $this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]); + $result = $this->executeCommand($command); + } else { + $this->printTaskError($result->getMessage()); + // the download was not successful + return $result; + } + } + } else { + return $result; + } + } + + // check the success of the conversion + if ($result->getExitCode() !== 0) { + $this->results['error'][] = $from; + } else { + $this->results['success'][] = $from; + } + } + } + + /** + * @return string + */ + protected function getOS() + { + $os = php_uname('s'); + $os .= '/'.php_uname('m'); + // replace x86_64 to x64, because the imagemin repo uses that + $os = str_replace('x86_64', 'x64', $os); + // replace i386, i686, etc to x86, because of imagemin + $os = preg_replace('/i[0-9]86/', 'x86', $os); + // turn info to lowercase, because of imagemin + $os = strtolower($os); + + return $os; + } + + /** + * @param string $command + * + * @return \Robo\Result + */ + protected function executeCommand($command) + { + // insert the options into the command + $a = explode(' ', $command); + $executable = array_shift($a); + foreach ($this->minifierOptions as $key => $value) { + // first prepend the value + if (!empty($value)) { + array_unshift($a, $value); + } + // then add the key + if (!is_numeric($key)) { + array_unshift($a, $key); + } + } + // check if the executable can be replaced with the downloaded one + if (array_key_exists($executable, $this->executablePaths)) { + $executable = $this->executablePaths[$executable]; + } + array_unshift($a, $executable); + $command = implode(' ', $a); + + // execute the command + $exec = new Exec($command); + + return $exec->inflect($this)->printed(false)->run(); + } + + /** + * @param string $executable + * + * @return \Robo\Result + */ + protected function installFromImagemin($executable) + { + // check if there is an url defined for the executable + if (!array_key_exists($executable, $this->imageminRepos)) { + $message = sprintf('The executable %s cannot be found in the defined imagemin repositories', $executable); + + return Result::error($this, $message); + } + $this->printTaskInfo('Downloading the {executable} executable from the imagemin repository', ['executable' => $executable]); + + $os = $this->getOS(); + $url = $this->imageminRepos[$executable].'/blob/master/vendor/'.$os.'/'.$executable.'?raw=true'; + if (substr($os, 0, 3) == 'win') { + // if it is win, add a .exe extension + $url = $this->imageminRepos[$executable].'/blob/master/vendor/'.$os.'/'.$executable.'.exe?raw=true'; + } + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is something wrong with the url, try it without the version info + $url = preg_replace('/x[68][64]\//', '', $url); + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is still something wrong with the url if it is win, try with win32 + if (substr($os, 0, 3) == 'win') { + $url = preg_replace('win/', 'win32/', $url); + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is nothing more we can do + $message = sprintf('Could not download the executable %s', $executable); + + return Result::error($this, $message); + } + } + // if it is not windows there is nothing we can do + $message = sprintf('Could not download the executable %s', $executable); + + return Result::error($this, $message); + } + } + // check if target directory exists + if (!is_dir($this->executableTargetDir)) { + mkdir($this->executableTargetDir); + } + // save the executable into the target dir + $path = $this->executableTargetDir.'/'.$executable; + if (substr($os, 0, 3) == 'win') { + // if it is win, add a .exe extension + $path = $this->executableTargetDir.'/'.$executable.'.exe'; + } + $result = file_put_contents($path, $data); + if ($result === false) { + $message = sprintf('Could not copy the executable %s to %s', $executable, $target_dir); + + return Result::error($this, $message); + } + // set the binary to executable + chmod($path, 0755); + + // if everything successful, store the executable path + $this->executablePaths[$executable] = $this->executableTargetDir.'/'.$executable; + // if it is win, add a .exe extension + if (substr($os, 0, 3) == 'win') { + $this->executablePaths[$executable] .= '.exe'; + } + + $message = sprintf('Executable %s successfully downloaded', $executable); + + return Result::success($this, $message); + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function optipng($from, $to) + { + $command = sprintf('optipng -quiet -out "%s" -- "%s"', $to, $from); + if ($from != $to && is_file($to)) { + // earlier versions of optipng do not overwrite the target without a backup + // http://sourceforge.net/p/optipng/bugs/37/ + unlink($to); + } + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegtran($from, $to) + { + $command = sprintf('jpegtran -optimize -outfile "%s" "%s"', $to, $from); + + return $command; + } + + protected function gifsicle($from, $to) + { + $command = sprintf('gifsicle -o "%s" "%s"', $to, $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function svgo($from, $to) + { + $command = sprintf('svgo "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngquant($from, $to) + { + $command = sprintf('pngquant --force --output "%s" "%s"', $to, $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function advpng($from, $to) + { + // advpng does not have any output parameters, copy the file and then compress the copy + $command = sprintf('advpng --recompress --quiet "%s"', $to); + $this->fs->copy($from, $to, true); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngout($from, $to) + { + $command = sprintf('pngout -y -q "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function zopflipng($from, $to) + { + $command = sprintf('zopflipng -y "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngcrush($from, $to) + { + $command = sprintf('pngcrush -q -ow "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegoptim($from, $to) + { + // jpegoptim only takes the destination directory as an argument + $command = sprintf('jpegoptim --quiet -o --dest "%s" "%s"', dirname($to), $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegRecompress($from, $to) + { + $command = sprintf('jpeg-recompress --quiet "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $text + * + * @return string + */ + public static function camelCase($text) + { + // non-alpha and non-numeric characters become spaces + $text = preg_replace('/[^a-z0-9]+/i', ' ', $text); + $text = trim($text); + // uppercase the first character of each word + $text = ucwords($text); + $text = str_replace(" ", "", $text); + $text = lcfirst($text); + + return $text; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Less.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Less.php new file mode 100644 index 00000000..4cfa0978 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Less.php @@ -0,0 +1,108 @@ +taskLess([ + * 'less/default.less' => 'css/default.css' + * ]) + * ->run(); + * ?> + * ``` + * + * Use one of both less compilers in your project: + * + * ``` + * "leafo/lessphp": "~0.5", + * "oyejorge/less.php": "~1.5" + * ``` + * + * Specify directory (string or array) for less imports lookup: + * + * ```php + * taskLess([ + * 'less/default.less' => 'css/default.css' + * ]) + * ->importDir('less') + * ->compiler('lessphp') + * ->run(); + * ?> + * ``` + * + * You can implement additional compilers by extending this task and adding a + * method named after them and overloading the lessCompilers() method to + * inject the name there. + */ +class Less extends CssPreprocessor +{ + const FORMAT_NAME = 'less'; + + /** + * @var string[] + */ + protected $compilers = [ + 'less', // https://github.com/oyejorge/less.php + 'lessphp', //https://github.com/leafo/lessphp + ]; + + /** + * lessphp compiler + * @link https://github.com/leafo/lessphp + * + * @param string $file + * + * @return string + */ + protected function lessphp($file) + { + if (!class_exists('\lessc')) { + return Result::errorMissingPackage($this, 'lessc', 'leafo/lessphp'); + } + + $lessCode = file_get_contents($file); + + $less = new \lessc(); + if (isset($this->compilerOptions['importDirs'])) { + $less->setImportDir($this->compilerOptions['importDirs']); + } + + return $less->compile($lessCode); + } + + /** + * less compiler + * @link https://github.com/oyejorge/less.php + * + * @param string $file + * + * @return string + */ + protected function less($file) + { + if (!class_exists('\Less_Parser')) { + return Result::errorMissingPackage($this, 'Less_Parser', 'oyejorge/less.php'); + } + + $lessCode = file_get_contents($file); + + $parser = new \Less_Parser(); + $parser->SetOptions($this->compilerOptions); + if (isset($this->compilerOptions['importDirs'])) { + $importDirs = []; + foreach ($this->compilerOptions['importDirs'] as $dir) { + $importDirs[$dir] = $dir; + } + $parser->SetImportDirs($importDirs); + } + + $parser->parse($lessCode); + + return $parser->getCss(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Minify.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Minify.php new file mode 100644 index 00000000..3187714e --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Minify.php @@ -0,0 +1,297 @@ +taskMinify( 'web/assets/theme.css' ) + * ->run() + * ?> + * ``` + * Please install additional dependencies to use: + * + * ``` + * "patchwork/jsqueeze": "~1.0", + * "natxet/CssMin": "~3.0" + * ``` + */ +class Minify extends BaseTask +{ + /** + * @var array + */ + protected $types = ['css', 'js']; + + /** + * @var string + */ + protected $text; + + /** + * @var string + */ + protected $dst; + + /** + * @var string + */ + protected $type; + + /** + * @var array + */ + protected $squeezeOptions = [ + 'singleLine' => true, + 'keepImportantComments' => true, + 'specialVarRx' => false, + ]; + + /** + * Constructor. Accepts asset file path or string source. + * + * @param string $input + */ + public function __construct($input) + { + if (file_exists($input)) { + $this->fromFile($input); + return; + } + + $this->fromText($input); + } + + /** + * Sets destination. Tries to guess type from it. + * + * @param string $dst + * + * @return $this + */ + public function to($dst) + { + $this->dst = $dst; + + if (!empty($this->dst) && empty($this->type)) { + $this->type($this->getExtension($this->dst)); + } + + return $this; + } + + /** + * Sets type with validation. + * + * @param string $type css|js + * + * @return $this + */ + public function type($type) + { + $type = strtolower($type); + + if (in_array($type, $this->types)) { + $this->type = $type; + } + + return $this; + } + + /** + * Sets text from string source. + * + * @param string $text + * + * @return $this + */ + protected function fromText($text) + { + $this->text = (string)$text; + unset($this->type); + + return $this; + } + + /** + * Sets text from asset file path. Tries to guess type and set default destination. + * + * @param string $path + * + * @return $this + */ + protected function fromFile($path) + { + $this->text = file_get_contents($path); + + unset($this->type); + $this->type($this->getExtension($path)); + + if (empty($this->dst) && !empty($this->type)) { + $ext_length = strlen($this->type) + 1; + $this->dst = substr($path, 0, -$ext_length) . '.min.' . $this->type; + } + + return $this; + } + + /** + * Gets file extension from path. + * + * @param string $path + * + * @return string + */ + protected function getExtension($path) + { + return pathinfo($path, PATHINFO_EXTENSION); + } + + /** + * Minifies and returns text. + * + * @return string|bool + */ + protected function getMinifiedText() + { + switch ($this->type) { + case 'css': + if (!class_exists('\CssMin')) { + return Result::errorMissingPackage($this, 'CssMin', 'natxet/CssMin'); + } + + return \CssMin::minify($this->text); + break; + + case 'js': + if (!class_exists('\JSqueeze') && !class_exists('\Patchwork\JSqueeze')) { + return Result::errorMissingPackage($this, 'Patchwork\JSqueeze', 'patchwork/jsqueeze'); + } + + if (class_exists('\JSqueeze')) { + $jsqueeze = new \JSqueeze(); + } else { + $jsqueeze = new \Patchwork\JSqueeze(); + } + + return $jsqueeze->squeeze( + $this->text, + $this->squeezeOptions['singleLine'], + $this->squeezeOptions['keepImportantComments'], + $this->squeezeOptions['specialVarRx'] + ); + break; + } + + return false; + } + + /** + * Single line option for the JS minimisation. + * + * @param bool $singleLine + * + * @return $this + */ + public function singleLine($singleLine) + { + $this->squeezeOptions['singleLine'] = (bool)$singleLine; + return $this; + } + + /** + * keepImportantComments option for the JS minimisation. + * + * @param bool $keepImportantComments + * + * @return $this + */ + public function keepImportantComments($keepImportantComments) + { + $this->squeezeOptions['keepImportantComments'] = (bool)$keepImportantComments; + return $this; + } + + /** + * specialVarRx option for the JS minimisation. + * + * @param bool $specialVarRx + * + * @return $this ; + */ + public function specialVarRx($specialVarRx) + { + $this->squeezeOptions['specialVarRx'] = (bool)$specialVarRx; + return $this; + } + + /** + * @return string + */ + public function __toString() + { + return (string) $this->getMinifiedText(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->type)) { + return Result::error($this, 'Unknown asset type.'); + } + + if (empty($this->dst)) { + return Result::error($this, 'Unknown file destination.'); + } + + if (file_exists($this->dst) && !is_writable($this->dst)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + + $size_before = strlen($this->text); + $minified = $this->getMinifiedText(); + + if ($minified instanceof Result) { + return $minified; + } elseif (false === $minified) { + return Result::error($this, 'Minification failed.'); + } + + $size_after = strlen($minified); + + // Minification did not reduce file size, so use original file. + if ($size_after > $size_before) { + $minified = $this->text; + $size_after = $size_before; + } + + $dst = $this->dst . '.part'; + $write_result = file_put_contents($dst, $minified); + + if (false === $write_result) { + @unlink($dst); + return Result::error($this, 'File write failed.'); + } + // Cannot be cross-volume; should always succeed. + @rename($dst, $this->dst); + if ($size_before === 0) { + $minified_percent = 0; + } else { + $minified_percent = number_format(100 - ($size_after / $size_before * 100), 1); + } + $this->printTaskSuccess('Wrote {filepath}', ['filepath' => $this->dst]); + $context = [ + 'bytes' => $this->formatBytes($size_after), + 'reduction' => $this->formatBytes(($size_before - $size_after)), + 'percentage' => $minified_percent, + ]; + $this->printTaskSuccess('Wrote {bytes} (reduced by {reduction} / {percentage})', $context); + return Result::success($this, 'Asset minified.'); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Scss.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Scss.php new file mode 100644 index 00000000..ffd39345 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/Scss.php @@ -0,0 +1,93 @@ +taskScss([ + * 'scss/default.scss' => 'css/default.css' + * ]) + * ->importDir('assets/styles') + * ->run(); + * ?> + * ``` + * + * Use the following scss compiler in your project: + * + * ``` + * "leafo/scssphp": "~0.1", + * ``` + * + * You can implement additional compilers by extending this task and adding a + * method named after them and overloading the scssCompilers() method to + * inject the name there. + */ +class Scss extends CssPreprocessor +{ + const FORMAT_NAME = 'scss'; + + /** + * @var string[] + */ + protected $compilers = [ + 'scssphp', // https://github.com/leafo/scssphp + ]; + + /** + * scssphp compiler + * @link https://github.com/leafo/scssphp + * + * @param string $file + * + * @return string + */ + protected function scssphp($file) + { + if (!class_exists('\Leafo\ScssPhp\Compiler')) { + return Result::errorMissingPackage($this, 'scssphp', 'leafo/scssphp'); + } + + $scssCode = file_get_contents($file); + $scss = new \Leafo\ScssPhp\Compiler(); + + // set options for the scssphp compiler + if (isset($this->compilerOptions['importDirs'])) { + $scss->setImportPaths($this->compilerOptions['importDirs']); + } + + if (isset($this->compilerOptions['formatter'])) { + $scss->setFormatter($this->compilerOptions['formatter']); + } + + return $scss->compile($scssCode); + } + + /** + * Sets the formatter for scssphp + * + * The method setFormatter($formatterName) sets the current formatter to $formatterName, + * the name of a class as a string that implements the formatting interface. See the source + * for Leafo\ScssPhp\Formatter\Expanded for an example. + * + * Five formatters are included with leafo/scssphp: + * - Leafo\ScssPhp\Formatter\Expanded + * - Leafo\ScssPhp\Formatter\Nested (default) + * - Leafo\ScssPhp\Formatter\Compressed + * - Leafo\ScssPhp\Formatter\Compact + * - Leafo\ScssPhp\Formatter\Crunched + * + * @link http://leafo.github.io/scssphp/docs/#output-formatting + * + * @param string $formatterName + * + * @return $this + */ + public function setFormatter($formatterName) + { + return parent::setFormatter($formatterName); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/loadTasks.php new file mode 100644 index 00000000..12192dd8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Assets/loadTasks.php @@ -0,0 +1,45 @@ +task(Minify::class, $input); + } + + /** + * @param string|string[] $input + * + * @return \Robo\Task\Assets\ImageMinify + */ + protected function taskImageMinify($input) + { + return $this->task(ImageMinify::class, $input); + } + + /** + * @param array $input + * + * @return \Robo\Task\Assets\Less + */ + protected function taskLess($input) + { + return $this->task(Less::class, $input); + } + + /** + * @param array $input + * + * @return \Robo\Task\Assets\Scss + */ + protected function taskScss($input) + { + return $this->task(Scss::class, $input); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/Exec.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/Exec.php new file mode 100644 index 00000000..c3e47917 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/Exec.php @@ -0,0 +1,125 @@ +taskExec('compass')->arg('watch')->run(); + * // or use shortcut + * $this->_exec('compass watch'); + * + * $this->taskExec('compass watch')->background()->run(); + * + * if ($this->taskExec('phpunit .')->run()->wasSuccessful()) { + * $this->say('tests passed'); + * } + * + * ?> + * ``` + */ +class Exec extends BaseTask implements CommandInterface, PrintedInterface, SimulatedInterface +{ + use \Robo\Common\CommandReceiver; + use \Robo\Common\ExecOneCommand; + + /** + * @var static[] + */ + protected static $instances = []; + + /** + * @var string|\Robo\Contract\CommandInterface + */ + protected $command; + + /** + * @param string|\Robo\Contract\CommandInterface $command + */ + public function __construct($command) + { + $this->command = $this->receiveCommand($command); + } + + /** + * + */ + public function __destruct() + { + $this->stop(); + } + + /** + * Executes command in background mode (asynchronously) + * + * @return $this + */ + public function background($arg = true) + { + self::$instances[] = $this; + $this->background = $arg; + return $this; + } + + /** + * {@inheritdoc} + */ + protected function getCommandDescription() + { + return $this->getCommand(); + } + /** + * {@inheritdoc} + */ + public function getCommand() + { + return trim($this->command . $this->arguments); + } + + /** + * {@inheritdoc} + */ + public function simulate($context) + { + $this->printAction($context); + } + + public static function stopRunningJobs() + { + foreach (self::$instances as $instance) { + if ($instance) { + unset($instance); + } + } + } + + /** + * {@inheritdoc} + */ + public function run() + { + // TODO: Symfony 4 requires that we supply the working directory. + $result_data = $this->execute(new Process($this->getCommand(), getcwd())); + return new Result( + $this, + $result_data->getExitCode(), + $result_data->getMessage(), + $result_data->getData() + ); + } +} + +if (function_exists('pcntl_signal')) { + pcntl_signal(SIGTERM, ['Robo\Task\Base\Exec', 'stopRunningJobs']); +} + +register_shutdown_function(['Robo\Task\Base\Exec', 'stopRunningJobs']); diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/ExecStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/ExecStack.php new file mode 100644 index 00000000..51b39ef1 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/ExecStack.php @@ -0,0 +1,23 @@ +taskExecStack() + * ->stopOnFail() + * ->exec('mkdir site') + * ->exec('cd site') + * ->run(); + * + * ?> + * ``` + */ +class ExecStack extends CommandStack +{ +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/ParallelExec.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/ParallelExec.php new file mode 100644 index 00000000..c98b7841 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/ParallelExec.php @@ -0,0 +1,199 @@ +taskParallelExec() + * ->process('php ~/demos/script.php hey') + * ->process('php ~/demos/script.php hoy') + * ->process('php ~/demos/script.php gou') + * ->run(); + * ?> + * ``` + */ +class ParallelExec extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\CommandReceiver; + + /** + * @var Process[] + */ + protected $processes = []; + + /** + * @var null|int + */ + protected $timeout = null; + + /** + * @var null|int + */ + protected $idleTimeout = null; + + /** + * @var null|int + */ + protected $waitInterval = 0; + + /** + * @var bool + */ + protected $isPrinted = false; + + /** + * {@inheritdoc} + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * @param bool $isPrinted + * + * @return $this + */ + public function printed($isPrinted = true) + { + $this->isPrinted = $isPrinted; + return $this; + } + + /** + * @param string|\Robo\Contract\CommandInterface $command + * + * @return $this + */ + public function process($command) + { + // TODO: Symfony 4 requires that we supply the working directory. + $this->processes[] = new Process($this->receiveCommand($command), getcwd()); + return $this; + } + + /** + * Stops process if it runs longer then `$timeout` (seconds). + * + * @param int $timeout + * + * @return $this + */ + public function timeout($timeout) + { + $this->timeout = $timeout; + return $this; + } + + /** + * Stops process if it does not output for time longer then `$timeout` (seconds). + * + * @param int $idleTimeout + * + * @return $this + */ + public function idleTimeout($idleTimeout) + { + $this->idleTimeout = $idleTimeout; + return $this; + } + + /** + * Parallel processing will wait `$waitInterval` seconds after launching each process and before + * the next one. + * + * @param int $waitInterval + * + * @return $this + */ + public function waitInterval($waitInterval) + { + $this->waitInterval = $waitInterval; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return implode(' && ', $this->processes); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + return count($this->processes); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->startProgressIndicator(); + $running = []; + $queue = $this->processes; + $nextTime = time(); + while (true) { + if (($nextTime <= time()) && !empty($queue)) { + $process = array_shift($queue); + $process->setIdleTimeout($this->idleTimeout); + $process->setTimeout($this->timeout); + $process->start(); + $this->printTaskInfo($process->getCommandLine()); + $running[] = $process; + $nextTime = time() + $this->waitInterval; + } + foreach ($running as $k => $process) { + try { + $process->checkTimeout(); + } catch (ProcessTimedOutException $e) { + $this->printTaskWarning("Process timed out for {command}", ['command' => $process->getCommandLine(), '_style' => ['command' => 'fg=white;bg=magenta']]); + } + if (!$process->isRunning()) { + $this->advanceProgressIndicator(); + if ($this->isPrinted) { + $this->printTaskInfo("Output for {command}:\n\n{output}", ['command' => $process->getCommandLine(), 'output' => $process->getOutput(), '_style' => ['command' => 'fg=white;bg=magenta']]); + $errorOutput = $process->getErrorOutput(); + if ($errorOutput) { + $this->printTaskError(rtrim($errorOutput)); + } + } + unset($running[$k]); + } + } + if (empty($running) && empty($queue)) { + break; + } + usleep(1000); + } + $this->stopProgressIndicator(); + + $errorMessage = ''; + $exitCode = 0; + foreach ($this->processes as $p) { + if ($p->getExitCode() === 0) { + continue; + } + $errorMessage .= "'" . $p->getCommandLine() . "' exited with code ". $p->getExitCode()." \n"; + $exitCode = max($exitCode, $p->getExitCode()); + } + if (!$errorMessage) { + $this->printTaskSuccess('{process-count} processes finished running', ['process-count' => count($this->processes)]); + } + + return new Result($this, $exitCode, $errorMessage, ['time' => $this->getExecutionTime()]); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/SymfonyCommand.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/SymfonyCommand.php new file mode 100644 index 00000000..708ea845 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/SymfonyCommand.php @@ -0,0 +1,75 @@ +taskSymfonyCommand(new \Codeception\Command\Run('run')) + * ->arg('suite','acceptance') + * ->opt('debug') + * ->run(); + * + * // Artisan Command + * $this->taskSymfonyCommand(new ModelGeneratorCommand()) + * ->arg('name', 'User') + * ->run(); + * ?> + * ``` + */ +class SymfonyCommand extends BaseTask +{ + /** + * @var \Symfony\Component\Console\Command\Command + */ + protected $command; + + /** + * @var string[] + */ + protected $input; + + public function __construct(Command $command) + { + $this->command = $command; + $this->input = []; + } + + /** + * @param string $arg + * @param string $value + * + * @return $this + */ + public function arg($arg, $value) + { + $this->input[$arg] = $value; + return $this; + } + + public function opt($option, $value = null) + { + $this->input["--$option"] = $value; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running command {command}', ['command' => $this->command->getName()]); + return new Result( + $this, + $this->command->run(new ArrayInput($this->input), Robo::output()) + ); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/Watch.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/Watch.php new file mode 100644 index 00000000..d7940ac9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/Watch.php @@ -0,0 +1,89 @@ +taskWatch() + * ->monitor('composer.json', function() { + * $this->taskComposerUpdate()->run(); + * })->monitor('src', function() { + * $this->taskExec('phpunit')->run(); + * })->run(); + * ?> + * ``` + */ +class Watch extends BaseTask +{ + /** + * @var \Closure + */ + protected $closure; + + /** + * @var array + */ + protected $monitor = []; + + /** + * @var object + */ + protected $bindTo; + + /** + * @param $bindTo + */ + public function __construct($bindTo) + { + $this->bindTo = $bindTo; + } + + /** + * @param string|string[] $paths + * @param \Closure $callable + * + * @return $this + */ + public function monitor($paths, \Closure $callable) + { + if (!is_array($paths)) { + $paths = [$paths]; + } + $this->monitor[] = [$paths, $callable]; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!class_exists('Lurker\\ResourceWatcher')) { + return Result::errorMissingPackage($this, 'ResourceWatcher', 'henrikbjorn/lurker'); + } + + $watcher = new ResourceWatcher(); + + foreach ($this->monitor as $k => $monitor) { + /** @var \Closure $closure */ + $closure = $monitor[1]; + $closure->bindTo($this->bindTo); + foreach ($monitor[0] as $i => $dir) { + $watcher->track("fs.$k.$i", $dir, FilesystemEvent::MODIFY); + $this->printTaskInfo('Watching {dir} for changes...', ['dir' => $dir]); + $watcher->addListener("fs.$k.$i", $closure); + } + } + + $watcher->start(); + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/loadShortcuts.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/loadShortcuts.php new file mode 100644 index 00000000..dba0af66 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/loadShortcuts.php @@ -0,0 +1,17 @@ +taskExec($command)->run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/loadTasks.php new file mode 100644 index 00000000..ab5301bb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Base/loadTasks.php @@ -0,0 +1,48 @@ +task(Exec::class, $command); + } + + /** + * @return ExecStack + */ + protected function taskExecStack() + { + return $this->task(ExecStack::class); + } + + /** + * @return ParallelExec + */ + protected function taskParallelExec() + { + return $this->task(ParallelExec::class); + } + + /** + * @param $command + * @return SymfonyCommand + */ + protected function taskSymfonyCommand($command) + { + return $this->task(SymfonyCommand::class, $command); + } + + /** + * @return Watch + */ + protected function taskWatch() + { + return $this->task(Watch::class, $this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/BaseTask.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/BaseTask.php new file mode 100644 index 00000000..66155c09 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/BaseTask.php @@ -0,0 +1,60 @@ +logger) { + $child->setLogger($this->logger); + } + if ($child instanceof ProgressIndicatorAwareInterface && $this->progressIndicator) { + $child->setProgressIndicator($this->progressIndicator); + } + if ($child instanceof ConfigAwareInterface && $this->getConfig()) { + $child->setConfig($this->getConfig()); + } + if ($child instanceof VerbosityThresholdInterface && $this->outputAdapter()) { + $child->setOutputAdapter($this->outputAdapter()); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Base.php new file mode 100644 index 00000000..9bc614c6 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Base.php @@ -0,0 +1,88 @@ +option('allow-root'); + return $this; + } + + /** + * adds `force-latest` option to bower + * + * @return $this + */ + public function forceLatest() + { + $this->option('force-latest'); + return $this; + } + + /** + * adds `production` option to bower + * + * @return $this + */ + public function noDev() + { + $this->option('production'); + return $this; + } + + /** + * adds `offline` option to bower + * + * @return $this + */ + public function offline() + { + $this->option('offline'); + return $this; + } + + /** + * Base constructor. + * + * @param null|string $pathToBower + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToBower = null) + { + $this->command = $pathToBower; + if (!$this->command) { + $this->command = $this->findExecutable('bower'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Bower executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Install.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Install.php new file mode 100644 index 00000000..c3c0ce75 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Install.php @@ -0,0 +1,36 @@ +taskBowerInstall()->run(); + * + * // prefer dist with custom path + * $this->taskBowerInstall('path/to/my/bower') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Install extends Base implements CommandInterface +{ + /** + * {@inheritdoc} + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Install Bower packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Update.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Update.php new file mode 100644 index 00000000..f0dfa94e --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/Update.php @@ -0,0 +1,34 @@ +taskBowerUpdate->run(); + * + * // prefer dist with custom path + * $this->taskBowerUpdate('path/to/my/bower') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Update Bower packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/loadTasks.php new file mode 100644 index 00000000..6e33f8ac --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Bower/loadTasks.php @@ -0,0 +1,25 @@ +task(Install::class, $pathToBower); + } + + /** + * @param null|string $pathToBower + * + * @return Update + */ + protected function taskBowerUpdate($pathToBower = null) + { + return $this->task(Update::class, $pathToBower); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/CommandStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/CommandStack.php new file mode 100644 index 00000000..f1cb4492 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/CommandStack.php @@ -0,0 +1,134 @@ +exec); + } + + /** + * @param string $executable + * + * @return $this + */ + public function executable($executable) + { + $this->executable = $executable; + return $this; + } + + /** + * @param string|string[] $command + * + * @return $this + */ + public function exec($command) + { + if (is_array($command)) { + $command = implode(' ', array_filter($command)); + } + + $command = $this->executable . ' ' . $this->stripExecutableFromCommand($command); + $this->exec[] = trim($command); + return $this; + } + + /** + * @param bool $stopOnFail + * + * @return $this + */ + public function stopOnFail($stopOnFail = true) + { + $this->stopOnFail = $stopOnFail; + return $this; + } + + public function result($result) + { + $this->result = $result; + return $this; + } + + /** + * @param string $command + * + * @return string + */ + protected function stripExecutableFromCommand($command) + { + $command = trim($command); + $executable = $this->executable . ' '; + if (strpos($command, $executable) === 0) { + $command = substr($command, strlen($executable)); + } + return $command; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->exec)) { + throw new TaskException($this, 'You must add at least one command'); + } + // If 'stopOnFail' is not set, or if there is only one command to run, + // then execute the single command to run. + if (!$this->stopOnFail || (count($this->exec) == 1)) { + $this->printTaskInfo('{command}', ['command' => $this->getCommand()]); + return $this->executeCommand($this->getCommand()); + } + + // When executing multiple commands in 'stopOnFail' mode, run them + // one at a time so that the result will have the exact command + // that failed available to the caller. This is at the expense of + // losing the output from all successful commands. + $data = []; + $message = ''; + $result = null; + foreach ($this->exec as $command) { + $this->printTaskInfo("Executing {command}", ['command' => $command]); + $result = $this->executeCommand($command); + $result->accumulateExecutionTime($data); + $message = $result->accumulateMessage($message); + $data = $result->mergeData($data); + if (!$result->wasSuccessful()) { + return $result; + } + } + + return $result; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Base.php new file mode 100644 index 00000000..de3fe217 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Base.php @@ -0,0 +1,248 @@ +command = $pathToComposer; + if (!$this->command) { + $this->command = $this->findExecutablePhar('composer'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Neither local composer.phar nor global composer installation could be found."); + } + } + + /** + * adds `prefer-dist` option to composer + * + * @return $this + */ + public function preferDist($preferDist = true) + { + if (!$preferDist) { + return $this->preferSource(); + } + $this->prefer = '--prefer-dist'; + return $this; + } + + /** + * adds `prefer-source` option to composer + * + * @return $this + */ + public function preferSource() + { + $this->prefer = '--prefer-source'; + return $this; + } + + /** + * adds `dev` option to composer + * + * @return $this + */ + public function dev($dev = true) + { + if (!$dev) { + return $this->noDev(); + } + $this->dev = '--dev'; + return $this; + } + + /** + * adds `no-dev` option to composer + * + * @return $this + */ + public function noDev() + { + $this->dev = '--no-dev'; + return $this; + } + + /** + * adds `ansi` option to composer + * + * @return $this + */ + public function ansi($ansi = true) + { + if (!$ansi) { + return $this->noAnsi(); + } + $this->ansi = '--ansi'; + return $this; + } + + /** + * adds `no-ansi` option to composer + * + * @return $this + */ + public function noAnsi() + { + $this->ansi = '--no-ansi'; + return $this; + } + + public function interaction($interaction = true) + { + if (!$interaction) { + return $this->noInteraction(); + } + return $this; + } + + /** + * adds `no-interaction` option to composer + * + * @return $this + */ + public function noInteraction() + { + $this->nointeraction = '--no-interaction'; + return $this; + } + + /** + * adds `optimize-autoloader` option to composer + * + * @return $this + */ + public function optimizeAutoloader($optimize = true) + { + if ($optimize) { + $this->option('--optimize-autoloader'); + } + return $this; + } + + /** + * adds `ignore-platform-reqs` option to composer + * + * @return $this + */ + public function ignorePlatformRequirements($ignore = true) + { + $this->option('--ignore-platform-reqs'); + return $this; + } + + /** + * disable plugins + * + * @return $this + */ + public function disablePlugins($disable = true) + { + if ($disable) { + $this->option('--no-plugins'); + } + return $this; + } + + /** + * skip scripts + * + * @return $this + */ + public function noScripts($disable = true) + { + if ($disable) { + $this->option('--no-scripts'); + } + return $this; + } + + /** + * adds `--working-dir $dir` option to composer + * + * @return $this + */ + public function workingDir($dir) + { + $this->option("--working-dir", $dir); + return $this; + } + + /** + * Copy class fields into command options as directed. + */ + public function buildCommand() + { + if (!isset($this->ansi) && $this->getConfig()->get(\Robo\Config\Config::DECORATED)) { + $this->ansi(); + } + if (!isset($this->nointeraction) && !$this->getConfig()->get(\Robo\Config\Config::INTERACTIVE)) { + $this->noInteraction(); + } + $this->option($this->prefer) + ->option($this->dev) + ->option($this->nointeraction) + ->option($this->ansi); + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + if (!$this->built) { + $this->buildCommand(); + $this->built = true; + } + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Config.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Config.php new file mode 100644 index 00000000..b5a6bbff --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Config.php @@ -0,0 +1,93 @@ +taskComposerConfig()->set('bin-dir', 'bin/')->run(); + * ?> + * ``` + */ +class Config extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'config'; + + /** + * Set a configuration value + * @return $this + */ + public function set($key, $value) + { + $this->arg($key); + $this->arg($value); + return $this; + } + + /** + * Operate on the global repository + * @return $this + */ + public function useGlobal($useGlobal = true) + { + if ($useGlobal) { + $this->option('global'); + } + return $this; + } + + /** + * @return $this + */ + public function repository($id, $uri, $repoType = 'vcs') + { + $this->arg("repositories.$id"); + $this->arg($repoType); + $this->arg($uri); + return $this; + } + + /** + * @return $this + */ + public function removeRepository($id) + { + $this->option('unset', "repositories.$id"); + return $this; + } + + /** + * @return $this + */ + public function disableRepository($id) + { + $this->arg("repositories.$id"); + $this->arg('false'); + return $this; + } + + /** + * @return $this + */ + public function enableRepository($id) + { + $this->arg("repositories.$id"); + $this->arg('true'); + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Configuring composer.json: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/CreateProject.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/CreateProject.php new file mode 100644 index 00000000..5f979a64 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/CreateProject.php @@ -0,0 +1,112 @@ +taskComposerCreateProject()->source('foo/bar')->target('myBar')->run(); + * ?> + * ``` + */ +class CreateProject extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'create-project'; + + protected $source; + protected $target = ''; + protected $version = ''; + + /** + * @return $this + */ + public function source($source) + { + $this->source = $source; + return $this; + } + + /** + * @return $this + */ + public function target($target) + { + $this->target = $target; + return $this; + } + + /** + * @return $this + */ + public function version($version) + { + $this->version = $version; + return $this; + } + + public function keepVcs($keep = true) + { + if ($keep) { + $this->option('--keep-vcs'); + } + return $this; + } + + public function noInstall($noInstall = true) + { + if ($noInstall) { + $this->option('--no-install'); + } + return $this; + } + + /** + * @return $this + */ + public function repository($repository) + { + if (!empty($repository)) { + $this->option('repository', $repository); + } + return $this; + } + + /** + * @return $this + */ + public function stability($stability) + { + if (!empty($stability)) { + $this->option('stability', $stability); + } + return $this; + } + + public function buildCommand() + { + $this->arg($this->source); + if (!empty($this->target)) { + $this->arg($this->target); + } + if (!empty($this->version)) { + $this->arg($this->version); + } + + return parent::buildCommand(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Creating project: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/DumpAutoload.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/DumpAutoload.php new file mode 100644 index 00000000..55b1ea00 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/DumpAutoload.php @@ -0,0 +1,62 @@ +taskComposerDumpAutoload()->run(); + * + * // dump auto loader with custom path + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader dump with custom path + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->optimize() + * ->run(); + * + * // optimize autoloader dump with custom path and no dev + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->optimize() + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class DumpAutoload extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'dump-autoload'; + + /** + * @var string + */ + protected $optimize; + + /** + * @return $this + */ + public function optimize($optimize = true) + { + if ($optimize) { + $this->option("--optimize"); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Dumping Autoloader: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Init.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Init.php new file mode 100644 index 00000000..c841299d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Init.php @@ -0,0 +1,115 @@ +taskComposerInit()->run(); + * ?> + * ``` + */ +class Init extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'init'; + + /** + * @return $this + */ + public function projectName($projectName) + { + $this->option('name', $projectName); + return $this; + } + + /** + * @return $this + */ + public function description($description) + { + $this->option('description', $description); + return $this; + } + + /** + * @return $this + */ + public function author($author) + { + $this->option('author', $author); + return $this; + } + + /** + * @return $this + */ + public function projectType($type) + { + $this->option('type', $type); + return $this; + } + + /** + * @return $this + */ + public function homepage($homepage) + { + $this->option('homepage', $homepage); + return $this; + } + + /** + * 'require' is a keyword, so it cannot be a method name. + * @return $this + */ + public function dependency($project, $version = null) + { + if (isset($version)) { + $project .= ":$version"; + } + $this->option('require', $project); + return $this; + } + + /** + * @return $this + */ + public function stability($stability) + { + $this->option('stability', $stability); + return $this; + } + + /** + * @return $this + */ + public function license($license) + { + $this->option('license', $license); + return $this; + } + + /** + * @return $this + */ + public function repository($repository) + { + $this->option('repository', $repository); + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Creating composer.json: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Install.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Install.php new file mode 100644 index 00000000..76cb9861 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Install.php @@ -0,0 +1,40 @@ +taskComposerInstall()->run(); + * + * // prefer dist with custom path + * $this->taskComposerInstall('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader with custom path + * $this->taskComposerInstall('path/to/my/composer.phar') + * ->optimizeAutoloader() + * ->run(); + * ?> + * ``` + */ +class Install extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Installing Packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Remove.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Remove.php new file mode 100644 index 00000000..b0316f05 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Remove.php @@ -0,0 +1,85 @@ +taskComposerRemove()->run(); + * ?> + * ``` + */ +class Remove extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'remove'; + + /** + * @return $this + */ + public function dev($dev = true) + { + if ($dev) { + $this->option('--dev'); + } + return $this; + } + + /** + * @return $this + */ + public function noProgress($noProgress = true) + { + if ($noProgress) { + $this->option('--no-progress'); + } + return $this; + } + + /** + * @return $this + */ + public function noUpdate($noUpdate = true) + { + if ($noUpdate) { + $this->option('--no-update'); + } + return $this; + } + + /** + * @return $this + */ + public function updateNoDev($updateNoDev = true) + { + if ($updateNoDev) { + $this->option('--update-no-dev'); + } + return $this; + } + + /** + * @return $this + */ + public function noUpdateWithDependencies($updateWithDependencies = true) + { + if ($updateWithDependencies) { + $this->option('--no-update-with-dependencies'); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Removing packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/RequireDependency.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/RequireDependency.php new file mode 100644 index 00000000..6cdbf613 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/RequireDependency.php @@ -0,0 +1,50 @@ +taskComposerRequire()->dependency('foo/bar', '^.2.4.8')->run(); + * ?> + * ``` + */ +class RequireDependency extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'require'; + + /** + * 'require' is a keyword, so it cannot be a method name. + * @return $this + */ + public function dependency($project, $version = null) + { + $project = (array)$project; + + if (isset($version)) { + $project = array_map( + function ($item) use ($version) { + return "$item:$version"; + }, + $project + ); + } + $this->args($project); + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Requiring packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Update.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Update.php new file mode 100644 index 00000000..3a0a64af --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Update.php @@ -0,0 +1,40 @@ +taskComposerUpdate()->run(); + * + * // prefer dist with custom path + * $this->taskComposerUpdate('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader with custom path + * $this->taskComposerUpdate('path/to/my/composer.phar') + * ->optimizeAutoloader() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Updating Packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Validate.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Validate.php new file mode 100644 index 00000000..adb15854 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/Validate.php @@ -0,0 +1,85 @@ +taskComposerValidate()->run(); + * ?> + * ``` + */ +class Validate extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'validate'; + + /** + * @return $this + */ + public function noCheckAll($noCheckAll = true) + { + if ($noCheckAll) { + $this->option('--no-check-all'); + } + return $this; + } + + /** + * @return $this + */ + public function noCheckLock($noCheckLock = true) + { + if ($noCheckLock) { + $this->option('--no-check-lock'); + } + return $this; + } + + /** + * @return $this + */ + public function noCheckPublish($noCheckPublish = true) + { + if ($noCheckPublish) { + $this->option('--no-check-publish'); + } + return $this; + } + + /** + * @return $this + */ + public function withDependencies($withDependencies = true) + { + if ($withDependencies) { + $this->option('--with-dependencies'); + } + return $this; + } + + /** + * @return $this + */ + public function strict($strict = true) + { + if ($strict) { + $this->option('--strict'); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Validating composer.json: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/loadTasks.php new file mode 100644 index 00000000..6b074ba3 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Composer/loadTasks.php @@ -0,0 +1,95 @@ +task(Install::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Update + */ + protected function taskComposerUpdate($pathToComposer = null) + { + return $this->task(Update::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return DumpAutoload + */ + protected function taskComposerDumpAutoload($pathToComposer = null) + { + return $this->task(DumpAutoload::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Init + */ + protected function taskComposerInit($pathToComposer = null) + { + return $this->task(Init::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Init + */ + protected function taskComposerConfig($pathToComposer = null) + { + return $this->task(Config::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Validate + */ + protected function taskComposerValidate($pathToComposer = null) + { + return $this->task(Validate::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Remove + */ + protected function taskComposerRemove($pathToComposer = null) + { + return $this->task(Remove::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Remove + */ + protected function taskComposerRequire($pathToComposer = null) + { + return $this->task(RequireDependency::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Remove + */ + protected function taskComposerCreateProject($pathToComposer = null) + { + return $this->task(CreateProject::class, $pathToComposer); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/Changelog.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/Changelog.php new file mode 100644 index 00000000..44af6d82 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/Changelog.php @@ -0,0 +1,246 @@ +taskChangelog() + * ->version($version) + * ->change("released to github") + * ->run(); + * ?> + * ``` + * + * Changes can be asked from Console + * + * ``` php + * taskChangelog() + * ->version($version) + * ->askForChanges() + * ->run(); + * ?> + * ``` + */ +class Changelog extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $filename; + + /** + * @var array + */ + protected $log = []; + + /** + * @var string + */ + protected $anchor = "# Changelog"; + + /** + * @var string + */ + protected $version = ""; + + /** + * @var string + */ + protected $body = ""; + + /** + * @var string + */ + protected $header = ""; + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * Sets the changelog body text. + * + * This method permits the raw changelog text to be set directly If this is set, $this->log changes will be ignored. + * + * @param string $body + * + * @return $this + */ + public function setBody($body) + { + $this->body = $body; + return $this; + } + + /** + * @param string $header + * + * @return $this + */ + public function setHeader($header) + { + $this->header = $header; + return $this; + } + + /** + * @param string $item + * + * @return $this + */ + public function log($item) + { + $this->log[] = $item; + return $this; + } + + /** + * @param string $anchor + * + * @return $this + */ + public function anchor($anchor) + { + $this->anchor = $anchor; + return $this; + } + + /** + * @param string $version + * + * @return $this + */ + public function version($version) + { + $this->version = $version; + return $this; + } + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param array $data + * + * @return $this + */ + public function changes(array $data) + { + $this->log = array_merge($this->log, $data); + return $this; + } + + /** + * @param string $change + * + * @return $this + */ + public function change($change) + { + $this->log[] = $change; + return $this; + } + + /** + * @return array + */ + public function getChanges() + { + return $this->log; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->body)) { + if (empty($this->log)) { + return Result::error($this, "Changelog is empty"); + } + $this->body = $this->generateBody(); + } + if (empty($this->header)) { + $this->header = $this->generateHeader(); + } + + $text = $this->header . $this->body; + + if (!file_exists($this->filename)) { + $this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]); + $res = file_put_contents($this->filename, $this->anchor); + if ($res === false) { + return Result::error($this, "File {filename} cant be created", ['filename' => $this->filename]); + } + } + + /** @var \Robo\Result $result */ + // trying to append to changelog for today + $result = $this->collectionBuilder()->taskReplaceInFile($this->filename) + ->from($this->header) + ->to($text) + ->run(); + + if (!isset($result['replaced']) || !$result['replaced']) { + $result = $this->collectionBuilder()->taskReplaceInFile($this->filename) + ->from($this->anchor) + ->to($this->anchor . "\n\n" . $text) + ->run(); + } + + return new Result($this, $result->getExitCode(), $result->getMessage(), $this->log); + } + + /** + * @return \Robo\Result|string + */ + protected function generateBody() + { + $text = implode("\n", array_map([$this, 'processLogRow'], $this->log)); + $text .= "\n"; + + return $text; + } + + /** + * @return string + */ + protected function generateHeader() + { + return "#### {$this->version}\n\n"; + } + + /** + * @param $i + * + * @return string + */ + public function processLogRow($i) + { + return "* $i *" . date('Y-m-d') . "*"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GenerateMarkdownDoc.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GenerateMarkdownDoc.php new file mode 100644 index 00000000..0c3ec26c --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GenerateMarkdownDoc.php @@ -0,0 +1,782 @@ +taskGenDoc('models.md') + * ->docClass('Model\User') // take class Model\User + * ->docClass('Model\Post') // take class Model\Post + * ->filterMethods(function(\ReflectionMethod $r) { + * return $r->isPublic() or $r->isProtected(); // process public and protected methods + * })->processClass(function(\ReflectionClass $r, $text) { + * return "Class ".$r->getName()."\n\n$text\n\n###Methods\n"; + * })->run(); + * ``` + * + * By default this task generates a documentation for each public method of a class. + * It combines method signature with a docblock. Both can be post-processed. + * + * ``` php + * taskGenDoc('models.md') + * ->docClass('Model\User') + * ->processClassSignature(false) // false can be passed to not include class signature + * ->processClassDocBlock(function(\ReflectionClass $r, $text) { + * return "[This is part of application model]\n" . $text; + * })->processMethodSignature(function(\ReflectionMethod $r, $text) { + * return "#### {$r->name}()"; + * })->processMethodDocBlock(function(\ReflectionMethod $r, $text) { + * return strpos($r->name, 'save')===0 ? "[Saves to the database]\n" . $text : $text; + * })->run(); + * ``` + */ +class GenerateMarkdownDoc extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string[] + */ + protected $docClass = []; + + /** + * @var callable + */ + protected $filterMethods; + + /** + * @var callable + */ + protected $filterClasses; + + /** + * @var callable + */ + protected $filterProperties; + + /** + * @var callable + */ + protected $processClass; + + /** + * @var callable|false + */ + protected $processClassSignature; + + /** + * @var callable|false + */ + protected $processClassDocBlock; + + /** + * @var callable|false + */ + protected $processMethod; + + /** + * @var callable|false + */ + protected $processMethodSignature; + + /** + * @var callable|false + */ + protected $processMethodDocBlock; + + /** + * @var callable|false + */ + protected $processProperty; + + /** + * @var callable|false + */ + protected $processPropertySignature; + + /** + * @var callable|false + */ + protected $processPropertyDocBlock; + + /** + * @var callable + */ + protected $reorder; + + /** + * @var callable + */ + protected $reorderMethods; + + /** + * @todo Unused property. + * + * @var callable + */ + protected $reorderProperties; + + /** + * @var string + */ + protected $filename; + + /** + * @var string + */ + protected $prepend = ""; + + /** + * @var string + */ + protected $append = ""; + + /** + * @var string + */ + protected $text; + + /** + * @var string[] + */ + protected $textForClass = []; + + /** + * @param string $filename + * + * @return static + */ + public static function init($filename) + { + return new static($filename); + } + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * Put a class you want to be documented. + * + * @param string $item + * + * @return $this + */ + public function docClass($item) + { + $this->docClass[] = $item; + return $this; + } + + /** + * Using a callback function filter out methods that won't be documented. + * + * @param callable $filterMethods + * + * @return $this + */ + public function filterMethods($filterMethods) + { + $this->filterMethods = $filterMethods; + return $this; + } + + /** + * Using a callback function filter out classes that won't be documented. + * + * @param callable $filterClasses + * + * @return $this + */ + public function filterClasses($filterClasses) + { + $this->filterClasses = $filterClasses; + return $this; + } + + /** + * Using a callback function filter out properties that won't be documented. + * + * @param callable $filterProperties + * + * @return $this + */ + public function filterProperties($filterProperties) + { + $this->filterProperties = $filterProperties; + return $this; + } + + /** + * Post-process class documentation. + * + * @param callable $processClass + * + * @return $this + */ + public function processClass($processClass) + { + $this->processClass = $processClass; + return $this; + } + + /** + * Post-process class signature. Provide *false* to skip. + * + * @param callable|false $processClassSignature + * + * @return $this + */ + public function processClassSignature($processClassSignature) + { + $this->processClassSignature = $processClassSignature; + return $this; + } + + /** + * Post-process class docblock contents. Provide *false* to skip. + * + * @param callable|false $processClassDocBlock + * + * @return $this + */ + public function processClassDocBlock($processClassDocBlock) + { + $this->processClassDocBlock = $processClassDocBlock; + return $this; + } + + /** + * Post-process method documentation. Provide *false* to skip. + * + * @param callable|false $processMethod + * + * @return $this + */ + public function processMethod($processMethod) + { + $this->processMethod = $processMethod; + return $this; + } + + /** + * Post-process method signature. Provide *false* to skip. + * + * @param callable|false $processMethodSignature + * + * @return $this + */ + public function processMethodSignature($processMethodSignature) + { + $this->processMethodSignature = $processMethodSignature; + return $this; + } + + /** + * Post-process method docblock contents. Provide *false* to skip. + * + * @param callable|false $processMethodDocBlock + * + * @return $this + */ + public function processMethodDocBlock($processMethodDocBlock) + { + $this->processMethodDocBlock = $processMethodDocBlock; + return $this; + } + + /** + * Post-process property documentation. Provide *false* to skip. + * + * @param callable|false $processProperty + * + * @return $this + */ + public function processProperty($processProperty) + { + $this->processProperty = $processProperty; + return $this; + } + + /** + * Post-process property signature. Provide *false* to skip. + * + * @param callable|false $processPropertySignature + * + * @return $this + */ + public function processPropertySignature($processPropertySignature) + { + $this->processPropertySignature = $processPropertySignature; + return $this; + } + + /** + * Post-process property docblock contents. Provide *false* to skip. + * + * @param callable|false $processPropertyDocBlock + * + * @return $this + */ + public function processPropertyDocBlock($processPropertyDocBlock) + { + $this->processPropertyDocBlock = $processPropertyDocBlock; + return $this; + } + + /** + * Use a function to reorder classes. + * + * @param callable $reorder + * + * @return $this + */ + public function reorder($reorder) + { + $this->reorder = $reorder; + return $this; + } + + /** + * Use a function to reorder methods in class. + * + * @param callable $reorderMethods + * + * @return $this + */ + public function reorderMethods($reorderMethods) + { + $this->reorderMethods = $reorderMethods; + return $this; + } + + /** + * @param callable $reorderProperties + * + * @return $this + */ + public function reorderProperties($reorderProperties) + { + $this->reorderProperties = $reorderProperties; + return $this; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * Inserts text at the beginning of markdown file. + * + * @param string $prepend + * + * @return $this + */ + public function prepend($prepend) + { + $this->prepend = $prepend; + return $this; + } + + /** + * Inserts text at the end of markdown file. + * + * @param string $append + * + * @return $this + */ + public function append($append) + { + $this->append = $append; + return $this; + } + + /** + * @param string $text + * + * @return $this + */ + public function text($text) + { + $this->text = $text; + return $this; + } + + /** + * @param string $item + * + * @return $this + */ + public function textForClass($item) + { + $this->textForClass[] = $item; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + foreach ($this->docClass as $class) { + $this->printTaskInfo("Processing {class}", ['class' => $class]); + $this->textForClass[$class] = $this->documentClass($class); + } + + if (is_callable($this->reorder)) { + $this->printTaskInfo("Applying reorder function"); + call_user_func_array($this->reorder, [$this->textForClass]); + } + + $this->text = implode("\n", $this->textForClass); + + /** @var \Robo\Result $result */ + $result = $this->collectionBuilder()->taskWriteToFile($this->filename) + ->line($this->prepend) + ->text($this->text) + ->line($this->append) + ->run(); + + $this->printTaskSuccess('{filename} created. {class-count} classes documented', ['filename' => $this->filename, 'class-count' => count($this->docClass)]); + + return new Result($this, $result->getExitCode(), $result->getMessage(), $this->textForClass); + } + + /** + * @param string $class + * + * @return null|string + */ + protected function documentClass($class) + { + if (!class_exists($class)) { + return ""; + } + $refl = new \ReflectionClass($class); + + if (is_callable($this->filterClasses)) { + $ret = call_user_func($this->filterClasses, $refl); + if (!$ret) { + return; + } + } + $doc = $this->documentClassSignature($refl); + $doc .= "\n" . $this->documentClassDocBlock($refl); + $doc .= "\n"; + + if (is_callable($this->processClass)) { + $doc = call_user_func($this->processClass, $refl, $doc); + } + + $properties = []; + foreach ($refl->getProperties() as $reflProperty) { + $properties[] = $this->documentProperty($reflProperty); + } + + $properties = array_filter($properties); + $doc .= implode("\n", $properties); + + $methods = []; + foreach ($refl->getMethods() as $reflMethod) { + $methods[$reflMethod->name] = $this->documentMethod($reflMethod); + } + if (is_callable($this->reorderMethods)) { + call_user_func_array($this->reorderMethods, [&$methods]); + } + + $methods = array_filter($methods); + + $doc .= implode("\n", $methods)."\n"; + + return $doc; + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return string + */ + protected function documentClassSignature(\ReflectionClass $reflectionClass) + { + if ($this->processClassSignature === false) { + return ""; + } + + $signature = "## {$reflectionClass->name}\n\n"; + + if ($parent = $reflectionClass->getParentClass()) { + $signature .= "* *Extends* `{$parent->name}`"; + } + $interfaces = $reflectionClass->getInterfaceNames(); + if (count($interfaces)) { + $signature .= "\n* *Implements* `" . implode('`, `', $interfaces) . '`'; + } + $traits = $reflectionClass->getTraitNames(); + if (count($traits)) { + $signature .= "\n* *Uses* `" . implode('`, `', $traits) . '`'; + } + if (is_callable($this->processClassSignature)) { + $signature = call_user_func($this->processClassSignature, $reflectionClass, $signature); + } + + return $signature; + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return string + */ + protected function documentClassDocBlock(\ReflectionClass $reflectionClass) + { + if ($this->processClassDocBlock === false) { + return ""; + } + $doc = self::indentDoc($reflectionClass->getDocComment()); + if (is_callable($this->processClassDocBlock)) { + $doc = call_user_func($this->processClassDocBlock, $reflectionClass, $doc); + } + return $doc; + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethod(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethod === false) { + return ""; + } + if (is_callable($this->filterMethods)) { + $ret = call_user_func($this->filterMethods, $reflectedMethod); + if (!$ret) { + return ""; + } + } else { + if (!$reflectedMethod->isPublic()) { + return ""; + } + } + + $signature = $this->documentMethodSignature($reflectedMethod); + $docblock = $this->documentMethodDocBlock($reflectedMethod); + $methodDoc = "$signature $docblock"; + if (is_callable($this->processMethod)) { + $methodDoc = call_user_func($this->processMethod, $reflectedMethod, $methodDoc); + } + return $methodDoc; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentProperty(\ReflectionProperty $reflectedProperty) + { + if ($this->processProperty === false) { + return ""; + } + if (is_callable($this->filterProperties)) { + $ret = call_user_func($this->filterProperties, $reflectedProperty); + if (!$ret) { + return ""; + } + } else { + if (!$reflectedProperty->isPublic()) { + return ""; + } + } + $signature = $this->documentPropertySignature($reflectedProperty); + $docblock = $this->documentPropertyDocBlock($reflectedProperty); + $propertyDoc = $signature . $docblock; + if (is_callable($this->processProperty)) { + $propertyDoc = call_user_func($this->processProperty, $reflectedProperty, $propertyDoc); + } + return $propertyDoc; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentPropertySignature(\ReflectionProperty $reflectedProperty) + { + if ($this->processPropertySignature === false) { + return ""; + } + $modifiers = implode(' ', \Reflection::getModifierNames($reflectedProperty->getModifiers())); + $signature = "#### *$modifiers* {$reflectedProperty->name}"; + if (is_callable($this->processPropertySignature)) { + $signature = call_user_func($this->processPropertySignature, $reflectedProperty, $signature); + } + return $signature; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentPropertyDocBlock(\ReflectionProperty $reflectedProperty) + { + if ($this->processPropertyDocBlock === false) { + return ""; + } + $propertyDoc = $reflectedProperty->getDocComment(); + // take from parent + if (!$propertyDoc) { + $parent = $reflectedProperty->getDeclaringClass(); + while ($parent = $parent->getParentClass()) { + if ($parent->hasProperty($reflectedProperty->name)) { + $propertyDoc = $parent->getProperty($reflectedProperty->name)->getDocComment(); + } + } + } + $propertyDoc = self::indentDoc($propertyDoc, 7); + $propertyDoc = preg_replace("~^@(.*?)([$\s])~", ' * `$1` $2', $propertyDoc); // format annotations + if (is_callable($this->processPropertyDocBlock)) { + $propertyDoc = call_user_func($this->processPropertyDocBlock, $reflectedProperty, $propertyDoc); + } + return ltrim($propertyDoc); + } + + /** + * @param \ReflectionParameter $param + * + * @return string + */ + protected function documentParam(\ReflectionParameter $param) + { + $text = ""; + if ($param->isArray()) { + $text .= 'array '; + } + if ($param->isCallable()) { + $text .= 'callable '; + } + $text .= '$' . $param->name; + if ($param->isDefaultValueAvailable()) { + if ($param->allowsNull()) { + $text .= ' = null'; + } else { + $text .= ' = ' . str_replace("\n", ' ', print_r($param->getDefaultValue(), true)); + } + } + + return $text; + } + + /** + * @param string $doc + * @param int $indent + * + * @return string + */ + public static function indentDoc($doc, $indent = 3) + { + if (!$doc) { + return $doc; + } + return implode( + "\n", + array_map( + function ($line) use ($indent) { + return substr($line, $indent); + }, + explode("\n", $doc) + ) + ); + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethodSignature(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethodSignature === false) { + return ""; + } + $modifiers = implode(' ', \Reflection::getModifierNames($reflectedMethod->getModifiers())); + $params = implode( + ', ', + array_map( + function ($p) { + return $this->documentParam($p); + }, + $reflectedMethod->getParameters() + ) + ); + $signature = "#### *$modifiers* {$reflectedMethod->name}($params)"; + if (is_callable($this->processMethodSignature)) { + $signature = call_user_func($this->processMethodSignature, $reflectedMethod, $signature); + } + return $signature; + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethodDocBlock(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethodDocBlock === false) { + return ""; + } + $methodDoc = $reflectedMethod->getDocComment(); + // take from parent + if (!$methodDoc) { + $parent = $reflectedMethod->getDeclaringClass(); + while ($parent = $parent->getParentClass()) { + if ($parent->hasMethod($reflectedMethod->name)) { + $methodDoc = $parent->getMethod($reflectedMethod->name)->getDocComment(); + } + } + } + // take from interface + if (!$methodDoc) { + $interfaces = $reflectedMethod->getDeclaringClass()->getInterfaces(); + foreach ($interfaces as $interface) { + $i = new \ReflectionClass($interface->name); + if ($i->hasMethod($reflectedMethod->name)) { + $methodDoc = $i->getMethod($reflectedMethod->name)->getDocComment(); + break; + } + } + } + + $methodDoc = self::indentDoc($methodDoc, 7); + $methodDoc = preg_replace("~^@(.*?) ([$\s])~m", ' * `$1` $2', $methodDoc); // format annotations + if (is_callable($this->processMethodDocBlock)) { + $methodDoc = call_user_func($this->processMethodDocBlock, $reflectedMethod, $methodDoc); + } + + return $methodDoc; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GenerateTask.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GenerateTask.php new file mode 100644 index 00000000..9d7a698e --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GenerateTask.php @@ -0,0 +1,107 @@ +taskGenerateTask('Symfony\Component\Filesystem\Filesystem', 'FilesystemStack') + * ->run(); + * ``` + */ +class GenerateTask extends BaseTask +{ + /** + * @var string + */ + protected $className; + + /** + * @var string + */ + protected $wrapperClassName; + + /** + * @param string $className + * @param string $wrapperClassName + */ + public function __construct($className, $wrapperClassName = '') + { + $this->className = $className; + $this->wrapperClassName = $wrapperClassName; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $delegate = new \ReflectionClass($this->className); + $replacements = []; + + $leadingCommentChars = " * "; + $methodDescriptions = []; + $methodImplementations = []; + $immediateMethods = []; + foreach ($delegate->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + $methodName = $method->name; + $getter = preg_match('/^(get|has|is)/', $methodName); + $setter = preg_match('/^(set|unset)/', $methodName); + $argPrototypeList = []; + $argNameList = []; + $needsImplementation = false; + foreach ($method->getParameters() as $arg) { + $argDescription = '$' . $arg->name; + $argNameList[] = $argDescription; + if ($arg->isOptional()) { + $argDescription = $argDescription . ' = ' . str_replace("\n", "", var_export($arg->getDefaultValue(), true)); + // We will create wrapper methods for any method that + // has default parameters. + $needsImplementation = true; + } + $argPrototypeList[] = $argDescription; + } + $argPrototypeString = implode(', ', $argPrototypeList); + $argNameListString = implode(', ', $argNameList); + + if ($methodName[0] != '_') { + $methodDescriptions[] = "@method $methodName($argPrototypeString)"; + + if ($getter) { + $immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n return \$this->delegate->$methodName($argNameListString);\n }"; + } elseif ($setter) { + $immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n return \$this;\n }"; + } elseif ($needsImplementation) { + // Include an implementation for the wrapper method if necessary + $methodImplementations[] = " protected function _$methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n }"; + } + } + } + + $classNameParts = explode('\\', $this->className); + $delegate = array_pop($classNameParts); + $delegateNamespace = implode('\\', $classNameParts); + + if (empty($this->wrapperClassName)) { + $this->wrapperClassName = $delegate; + } + + $replacements['{delegateNamespace}'] = $delegateNamespace; + $replacements['{delegate}'] = $delegate; + $replacements['{wrapperClassName}'] = $this->wrapperClassName; + $replacements['{taskname}'] = "task$delegate"; + $replacements['{methodList}'] = $leadingCommentChars . implode("\n$leadingCommentChars", $methodDescriptions); + $replacements['{immediateMethods}'] = "\n\n" . implode("\n\n", $immediateMethods); + $replacements['{methodImplementations}'] = "\n\n" . implode("\n\n", $methodImplementations); + + $template = file_get_contents(__DIR__ . '/../../../data/Task/Development/GeneratedWrapper.tmpl'); + $template = str_replace(array_keys($replacements), array_values($replacements), $template); + + // Returning data in the $message will cause it to be printed. + return Result::success($this, $template); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GitHub.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GitHub.php new file mode 100644 index 00000000..9fc9909d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GitHub.php @@ -0,0 +1,157 @@ +repo = $repo; + return $this; + } + + /** + * @param string $owner + * + * @return $this + */ + public function owner($owner) + { + $this->owner = $owner; + return $this; + } + + /** + * @param string $uri + * + * @return $this + */ + public function uri($uri) + { + list($this->owner, $this->repo) = explode('/', $uri); + return $this; + } + + /** + * @return string + */ + protected function getUri() + { + return $this->owner . '/' . $this->repo; + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + $this->user = $user; + return $this; + } + + /** + * @param $password + * + * @return $this + */ + public function password($password) + { + $this->password = $password; + return $this; + } + + /** + * @param $accessToken + * + * @return $this + */ + public function accessToken($token) + { + $this->accessToken = $token; + return $this; + } + + /** + * @param string $uri + * @param array $params + * @param string $method + * + * @return array + * + * @throws \Robo\Exception\TaskException + */ + protected function sendRequest($uri, $params = [], $method = 'POST') + { + if (!$this->owner or !$this->repo) { + throw new TaskException($this, 'Repo URI is not set'); + } + + $ch = curl_init(); + $url = sprintf('%s/repos/%s/%s', self::GITHUB_URL, $this->getUri(), $uri); + $this->printTaskInfo($url); + $this->printTaskInfo('{method} {url}', ['method' => $method, 'url' => $url]); + + if (!empty($this->user)) { + curl_setopt($ch, CURLOPT_USERPWD, $this->user . ':' . $this->password); + } + + if (!empty($this->accessToken)) { + $url .= "?access_token=" . $this->accessToken; + } + + curl_setopt_array( + $ch, + array( + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => $method != 'GET', + CURLOPT_POSTFIELDS => json_encode($params), + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_USERAGENT => "Robo" + ) + ); + + $output = curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $response = json_decode($output); + + $this->printTaskInfo($output); + return [$code, $response]; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GitHubRelease.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GitHubRelease.php new file mode 100644 index 00000000..bf7a4889 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/GitHubRelease.php @@ -0,0 +1,208 @@ +taskGitHubRelease('0.1.0') + * ->uri('consolidation-org/Robo') + * ->description('Add stuff people need.') + * ->change('Fix #123') + * ->change('Add frobulation method to all widgets') + * ->run(); + * ?> + * ``` + */ +class GitHubRelease extends GitHub +{ + /** + * @var string + */ + protected $tag; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $description = ''; + + /** + * @var string[] + */ + protected $changes = []; + + /** + * @var bool + */ + protected $draft = false; + + /** + * @var bool + */ + protected $prerelease = false; + + /** + * @var string + */ + protected $comittish = 'master'; + + /** + * @param string $tag + */ + public function __construct($tag) + { + $this->tag = $tag; + } + + /** + * @param string $tag + * + * @return $this + */ + public function tag($tag) + { + $this->tag = $tag; + return $this; + } + + /** + * @param bool $draft + * + * @return $this + */ + public function draft($draft) + { + $this->draft = $draft; + return $this; + } + + /** + * @param string $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this; + } + + /** + * @param string $description + * + * @return $this + */ + public function description($description) + { + $this->description = $description; + return $this; + } + + /** + * @param bool $prerelease + * + * @return $this + */ + public function prerelease($prerelease) + { + $this->prerelease = $prerelease; + return $this; + } + + /** + * @param string $comittish + * + * @return $this + */ + public function comittish($comittish) + { + $this->comittish = $comittish; + return $this; + } + + /** + * @param string $description + * + * @return $this + */ + public function appendDescription($description) + { + if (!empty($this->description)) { + $this->description .= "\n\n"; + } + $this->description .= $description; + return $this; + } + + public function changes(array $changes) + { + $this->changes = array_merge($this->changes, $changes); + return $this; + } + + /** + * @param string $change + * + * @return $this + */ + public function change($change) + { + $this->changes[] = $change; + return $this; + } + + /** + * @return string + */ + protected function getBody() + { + $body = $this->description; + if (!empty($this->changes)) { + $changes = array_map( + function ($line) { + return "* $line"; + }, + $this->changes + ); + $changesText = implode("\n", $changes); + $body .= "### Changelog \n\n$changesText"; + } + return $body; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Releasing {tag}', ['tag' => $this->tag]); + $this->startTimer(); + list($code, $data) = $this->sendRequest( + 'releases', + [ + "tag_name" => $this->tag, + "target_commitish" => $this->comittish, + "name" => $this->name, + "body" => $this->getBody(), + "draft" => $this->draft, + "prerelease" => $this->prerelease + ] + ); + $this->stopTimer(); + + return new Result( + $this, + in_array($code, [200, 201]) ? 0 : 1, + isset($data->message) ? $data->message : '', + ['response' => $data, 'time' => $this->getExecutionTime()] + ); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/OpenBrowser.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/OpenBrowser.php new file mode 100644 index 00000000..ea01b326 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/OpenBrowser.php @@ -0,0 +1,80 @@ +taskOpenBrowser('http://localhost') + * ->run(); + * + * // open two browser windows + * $this->taskOpenBrowser([ + * 'http://localhost/mysite', + * 'http://localhost/mysite2' + * ]) + * ->run(); + * ``` + */ +class OpenBrowser extends BaseTask +{ + /** + * @var string[] + */ + protected $urls = []; + + /** + * @param string|array $url + */ + public function __construct($url) + { + $this->urls = (array) $url; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $openCommand = $this->getOpenCommand(); + + if (empty($openCommand)) { + return Result::error($this, 'no suitable browser opening command found'); + } + + foreach ($this->urls as $url) { + passthru(sprintf($openCommand, ProcessUtils::escapeArgument($url))); + $this->printTaskInfo('Opened {url}', ['url' => $url]); + } + + return Result::success($this); + } + + /** + * @return null|string + */ + private function getOpenCommand() + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + return 'start "web" explorer "%s"'; + } + + passthru('which xdg-open', $linux); + passthru('which open', $osx); + + if (0 === $linux) { + return 'xdg-open %s'; + } + + if (0 === $osx) { + return 'open %s'; + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/PackPhar.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/PackPhar.php new file mode 100644 index 00000000..6d0a04d7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/PackPhar.php @@ -0,0 +1,252 @@ +taskPackPhar('package/codecept.phar') + * ->compress() + * ->stub('package/stub.php'); + * + * $finder = Finder::create() + * ->name('*.php') + * ->in('src'); + * + * foreach ($finder as $file) { + * $pharTask->addFile('src/'.$file->getRelativePathname(), $file->getRealPath()); + * } + * + * $finder = Finder::create()->files() + * ->name('*.php') + * ->in('vendor'); + * + * foreach ($finder as $file) { + * $pharTask->addStripped('vendor/'.$file->getRelativePathname(), $file->getRealPath()); + * } + * $pharTask->run(); + * + * // verify Phar is packed correctly + * $code = $this->_exec('php package/codecept.phar'); + * ?> + * ``` + */ +class PackPhar extends BaseTask implements PrintedInterface, ProgressIndicatorAwareInterface +{ + /** + * @var \Phar + */ + protected $phar; + + /** + * @var null|string + */ + protected $compileDir = null; + + /** + * @var string + */ + protected $filename; + + /** + * @var bool + */ + protected $compress = false; + + protected $stub; + + protected $bin; + + /** + * @var string + */ + protected $stubTemplate = <<filename = $filename; + if (file_exists($file->getRealPath())) { + @unlink($file->getRealPath()); + } + $this->phar = new \Phar($file->getPathname(), 0, $file->getFilename()); + } + + /** + * @param bool $compress + * + * @return $this + */ + public function compress($compress = true) + { + $this->compress = $compress; + return $this; + } + + /** + * @param string $stub + * + * @return $this + */ + public function stub($stub) + { + $this->phar->setStub(file_get_contents($stub)); + return $this; + } + + /** + * {@inheritdoc} + */ + public function progressIndicatorSteps() + { + // run() will call advanceProgressIndicator() once for each + // file, one after calling stopBuffering, and again after compression. + return count($this->files)+2; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]); + $this->phar->setSignatureAlgorithm(\Phar::SHA1); + $this->phar->startBuffering(); + + $this->printTaskInfo('Packing {file-count} files into phar', ['file-count' => count($this->files)]); + + $this->startProgressIndicator(); + foreach ($this->files as $path => $content) { + $this->phar->addFromString($path, $content); + $this->advanceProgressIndicator(); + } + $this->phar->stopBuffering(); + $this->advanceProgressIndicator(); + + if ($this->compress and in_array('GZ', \Phar::getSupportedCompression())) { + if (count($this->files) > 1000) { + $this->printTaskInfo('Too many files. Compression DISABLED'); + } else { + $this->printTaskInfo('{filename} compressed', ['filename' => $this->filename]); + $this->phar = $this->phar->compressFiles(\Phar::GZ); + } + } + $this->advanceProgressIndicator(); + $this->stopProgressIndicator(); + $this->printTaskSuccess('{filename} produced', ['filename' => $this->filename]); + return Result::success($this, '', ['time' => $this->getExecutionTime()]); + } + + /** + * @param string $path + * @param string $file + * + * @return $this + */ + public function addStripped($path, $file) + { + $this->files[$path] = $this->stripWhitespace(file_get_contents($file)); + return $this; + } + + /** + * @param string $path + * @param string $file + * + * @return $this + */ + public function addFile($path, $file) + { + $this->files[$path] = file_get_contents($file); + return $this; + } + + /** + * @param \Symfony\Component\Finder\SplFileInfo[] $files + */ + public function addFiles($files) + { + foreach ($files as $file) { + $this->addFile($file->getRelativePathname(), $file->getRealPath()); + } + } + + /** + * @param string $file + * + * @return $this + */ + public function executable($file) + { + $source = file_get_contents($file); + if (strpos($source, '#!/usr/bin/env php') === 0) { + $source = substr($source, strpos($source, 'phar->setStub(sprintf($this->stubTemplate, $source)); + return $this; + } + + /** + * Strips whitespace from source. Taken from composer + * + * @param string $source + * + * @return string + */ + private function stripWhitespace($source) + { + if (!function_exists('token_get_all')) { + return $source; + } + + $output = ''; + foreach (token_get_all($source) as $token) { + if (is_string($token)) { + $output .= $token; + } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { + // $output .= $token[1]; + $output .= str_repeat("\n", substr_count($token[1], "\n")); + } elseif (T_WHITESPACE === $token[0]) { + // reduce wide spaces + $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]); + // normalize newlines to \n + $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace); + // trim leading spaces + $whitespace = preg_replace('{\n +}', "\n", $whitespace); + $output .= $whitespace; + } else { + $output .= $token[1]; + } + } + + return $output; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/PhpServer.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/PhpServer.php new file mode 100644 index 00000000..6dd36680 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/PhpServer.php @@ -0,0 +1,86 @@ +taskServer(8000) + * ->dir('public') + * ->run(); + * + * // run with IP 0.0.0.0 + * $this->taskServer(8000) + * ->host('0.0.0.0') + * ->run(); + * + * // execute server in background + * $this->taskServer(8000) + * ->background() + * ->run(); + * ?> + * ``` + */ +class PhpServer extends Exec +{ + /** + * @var int + */ + protected $port; + + /** + * @var string + */ + protected $host = '127.0.0.1'; + + /** + * {@inheritdoc} + */ + protected $command = 'php -S %s:%d '; + + /** + * @param int $port + */ + public function __construct($port) + { + $this->port = $port; + + if (strtolower(PHP_OS) === 'linux') { + $this->command = 'exec php -S %s:%d '; + } + } + + /** + * @param string $host + * + * @return $this + */ + public function host($host) + { + $this->host = $host; + return $this; + } + + /** + * @param string $path + * + * @return $this + */ + public function dir($path) + { + $this->command .= "-t $path"; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return sprintf($this->command . $this->arguments, $this->host, $this->port); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/SemVer.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/SemVer.php new file mode 100644 index 00000000..6c807d89 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/SemVer.php @@ -0,0 +1,255 @@ +taskSemVer('.semver') + * ->increment() + * ->run(); + * ?> + * ``` + * + */ +class SemVer implements TaskInterface +{ + const SEMVER = "---\n:major: %d\n:minor: %d\n:patch: %d\n:special: '%s'\n:metadata: '%s'"; + + const REGEX = "/^\-\-\-\n:major:\s(0|[1-9]\d*)\n:minor:\s(0|[1-9]\d*)\n:patch:\s(0|[1-9]\d*)\n:special:\s'([a-zA-z0-9]*\.?(?:0|[1-9]\d*)?)'\n:metadata:\s'((?:0|[1-9]\d*)?(?:\.[a-zA-z0-9\.]*)?)'/"; + + const REGEX_STRING = '/^(?[0-9]+)\.(?[0-9]+)\.(?[0-9]+)(|-(?[0-9a-zA-Z.]+))(|\+(?[0-9a-zA-Z.]+))$/'; + + /** + * @var string + */ + protected $format = 'v%M.%m.%p%s'; + + /** + * @var string + */ + protected $specialSeparator = '-'; + + /** + * @var string + */ + protected $metadataSeparator = '+'; + + /** + * @var string + */ + protected $path; + + /** + * @var array + */ + protected $version = [ + 'major' => 0, + 'minor' => 0, + 'patch' => 0, + 'special' => '', + 'metadata' => '' + ]; + + /** + * @param string $filename + */ + public function __construct($filename = '') + { + $this->path = $filename; + + if (file_exists($this->path)) { + $semverFileContents = file_get_contents($this->path); + $this->parseFile($semverFileContents); + } + } + + /** + * @return string + */ + public function __toString() + { + $search = ['%M', '%m', '%p', '%s']; + $replace = $this->version + ['extra' => '']; + + foreach (['special', 'metadata'] as $key) { + if (!empty($replace[$key])) { + $separator = $key . 'Separator'; + $replace['extra'] .= $this->{$separator} . $replace[$key]; + } + unset($replace[$key]); + } + + return str_replace($search, $replace, $this->format); + } + + public function version($version) + { + $this->parseString($version); + return $this; + } + + /** + * @param string $format + * + * @return $this + */ + public function setFormat($format) + { + $this->format = $format; + return $this; + } + + /** + * @param string $separator + * + * @return $this + */ + public function setMetadataSeparator($separator) + { + $this->metadataSeparator = $separator; + return $this; + } + + /** + * @param string $separator + * + * @return $this + */ + public function setPrereleaseSeparator($separator) + { + $this->specialSeparator = $separator; + return $this; + } + + /** + * @param string $what + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function increment($what = 'patch') + { + switch ($what) { + case 'major': + $this->version['major']++; + $this->version['minor'] = 0; + $this->version['patch'] = 0; + break; + case 'minor': + $this->version['minor']++; + $this->version['patch'] = 0; + break; + case 'patch': + $this->version['patch']++; + break; + default: + throw new TaskException( + $this, + 'Bad argument, only one of the following is allowed: major, minor, patch' + ); + } + return $this; + } + + /** + * @param string $tag + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function prerelease($tag = 'RC') + { + if (!is_string($tag)) { + throw new TaskException($this, 'Bad argument, only strings allowed.'); + } + + $number = 0; + + if (!empty($this->version['special'])) { + list($current, $number) = explode('.', $this->version['special']); + if ($tag != $current) { + $number = 0; + } + } + + $number++; + + $this->version['special'] = implode('.', [$tag, $number]); + return $this; + } + + /** + * @param array|string $data + * + * @return $this + */ + public function metadata($data) + { + if (is_array($data)) { + $data = implode('.', $data); + } + + $this->version['metadata'] = $data; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $written = $this->dump(); + return new Result($this, (int)($written === false), $this->__toString()); + } + + /** + * @return bool + * + * @throws \Robo\Exception\TaskException + */ + protected function dump() + { + if (empty($this->path)) { + return true; + } + extract($this->version); + $semver = sprintf(self::SEMVER, $major, $minor, $patch, $special, $metadata); + if (is_writeable($this->path) === false || file_put_contents($this->path, $semver) === false) { + throw new TaskException($this, 'Failed to write semver file.'); + } + return true; + } + + protected function parseString($semverString) + { + if (!preg_match_all(self::REGEX_STRING, $semverString, $matches)) { + throw new TaskException($this, 'Bad semver value: ' . $semverString); + } + + $this->version = array_intersect_key($matches, $this->version); + $this->version = array_map(function ($item) { + return $item[0]; + }, $this->version); + } + + /** + * @throws \Robo\Exception\TaskException + */ + protected function parseFile($semverFileContents) + { + if (!preg_match_all(self::REGEX, $semverFileContents, $matches)) { + throw new TaskException($this, 'Bad semver file.'); + } + + list(, $major, $minor, $patch, $special, $metadata) = array_map('current', $matches); + $this->version = compact('major', 'minor', 'patch', 'special', 'metadata'); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/loadTasks.php new file mode 100644 index 00000000..e3dc49a3 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Development/loadTasks.php @@ -0,0 +1,86 @@ +task(Changelog::class, $filename); + } + + /** + * @param string $filename + * + * @return GenerateMarkdownDoc + */ + protected function taskGenDoc($filename) + { + return $this->task(GenerateMarkdownDoc::class, $filename); + } + + /** + * @param string $className + * @param string $wrapperClassName + * + * @return \Robo\Task\Development\GenerateTask + */ + protected function taskGenTask($className, $wrapperClassName = '') + { + return $this->task(GenerateTask::class, $className, $wrapperClassName); + } + + /** + * @param string $pathToSemVer + * + * @return SemVer + */ + protected function taskSemVer($pathToSemVer = '.semver') + { + return $this->task(SemVer::class, $pathToSemVer); + } + + /** + * @param int $port + * + * @return PhpServer + */ + protected function taskServer($port = 8000) + { + return $this->task(PhpServer::class, $port); + } + + /** + * @param string $filename + * + * @return PackPhar + */ + protected function taskPackPhar($filename) + { + return $this->task(PackPhar::class, $filename); + } + + /** + * @param string $tag + * + * @return GitHubRelease + */ + protected function taskGitHubRelease($tag) + { + return $this->task(GitHubRelease::class, $tag); + } + + /** + * @param string|array $url + * + * @return OpenBrowser + */ + protected function taskOpenBrowser($url) + { + return $this->task(OpenBrowser::class, $url); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Base.php new file mode 100644 index 00000000..135f39e7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Base.php @@ -0,0 +1,28 @@ +getCommand(); + return $this->executeCommand($command); + } + + abstract public function getCommand(); +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Build.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Build.php new file mode 100644 index 00000000..11eb92ab --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Build.php @@ -0,0 +1,55 @@ +taskDockerBuild()->run(); + * + * $this->taskDockerBuild('path/to/dir') + * ->tag('database') + * ->run(); + * + * ?> + * + * ``` + * + * Class Build + * @package Robo\Task\Docker + */ +class Build extends Base +{ + /** + * @var string + */ + protected $path; + + /** + * @param string $path + */ + public function __construct($path = '.') + { + $this->command = "docker build"; + $this->path = $path; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->path; + } + + /** + * @param string $tag + * + * @return $this + */ + public function tag($tag) + { + return $this->option('-t', $tag); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Commit.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Commit.php new file mode 100644 index 00000000..302f1920 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Commit.php @@ -0,0 +1,66 @@ +taskDockerCommit($containerId) + * ->name('my/database') + * ->run(); + * + * // alternatively you can take the result from DockerRun task: + * + * $result = $this->taskDockerRun('db') + * ->exec('./prepare_database.sh') + * ->run(); + * + * $task->dockerCommit($result) + * ->name('my/database') + * ->run(); + * ``` + */ +class Commit extends Base +{ + /** + * @var string + */ + protected $command = "docker commit"; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->cid . ' ' . $this->name . ' ' . $this->arguments; + } + + /** + * @param $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Exec.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Exec.php new file mode 100644 index 00000000..fa67c8da --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Exec.php @@ -0,0 +1,95 @@ +taskDockerRun('test_env') + * ->detached() + * ->run(); + * + * $this->taskDockerExec($test) + * ->interactive() + * ->exec('./runtests') + * ->run(); + * + * // alternatively use commands from other tasks + * + * $this->taskDockerExec($test) + * ->interactive() + * ->exec($this->taskCodecept()->suite('acceptance')) + * ->run(); + * ?> + * ``` + * + */ +class Exec extends Base +{ + use CommandReceiver; + + /** + * @var string + */ + protected $command = "docker exec"; + + /** + * @var string + */ + protected $cid; + + /** + * @var string + */ + protected $run = ''; + + /** + * @param string|\Robo\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * @return $this + */ + public function detached() + { + $this->option('-d'); + return $this; + } + + /** + * {@inheritdoc)} + */ + public function interactive($interactive = true) + { + if ($interactive) { + $this->option('-i'); + } + return parent::interactive($interactive); + } + + /** + * @param string|\Robo\Contract\CommandInterface $command + * + * @return $this + */ + public function exec($command) + { + $this->run = $this->receiveCommand($command); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid.' '.$this->run; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Pull.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Pull.php new file mode 100644 index 00000000..32ba5b40 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Pull.php @@ -0,0 +1,33 @@ +taskDockerPull('wordpress') + * ->run(); + * + * ?> + * ``` + * + */ +class Pull extends Base +{ + /** + * @param string $image + */ + public function __construct($image) + { + $this->command = "docker pull $image "; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Remove.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Remove.php new file mode 100644 index 00000000..0a8c0ac6 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Remove.php @@ -0,0 +1,32 @@ +taskDockerRemove($container) + * ->run(); + * ?> + * ``` + * + */ +class Remove extends Base +{ + /** + * @param string $container + */ + public function __construct($container) + { + $this->command = "docker rm $container "; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Result.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Result.php new file mode 100644 index 00000000..0533159a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Result.php @@ -0,0 +1,35 @@ +taskDockerRun('mysql')->run(); + * + * $result = $this->taskDockerRun('my_db_image') + * ->env('DB', 'database_name') + * ->volume('/path/to/data', '/data') + * ->detached() + * ->publish(3306) + * ->name('my_mysql') + * ->run(); + * + * // retrieve container's cid: + * $this->say("Running container ".$result->getCid()); + * + * // execute script inside container + * $result = $this->taskDockerRun('db') + * ->exec('prepare_test_data.sh') + * ->run(); + * + * $this->taskDockerCommit($result) + * ->name('test_db') + * ->run(); + * + * // link containers + * $mysql = $this->taskDockerRun('mysql') + * ->name('wp_db') // important to set name for linked container + * ->env('MYSQL_ROOT_PASSWORD', '123456') + * ->run(); + * + * $this->taskDockerRun('wordpress') + * ->link($mysql) + * ->publish(80, 8080) + * ->detached() + * ->run(); + * + * ?> + * ``` + * + */ +class Run extends Base +{ + use CommandReceiver; + + /** + * @var string + */ + protected $image = ''; + + /** + * @var string + */ + protected $run = ''; + + /** + * @var string + */ + protected $cidFile; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $dir; + + /** + * @param string $image + */ + public function __construct($image) + { + $this->image = $image; + } + + /** + * {@inheritdoc} + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + if ($this->isPrinted) { + $this->option('-i'); + } + if ($this->cidFile) { + $this->option('cidfile', $this->cidFile); + } + return trim('docker run ' . $this->arguments . ' ' . $this->image . ' ' . $this->run); + } + + /** + * @return $this + */ + public function detached() + { + $this->option('-d'); + return $this; + } + + /** + * {@inheritdoc)} + */ + public function interactive($interactive = true) + { + if ($interactive) { + $this->option('-i'); + } + return parent::interactive($interactive); + } + + /** + * @param string|\Robo\Contract\CommandInterface $run + * + * @return $this + */ + public function exec($run) + { + $this->run = $this->receiveCommand($run); + return $this; + } + + /** + * @param string $from + * @param null|string $to + * + * @return $this + */ + public function volume($from, $to = null) + { + $volume = $to ? "$from:$to" : $from; + $this->option('-v', $volume); + return $this; + } + + /** + * Set environment variables. + * n.b. $this->env($variable, $value) also available here, + * inherited from ExecTrait. + * + * @param array $env + * @return type + */ + public function envVars(array $env) + { + foreach ($env as $variable => $value) { + $this->setDockerEnv($variable, $value); + } + return $this; + } + + /** + * @param string $variable + * @param null|string $value + * + * @return $this + */ + protected function setDockerEnv($variable, $value = null) + { + $env = $value ? "$variable=$value" : $variable; + return $this->option("-e", $env); + } + + /** + * @param null|int $port + * @param null|int $portTo + * + * @return $this + */ + public function publish($port = null, $portTo = null) + { + if (!$port) { + return $this->option('-P'); + } + if ($portTo) { + $port = "$port:$portTo"; + } + return $this->option('-p', $port); + } + + /** + * @param string $dir + * + * @return $this + */ + public function containerWorkdir($dir) + { + return $this->option('-w', $dir); + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + return $this->option('-u', $user); + } + + /** + * @return $this + */ + public function privileged() + { + return $this->option('--privileged'); + } + + /** + * @param string $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this->option('name', $name); + } + + /** + * @param string|\Robo\Task\Docker\Result $name + * @param string $alias + * + * @return $this + */ + public function link($name, $alias) + { + if ($name instanceof Result) { + $name = $name->getContainerName(); + } + $this->option('link', "$name:$alias"); + return $this; + } + + /** + * @param string $dir + * + * @return $this + */ + public function tmpDir($dir) + { + $this->dir = $dir; + return $this; + } + + /** + * @return string + */ + public function getTmpDir() + { + return $this->dir ? $this->dir : sys_get_temp_dir(); + } + + /** + * @return string + */ + public function getUniqId() + { + return uniqid(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->cidFile = $this->getTmpDir() . '/docker_' . $this->getUniqId() . '.cid'; + $result = parent::run(); + $result['cid'] = $this->getCid(); + return $result; + } + + /** + * @return null|string + */ + protected function getCid() + { + if (!$this->cidFile || !file_exists($this->cidFile)) { + return null; + } + $cid = trim(file_get_contents($this->cidFile)); + @unlink($this->cidFile); + return $cid; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Start.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Start.php new file mode 100644 index 00000000..ef19d74d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Start.php @@ -0,0 +1,41 @@ +taskDockerStart($cidOrResult) + * ->run(); + * ?> + * ``` + */ +class Start extends Base +{ + /** + * @var string + */ + protected $command = "docker start"; + + /** + * @var null|string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Stop.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Stop.php new file mode 100644 index 00000000..4d0d436d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/Stop.php @@ -0,0 +1,41 @@ +taskDockerStop($cidOrResult) + * ->run(); + * ?> + * ``` + */ +class Stop extends Base +{ + /** + * @var string + */ + protected $command = "docker stop"; + + /** + * @var null|string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/loadTasks.php new file mode 100644 index 00000000..e58f5ef0 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Docker/loadTasks.php @@ -0,0 +1,85 @@ +task(Run::class, $image); + } + + /** + * @param string $image + * + * @return \Robo\Task\Docker\Pull + */ + protected function taskDockerPull($image) + { + return $this->task(Pull::class, $image); + } + + /** + * @param string $path + * + * @return \Robo\Task\Docker\Build + */ + protected function taskDockerBuild($path = '.') + { + return $this->task(Build::class, $path); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Stop + */ + protected function taskDockerStop($cidOrResult) + { + return $this->task(Stop::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Commit + */ + protected function taskDockerCommit($cidOrResult) + { + return $this->task(Commit::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Start + */ + protected function taskDockerStart($cidOrResult) + { + return $this->task(Start::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Remove + */ + protected function taskDockerRemove($cidOrResult) + { + return $this->task(Remove::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Exec + */ + protected function taskDockerExec($cidOrResult) + { + return $this->task(Exec::class, $cidOrResult); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Concat.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Concat.php new file mode 100644 index 00000000..12b1eca0 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Concat.php @@ -0,0 +1,101 @@ +taskConcat([ + * 'web/assets/screen.css', + * 'web/assets/print.css', + * 'web/assets/theme.css' + * ]) + * ->to('web/assets/style.css') + * ->run() + * ?> + * ``` + */ +class Concat extends BaseTask +{ + use ResourceExistenceChecker; + + /** + * @var array|Iterator + */ + protected $files; + + /** + * @var string + */ + protected $dst; + + /** + * Constructor. + * + * @param array|Iterator $files + */ + public function __construct($files) + { + $this->files = $files; + } + + /** + * set the destination file + * + * @param string $dst + * + * @return $this + */ + public function to($dst) + { + $this->dst = $dst; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (is_null($this->dst) || "" === $this->dst) { + return Result::error($this, 'You must specify a destination file with to() method.'); + } + + if (!$this->checkResources($this->files, 'file')) { + return Result::error($this, 'Source files are missing!'); + } + + if (file_exists($this->dst) && !is_writable($this->dst)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + + $dump = ''; + + foreach ($this->files as $path) { + foreach (glob($path) as $file) { + $dump .= file_get_contents($file) . "\n"; + } + } + + $this->printTaskInfo('Writing {destination}', ['destination' => $this->dst]); + + $dst = $this->dst . '.part'; + $write_result = file_put_contents($dst, $dump); + + if (false === $write_result) { + @unlink($dst); + return Result::error($this, 'File write failed.'); + } + // Cannot be cross-volume; should always succeed. + @rename($dst, $this->dst); + + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Replace.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Replace.php new file mode 100644 index 00000000..0107df13 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Replace.php @@ -0,0 +1,141 @@ +taskReplaceInFile('VERSION') + * ->from('0.2.0') + * ->to('0.3.0') + * ->run(); + * + * $this->taskReplaceInFile('README.md') + * ->from(date('Y')-1) + * ->to(date('Y')) + * ->run(); + * + * $this->taskReplaceInFile('config.yml') + * ->regex('~^service:~') + * ->to('services:') + * ->run(); + * + * $this->taskReplaceInFile('box/robo.txt') + * ->from(array('##dbname##', '##dbhost##')) + * ->to(array('robo', 'localhost')) + * ->run(); + * ?> + * ``` + */ +class Replace extends BaseTask +{ + /** + * @var string + */ + protected $filename; + + /** + * @var string|string[] + */ + protected $from; + + /** + * @var string|string[] + */ + protected $to; + + /** + * @var string + */ + protected $regex; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * String(s) to be replaced. + * + * @param string|string[] $from + * + * @return $this + */ + public function from($from) + { + $this->from = $from; + return $this; + } + + /** + * Value(s) to be set as a replacement. + * + * @param string|string[] $to + * + * @return $this + */ + public function to($to) + { + $this->to = $to; + return $this; + } + + /** + * Regex to match string to be replaced. + * + * @param string $regex + * + * @return $this + */ + public function regex($regex) + { + $this->regex = $regex; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!file_exists($this->filename)) { + $this->printTaskError('File {filename} does not exist', ['filename' => $this->filename]); + return false; + } + + $text = file_get_contents($this->filename); + if ($this->regex) { + $text = preg_replace($this->regex, $this->to, $text, -1, $count); + } else { + $text = str_replace($this->from, $this->to, $text, $count); + } + if ($count > 0) { + $res = file_put_contents($this->filename, $text); + if ($res === false) { + return Result::error($this, "Error writing to file {filename}.", ['filename' => $this->filename]); + } + $this->printTaskSuccess("{filename} updated. {count} items replaced", ['filename' => $this->filename, 'count' => $count]); + } else { + $this->printTaskInfo("{filename} unchanged. {count} items replaced", ['filename' => $this->filename, 'count' => $count]); + } + return Result::success($this, '', ['replaced' => $count]); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/TmpFile.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/TmpFile.php new file mode 100644 index 00000000..4a18691d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/TmpFile.php @@ -0,0 +1,72 @@ +collectionBuilder(); + * $tmpFilePath = $collection->taskTmpFile() + * ->line('-----') + * ->line(date('Y-m-d').' '.$title) + * ->line('----') + * ->getPath(); + * $collection->run(); + * ?> + * ``` + */ +class TmpFile extends Write implements CompletionInterface +{ + /** + * @param string $filename + * @param string $extension + * @param string $baseDir + * @param bool $includeRandomPart + */ + public function __construct($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true) + { + if (empty($baseDir)) { + $baseDir = sys_get_temp_dir(); + } + if ($includeRandomPart) { + $random = static::randomString(); + $filename = "{$filename}_{$random}"; + } + $filename .= $extension; + parent::__construct("{$baseDir}/{$filename}"); + } + + /** + * Generate a suitably random string to use as the suffix for our + * temporary file. + * + * @param int $length + * + * @return string + */ + private static function randomString($length = 12) + { + return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, $length); + } + + /** + * Delete this file when our collection completes. + * If this temporary file is not part of a collection, + * then it will be deleted when the program terminates, + * presuming that it was created by taskTmpFile() or _tmpFile(). + */ + public function complete() + { + unlink($this->getPath()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Write.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Write.php new file mode 100644 index 00000000..dc2199f9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/Write.php @@ -0,0 +1,335 @@ +taskWriteToFile('blogpost.md') + * ->line('-----') + * ->line(date('Y-m-d').' '.$title) + * ->line('----') + * ->run(); + * ?> + * ``` + */ +class Write extends BaseTask +{ + /** + * @var array + */ + protected $stack = []; + + /** + * @var string + */ + protected $filename; + + /** + * @var bool + */ + protected $append = false; + + /** + * @var null|string + */ + protected $originalContents = null; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * @param bool $append + * + * @return $this + */ + public function append($append = true) + { + $this->append = $append; + return $this; + } + + /** + * add a line. + * + * @param string $line + * + * @return $this The current instance + */ + public function line($line) + { + $this->text($line . "\n"); + return $this; + } + + /** + * add more lines. + * + * @param array $lines + * + * @return $this The current instance + */ + public function lines(array $lines) + { + $this->text(implode("\n", $lines) . "\n"); + return $this; + } + + /** + * add a text. + * + * @param string $text + * + * @return $this The current instance + */ + public function text($text) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * add a text from a file. + * + * Note that the file is read in the run() method of this task. + * To load text from the current state of a file (e.g. one that may + * be deleted or altered by other tasks prior the execution of this one), + * use: + * $task->text(file_get_contents($filename)); + * + * @param string $filename + * + * @return $this The current instance + */ + public function textFromFile($filename) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * substitute a placeholder with value, placeholder must be enclosed by `{}`. + * + * @param string $name + * @param string $val + * + * @return $this The current instance + */ + public function place($name, $val) + { + $this->replace('{'.$name.'}', $val); + + return $this; + } + + /** + * replace any string with value. + * + * @param string $string + * @param string $replacement + * + * @return $this The current instance + */ + public function replace($string, $replacement) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * replace any string with value using regular expression. + * + * @param string $pattern + * @param string $replacement + * + * @return $this The current instance + */ + public function regexReplace($pattern, $replacement) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * Append the provided text to the end of the buffer if the provided + * regex pattern matches any text already in the buffer. + * + * @param string $pattern + * @param string $text + * + * @return $this + */ + public function appendIfMatches($pattern, $text) + { + $this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, true]); + return $this; + } + + /** + * Append the provided text to the end of the buffer unless the provided + * regex pattern matches any text already in the buffer. + * + * @param string $pattern + * @param string $text + * + * @return $this + */ + public function appendUnlessMatches($pattern, $text) + { + $this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, false]); + return $this; + } + + /** + * @param $contents string + * @param $filename string + * + * @return string + */ + protected function textFromFileCollect($contents, $filename) + { + if (file_exists($filename)) { + $contents .= file_get_contents($filename); + } + return $contents; + } + + /** + * @param string|string[] $contents + * @param string|string[] $string + * @param string|string[] $replacement + * + * @return string|string[] + */ + protected function replaceCollect($contents, $string, $replacement) + { + return str_replace($string, $replacement, $contents); + } + + /** + * @param string|string[] $contents + * @param string|string[] $pattern + * @param string|string[] $replacement + * + * @return string|string[] + */ + protected function regexReplaceCollect($contents, $pattern, $replacement) + { + return preg_replace($pattern, $replacement, $contents); + } + + /** + * @param string $contents + * @param string $text + * + * @return string + */ + protected function textCollect($contents, $text) + { + return $contents . $text; + } + + /** + * @param string $contents + * @param string $pattern + * @param string $text + * @param bool $shouldMatch + * + * @return string + */ + protected function appendIfMatchesCollect($contents, $pattern, $text, $shouldMatch) + { + if (preg_match($pattern, $contents) == $shouldMatch) { + $contents .= $text; + } + return $contents; + } + + /** + * @return string + */ + public function originalContents() + { + if (!isset($this->originalContents)) { + $this->originalContents = ''; + if (file_exists($this->filename)) { + $this->originalContents = file_get_contents($this->filename); + } + } + return $this->originalContents; + } + + /** + * @return bool + */ + public function wouldChange() + { + return $this->originalContents() != $this->getContentsToWrite(); + } + + /** + * @return string + */ + protected function getContentsToWrite() + { + $contents = ""; + if ($this->append) { + $contents = $this->originalContents(); + } + foreach ($this->stack as $action) { + $command = array_shift($action); + if (method_exists($this, $command)) { + array_unshift($action, $contents); + $contents = call_user_func_array([$this, $command], $action); + } + } + return $contents; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo("Writing to {filename}.", ['filename' => $this->filename]); + $contents = $this->getContentsToWrite(); + if (!file_exists(dirname($this->filename))) { + mkdir(dirname($this->filename), 0777, true); + } + $res = file_put_contents($this->filename, $contents); + if ($res === false) { + return Result::error($this, "File {$this->filename} couldn't be created"); + } + + return Result::success($this); + } + + /** + * @return string + */ + public function getPath() + { + return $this->filename; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/loadTasks.php new file mode 100644 index 00000000..c5f39c95 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/File/loadTasks.php @@ -0,0 +1,48 @@ +task(Concat::class, $files); + } + + /** + * @param string $file + * + * @return \Robo\Task\File\Replace + */ + protected function taskReplaceInFile($file) + { + return $this->task(Replace::class, $file); + } + + /** + * @param string $file + * + * @return \Robo\Task\File\Write + */ + protected function taskWriteToFile($file) + { + return $this->task(Write::class, $file); + } + + /** + * @param string $filename + * @param string $extension + * @param string $baseDir + * @param bool $includeRandomPart + * + * @return \Robo\Task\File\TmpFile + */ + protected function taskTmpFile($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true) + { + return $this->task(TmpFile::class, $filename, $extension, $baseDir, $includeRandomPart); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/BaseDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/BaseDir.php new file mode 100644 index 00000000..434334d7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/BaseDir.php @@ -0,0 +1,30 @@ +dirs = $dirs + : $this->dirs[] = $dirs; + + $this->fs = new sfFilesystem(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/CleanDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/CleanDir.php new file mode 100644 index 00000000..762f8550 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/CleanDir.php @@ -0,0 +1,63 @@ +taskCleanDir(['tmp','logs'])->run(); + * // as shortcut + * $this->_cleanDir('app/cache'); + * ?> + * ``` + */ +class CleanDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $dir) { + $this->emptyDir($dir); + $this->printTaskInfo("Cleaned {dir}", ['dir' => $dir]); + } + return Result::success($this); + } + + /** + * @param string $path + */ + protected function emptyDir($path) + { + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ($iterator as $path) { + if ($path->isDir()) { + $dir = (string)$path; + if (basename($dir) === '.' || basename($dir) === '..') { + continue; + } + $this->fs->remove($dir); + } else { + $file = (string)$path; + if (basename($file) === '.gitignore' || basename($file) === '.gitkeep') { + continue; + } + $this->fs->remove($file); + } + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/CopyDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/CopyDir.php new file mode 100644 index 00000000..08482222 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/CopyDir.php @@ -0,0 +1,162 @@ +taskCopyDir(['dist/config' => 'config'])->run(); + * // as shortcut + * $this->_copyDir('dist/config', 'config'); + * ?> + * ``` + */ +class CopyDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * Explicitly declare our consturctor, so that + * our copyDir() method does not look like a php4 constructor. + */ + public function __construct($dirs) + { + parent::__construct($dirs); + } + + /** + * @var int + */ + protected $chmod = 0755; + + /** + * Files to exclude on copying. + * + * @var string[] + */ + protected $exclude = []; + + /** + * Overwrite destination files newer than source files. + */ + protected $overwrite = true; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $src => $dst) { + $this->copyDir($src, $dst); + $this->printTaskInfo('Copied from {source} to {destination}', ['source' => $src, 'destination' => $dst]); + } + return Result::success($this); + } + + /** + * Sets the default folder permissions for the destination if it doesn't exist + * + * @link http://en.wikipedia.org/wiki/Chmod + * @link http://php.net/manual/en/function.mkdir.php + * @link http://php.net/manual/en/function.chmod.php + * + * @param int $value + * + * @return $this + */ + public function dirPermissions($value) + { + $this->chmod = (int)$value; + return $this; + } + + /** + * List files to exclude. + * + * @param string[] $exclude + * + * @return $this + */ + public function exclude($exclude = []) + { + $this->exclude = $this->simplifyForCompare($exclude); + return $this; + } + + /** + * Destination files newer than source files are overwritten. + * + * @param bool $overwrite + * + * @return $this + */ + public function overwrite($overwrite) + { + $this->overwrite = $overwrite; + return $this; + } + + /** + * Copies a directory to another location. + * + * @param string $src Source directory + * @param string $dst Destination directory + * @param string $parent Parent directory + * + * @throws \Robo\Exception\TaskException + */ + protected function copyDir($src, $dst, $parent = '') + { + $dir = @opendir($src); + if (false === $dir) { + throw new TaskException($this, "Cannot open source directory '" . $src . "'"); + } + if (!is_dir($dst)) { + mkdir($dst, $this->chmod, true); + } + while (false !== ($file = readdir($dir))) { + // Support basename and full path exclusion. + if ($this->excluded($file, $src, $parent)) { + continue; + } + $srcFile = $src . '/' . $file; + $destFile = $dst . '/' . $file; + if (is_dir($srcFile)) { + $this->copyDir($srcFile, $destFile, $parent . $file . DIRECTORY_SEPARATOR); + } else { + $this->fs->copy($srcFile, $destFile, $this->overwrite); + } + } + closedir($dir); + } + + /** + * Check to see if the current item is excluded. + */ + protected function excluded($file, $src, $parent) + { + return + ($file == '.') || + ($file == '..') || + in_array($file, $this->exclude) || + in_array($this->simplifyForCompare($parent . $file), $this->exclude) || + in_array($this->simplifyForCompare($src . DIRECTORY_SEPARATOR . $file), $this->exclude); + } + + /** + * Avoid problems comparing paths on Windows that may have a + * combination of DIRECTORY_SEPARATOR and /. + */ + protected function simplifyForCompare($item) + { + return str_replace(DIRECTORY_SEPARATOR, '/', $item); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/DeleteDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/DeleteDir.php new file mode 100644 index 00000000..25cf007b --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/DeleteDir.php @@ -0,0 +1,36 @@ +taskDeleteDir('tmp')->run(); + * // as shortcut + * $this->_deleteDir(['tmp', 'log']); + * ?> + * ``` + */ +class DeleteDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $dir) { + $this->fs->remove($dir); + $this->printTaskInfo("Deleted {dir}...", ['dir' => $dir]); + } + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/FilesystemStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/FilesystemStack.php new file mode 100644 index 00000000..8663e245 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/FilesystemStack.php @@ -0,0 +1,154 @@ +taskFilesystemStack() + * ->mkdir('logs') + * ->touch('logs/.gitignore') + * ->chgrp('www', 'www-data') + * ->symlink('/var/log/nginx/error.log', 'logs/error.log') + * ->run(); + * + * // one line + * $this->_touch('.gitignore'); + * $this->_mkdir('logs'); + * + * ?> + * ``` + * + * @method $this mkdir(string|array|\Traversable $dir, int $mode = 0777) + * @method $this touch(string|array|\Traversable $file, int $time = null, int $atime = null) + * @method $this copy(string $from, string $to, bool $force = false) + * @method $this chmod(string|array|\Traversable $file, int $permissions, int $umask = 0000, bool $recursive = false) + * @method $this chgrp(string|array|\Traversable $file, string $group, bool $recursive = false) + * @method $this chown(string|array|\Traversable $file, string $user, bool $recursive = false) + * @method $this remove(string|array|\Traversable $file) + * @method $this rename(string $from, string $to, bool $force = false) + * @method $this symlink(string $from, string $to, bool $copyOnWindows = false) + * @method $this mirror(string $from, string $to, \Traversable $iterator = null, array $options = []) + */ +class FilesystemStack extends StackBasedTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var \Symfony\Component\Filesystem\Filesystem + */ + protected $fs; + + public function __construct() + { + $this->fs = new sfFilesystem(); + } + + /** + * @return \Symfony\Component\Filesystem\Filesystem + */ + protected function getDelegate() + { + return $this->fs; + } + + /** + * @param string $from + * @param string $to + * @param bool $force + */ + protected function _copy($from, $to, $force = false) + { + $this->fs->copy($from, $to, $force); + } + + /** + * @param string|string[]|\Traversable $file + * @param int $permissions + * @param int $umask + * @param bool $recursive + */ + protected function _chmod($file, $permissions, $umask = 0000, $recursive = false) + { + $this->fs->chmod($file, $permissions, $umask, $recursive); + } + + /** + * @param string|string[]|\Traversable $file + * @param string $group + * @param bool $recursive + */ + protected function _chgrp($file, $group, $recursive = null) + { + $this->fs->chgrp($file, $group, $recursive); + } + + /** + * @param string|string[]|\Traversable $file + * @param string $user + * @param bool $recursive + */ + protected function _chown($file, $user, $recursive = null) + { + $this->fs->chown($file, $user, $recursive); + } + + /** + * @param string $origin + * @param string $target + * @param bool $overwrite + * + * @return null|true|\Robo\Result + */ + protected function _rename($origin, $target, $overwrite = false) + { + // we check that target does not exist + if ((!$overwrite && is_readable($target)) || (file_exists($target) && !is_writable($target))) { + throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target); + } + + // Due to a bug (limitation) in PHP, cross-volume renames do not work. + // See: https://bugs.php.net/bug.php?id=54097 + if (true !== @rename($origin, $target)) { + return $this->crossVolumeRename($origin, $target); + } + return true; + } + + /** + * @param string $origin + * @param string $target + * + * @return null|\Robo\Result + */ + protected function crossVolumeRename($origin, $target) + { + // First step is to try to get rid of the target. If there + // is a single, deletable file, then we will just unlink it. + if (is_file($target)) { + unlink($target); + } + // If the target still exists, we will try to delete it. + // TODO: Note that if this fails partway through, then we cannot + // adequately rollback. Perhaps we need to preflight the operation + // and determine if everything inside of $target is writable. + if (file_exists($target)) { + $this->fs->remove($target); + } + + /** @var \Robo\Result $result */ + $result = $this->collectionBuilder()->taskCopyDir([$origin => $target])->run(); + if (!$result->wasSuccessful()) { + return $result; + } + $this->fs->remove($origin); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/FlattenDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/FlattenDir.php new file mode 100644 index 00000000..6e885112 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/FlattenDir.php @@ -0,0 +1,294 @@ +taskFlattenDir(['assets/*.min.js' => 'dist'])->run(); + * // or use shortcut + * $this->_flattenDir('assets/*.min.js', 'dist'); + * ?> + * ``` + * + * You can also define the target directory with an additional method, instead of + * key/value pairs. More similar to the gulp-flatten syntax: + * + * ``` php + * taskFlattenDir(['assets/*.min.js']) + * ->to('dist') + * ->run(); + * ?> + * ``` + * + * You can also append parts of the parent directories to the target path. If you give + * the value `1` to the `includeParents()` method, then the top parent will be appended + * to the target directory resulting in a path such as `dist/assets/asset-library1.min.js`. + * + * If you give a negative number, such as `-1` (the same as specifying `array(0, 1)` then + * the bottom parent will be appended, resulting in a path such as + * `dist/asset-library1/asset-library1.min.js`. + * + * The top parent directory will always be starting from the relative path to the current + * directory. You can override that with the `parentDir()` method. If in the above example + * you would specify `assets`, then the top parent directory would be `asset-library1`. + * + * ``` php + * taskFlattenDir(['assets/*.min.js' => 'dist']) + * ->parentDir('assets') + * ->includeParents(1) + * ->run(); + * ?> + * ``` + */ +class FlattenDir extends BaseDir +{ + /** + * @var int + */ + protected $chmod = 0755; + + /** + * @var int[] + */ + protected $parents = array(0, 0); + + /** + * @var string + */ + protected $parentDir = ''; + + /** + * @var string + */ + protected $to; + + /** + * {@inheritdoc} + */ + public function __construct($dirs) + { + parent::__construct($dirs); + $this->parentDir = getcwd(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // find the files + $files = $this->findFiles($this->dirs); + + // copy the files + $this->copyFiles($files); + + $fileNoun = count($files) == 1 ? ' file' : ' files'; + $this->printTaskSuccess("Copied {count} $fileNoun to {destination}", ['count' => count($files), 'destination' => $this->to]); + + return Result::success($this); + } + + /** + * Sets the default folder permissions for the destination if it does not exist. + * + * @link http://en.wikipedia.org/wiki/Chmod + * @link http://php.net/manual/en/function.mkdir.php + * @link http://php.net/manual/en/function.chmod.php + * + * @param int $permission + * + * @return $this + */ + public function dirPermissions($permission) + { + $this->chmod = (int) $permission; + + return $this; + } + + /** + * Sets the value from which direction and how much parent dirs should be included. + * Accepts a positive or negative integer or an array with two integer values. + * + * @param int|int[] $parents + * + * @return $this + * + * @throws TaskException + */ + public function includeParents($parents) + { + if (is_int($parents)) { + // if an integer is given check whether it is for top or bottom parent + if ($parents >= 0) { + $this->parents[0] = $parents; + return $this; + } + $this->parents[1] = 0 - $parents; + return $this; + } + + if (is_array($parents)) { + // check if the array has two values no more, no less + if (count($parents) == 2) { + $this->parents = $parents; + return $this; + } + } + + throw new TaskException($this, 'includeParents expects an integer or an array with two values'); + } + + /** + * Sets the parent directory from which the relative parent directories will be calculated. + * + * @param string $dir + * + * @return $this + */ + public function parentDir($dir) + { + if (!$this->fs->isAbsolutePath($dir)) { + // attach the relative path to current working directory + $dir = getcwd().'/'.$dir; + } + $this->parentDir = $dir; + + return $this; + } + + /** + * Sets the target directory where the files will be copied to. + * + * @param string $target + * + * @return $this + */ + public function to($target) + { + $this->to = rtrim($target, '/'); + + return $this; + } + + /** + * @param array $dirs + * + * @return array|\Robo\Result + * + * @throws \Robo\Exception\TaskException + */ + protected function findFiles($dirs) + { + $files = array(); + + // find the files + foreach ($dirs as $k => $v) { + // reset finder + $finder = new Finder(); + + $dir = $k; + $to = $v; + // check if target was given with the to() method instead of key/value pairs + if (is_int($k)) { + $dir = $v; + if (isset($this->to)) { + $to = $this->to; + } else { + throw new TaskException($this, 'target directory is not defined'); + } + } + + try { + $finder->files()->in($dir); + } catch (\InvalidArgumentException $e) { + // if finder cannot handle it, try with in()->name() + if (strpos($dir, '/') === false) { + $dir = './'.$dir; + } + $parts = explode('/', $dir); + $new_dir = implode('/', array_slice($parts, 0, -1)); + try { + $finder->files()->in($new_dir)->name(array_pop($parts)); + } catch (\InvalidArgumentException $e) { + return Result::fromException($this, $e); + } + } + + foreach ($finder as $file) { + // store the absolute path as key and target as value in the files array + $files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to); + } + $fileNoun = count($files) == 1 ? ' file' : ' files'; + $this->printTaskInfo("Found {count} $fileNoun in {dir}", ['count' => count($files), 'dir' => $dir]); + } + + return $files; + } + + /** + * @param string $file + * @param string $to + * + * @return string + */ + protected function getTarget($file, $to) + { + $target = $to.'/'.basename($file); + if ($this->parents !== array(0, 0)) { + // if the parent is set, create additional directories inside target + // get relative path to parentDir + $rel_path = $this->fs->makePathRelative(dirname($file), $this->parentDir); + // get top parents and bottom parents + $parts = explode('/', rtrim($rel_path, '/')); + $prefix_dir = ''; + $prefix_dir .= ($this->parents[0] > 0 ? implode('/', array_slice($parts, 0, $this->parents[0])).'/' : ''); + $prefix_dir .= ($this->parents[1] > 0 ? implode('/', array_slice($parts, (0 - $this->parents[1]), $this->parents[1])) : ''); + $prefix_dir = rtrim($prefix_dir, '/'); + $target = $to.'/'.$prefix_dir.'/'.basename($file); + } + + return $target; + } + + /** + * @param array $files + */ + protected function copyFiles($files) + { + // copy the files + foreach ($files as $from => $to) { + // check if target dir exists + if (!is_dir(dirname($to))) { + $this->fs->mkdir(dirname($to), $this->chmod); + } + $this->fs->copy($from, $to); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/MirrorDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/MirrorDir.php new file mode 100644 index 00000000..4eda9097 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/MirrorDir.php @@ -0,0 +1,40 @@ +taskMirrorDir(['dist/config/' => 'config/'])->run(); + * // or use shortcut + * $this->_mirrorDir('dist/config/', 'config/'); + * + * ?> + * ``` + */ +class MirrorDir extends BaseDir +{ + /** + * {@inheritdoc} + */ + public function run() + { + foreach ($this->dirs as $src => $dst) { + $this->fs->mirror( + $src, + $dst, + null, + [ + 'override' => true, + 'copy_on_windows' => true, + 'delete' => true + ] + ); + $this->printTaskInfo("Mirrored from {source} to {destination}", ['source' => $src, 'destination' => $dst]); + } + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/TmpDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/TmpDir.php new file mode 100644 index 00000000..104318de --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/TmpDir.php @@ -0,0 +1,173 @@ +run(). + * $collection = $this->collectionBuilder(); + * $tmpPath = $collection->tmpDir()->getPath(); + * $collection->taskFilesystemStack() + * ->mkdir("$tmpPath/log") + * ->touch("$tmpPath/log/error.txt"); + * $collection->run(); + * // as shortcut (deleted when program exits) + * $tmpPath = $this->_tmpDir(); + * ?> + * ``` + */ +class TmpDir extends BaseDir implements CompletionInterface +{ + /** + * @var string + */ + protected $base; + + /** + * @var string + */ + protected $prefix; + + /** + * @var bool + */ + protected $cwd; + + /** + * @var string + */ + protected $savedWorkingDirectory; + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + */ + public function __construct($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + if (empty($base)) { + $base = sys_get_temp_dir(); + } + $path = "{$base}/{$prefix}"; + if ($includeRandomPart) { + $path = static::randomLocation($path); + } + parent::__construct(["$path"]); + } + + /** + * Add a random part to a path, ensuring that the directory does + * not (currently) exist. + * + * @param string $path The base/prefix path to add a random component to + * @param int $length Number of digits in the random part + * + * @return string + */ + protected static function randomLocation($path, $length = 12) + { + $random = static::randomString($length); + while (is_dir("{$path}_{$random}")) { + $random = static::randomString($length); + } + return "{$path}_{$random}"; + } + + /** + * Generate a suitably random string to use as the suffix for our + * temporary directory. + * + * @param int $length + * + * @return string + */ + protected static function randomString($length = 12) + { + return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, max($length, 3)); + } + + /** + * Flag that we should cwd to the temporary directory when it is + * created, and restore the old working directory when it is deleted. + * + * @param bool $shouldChangeWorkingDirectory + * + * @return $this + */ + public function cwd($shouldChangeWorkingDirectory = true) + { + $this->cwd = $shouldChangeWorkingDirectory; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Save the current working directory + $this->savedWorkingDirectory = getcwd(); + foreach ($this->dirs as $dir) { + $this->fs->mkdir($dir); + $this->printTaskInfo("Created {dir}...", ['dir' => $dir]); + + // Change the current working directory, if requested + if ($this->cwd) { + chdir($dir); + } + } + + return Result::success($this, '', ['path' => $this->getPath()]); + } + + protected function restoreWorkingDirectory() + { + // Restore the current working directory, if we redirected it. + if ($this->cwd) { + chdir($this->savedWorkingDirectory); + } + } + + protected function deleteTmpDir() + { + foreach ($this->dirs as $dir) { + $this->fs->remove($dir); + } + } + + /** + * Delete this directory when our collection completes. + * If this temporary directory is not part of a collection, + * then it will be deleted when the program terminates, + * presuming that it was created by taskTmpDir() or _tmpDir(). + */ + public function complete() + { + $this->restoreWorkingDirectory(); + $this->deleteTmpDir(); + } + + /** + * Get a reference to the path to the temporary directory, so that + * it may be used to create other tasks. Note that the directory + * is not actually created until the task runs. + * + * @return string + */ + public function getPath() + { + return $this->dirs[0]; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/WorkDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/WorkDir.php new file mode 100644 index 00000000..4b75c6ed --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/WorkDir.php @@ -0,0 +1,126 @@ +collectionBuilder(); + * $workingPath = $collection->workDir("build")->getPath(); + * $collection->taskFilesystemStack() + * ->mkdir("$workingPath/log") + * ->touch("$workingPath/log/error.txt"); + * $collection->run(); + * ?> + * ``` + */ +class WorkDir extends TmpDir implements RollbackInterface, BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $finalDestination; + + /** + * @param string $finalDestination + */ + public function __construct($finalDestination) + { + $this->finalDestination = $finalDestination; + + // Create a temporary directory to work in. We will place our + // temporary directory in the same location as the final destination + // directory, so that the work directory can be moved into place + // without having to be copied, e.g. in a cross-volume rename scenario. + parent::__construct(basename($finalDestination), dirname($finalDestination)); + } + + /** + * Create our working directory. + * + * @return \Robo\Result + */ + public function run() + { + // Destination cannot be empty + if (empty($this->finalDestination)) { + return Result::error($this, "Destination directory not specified."); + } + + // Before we do anything else, ensure that any directory in the + // final destination is writable, so that we can at a minimum + // move it out of the way before placing our results there. + if (is_dir($this->finalDestination)) { + if (!is_writable($this->finalDestination)) { + return Result::error($this, "Destination directory {dir} exists and cannot be overwritten.", ['dir' => $this->finalDestination]); + } + } + + return parent::run(); + } + + /** + * Move our working directory into its final destination once the + * collection it belongs to completes. + */ + public function complete() + { + $this->restoreWorkingDirectory(); + + // Delete the final destination, if it exists. + // Move it out of the way first, in case it cannot + // be completely deleted. + if (file_exists($this->finalDestination)) { + $temporaryLocation = static::randomLocation($this->finalDestination . '_TO_DELETE_'); + // This should always work, because we already created a temporary + // folder in the parent directory of the final destination, and we + // have already checked to confirm that the final destination is + // writable. + rename($this->finalDestination, $temporaryLocation); + // This may silently fail, leaving artifacts behind, if there + // are permissions problems with some items somewhere inside + // the folder being deleted. + $this->fs->remove($temporaryLocation); + } + + // Move our working directory over the final destination. + // This should never be a cross-volume rename, so this should + // always succeed. + $workDir = reset($this->dirs); + if (file_exists($workDir)) { + rename($workDir, $this->finalDestination); + } + } + + /** + * Delete our working directory + */ + public function rollback() + { + $this->restoreWorkingDirectory(); + $this->deleteTmpDir(); + } + + /** + * Get a reference to the path to the temporary directory, so that + * it may be used to create other tasks. Note that the directory + * is not actually created until the task runs. + * + * @return string + */ + public function getPath() + { + return $this->dirs[0]; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/loadShortcuts.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/loadShortcuts.php new file mode 100644 index 00000000..fe72ce5a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/loadShortcuts.php @@ -0,0 +1,159 @@ +taskCopyDir([$src => $dst])->run(); + } + + /** + * @param string $src + * @param string $dst + * + * @return \Robo\Result + */ + protected function _mirrorDir($src, $dst) + { + return $this->taskMirrorDir([$src => $dst])->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _deleteDir($dir) + { + return $this->taskDeleteDir($dir)->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _cleanDir($dir) + { + return $this->taskCleanDir($dir)->run(); + } + + /** + * @param string $from + * @param string $to + * @param bool $overwrite + * + * @return \Robo\Result + */ + protected function _rename($from, $to, $overwrite = false) + { + return $this->taskFilesystemStack()->rename($from, $to, $overwrite)->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _mkdir($dir) + { + return $this->taskFilesystemStack()->mkdir($dir)->run(); + } + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return string + */ + protected function _tmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + $result = $this->taskTmpDir($prefix, $base, $includeRandomPart)->run(); + return isset($result['path']) ? $result['path'] : ''; + } + + /** + * @param string $file + * + * @return \Robo\Result + */ + protected function _touch($file) + { + return $this->taskFilesystemStack()->touch($file)->run(); + } + + /** + * @param string|string[] $file + * + * @return \Robo\Result + */ + protected function _remove($file) + { + return $this->taskFilesystemStack()->remove($file)->run(); + } + + /** + * @param string|string[] $file + * @param string $group + * + * @return \Robo\Result + */ + protected function _chgrp($file, $group) + { + return $this->taskFilesystemStack()->chgrp($file, $group)->run(); + } + + /** + * @param string|string[] $file + * @param int $permissions + * @param int $umask + * @param bool $recursive + * + * @return \Robo\Result + */ + protected function _chmod($file, $permissions, $umask = 0000, $recursive = false) + { + return $this->taskFilesystemStack()->chmod($file, $permissions, $umask, $recursive)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _symlink($from, $to) + { + return $this->taskFilesystemStack()->symlink($from, $to)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _copy($from, $to) + { + return $this->taskFilesystemStack()->copy($from, $to)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _flattenDir($from, $to) + { + return $this->taskFlattenDir([$from => $to])->run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/loadTasks.php new file mode 100644 index 00000000..8fecaaff --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Filesystem/loadTasks.php @@ -0,0 +1,85 @@ +task(CleanDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\DeleteDir + */ + protected function taskDeleteDir($dirs) + { + return $this->task(DeleteDir::class, $dirs); + } + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return \Robo\Task\Filesystem\WorkDir + */ + protected function taskTmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + return $this->task(TmpDir::class, $prefix, $base, $includeRandomPart); + } + + /** + * @param string $finalDestination + * + * @return \Robo\Task\Filesystem\TmpDir + */ + protected function taskWorkDir($finalDestination) + { + return $this->task(WorkDir::class, $finalDestination); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\CopyDir + */ + protected function taskCopyDir($dirs) + { + return $this->task(CopyDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\MirrorDir + */ + protected function taskMirrorDir($dirs) + { + return $this->task(MirrorDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\FlattenDir + */ + protected function taskFlattenDir($dirs) + { + return $this->task(FlattenDir::class, $dirs); + } + + /** + * @return \Robo\Task\Filesystem\FilesystemStack + */ + protected function taskFilesystemStack() + { + return $this->task(FilesystemStack::class); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/Base.php new file mode 100644 index 00000000..42728673 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/Base.php @@ -0,0 +1,97 @@ +option('silent'); + return $this; + } + + /** + * adds `--no-color` option to gulp + * + * @return $this + */ + public function noColor() + { + $this->option('no-color'); + return $this; + } + + /** + * adds `--color` option to gulp + * + * @return $this + */ + public function color() + { + $this->option('color'); + return $this; + } + + /** + * adds `--tasks-simple` option to gulp + * + * @return $this + */ + public function simple() + { + $this->option('tasks-simple'); + return $this; + } + + /** + * @param string $task + * @param null|string $pathToGulp + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($task, $pathToGulp = null) + { + $this->task = $task; + $this->command = $pathToGulp; + if (!$this->command) { + $this->command = $this->findExecutable('gulp'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Gulp executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} " . ProcessUtils::escapeArgument($this->task) . "{$this->arguments}"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/Run.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/Run.php new file mode 100644 index 00000000..8f2077b5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/Run.php @@ -0,0 +1,35 @@ +taskGulpRun()->run(); + * + * // run task 'clean' with --silent option + * $this->taskGulpRun('clean') + * ->silent() + * ->run(); + * ?> + * ``` + */ +class Run extends Base implements CommandInterface +{ + /** + * {@inheritdoc} + */ + public function run() + { + if (strlen($this->arguments)) { + $this->printTaskInfo('Running Gulp task: {gulp_task} with arguments: {arguments}', ['gulp_task' => $this->task, 'arguments' => $this->arguments]); + } else { + $this->printTaskInfo('Running Gulp task: {gulp_task} without arguments', ['gulp_task' => $this->task]); + } + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/loadTasks.php new file mode 100644 index 00000000..6fdc6ca7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Gulp/loadTasks.php @@ -0,0 +1,16 @@ +task(Run::class, $task, $pathToGulp); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Base.php new file mode 100644 index 00000000..35ff9c48 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Base.php @@ -0,0 +1,60 @@ +option('production'); + return $this; + } + + /** + * @param null|string $pathToNpm + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToNpm = null) + { + $this->command = $pathToNpm; + if (!$this->command) { + $this->command = $this->findExecutable('npm'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Npm executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Install.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Install.php new file mode 100644 index 00000000..65cbe618 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Install.php @@ -0,0 +1,36 @@ +taskNpmInstall()->run(); + * + * // prefer dist with custom path + * $this->taskNpmInstall('path/to/my/npm') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Install extends Base implements CommandInterface +{ + /** + * @var string + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Install Npm packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Update.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Update.php new file mode 100644 index 00000000..75421b30 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/Update.php @@ -0,0 +1,34 @@ +taskNpmUpdate()->run(); + * + * // prefer dist with custom path + * $this->taskNpmUpdate('path/to/my/npm') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * @var string + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Update Npm packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/loadTasks.php new file mode 100644 index 00000000..4d9a26eb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Npm/loadTasks.php @@ -0,0 +1,25 @@ +task(Install::class, $pathToNpm); + } + + /** + * @param null|string $pathToNpm + * + * @return \Robo\Task\Npm\Update + */ + protected function taskNpmUpdate($pathToNpm = null) + { + return $this->task(Update::class, $pathToNpm); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/Rsync.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/Rsync.php new file mode 100644 index 00000000..5c334af4 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/Rsync.php @@ -0,0 +1,484 @@ +taskRsync() + * ->fromPath('src/') + * ->toHost('localhost') + * ->toUser('dev') + * ->toPath('/var/www/html/app/') + * ->remoteShell('ssh -i public_key') + * ->recursive() + * ->excludeVcs() + * ->checksum() + * ->wholeFile() + * ->verbose() + * ->progress() + * ->humanReadable() + * ->stats() + * ->run(); + * ``` + * + * You could also clone the task and do a dry-run first: + * + * ``` php + * $rsync = $this->taskRsync() + * ->fromPath('src/') + * ->toPath('example.com:/var/www/html/app/') + * ->archive() + * ->excludeVcs() + * ->progress() + * ->stats(); + * + * $dryRun = clone $rsync; + * $dryRun->dryRun()->run(); + * if ('y' === $this->ask('Do you want to run (y/n)')) { + * $rsync->run(); + * } + * ``` + */ +class Rsync extends BaseTask implements CommandInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string + */ + protected $fromUser; + + /** + * @var string + */ + protected $fromHost; + + /** + * @var string + */ + protected $fromPath; + + /** + * @var string + */ + protected $toUser; + + /** + * @var string + */ + protected $toHost; + + /** + * @var string + */ + protected $toPath; + + /** + * @return static + */ + public static function init() + { + return new static(); + } + + public function __construct() + { + $this->command = 'rsync'; + } + + /** + * This can either be a full rsync path spec (user@host:path) or just a path. + * In case of the former do not specify host and user. + * + * @param string|array $path + * + * @return $this + */ + public function fromPath($path) + { + $this->fromPath = $path; + + return $this; + } + + /** + * This can either be a full rsync path spec (user@host:path) or just a path. + * In case of the former do not specify host and user. + * + * @param string $path + * + * @return $this + */ + public function toPath($path) + { + $this->toPath = $path; + + return $this; + } + + /** + * @param string $fromUser + * + * @return $this + */ + public function fromUser($fromUser) + { + $this->fromUser = $fromUser; + return $this; + } + + /** + * @param string $fromHost + * + * @return $this + */ + public function fromHost($fromHost) + { + $this->fromHost = $fromHost; + return $this; + } + + /** + * @param string $toUser + * + * @return $this + */ + public function toUser($toUser) + { + $this->toUser = $toUser; + return $this; + } + + /** + * @param string $toHost + * + * @return $this + */ + public function toHost($toHost) + { + $this->toHost = $toHost; + return $this; + } + + /** + * @return $this + */ + public function progress() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function stats() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function recursive() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function verbose() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function checksum() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function archive() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function compress() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function owner() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function group() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function times() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function delete() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @param int $seconds + * + * @return $this + */ + public function timeout($seconds) + { + $this->option(__FUNCTION__, $seconds); + + return $this; + } + + /** + * @return $this + */ + public function humanReadable() + { + $this->option('human-readable'); + + return $this; + } + + /** + * @return $this + */ + public function wholeFile() + { + $this->option('whole-file'); + + return $this; + } + + /** + * @return $this + */ + public function dryRun() + { + $this->option('dry-run'); + + return $this; + } + + /** + * @return $this + */ + public function itemizeChanges() + { + $this->option('itemize-changes'); + + return $this; + } + + /** + * Excludes .git, .svn and .hg items at any depth. + * + * @return $this + */ + public function excludeVcs() + { + return $this->exclude([ + '.git', + '.svn', + '.hg', + ]); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function exclude($pattern) + { + return $this->optionList(__FUNCTION__, $pattern); + } + + /** + * @param string $file + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function excludeFrom($file) + { + if (!is_readable($file)) { + throw new TaskException($this, "Exclude file $file is not readable"); + } + + return $this->option('exclude-from', $file); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function includeFilter($pattern) + { + return $this->optionList('include', $pattern); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function filter($pattern) + { + return $this->optionList(__FUNCTION__, $pattern); + } + + /** + * @param string $file + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function filesFrom($file) + { + if (!is_readable($file)) { + throw new TaskException($this, "Files-from file $file is not readable"); + } + + return $this->option('files-from', $file); + } + + /** + * @param string $command + * + * @return $this + */ + public function remoteShell($command) + { + $this->option('rsh', "'$command'"); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + + return $this->executeCommand($command); + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + foreach ((array)$this->fromPath as $from) { + $this->option(null, $this->getFromPathSpec($from)); + } + $this->option(null, $this->getToPathSpec()); + + return $this->command . $this->arguments; + } + + /** + * @return string + */ + protected function getFromPathSpec($from) + { + return $this->getPathSpec($this->fromHost, $this->fromUser, $from); + } + + /** + * @return string + */ + protected function getToPathSpec() + { + return $this->getPathSpec($this->toHost, $this->toUser, $this->toPath); + } + + /** + * @param string $host + * @param string $user + * @param string $path + * + * @return string + */ + protected function getPathSpec($host, $user, $path) + { + $spec = isset($path) ? $path : ''; + if (!empty($host)) { + $spec = "{$host}:{$spec}"; + } + if (!empty($user)) { + $spec = "{$user}@{$spec}"; + } + + return $spec; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/Ssh.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/Ssh.php new file mode 100644 index 00000000..69df9fe2 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/Ssh.php @@ -0,0 +1,273 @@ +taskSshExec('remote.example.com', 'user') + * ->remoteDir('/var/www/html') + * ->exec('ls -la') + * ->exec('chmod g+x logs') + * ->run(); + * + * ``` + * + * You can even exec other tasks (which implement CommandInterface): + * + * ```php + * $gitTask = $this->taskGitStack() + * ->checkout('master') + * ->pull(); + * + * $this->taskSshExec('remote.example.com') + * ->remoteDir('/var/www/html/site') + * ->exec($gitTask) + * ->run(); + * ``` + * + * You can configure the remote directory for all future calls: + * + * ```php + * \Robo\Task\Remote\Ssh::configure('remoteDir', '/some-dir'); + * ``` + */ +class Ssh extends BaseTask implements CommandInterface, SimulatedInterface +{ + use \Robo\Common\CommandReceiver; + use \Robo\Common\ExecOneCommand; + + /** + * @var null|string + */ + protected $hostname; + + /** + * @var null|string + */ + protected $user; + + /** + * @var bool + */ + protected $stopOnFail = true; + + /** + * @var array + */ + protected $exec = []; + + /** + * Changes to the given directory before running commands. + * + * @var string + */ + protected $remoteDir; + + /** + * @param null|string $hostname + * @param null|string $user + */ + public function __construct($hostname = null, $user = null) + { + $this->hostname = $hostname; + $this->user = $user; + } + + /** + * @param string $hostname + * + * @return $this + */ + public function hostname($hostname) + { + $this->hostname = $hostname; + return $this; + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + $this->user = $user; + return $this; + } + + /** + * Whether or not to chain commands together with && and stop the chain if one command fails. + * + * @param bool $stopOnFail + * + * @return $this + */ + public function stopOnFail($stopOnFail = true) + { + $this->stopOnFail = $stopOnFail; + return $this; + } + + /** + * Changes to the given directory before running commands. + * + * @param string $remoteDir + * + * @return $this + */ + public function remoteDir($remoteDir) + { + $this->remoteDir = $remoteDir; + return $this; + } + + /** + * @param string $filename + * + * @return $this + */ + public function identityFile($filename) + { + $this->option('-i', $filename); + + return $this; + } + + /** + * @param int $port + * + * @return $this + */ + public function port($port) + { + $this->option('-p', $port); + + return $this; + } + + /** + * @return $this + */ + public function forcePseudoTty() + { + $this->option('-t'); + + return $this; + } + + /** + * @return $this + */ + public function quiet() + { + $this->option('-q'); + + return $this; + } + + /** + * @return $this + */ + public function verbose() + { + $this->option('-v'); + + return $this; + } + + /** + * @param string|string[]|CommandInterface $command + * + * @return $this + */ + public function exec($command) + { + if (is_array($command)) { + $command = implode(' ', array_filter($command)); + } + + $this->exec[] = $command; + + return $this; + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + $commands = []; + foreach ($this->exec as $command) { + $commands[] = $this->receiveCommand($command); + } + + $remoteDir = $this->remoteDir ? $this->remoteDir : $this->getConfigValue('remoteDir'); + if (!empty($remoteDir)) { + array_unshift($commands, sprintf('cd "%s"', $remoteDir)); + } + $command = implode($this->stopOnFail ? ' && ' : ' ; ', $commands); + + return $this->sshCommand($command); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->validateParameters(); + $command = $this->getCommand(); + return $this->executeCommand($command); + } + + /** + * {@inheritdoc} + */ + public function simulate($context) + { + $command = $this->getCommand(); + $this->printTaskInfo("Running {command}", ['command' => $command] + $context); + } + + protected function validateParameters() + { + if (empty($this->hostname)) { + throw new TaskException($this, 'Please set a hostname'); + } + if (empty($this->exec)) { + throw new TaskException($this, 'Please add at least one command'); + } + } + + /** + * Returns an ssh command string running $command on the remote. + * + * @param string|CommandInterface $command + * + * @return string + */ + protected function sshCommand($command) + { + $command = $this->receiveCommand($command); + $sshOptions = $this->arguments; + $hostSpec = $this->hostname; + if ($this->user) { + $hostSpec = $this->user . '@' . $hostSpec; + } + + return "ssh{$sshOptions} {$hostSpec} '{$command}'"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/loadTasks.php new file mode 100644 index 00000000..092d2a55 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Remote/loadTasks.php @@ -0,0 +1,24 @@ +task(Rsync::class); + } + + /** + * @param null|string $hostname + * @param null|string $user + * + * @return \Robo\Task\Remote\Ssh + */ + protected function taskSshExec($hostname = null, $user = null) + { + return $this->task(Ssh::class, $hostname, $user); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Simulator.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Simulator.php new file mode 100644 index 00000000..e69d23fa --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Simulator.php @@ -0,0 +1,168 @@ +task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->constructorParameters = $constructorParameters; + } + + /** + * @param string $function + * @param array $args + * + * @return \Robo\Result|\Robo\Task\Simulator + */ + public function __call($function, $args) + { + $this->stack[] = array_merge([$function], $args); + $result = call_user_func_array([$this->task, $function], $args); + return $result == $this->task ? $this : $result; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $callchain = ''; + foreach ($this->stack as $action) { + $command = array_shift($action); + $parameters = $this->formatParameters($action); + $callchain .= "\n ->$command($parameters)"; + } + $context = $this->getTaskContext( + [ + '_level' => RoboLogLevel::SIMULATED_ACTION, + 'simulated' => TaskInfo::formatTaskName($this->task), + 'parameters' => $this->formatParameters($this->constructorParameters), + '_style' => ['simulated' => 'fg=blue;options=bold'], + ] + ); + + // RoboLogLevel::SIMULATED_ACTION + $this->printTaskInfo( + "Simulating {simulated}({parameters})$callchain", + $context + ); + + $result = null; + if ($this->task instanceof SimulatedInterface) { + $result = $this->task->simulate($context); + } + if (!isset($result)) { + $result = Result::success($this); + } + + return $result; + } + + /** + * Danger: reach through the simulated wrapper and pull out the command + * to be executed. This is used when using a simulated task with another + * simulated task that runs commands, e.g. the Remote\Ssh task. Using + * a simulated CommandInterface task with a non-simulated task may produce + * unexpected results (e.g. execution!). + * + * @return string + * + * @throws \Robo\Exception\TaskException + */ + public function getCommand() + { + if (!$this->task instanceof CommandInterface) { + throw new TaskException($this->task, 'Simulated task that is not a CommandInterface used as a CommandInterface.'); + } + return $this->task->getCommand(); + } + + /** + * @param string $action + * + * @return string + */ + protected function formatParameters($action) + { + $parameterList = array_map([$this, 'convertParameter'], $action); + return implode(', ', $parameterList); + } + + /** + * @param mixed $item + * + * @return string + */ + protected function convertParameter($item) + { + if (is_callable($item)) { + return 'inline_function(...)'; + } + if (is_array($item)) { + return $this->shortenParameter(var_export($item, true)); + } + if (is_object($item)) { + return '[' . get_class($item). ' object]'; + } + if (is_string($item)) { + return $this->shortenParameter("'$item'"); + } + if (is_null($item)) { + return 'null'; + } + return $item; + } + + /** + * @param string $item + * @param string $shortForm + * + * @return string + */ + protected function shortenParameter($item, $shortForm = '') + { + $maxLength = 80; + $tailLength = 20; + if (strlen($item) < $maxLength) { + return $item; + } + if (!empty($shortForm)) { + return $shortForm; + } + $item = trim($item); + $tail = preg_replace("#.*\n#ms", '', substr($item, -$tailLength)); + $head = preg_replace("#\n.*#ms", '', substr($item, 0, $maxLength - (strlen($tail) + 5))); + return "$head ... $tail"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/StackBasedTask.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/StackBasedTask.php new file mode 100644 index 00000000..91659f33 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/StackBasedTask.php @@ -0,0 +1,236 @@ +friz() + * ->fraz() + * ->frob(); + * + * We presume that the existing library throws an exception on error. + * + * You want: + * + * $result = $this->taskFrobinator($a, $b, $c) + * ->friz() + * ->fraz() + * ->frob() + * ->run(); + * + * Execution is deferred until run(), and a Robo\Result instance is + * returned. Additionally, using Robo will covert Exceptions + * into RoboResult objects. + * + * To create a new Robo task: + * + * - Make a new class that extends StackBasedTask + * - Give it a constructor that creates a new Frobinator + * - Override getDelegate(), and return the Frobinator instance + * + * Finally, add your new class to loadTasks.php as usual, + * and you are all done. + * + * If you need to add any methods to your task that should run + * immediately (e.g. to set parameters used at run() time), just + * implement them in your derived class. + * + * If you need additional methods that should run deferred, just + * define them as 'protected function _foo()'. Then, users may + * call $this->taskFrobinator()->foo() to get deferred execution + * of _foo(). + */ +abstract class StackBasedTask extends BaseTask +{ + /** + * @var array + */ + protected $stack = []; + + /** + * @var bool + */ + protected $stopOnFail = true; + + /** + * @param bool $stop + * + * @return $this + */ + public function stopOnFail($stop = true) + { + $this->stopOnFail = $stop; + return $this; + } + + /** + * Derived classes should override the getDelegate() method, and + * return an instance of the API class being wrapped. When this + * is done, any method of the delegate is available as a method of + * this class. Calling one of the delegate's methods will defer + * execution until the run() method is called. + * + * @return null + */ + protected function getDelegate() + { + return null; + } + + /** + * Derived classes that have more than one delegate may override + * getCommandList to add as many delegate commands as desired to + * the list of potential functions that __call() tried to find. + * + * @param string $function + * + * @return array + */ + protected function getDelegateCommandList($function) + { + return [[$this, "_$function"], [$this->getDelegate(), $function]]; + } + + /** + * Print progress about the commands being executed + * + * @param string $command + * @param string $action + */ + protected function printTaskProgress($command, $action) + { + $this->printTaskInfo('{command} {action}', ['command' => "{$command[1]}", 'action' => json_encode($action, JSON_UNESCAPED_SLASHES)]); + } + + /** + * Derived classes can override processResult to add more + * logic to result handling from functions. By default, it + * is assumed that if a function returns in int, then + * 0 == success, and any other value is the error code. + * + * @param int|\Robo\Result $function_result + * + * @return \Robo\Result + */ + protected function processResult($function_result) + { + if (is_int($function_result)) { + if ($function_result) { + return Result::error($this, $function_result); + } + } + return Result::success($this); + } + + /** + * Record a function to call later. + * + * @param string $command + * @param array $args + * + * @return $this + */ + protected function addToCommandStack($command, $args) + { + $this->stack[] = array_merge([$command], $args); + return $this; + } + + /** + * Any API function provided by the delegate that executes immediately + * may be handled by __call automatically. These operations will all + * be deferred until this task's run() method is called. + * + * @param string $function + * @param array $args + * + * @return $this + */ + public function __call($function, $args) + { + foreach ($this->getDelegateCommandList($function) as $command) { + if (method_exists($command[0], $command[1])) { + // Otherwise, we'll defer calling this function + // until run(), and return $this. + $this->addToCommandStack($command, $args); + return $this; + } + } + + $message = "Method $function does not exist.\n"; + throw new \BadMethodCallException($message); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + // run() will call advanceProgressIndicator() once for each + // file, one after calling stopBuffering, and again after compression. + return count($this->stack); + } + + /** + * Run all of the queued objects on the stack + * + * @return \Robo\Result + */ + public function run() + { + $this->startProgressIndicator(); + $result = Result::success($this); + + foreach ($this->stack as $action) { + $command = array_shift($action); + $this->printTaskProgress($command, $action); + $this->advanceProgressIndicator(); + // TODO: merge data from the result on this call + // with data from the result on the previous call? + // For now, the result always comes from the last function. + $result = $this->callTaskMethod($command, $action); + if ($this->stopOnFail && $result && !$result->wasSuccessful()) { + break; + } + } + + $this->stopProgressIndicator(); + + // todo: add timing information to the result + return $result; + } + + /** + * Execute one task method + * + * @param string $command + * @param string $action + * + * @return \Robo\Result + */ + protected function callTaskMethod($command, $action) + { + try { + $function_result = call_user_func_array($command, $action); + return $this->processResult($function_result); + } catch (\Exception $e) { + $this->printTaskError($e->getMessage()); + return Result::fromException($this, $e); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Atoum.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Atoum.php new file mode 100644 index 00000000..56b47d84 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Atoum.php @@ -0,0 +1,184 @@ +taskAtoum() + * ->files('path/to/test.php') + * ->configFile('config/dev.php') + * ->run() + * + * ?> + * ``` + */ +class Atoum extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * Atoum constructor. + * + * @param null|string $pathToAtoum + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToAtoum = null) + { + $this->command = $pathToAtoum; + if (!$this->command) { + $this->command = $this->findExecutable('atoum'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither local atoum nor global composer installation not found"); + } + } + + /** + * Tag or Tags to filter. + * + * @param string|array $tags + * + * @return $this + */ + public function tags($tags) + { + return $this->addMultipleOption('tags', $tags); + } + + /** + * Display result using the light reporter. + * + * @return $this + */ + public function lightReport() + { + $this->option("--use-light-report"); + + return $this; + } + + /** + * Display result using the tap reporter. + * + * @return $this + */ + public function tap() + { + $this->option("use-tap-report"); + + return $this; + } + + /** + * Path to the bootstrap file. + + * @param string $file + * + * @return $this + */ + public function bootstrap($file) + { + $this->option("bootstrap", $file); + + return $this; + } + + /** + * Path to the config file. + * + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option('-c', $file); + + return $this; + } + + /** + * Use atoum's debug mode. + * + * @return $this + */ + public function debug() + { + $this->option("debug"); + + return $this; + } + + /** + * Test file or test files to run. + * + * @param string|array + * + * @return $this + */ + public function files($files) + { + return $this->addMultipleOption('f', $files); + } + + /** + * Test directory or directories to run. + * + * @param string|array A single directory or a list of directories. + * + * @return $this + */ + public function directories($directories) + { + return $this->addMultipleOption('directories', $directories); + } + + /** + * @param string $option + * @param string|array $values + * + * @return $this + */ + protected function addMultipleOption($option, $values) + { + if (is_string($values)) { + $values = [$values]; + } + + foreach ($values as $value) { + $this->option($option, $value); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running atoum ' . $this->arguments); + + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Behat.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Behat.php new file mode 100644 index 00000000..7e4f1d41 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Behat.php @@ -0,0 +1,163 @@ +taskBehat() + * ->format('pretty') + * ->noInteraction() + * ->run(); + * ?> + * ``` + * + */ +class Behat extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string[] $formaters available formaters for format option + */ + protected $formaters = ['progress', 'pretty', 'junit']; + + /** + * @var string[] $verbose_levels available verbose levels + */ + protected $verbose_levels = ['v', 'vv']; + + /** + * Behat constructor. + * + * @param null|string $pathToBehat + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToBehat = null) + { + $this->command = $pathToBehat; + if (!$this->command) { + $this->command = $this->findExecutable('behat'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Behat found"); + } + } + + /** + * @return $this + */ + public function stopOnFail() + { + $this->option('stop-on-failure'); + return $this; + } + + /** + * @return $this + */ + public function noInteraction() + { + $this->option('no-interaction'); + return $this; + } + + /** + * @param $config_file + * + * @return $this + */ + public function config($config_file) + { + $this->option('config', $config_file); + return $this; + } + + /** + * @return $this + */ + public function colors() + { + $this->option('colors'); + return $this; + } + + /** + * @return $this + */ + public function noColors() + { + $this->option('no-colors'); + return $this; + } + + /** + * @param string $suite + * + * @return $this + */ + public function suite($suite) + { + $this->option('suite', $suite); + return $this; + } + + /** + * @param string $level + * + * @return $this + */ + public function verbose($level = 'v') + { + if (!in_array($level, $this->verbose_levels)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels)); + } + $this->option('-' . $level); + return $this; + } + + /** + * @param string $formater + * + * @return $this + */ + public function format($formater) + { + if (!in_array($formater, $this->formaters)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters)); + } + $this->option('format', $formater); + return $this; + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running behat {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Codecept.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Codecept.php new file mode 100644 index 00000000..1f8cce70 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Codecept.php @@ -0,0 +1,271 @@ +taskCodecept() + * ->suite('acceptance') + * ->env('chrome') + * ->group('admin') + * ->xml() + * ->html() + * ->run(); + * + * ?> + * ``` + * + */ +class Codecept extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @param string $pathToCodeception + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToCodeception = '') + { + $this->command = $pathToCodeception; + if (!$this->command) { + $this->command = $this->findExecutable('codecept'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Neither composer nor phar installation of Codeception found."); + } + $this->command .= ' run'; + } + + /** + * @param string $suite + * + * @return $this + */ + public function suite($suite) + { + $this->option(null, $suite); + return $this; + } + + /** + * @param string $testName + * + * @return $this + */ + public function test($testName) + { + $this->option(null, $testName); + return $this; + } + + /** + * set group option. Can be called multiple times + * + * @param string $group + * + * @return $this + */ + public function group($group) + { + $this->option("group", $group); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function excludeGroup($group) + { + $this->option("skip-group", $group); + return $this; + } + + /** + * generate json report + * + * @param string $file + * + * @return $this + */ + public function json($file = null) + { + $this->option("json", $file); + return $this; + } + + /** + * generate xml JUnit report + * + * @param string $file + * + * @return $this + */ + public function xml($file = null) + { + $this->option("xml", $file); + return $this; + } + + /** + * Generate html report + * + * @param string $dir + * + * @return $this + */ + public function html($dir = null) + { + $this->option("html", $dir); + return $this; + } + + /** + * generate tap report + * + * @param string $file + * + * @return $this + */ + public function tap($file = null) + { + $this->option("tap", $file); + return $this; + } + + /** + * provides config file other then default `codeception.yml` with `-c` option + * + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option("-c", $file); + return $this; + } + + /** + * collect codecoverage in raw format. You may pass name of cov file to save results + * + * @param null|string $cov + * + * @return $this + */ + public function coverage($cov = null) + { + $this->option("coverage", $cov); + return $this; + } + + /** + * execute in silent mode + * + * @return $this + */ + public function silent() + { + $this->option("silent"); + return $this; + } + + /** + * collect code coverage in xml format. You may pass name of xml file to save results + * + * @param string $xml + * + * @return $this + */ + public function coverageXml($xml = null) + { + $this->option("coverage-xml", $xml); + return $this; + } + + /** + * collect code coverage and generate html report. You may pass + * + * @param string $html + * + * @return $this + */ + public function coverageHtml($html = null) + { + $this->option("coverage-html", $html); + return $this; + } + + /** + * @param string $env + * + * @return $this + */ + public function env($env) + { + $this->option("env", $env); + return $this; + } + + /** + * @return $this + */ + public function debug() + { + $this->option("debug"); + return $this; + } + + /** + * @return $this + */ + public function noRebuild() + { + $this->option("no-rebuild"); + return $this; + } + + /** + * @param string $failGroup + * @return $this + */ + public function failGroup($failGroup) + { + $this->option('override', "extensions: config: Codeception\\Extension\\RunFailed: fail-group: {$failGroup}"); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Executing {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/PHPUnit.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/PHPUnit.php new file mode 100644 index 00000000..df67e1c7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/PHPUnit.php @@ -0,0 +1,199 @@ +taskPHPUnit() + * ->group('core') + * ->bootstrap('test/bootstrap.php') + * ->run() + * + * ?> + * ``` + */ +class PHPUnit extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * Directory of test files or single test file to run. Appended to + * the command and arguments. + * + * @var string + */ + protected $files = ''; + + public function __construct($pathToPhpUnit = null) + { + $this->command = $pathToPhpUnit; + if (!$this->command) { + $this->command = $this->findExecutablePhar('phpunit'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither local phpunit nor global composer installation not found"); + } + } + + /** + * @param string $filter + * + * @return $this + */ + public function filter($filter) + { + $this->option('filter', $filter); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function group($group) + { + $this->option("group", $group); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function excludeGroup($group) + { + $this->option("exclude-group", $group); + return $this; + } + + /** + * adds `log-json` option to runner + * + * @param string $file + * + * @return $this + */ + public function json($file = null) + { + $this->option("log-json", $file); + return $this; + } + + /** + * adds `log-junit` option + * + * @param string $file + * + * @return $this + */ + public function xml($file = null) + { + $this->option("log-junit", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function tap($file = "") + { + $this->option("log-tap", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function bootstrap($file) + { + $this->option("bootstrap", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option('-c', $file); + return $this; + } + + /** + * @return $this + */ + public function debug() + { + $this->option("debug"); + return $this; + } + + /** + * Directory of test files or single test file to run. + * + * @param string $files A single test file or a directory containing test files. + * + * @return $this + * + * @throws \Robo\Exception\TaskException + * + * @deprecated Use file() or dir() method instead + */ + public function files($files) + { + if (!empty($this->files) || is_array($files)) { + throw new \Robo\Exception\TaskException(__CLASS__, "Only one file or directory may be provided."); + } + $this->files = ' ' . $files; + + return $this; + } + + /** + * Test the provided file. + * + * @param string $file path to file to test + * + * @return $this + */ + public function file($file) + { + return $this->files($file); + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments . $this->files; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running PHPUnit {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Phpspec.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Phpspec.php new file mode 100644 index 00000000..dd6a5ae7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/Phpspec.php @@ -0,0 +1,116 @@ +taskPhpspec() + * ->format('pretty') + * ->noInteraction() + * ->run(); + * ?> + * ``` + * + */ +class Phpspec extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string[] $formaters available formaters for format option + */ + protected $formaters = ['progress', 'html', 'pretty', 'junit', 'dot', 'tap']; + + /** + * @var array $verbose_levels available verbose levels + */ + protected $verbose_levels = ['v', 'vv', 'vvv']; + + public function __construct($pathToPhpspec = null) + { + $this->command = $pathToPhpspec; + if (!$this->command) { + $this->command = $this->findExecutable('phpspec'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Phpspec found"); + } + $this->arg('run'); + } + + public function stopOnFail() + { + $this->option('stop-on-failure'); + return $this; + } + + public function noCodeGeneration() + { + $this->option('no-code-generation'); + return $this; + } + + public function quiet() + { + $this->option('quiet'); + return $this; + } + + public function verbose($level = 'v') + { + if (!in_array($level, $this->verbose_levels)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels)); + } + $this->option('-' . $level); + return $this; + } + + public function noAnsi() + { + $this->option('no-ansi'); + return $this; + } + + public function noInteraction() + { + $this->option('no-interaction'); + return $this; + } + + public function config($config_file) + { + $this->option('config', $config_file); + return $this; + } + + public function format($formater) + { + if (!in_array($formater, $this->formaters)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters)); + } + $this->option('format', $formater); + return $this; + } + + public function getCommand() + { + return $this->command . $this->arguments; + } + + public function run() + { + $this->printTaskInfo('Running phpspec {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/loadTasks.php new file mode 100644 index 00000000..43145b9b --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Testing/loadTasks.php @@ -0,0 +1,55 @@ +task(Codecept::class, $pathToCodeception); + } + + /** + * @param null|string $pathToPhpUnit + * + * @return \Robo\Task\Testing\PHPUnit + */ + protected function taskPhpUnit($pathToPhpUnit = null) + { + return $this->task(PHPUnit::class, $pathToPhpUnit); + } + + /** + * @param null $pathToPhpspec + * + * @return \Robo\Task\Testing\Phpspec + */ + protected function taskPhpspec($pathToPhpspec = null) + { + return $this->task(Phpspec::class, $pathToPhpspec); + } + + /** + * @param null $pathToAtoum + * + * @return \Robo\Task\Testing\Atoum + */ + protected function taskAtoum($pathToAtoum = null) + { + return $this->task(Atoum::class, $pathToAtoum); + } + + /** + * @param null $pathToBehat + * + * @return \Robo\Task\Testing\Behat + */ + protected function taskBehat($pathToBehat = null) + { + return $this->task(Behat::class, $pathToBehat); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/GitStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/GitStack.php new file mode 100644 index 00000000..6cb1783f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/GitStack.php @@ -0,0 +1,177 @@ +taskGitStack() + * ->stopOnFail() + * ->add('-A') + * ->commit('adding everything') + * ->push('origin','master') + * ->tag('0.6.0') + * ->push('origin','0.6.0') + * ->run() + * + * $this->taskGitStack() + * ->stopOnFail() + * ->add('doc/*') + * ->commit('doc updated') + * ->push() + * ->run(); + * ?> + * ``` + */ +class GitStack extends CommandStack +{ + /** + * @param string $pathToGit + */ + public function __construct($pathToGit = 'git') + { + $this->executable = $pathToGit; + } + + /** + * Executes `git clone` + * + * @param string $repo + * @param string $to + * + * @return $this + */ + public function cloneRepo($repo, $to = "", $branch = "") + { + $cmd = ['clone', $repo, $to]; + if (!empty($branch)) { + $cmd[] = "--branch $branch"; + } + return $this->exec($cmd); + } + + /** + * Executes `git clone` with depth 1 as default + * + * @param string $repo + * @param string $to + * @param string $branch + * @param int $depth + * + * @return $this + */ + public function cloneShallow($repo, $to = '', $branch = "", $depth = 1) + { + $cmd = ["clone --depth $depth", $repo, $to]; + if (!empty($branch)) { + $cmd[] = "--branch $branch"; + } + + return $this->exec($cmd); + } + + /** + * Executes `git add` command with files to add pattern + * + * @param string $pattern + * + * @return $this + */ + public function add($pattern) + { + return $this->exec([__FUNCTION__, $pattern]); + } + + /** + * Executes `git commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = "") + { + $message = ProcessUtils::escapeArgument($message); + return $this->exec([__FUNCTION__, "-m $message", $options]); + } + + /** + * Executes `git pull` command. + * + * @param string $origin + * @param string $branch + * + * @return $this + */ + public function pull($origin = '', $branch = '') + { + return $this->exec([__FUNCTION__, $origin, $branch]); + } + + /** + * Executes `git push` command + * + * @param string $origin + * @param string $branch + * + * @return $this + */ + public function push($origin = '', $branch = '') + { + return $this->exec([__FUNCTION__, $origin, $branch]); + } + + /** + * Performs git merge + * + * @param string $branch + * + * @return $this + */ + public function merge($branch) + { + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `git checkout` command + * + * @param string $branch + * + * @return $this + */ + public function checkout($branch) + { + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `git tag` command + * + * @param string $tag_name + * @param string $message + * + * @return $this + */ + public function tag($tag_name, $message = "") + { + if ($message != "") { + $message = "-m '$message'"; + } + return $this->exec([__FUNCTION__, $message, $tag_name]); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo("Running git commands..."); + return parent::run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/HgStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/HgStack.php new file mode 100644 index 00000000..71cc0ca9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/HgStack.php @@ -0,0 +1,153 @@ +hgStack + * ->cloneRepo('https://bitbucket.org/durin42/hgsubversion') + * ->pull() + * ->add() + * ->commit('changed') + * ->push() + * ->tag('0.6.0') + * ->push('0.6.0') + * ->run(); + * ?> + * ``` + */ +class HgStack extends CommandStack +{ + + /** + * @param string $pathToHg + */ + public function __construct($pathToHg = 'hg') + { + $this->executable = $pathToHg; + } + + /** + * Executes `hg clone` + * + * @param string $repo + * @param string $to + * + * @return $this + */ + public function cloneRepo($repo, $to = '') + { + return $this->exec(['clone', $repo, $to]); + } + + /** + * Executes `hg add` command with files to add by pattern + * + * @param string $include + * @param string $exclude + * + * @return $this + */ + public function add($include = '', $exclude = '') + { + if (strlen($include) > 0) { + $include = "-I {$include}"; + } + + if (strlen($exclude) > 0) { + $exclude = "-X {$exclude}"; + } + + return $this->exec([__FUNCTION__, $include, $exclude]); + } + + /** + * Executes `hg commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = '') + { + return $this->exec([__FUNCTION__, "-m '{$message}'", $options]); + } + + /** + * Executes `hg pull` command. + * + * @param string $branch + * + * @return $this + */ + public function pull($branch = '') + { + if (strlen($branch) > 0) { + $branch = "-b '{$branch}''"; + } + + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `hg push` command + * + * @param string $branch + * + * @return $this + */ + public function push($branch = '') + { + if (strlen($branch) > 0) { + $branch = "-b '{$branch}'"; + } + + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Performs hg merge + * + * @param string $revision + * + * @return $this + */ + public function merge($revision = '') + { + if (strlen($revision) > 0) { + $revision = "-r {$revision}"; + } + + return $this->exec([__FUNCTION__, $revision]); + } + + /** + * Executes `hg tag` command + * + * @param string $tag_name + * @param string $message + * + * @return $this + */ + public function tag($tag_name, $message = '') + { + if ($message !== '') { + $message = "-m '{$message}'"; + } + return $this->exec([__FUNCTION__, $message, $tag_name]); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running hg commands...'); + return parent::run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/SvnStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/SvnStack.php new file mode 100644 index 00000000..ec719b53 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/SvnStack.php @@ -0,0 +1,106 @@ +taskSvnStack() + * ->checkout('http://svn.collab.net/repos/svn/trunk') + * ->run() + * + * // alternatively + * $this->_svnCheckout('http://svn.collab.net/repos/svn/trunk'); + * + * $this->taskSvnStack('username', 'password') + * ->stopOnFail() + * ->update() + * ->add('doc/*') + * ->commit('doc updated') + * ->run(); + * ?> + * ``` + */ +class SvnStack extends CommandStack implements CommandInterface +{ + /** + * @var bool + */ + protected $stopOnFail = false; + + /** + * @var \Robo\Result + */ + protected $result; + + /** + * @param string $username + * @param string $password + * @param string $pathToSvn + */ + public function __construct($username = '', $password = '', $pathToSvn = 'svn') + { + $this->executable = $pathToSvn; + if (!empty($username)) { + $this->executable .= " --username $username"; + } + if (!empty($password)) { + $this->executable .= " --password $password"; + } + $this->result = Result::success($this); + } + + /** + * Updates `svn update` command + * + * @param string $path + * + * @return $this; + */ + public function update($path = '') + { + return $this->exec("update $path"); + } + + /** + * Executes `svn add` command with files to add pattern + * + * @param string $pattern + * + * @return $this + */ + public function add($pattern = '') + { + return $this->exec("add $pattern"); + } + + /** + * Executes `svn commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = "") + { + return $this->exec("commit -m '$message' $options"); + } + + /** + * Executes `svn checkout` command + * + * @param string $branch + * + * @return $this + */ + public function checkout($branch) + { + return $this->exec("checkout $branch"); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/loadShortcuts.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/loadShortcuts.php new file mode 100644 index 00000000..7d64ab58 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/loadShortcuts.php @@ -0,0 +1,35 @@ +taskSvnStack()->checkout($url)->run(); + } + + /** + * @param string $url + * + * @return \Robo\Result + */ + protected function _gitClone($url) + { + return $this->taskGitStack()->cloneRepo($url)->run(); + } + + /** + * @param string $url + * + * @return \Robo\Result + */ + protected function _hgClone($url) + { + return $this->taskHgStack()->cloneRepo($url)->run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/loadTasks.php new file mode 100644 index 00000000..6dd06228 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Task/Vcs/loadTasks.php @@ -0,0 +1,37 @@ +task(SvnStack::class, $username, $password, $pathToSvn); + } + + /** + * @param string $pathToGit + * + * @return \Robo\Task\Vcs\GitStack + */ + protected function taskGitStack($pathToGit = 'git') + { + return $this->task(GitStack::class, $pathToGit); + } + + /** + * @param string $pathToHg + * + * @return \Robo\Task\Vcs\HgStack + */ + protected function taskHgStack($pathToHg = 'hg') + { + return $this->task(HgStack::class, $pathToHg); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/TaskAccessor.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/TaskAccessor.php new file mode 100644 index 00000000..e65cd3eb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/TaskAccessor.php @@ -0,0 +1,47 @@ +task(Foo::class, $a, $b); + * + * instead of: + * + * $this->taskFoo($a, $b); + * + * The later form is preferred. + * + * @return \Robo\Collection\CollectionBuilder + */ + protected function task() + { + $args = func_get_args(); + $name = array_shift($args); + + $collectionBuilder = $this->collectionBuilder(); + return $collectionBuilder->build($name, $args); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/TaskInfo.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/TaskInfo.php new file mode 100644 index 00000000..ce59c2d5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/TaskInfo.php @@ -0,0 +1,35 @@ + TaskInfo::formatTaskName($task), + 'task' => $task, + ]; + } + + /** + * @param object $task + * + * @return string + */ + public static function formatTaskName($task) + { + $name = get_class($task); + $name = preg_replace('~Stack^~', '', $name); + $name = str_replace('Robo\\Task\Base\\', '', $name); + $name = str_replace('Robo\\Task\\', '', $name); + $name = str_replace('Robo\\Collection\\', '', $name); + return $name; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Tasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Tasks.php new file mode 100644 index 00000000..2822d7d5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony2/src/Tasks.php @@ -0,0 +1,23 @@ +getDefinition() + ->addOption( + new InputOption('--simulate', null, InputOption::VALUE_NONE, 'Run in simulated mode (show what would have happened).') + ); + $this->getDefinition() + ->addOption( + new InputOption('--progress-delay', null, InputOption::VALUE_REQUIRED, 'Number of seconds before progress bar is displayed in long-running task collections. Default: 2s.', Config::DEFAULT_PROGRESS_DELAY) + ); + + $this->getDefinition() + ->addOption( + new InputOption('--define', '-D', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Define a configuration item value.', []) + ); + } + + /** + * @param string $roboFile + * @param string $roboClass + */ + public function addInitRoboFileCommand($roboFile, $roboClass) + { + $createRoboFile = new Command('init'); + $createRoboFile->setDescription("Intitalizes basic RoboFile in current dir"); + $createRoboFile->setCode(function () use ($roboClass, $roboFile) { + $output = Robo::output(); + $output->writeln(" ~~~ Welcome to Robo! ~~~~ "); + $output->writeln(" ". basename($roboFile) ." will be created in the current directory "); + file_put_contents( + $roboFile, + 'writeln(" Edit this file to add your commands! "); + }); + $this->add($createRoboFile); + } + + /** + * Add self update command, do nothing if null is provided + * + * @param string $repository GitHub Repository for self update + */ + public function addSelfUpdateCommand($repository = null) + { + if (!$repository) { + return; + } + $selfUpdateCommand = new SelfUpdateCommand($this->getName(), $this->getVersion(), $repository); + $this->add($selfUpdateCommand); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CallableTask.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CallableTask.php new file mode 100644 index 00000000..ae9c54fc --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CallableTask.php @@ -0,0 +1,62 @@ +fn = $fn; + $this->reference = $reference; + } + + /** + * @return \Robo\Result + */ + public function run() + { + $result = call_user_func($this->fn, $this->getState()); + // If the function returns no result, then count it + // as a success. + if (!isset($result)) { + $result = Result::success($this->reference); + } + // If the function returns a result, it must either return + // a \Robo\Result or an exit code. In the later case, we + // convert it to a \Robo\Result. + if (!$result instanceof Result) { + $result = new Result($this->reference, $result); + } + + return $result; + } + + public function getState() + { + if ($this->reference instanceof StateAwareInterface) { + return $this->reference->getState(); + } + return new Data(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Collection.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Collection.php new file mode 100644 index 00000000..607435a4 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Collection.php @@ -0,0 +1,769 @@ +resetState(); + } + + public function setProgressBarAutoDisplayInterval($interval) + { + if (!$this->progressIndicator) { + return; + } + return $this->progressIndicator->setProgressBarAutoDisplayInterval($interval); + } + + /** + * {@inheritdoc} + */ + public function add(TaskInterface $task, $name = self::UNNAMEDTASK) + { + $task = new CompletionWrapper($this, $task); + $this->addToTaskList($name, $task); + return $this; + } + + /** + * {@inheritdoc} + */ + public function addCode(callable $code, $name = self::UNNAMEDTASK) + { + return $this->add(new CallableTask($code, $this), $name); + } + + /** + * {@inheritdoc} + */ + public function addIterable($iterable, callable $code) + { + $callbackTask = (new IterationTask($iterable, $code, $this))->inflect($this); + return $this->add($callbackTask); + } + + /** + * {@inheritdoc} + */ + public function rollback(TaskInterface $rollbackTask) + { + // Rollback tasks always try as hard as they can, and never report failures. + $rollbackTask = $this->ignoreErrorsTaskWrapper($rollbackTask); + return $this->wrapAndRegisterRollback($rollbackTask); + } + + /** + * {@inheritdoc} + */ + public function rollbackCode(callable $rollbackCode) + { + // Rollback tasks always try as hard as they can, and never report failures. + $rollbackTask = $this->ignoreErrorsCodeWrapper($rollbackCode); + return $this->wrapAndRegisterRollback($rollbackTask); + } + + /** + * {@inheritdoc} + */ + public function completion(TaskInterface $completionTask) + { + $collection = $this; + $completionRegistrationTask = new CallableTask( + function () use ($collection, $completionTask) { + + $collection->registerCompletion($completionTask); + }, + $this + ); + $this->addToTaskList(self::UNNAMEDTASK, $completionRegistrationTask); + return $this; + } + + /** + * {@inheritdoc} + */ + public function completionCode(callable $completionTask) + { + $completionTask = new CallableTask($completionTask, $this); + return $this->completion($completionTask); + } + + /** + * {@inheritdoc} + */ + public function before($name, $task, $nameOfTaskToAdd = self::UNNAMEDTASK) + { + return $this->addBeforeOrAfter(__FUNCTION__, $name, $task, $nameOfTaskToAdd); + } + + /** + * {@inheritdoc} + */ + public function after($name, $task, $nameOfTaskToAdd = self::UNNAMEDTASK) + { + return $this->addBeforeOrAfter(__FUNCTION__, $name, $task, $nameOfTaskToAdd); + } + + /** + * {@inheritdoc} + */ + public function progressMessage($text, $context = [], $level = LogLevel::NOTICE) + { + $context += ['name' => 'Progress']; + $context += TaskInfo::getTaskContext($this); + return $this->addCode( + function () use ($level, $text, $context) { + $context += $this->getState()->getData(); + $this->printTaskOutput($level, $text, $context); + } + ); + } + + /** + * @param \Robo\Contract\TaskInterface $rollbackTask + * + * @return $this + */ + protected function wrapAndRegisterRollback(TaskInterface $rollbackTask) + { + $collection = $this; + $rollbackRegistrationTask = new CallableTask( + function () use ($collection, $rollbackTask) { + $collection->registerRollback($rollbackTask); + }, + $this + ); + $this->addToTaskList(self::UNNAMEDTASK, $rollbackRegistrationTask); + return $this; + } + + /** + * Add either a 'before' or 'after' function or task. + * + * @param string $method + * @param string $name + * @param callable|TaskInterface $task + * @param string $nameOfTaskToAdd + * + * @return $this + */ + protected function addBeforeOrAfter($method, $name, $task, $nameOfTaskToAdd) + { + if (is_callable($task)) { + $task = new CallableTask($task, $this); + } + $existingTask = $this->namedTask($name); + $fn = [$existingTask, $method]; + call_user_func($fn, $task, $nameOfTaskToAdd); + return $this; + } + + /** + * Wrap the provided task in a wrapper that will ignore + * any errors or exceptions that may be produced. This + * is useful, for example, in adding optional cleanup tasks + * at the beginning of a task collection, to remove previous + * results which may or may not exist. + * + * TODO: Provide some way to specify which sort of errors + * are ignored, so that 'file not found' may be ignored, + * but 'permission denied' reported? + * + * @param \Robo\Contract\TaskInterface $task + * + * @return \Robo\Collection\CallableTask + */ + public function ignoreErrorsTaskWrapper(TaskInterface $task) + { + // If the task is a stack-based task, then tell it + // to try to run all of its operations, even if some + // of them fail. + if ($task instanceof StackBasedTask) { + $task->stopOnFail(false); + } + $ignoreErrorsInTask = function () use ($task) { + $data = []; + try { + $result = $this->runSubtask($task); + $message = $result->getMessage(); + $data = $result->getData(); + $data['exitcode'] = $result->getExitCode(); + } catch (\Exception $e) { + $message = $e->getMessage(); + } + + return Result::success($task, $message, $data); + }; + // Wrap our ignore errors callable in a task. + return new CallableTask($ignoreErrorsInTask, $this); + } + + /** + * @param callable $task + * + * @return \Robo\Collection\CallableTask + */ + public function ignoreErrorsCodeWrapper(callable $task) + { + return $this->ignoreErrorsTaskWrapper(new CallableTask($task, $this)); + } + + /** + * Return the list of task names added to this collection. + * + * @return array + */ + public function taskNames() + { + return array_keys($this->taskList); + } + + /** + * Test to see if a specified task name exists. + * n.b. before() and after() require that the named + * task exist; use this function to test first, if + * unsure. + * + * @param string $name + * + * @return bool + */ + public function hasTask($name) + { + return array_key_exists($name, $this->taskList); + } + + /** + * Find an existing named task. + * + * @param string $name + * The name of the task to insert before. The named task MUST exist. + * + * @return Element + * The task group for the named task. Generally this is only + * used to call 'before()' and 'after()'. + */ + protected function namedTask($name) + { + if (!$this->hasTask($name)) { + throw new \RuntimeException("Could not find task named $name"); + } + return $this->taskList[$name]; + } + + /** + * Add a list of tasks to our task collection. + * + * @param TaskInterface[] $tasks + * An array of tasks to run with rollback protection + * + * @return $this + */ + public function addTaskList(array $tasks) + { + foreach ($tasks as $name => $task) { + $this->add($task, $name); + } + return $this; + } + + /** + * Add the provided task to our task list. + * + * @param string $name + * @param \Robo\Contract\TaskInterface $task + * + * @return \Robo\Collection\Collection + */ + protected function addToTaskList($name, TaskInterface $task) + { + // All tasks are stored in a task group so that we have a place + // to hang 'before' and 'after' tasks. + $taskGroup = new Element($task); + return $this->addCollectionElementToTaskList($name, $taskGroup); + } + + /** + * @param int|string $name + * @param \Robo\Collection\Element $taskGroup + * + * @return $this + */ + protected function addCollectionElementToTaskList($name, Element $taskGroup) + { + // If a task name is not provided, then we'll let php pick + // the array index. + if (Result::isUnnamed($name)) { + $this->taskList[] = $taskGroup; + return $this; + } + // If we are replacing an existing task with the + // same name, ensure that our new task is added to + // the end. + $this->taskList[$name] = $taskGroup; + return $this; + } + + /** + * Set the parent collection. This is necessary so that nested + * collections' rollback and completion tasks can be added to the + * top-level collection, ensuring that the rollbacks for a collection + * will run if any later task fails. + * + * @param \Robo\Collection\NestedCollectionInterface $parentCollection + * + * @return $this + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->parentCollection = $parentCollection; + return $this; + } + + /** + * Get the appropriate parent collection to use + * + * @return CollectionInterface + */ + public function getParentCollection() + { + return $this->parentCollection ? $this->parentCollection : $this; + } + + /** + * Register a rollback task to run if there is any failure. + * + * Clients are free to add tasks to the rollback stack as + * desired; however, usually it is preferable to call + * Collection::rollback() instead. With that function, + * the rollback function will only be called if all of the + * tasks added before it complete successfully, AND some later + * task fails. + * + * One example of a good use-case for registering a callback + * function directly is to add a task that sends notification + * when a task fails. + * + * @param TaskInterface $rollbackTask + * The rollback task to run on failure. + */ + public function registerRollback(TaskInterface $rollbackTask) + { + if ($this->parentCollection) { + return $this->parentCollection->registerRollback($rollbackTask); + } + if ($rollbackTask) { + $this->rollbackStack[] = $rollbackTask; + } + } + + /** + * Register a completion task to run once all other tasks finish. + * Completion tasks run whether or not a rollback operation was + * triggered. They do not trigger rollbacks if they fail. + * + * The typical use-case for a completion function is to clean up + * temporary objects (e.g. temporary folders). The preferred + * way to do that, though, is to use Temporary::wrap(). + * + * On failures, completion tasks will run after all rollback tasks. + * If one task collection is nested inside another task collection, + * then the nested collection's completion tasks will run as soon as + * the nested task completes; they are not deferred to the end of + * the containing collection's execution. + * + * @param TaskInterface $completionTask + * The completion task to run at the end of all other operations. + */ + public function registerCompletion(TaskInterface $completionTask) + { + if ($this->parentCollection) { + return $this->parentCollection->registerCompletion($completionTask); + } + if ($completionTask) { + // Completion tasks always try as hard as they can, and never report failures. + $completionTask = $this->ignoreErrorsTaskWrapper($completionTask); + $this->completionStack[] = $completionTask; + } + } + + /** + * Return the count of steps in this collection + * + * @return int + */ + public function progressIndicatorSteps() + { + $steps = 0; + foreach ($this->taskList as $name => $taskGroup) { + $steps += $taskGroup->progressIndicatorSteps(); + } + return $steps; + } + + /** + * A Collection of tasks can provide a command via `getCommand()` + * if it contains a single task, and that task implements CommandInterface. + * + * @return string + * + * @throws \Robo\Exception\TaskException + */ + public function getCommand() + { + if (empty($this->taskList)) { + return ''; + } + + if (count($this->taskList) > 1) { + // TODO: We could potentially iterate over the items in the collection + // and concatenate the result of getCommand() from each one, and fail + // only if we encounter a command that is not a CommandInterface. + throw new TaskException($this, "getCommand() does not work on arbitrary collections of tasks."); + } + + $taskElement = reset($this->taskList); + $task = $taskElement->getTask(); + $task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + if ($task instanceof CommandInterface) { + return $task->getCommand(); + } + + throw new TaskException($task, get_class($task) . " does not implement CommandInterface, so can't be used to provide a command"); + } + + /** + * Run our tasks, and roll back if necessary. + * + * @return \Robo\Result + */ + public function run() + { + $result = $this->runWithoutCompletion(); + $this->complete(); + return $result; + } + + /** + * @return \Robo\Result + */ + private function runWithoutCompletion() + { + $result = Result::success($this); + + if (empty($this->taskList)) { + return $result; + } + + $this->startProgressIndicator(); + if ($result->wasSuccessful()) { + foreach ($this->taskList as $name => $taskGroup) { + $taskList = $taskGroup->getTaskList(); + $result = $this->runTaskList($name, $taskList, $result); + if (!$result->wasSuccessful()) { + $this->fail(); + return $result; + } + } + $this->taskList = []; + } + $this->stopProgressIndicator(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * Run every task in a list, but only up to the first failure. + * Return the failing result, or success if all tasks run. + * + * @param string $name + * @param TaskInterface[] $taskList + * @param \Robo\Result $result + * + * @return \Robo\Result + * + * @throws \Robo\Exception\TaskExitException + */ + private function runTaskList($name, array $taskList, Result $result) + { + try { + foreach ($taskList as $taskName => $task) { + $taskResult = $this->runSubtask($task); + $this->advanceProgressIndicator(); + // If the current task returns an error code, then stop + // execution and signal a rollback. + if (!$taskResult->wasSuccessful()) { + return $taskResult; + } + // We accumulate our results into a field so that tasks that + // have a reference to the collection may examine and modify + // the incremental results, if they wish. + $key = Result::isUnnamed($taskName) ? $name : $taskName; + $result->accumulate($key, $taskResult); + // The result message will be the message of the last task executed. + $result->setMessage($taskResult->getMessage()); + } + } catch (TaskExitException $exitException) { + $this->fail(); + throw $exitException; + } catch (\Exception $e) { + // Tasks typically should not throw, but if one does, we will + // convert it into an error and roll back. + return Result::fromException($task, $e, $result->getData()); + } + return $result; + } + + /** + * Force the rollback functions to run + * + * @return $this + */ + public function fail() + { + $this->disableProgressIndicator(); + $this->runRollbackTasks(); + $this->complete(); + return $this; + } + + /** + * Force the completion functions to run + * + * @return $this + */ + public function complete() + { + $this->detatchProgressIndicator(); + $this->runTaskListIgnoringFailures($this->completionStack); + $this->reset(); + return $this; + } + + /** + * Reset this collection, removing all tasks. + * + * @return $this + */ + public function reset() + { + $this->taskList = []; + $this->completionStack = []; + $this->rollbackStack = []; + return $this; + } + + /** + * Run all of our rollback tasks. + * + * Note that Collection does not implement RollbackInterface, but + * it may still be used as a task inside another task collection + * (i.e. you can nest task collections, if desired). + */ + protected function runRollbackTasks() + { + $this->runTaskListIgnoringFailures($this->rollbackStack); + // Erase our rollback stack once we have finished rolling + // everything back. This will allow us to potentially use + // a command collection more than once (e.g. to retry a + // failed operation after doing some error recovery). + $this->rollbackStack = []; + } + + /** + * @param TaskInterface|NestedCollectionInterface|WrappedTaskInterface $task + * + * @return \Robo\Result + */ + protected function runSubtask($task) + { + $original = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->setParentCollectionForTask($original, $this->getParentCollection()); + if ($original instanceof InflectionInterface) { + $original->inflect($this); + } + if ($original instanceof StateAwareInterface) { + $original->setState($this->getState()); + } + $this->doDeferredInitialization($original); + $taskResult = $task->run(); + $taskResult = Result::ensureResult($task, $taskResult); + $this->doStateUpdates($original, $taskResult); + return $taskResult; + } + + protected function doStateUpdates($task, Data $taskResult) + { + $this->updateState($taskResult); + $key = spl_object_hash($task); + if (array_key_exists($key, $this->messageStoreKeys)) { + $state = $this->getState(); + list($stateKey, $sourceKey) = $this->messageStoreKeys[$key]; + $value = empty($sourceKey) ? $taskResult->getMessage() : $taskResult[$sourceKey]; + $state[$stateKey] = $value; + } + } + + public function storeState($task, $key, $source = '') + { + $this->messageStoreKeys[spl_object_hash($task)] = [$key, $source]; + + return $this; + } + + public function deferTaskConfiguration($task, $functionName, $stateKey) + { + return $this->defer( + $task, + function ($task, $state) use ($functionName, $stateKey) { + $fn = [$task, $functionName]; + $value = $state[$stateKey]; + $fn($value); + } + ); + } + + /** + * Defer execution of a callback function until just before a task + * runs. Use this time to provide more settings for the task, e.g. from + * the collection's shared state, which is populated with the results + * of previous test runs. + */ + public function defer($task, $callback) + { + $this->deferredCallbacks[spl_object_hash($task)][] = $callback; + + return $this; + } + + protected function doDeferredInitialization($task) + { + // If the task is a state consumer, then call its receiveState method + if ($task instanceof \Robo\State\Consumer) { + $task->receiveState($this->getState()); + } + + // Check and see if there are any deferred callbacks for this task. + $key = spl_object_hash($task); + if (!array_key_exists($key, $this->deferredCallbacks)) { + return; + } + + // Call all of the deferred callbacks + foreach ($this->deferredCallbacks[$key] as $fn) { + $fn($task, $this->getState()); + } + } + + /** + * @param TaskInterface|NestedCollectionInterface|WrappedTaskInterface $task + * @param $parentCollection + */ + protected function setParentCollectionForTask($task, $parentCollection) + { + if ($task instanceof NestedCollectionInterface) { + $task->setParentCollection($parentCollection); + } + } + + /** + * Run all of the tasks in a provided list, ignoring failures. + * This is used to roll back or complete. + * + * @param TaskInterface[] $taskList + */ + protected function runTaskListIgnoringFailures(array $taskList) + { + foreach ($taskList as $task) { + try { + $this->runSubtask($task); + } catch (\Exception $e) { + // Ignore rollback failures. + } + } + } + + /** + * Give all of our tasks to the provided collection builder. + * + * @param CollectionBuilder $builder + */ + public function transferTasks($builder) + { + foreach ($this->taskList as $name => $taskGroup) { + // TODO: We are abandoning all of our before and after tasks here. + // At the moment, transferTasks is only called under conditions where + // there will be none of these, but care should be taken if that changes. + $task = $taskGroup->getTask(); + $builder->addTaskToCollection($task); + } + $this->reset(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionBuilder.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionBuilder.php new file mode 100644 index 00000000..3e037b01 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionBuilder.php @@ -0,0 +1,571 @@ +collectionBuilder() + * ->taskFilesystemStack() + * ->mkdir('g') + * ->touch('g/g.txt') + * ->rollback( + * $this->taskDeleteDir('g') + * ) + * ->taskFilesystemStack() + * ->mkdir('g/h') + * ->touch('g/h/h.txt') + * ->taskFilesystemStack() + * ->mkdir('g/h/i/c') + * ->touch('g/h/i/i.txt') + * ->run() + * ?> + * + * In the example above, the `taskDeleteDir` will be called if + * ``` + */ +class CollectionBuilder extends BaseTask implements NestedCollectionInterface, WrappedTaskInterface, CommandInterface, StateAwareInterface +{ + use StateAwareTrait; + + /** + * @var \Robo\Tasks + */ + protected $commandFile; + + /** + * @var CollectionInterface + */ + protected $collection; + + /** + * @var TaskInterface + */ + protected $currentTask; + + /** + * @var bool + */ + protected $simulated; + + /** + * @param \Robo\Tasks $commandFile + */ + public function __construct($commandFile) + { + $this->commandFile = $commandFile; + $this->resetState(); + } + + public static function create($container, $commandFile) + { + $builder = new self($commandFile); + + $builder->setLogger($container->get('logger')); + $builder->setProgressIndicator($container->get('progressIndicator')); + $builder->setConfig($container->get('config')); + $builder->setOutputAdapter($container->get('outputAdapter')); + + return $builder; + } + + /** + * @param bool $simulated + * + * @return $this + */ + public function simulated($simulated = true) + { + $this->simulated = $simulated; + return $this; + } + + /** + * @return bool + */ + public function isSimulated() + { + if (!isset($this->simulated)) { + $this->simulated = $this->getConfig()->get(Config::SIMULATE); + } + return $this->simulated; + } + + /** + * Create a temporary directory to work in. When the collection + * completes or rolls back, the temporary directory will be deleted. + * Returns the path to the location where the directory will be + * created. + * + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return string + */ + public function tmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + // n.b. Any task that the builder is asked to create is + // automatically added to the builder's collection, and + // wrapped in the builder object. Therefore, the result + // of any call to `taskFoo()` from within the builder will + // always be `$this`. + return $this->taskTmpDir($prefix, $base, $includeRandomPart)->getPath(); + } + + /** + * Create a working directory to hold results. A temporary directory + * is first created to hold the intermediate results. After the + * builder finishes, the work directory is moved into its final location; + * any results already in place will be moved out of the way and + * then deleted. + * + * @param string $finalDestination The path where the working directory + * will be moved once the task collection completes. + * + * @return string + */ + public function workDir($finalDestination) + { + // Creating the work dir task in this context adds it to our task collection. + return $this->taskWorkDir($finalDestination)->getPath(); + } + + public function addTask(TaskInterface $task) + { + $this->getCollection()->add($task); + return $this; + } + + /** + * Add arbitrary code to execute as a task. + * + * @see \Robo\Collection\CollectionInterface::addCode + * + * @param callable $code + * @param int|string $name + * @return $this + */ + public function addCode(callable $code, $name = \Robo\Collection\CollectionInterface::UNNAMEDTASK) + { + $this->getCollection()->addCode($code, $name); + return $this; + } + + /** + * Add a list of tasks to our task collection. + * + * @param TaskInterface[] $tasks + * An array of tasks to run with rollback protection + * + * @return $this + */ + public function addTaskList(array $tasks) + { + $this->getCollection()->addTaskList($tasks); + return $this; + } + + public function rollback(TaskInterface $task) + { + // Ensure that we have a collection if we are going to add + // a rollback function. + $this->getCollection()->rollback($task); + return $this; + } + + public function rollbackCode(callable $rollbackCode) + { + $this->getCollection()->rollbackCode($rollbackCode); + return $this; + } + + public function completion(TaskInterface $task) + { + $this->getCollection()->completion($task); + return $this; + } + + public function completionCode(callable $completionCode) + { + $this->getCollection()->completionCode($completionCode); + return $this; + } + + /** + * @param string $text + * @param array $context + * @param string $level + * + * @return $this + */ + public function progressMessage($text, $context = [], $level = LogLevel::NOTICE) + { + $this->getCollection()->progressMessage($text, $context, $level); + return $this; + } + + /** + * @param \Robo\Collection\NestedCollectionInterface $parentCollection + * + * @return $this + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->getCollection()->setParentCollection($parentCollection); + return $this; + } + + /** + * Called by the factory method of each task; adds the current + * task to the task builder. + * + * TODO: protected + * + * @param TaskInterface $task + * + * @return $this + */ + public function addTaskToCollection($task) + { + // Postpone creation of the collection until the second time + // we are called. At that time, $this->currentTask will already + // be populated. We call 'getCollection()' so that it will + // create the collection and add the current task to it. + // Note, however, that if our only tasks implements NestedCollectionInterface, + // then we should force this builder to use a collection. + if (!$this->collection && (isset($this->currentTask) || ($task instanceof NestedCollectionInterface))) { + $this->getCollection(); + } + $this->currentTask = $task; + if ($this->collection) { + $this->collection->add($task); + } + return $this; + } + + public function getState() + { + $collection = $this->getCollection(); + return $collection->getState(); + } + + public function storeState($key, $source = '') + { + return $this->callCollectionStateFuntion(__FUNCTION__, func_get_args()); + } + + public function deferTaskConfiguration($functionName, $stateKey) + { + return $this->callCollectionStateFuntion(__FUNCTION__, func_get_args()); + } + + public function defer($callback) + { + return $this->callCollectionStateFuntion(__FUNCTION__, func_get_args()); + } + + protected function callCollectionStateFuntion($functionName, $args) + { + $currentTask = ($this->currentTask instanceof WrappedTaskInterface) ? $this->currentTask->original() : $this->currentTask; + + array_unshift($args, $currentTask); + $collection = $this->getCollection(); + $fn = [$collection, $functionName]; + + call_user_func_array($fn, $args); + return $this; + } + + public function setVerbosityThreshold($verbosityThreshold) + { + $currentTask = ($this->currentTask instanceof WrappedTaskInterface) ? $this->currentTask->original() : $this->currentTask; + if ($currentTask) { + $currentTask->setVerbosityThreshold($verbosityThreshold); + return $this; + } + parent::setVerbosityThreshold($verbosityThreshold); + return $this; + } + + + /** + * Return the current task for this collection builder. + * TODO: Not needed? + * + * @return \Robo\Contract\TaskInterface + */ + public function getCollectionBuilderCurrentTask() + { + return $this->currentTask; + } + + /** + * Create a new builder with its own task collection + * + * @return CollectionBuilder + */ + public function newBuilder() + { + $collectionBuilder = new self($this->commandFile); + $collectionBuilder->inflect($this); + $collectionBuilder->simulated($this->isSimulated()); + $collectionBuilder->setVerbosityThreshold($this->verbosityThreshold()); + $collectionBuilder->setState($this->getState()); + + return $collectionBuilder; + } + + /** + * Calling the task builder with methods of the current + * task calls through to that method of the task. + * + * There is extra complexity in this function that could be + * simplified if we attached the 'LoadAllTasks' and custom tasks + * to the collection builder instead of the RoboFile. While that + * change would be a better design overall, it would require that + * the user do a lot more work to set up and use custom tasks. + * We therefore take on some additional complexity here in order + * to allow users to maintain their tasks in their RoboFile, which + * is much more convenient. + * + * Calls to $this->collectionBuilder()->taskFoo() cannot be made + * directly because all of the task methods are protected. These + * calls will therefore end up here. If the method name begins + * with 'task', then it is eligible to be used with the builder. + * + * When we call getBuiltTask, below, it will use the builder attached + * to the commandfile to build the task. However, this is not what we + * want: the task needs to be built from THIS collection builder, so that + * it will be affected by whatever state is active in this builder. + * To do this, we have two choices: 1) save and restore the builder + * in the commandfile, or 2) clone the commandfile and set this builder + * on the copy. 1) is vulnerable to failure in multithreaded environments + * (currently not supported), while 2) might cause confusion if there + * is shared state maintained in the commandfile, which is in the + * domain of the user. + * + * Note that even though we are setting up the commandFile to + * use this builder, getBuiltTask always creates a new builder + * (which is constructed using all of the settings from the + * commandFile's builder), and the new task is added to that. + * We therefore need to transfer the newly built task into this + * builder. The temporary builder is discarded. + * + * @param string $fn + * @param array $args + * + * @return $this|mixed + */ + public function __call($fn, $args) + { + if (preg_match('#^task[A-Z]#', $fn) && (method_exists($this->commandFile, 'getBuiltTask'))) { + $saveBuilder = $this->commandFile->getBuilder(); + $this->commandFile->setBuilder($this); + $temporaryBuilder = $this->commandFile->getBuiltTask($fn, $args); + $this->commandFile->setBuilder($saveBuilder); + if (!$temporaryBuilder) { + throw new \BadMethodCallException("No such method $fn: task does not exist in " . get_class($this->commandFile)); + } + $temporaryBuilder->getCollection()->transferTasks($this); + return $this; + } + if (!isset($this->currentTask)) { + throw new \BadMethodCallException("No such method $fn: current task undefined in collection builder."); + } + // If the method called is a method of the current task, + // then call through to the current task's setter method. + $result = call_user_func_array([$this->currentTask, $fn], $args); + + // If something other than a setter method is called, then return its result. + $currentTask = ($this->currentTask instanceof WrappedTaskInterface) ? $this->currentTask->original() : $this->currentTask; + if (isset($result) && ($result !== $currentTask)) { + return $result; + } + + return $this; + } + + /** + * Construct the desired task and add it to this builder. + * + * @param string|object $name + * @param array $args + * + * @return \Robo\Collection\CollectionBuilder + */ + public function build($name, $args) + { + $reflection = new ReflectionClass($name); + $task = $reflection->newInstanceArgs($args); + if (!$task) { + throw new RuntimeException("Can not construct task $name"); + } + $task = $this->fixTask($task, $args); + $this->configureTask($name, $task); + return $this->addTaskToCollection($task); + } + + /** + * @param InflectionInterface $task + * @param array $args + * + * @return \Robo\Collection\CompletionWrapper|\Robo\Task\Simulator + */ + protected function fixTask($task, $args) + { + if ($task instanceof InflectionInterface) { + $task->inflect($this); + } + if ($task instanceof BuilderAwareInterface) { + $task->setBuilder($this); + } + if ($task instanceof VerbosityThresholdInterface) { + $task->setVerbosityThreshold($this->verbosityThreshold()); + } + + // Do not wrap our wrappers. + if ($task instanceof CompletionWrapper || $task instanceof Simulator) { + return $task; + } + + // Remember whether or not this is a task before + // it gets wrapped in any decorator. + $isTask = $task instanceof TaskInterface; + $isCollection = $task instanceof NestedCollectionInterface; + + // If the task implements CompletionInterface, ensure + // that its 'complete' method is called when the application + // terminates -- but only if its 'run' method is called + // first. If the task is added to a collection, then the + // task will be unwrapped via its `original` method, and + // it will be re-wrapped with a new completion wrapper for + // its new collection. + if ($task instanceof CompletionInterface) { + $task = new CompletionWrapper(Temporary::getCollection(), $task); + } + + // If we are in simulated mode, then wrap any task in + // a TaskSimulator. + if ($isTask && !$isCollection && ($this->isSimulated())) { + $task = new \Robo\Task\Simulator($task, $args); + $task->inflect($this); + } + + return $task; + } + + /** + * Check to see if there are any setter methods defined in configuration + * for this task. + */ + protected function configureTask($taskClass, $task) + { + $taskClass = static::configClassIdentifier($taskClass); + $configurationApplier = new ConfigForSetters($this->getConfig(), $taskClass, 'task.'); + $configurationApplier->apply($task, 'settings'); + + // TODO: If we counted each instance of $taskClass that was called from + // this builder, then we could also apply configuration from + // "task.{$taskClass}[$N].settings" + + // TODO: If the builder knew what the current command name was, + // then we could also search for task configuration under + // command-specific keys such as "command.{$commandname}.task.{$taskClass}.settings". + } + + /** + * When we run the collection builder, run everything in the collection. + * + * @return \Robo\Result + */ + public function run() + { + $this->startTimer(); + $result = $this->runTasks(); + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + $result->mergeData($this->getState()->getData()); + return $result; + } + + /** + * If there is a single task, run it; if there is a collection, run + * all of its tasks. + * + * @return \Robo\Result + */ + protected function runTasks() + { + if (!$this->collection && $this->currentTask) { + $result = $this->currentTask->run(); + return Result::ensureResult($this->currentTask, $result); + } + return $this->getCollection()->run(); + } + + /** + * @return string + */ + public function getCommand() + { + if (!$this->collection && $this->currentTask) { + $task = $this->currentTask; + $task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + if ($task instanceof CommandInterface) { + return $task->getCommand(); + } + } + + return $this->getCollection()->getCommand(); + } + + /** + * @return \Robo\Collection\Collection + */ + public function original() + { + return $this->getCollection(); + } + + /** + * Return the collection of tasks associated with this builder. + * + * @return CollectionInterface + */ + public function getCollection() + { + if (!isset($this->collection)) { + $this->collection = new Collection(); + $this->collection->inflect($this); + $this->collection->setState($this->getState()); + $this->collection->setProgressBarAutoDisplayInterval($this->getConfig()->get(Config::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL)); + + if (isset($this->currentTask)) { + $this->collection->add($this->currentTask); + } + } + return $this->collection; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionInterface.php new file mode 100644 index 00000000..173ca169 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CollectionInterface.php @@ -0,0 +1,151 @@ +run(); + } catch (\Exception $e) { + return Result::fromException($result, $e); + } + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CompletionWrapper.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CompletionWrapper.php new file mode 100644 index 00000000..3e81bd91 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/CompletionWrapper.php @@ -0,0 +1,106 @@ +collection = $collection; + $this->task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->rollbackTask = $rollbackTask; + } + + /** + * {@inheritdoc} + */ + public function original() + { + return $this->task; + } + + /** + * Before running this task, register its rollback and completion + * handlers on its collection. The reason this class exists is to + * defer registration of rollback and completion tasks until 'run()' time. + * + * @return \Robo\Result + */ + public function run() + { + if ($this->rollbackTask) { + $this->collection->registerRollback($this->rollbackTask); + } + if ($this->task instanceof RollbackInterface) { + $this->collection->registerRollback(new CallableTask([$this->task, 'rollback'], $this->task)); + } + if ($this->task instanceof CompletionInterface) { + $this->collection->registerCompletion(new CallableTask([$this->task, 'complete'], $this->task)); + } + + return $this->task->run(); + } + + /** + * Make this wrapper object act like the class it wraps. + * + * @param string $function + * @param array $args + * + * @return mixed + */ + public function __call($function, $args) + { + return call_user_func_array(array($this->task, $function), $args); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Element.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Element.php new file mode 100644 index 00000000..b67b56bb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Element.php @@ -0,0 +1,116 @@ +task = $task; + } + + /** + * @param mixed $before + * @param string $name + */ + public function before($before, $name) + { + if ($name) { + $this->before[$name] = $before; + } else { + $this->before[] = $before; + } + } + + /** + * @param mixed $after + * @param string $name + */ + public function after($after, $name) + { + if ($name) { + $this->after[$name] = $after; + } else { + $this->after[] = $after; + } + } + + /** + * @return array + */ + public function getBefore() + { + return $this->before; + } + + /** + * @return array + */ + public function getAfter() + { + return $this->after; + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function getTask() + { + return $this->task; + } + + /** + * @return array + */ + public function getTaskList() + { + return array_merge($this->getBefore(), [$this->getTask()], $this->getAfter()); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + $steps = 0; + foreach ($this->getTaskList() as $task) { + if ($task instanceof WrappedTaskInterface) { + $task = $task->original(); + } + // If the task is a ProgressIndicatorAwareInterface, then it + // will advance the progress indicator a number of times. + if ($task instanceof ProgressIndicatorAwareInterface) { + $steps += $task->progressIndicatorSteps(); + } + // We also advance the progress indicator once regardless + // of whether it is progress-indicator aware or not. + $steps++; + } + return $steps; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/NestedCollectionInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/NestedCollectionInterface.php new file mode 100644 index 00000000..5e32cf37 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/NestedCollectionInterface.php @@ -0,0 +1,12 @@ +iterable = $iterable; + } + + /** + * @param string $message + * @param array $context + * + * @return $this + */ + public function iterationMessage($message, $context = []) + { + $this->message = $message; + $this->context = $context + ['name' => 'Progress']; + return $this; + } + + /** + * @param int|string $key + * @param mixed $value + */ + protected function showIterationMessage($key, $value) + { + if ($this->message) { + $context = ['key' => $key, 'value' => $value]; + $context += $this->context; + $context += TaskInfo::getTaskContext($this); + $this->printTaskInfo($this->message, $context); + } + } + + /** + * @param callable $fn + * + * @return $this + */ + public function withEachKeyValueCall(callable $fn) + { + $this->functionStack[] = $fn; + return $this; + } + + /** + * @param callable $fn + * + * @return \Robo\Collection\TaskForEach + */ + public function call(callable $fn) + { + return $this->withEachKeyValueCall( + function ($key, $value) use ($fn) { + return call_user_func($fn, $value); + } + ); + } + + /** + * @param callable $fn + * + * @return \Robo\Collection\TaskForEach + */ + public function withBuilder(callable $fn) + { + $this->countingStack[] = + function ($key, $value) use ($fn) { + // Create a new builder for every iteration + $builder = $this->collectionBuilder(); + // The user function should build task operations using + // the $key / $value parameters; we will call run() on + // the builder thus constructed. + call_user_func($fn, $builder, $key, $value); + return $builder->getCollection()->progressIndicatorSteps(); + }; + return $this->withEachKeyValueCall( + function ($key, $value) use ($fn) { + // Create a new builder for every iteration + $builder = $this->collectionBuilder() + ->setParentCollection($this->parentCollection); + // The user function should build task operations using + // the $key / $value parameters; we will call run() on + // the builder thus constructed. + call_user_func($fn, $builder, $key, $value); + return $builder->run(); + } + ); + } + + /** + * {@inheritdoc} + */ + public function setParentCollection(NestedCollectionInterface $parentCollection) + { + $this->parentCollection = $parentCollection; + return $this; + } + + /** + * {@inheritdoc} + */ + public function progressIndicatorSteps() + { + $multiplier = count($this->functionStack); + if (!empty($this->countingStack)) { + $value = reset($this->iterable); + $key = key($this->iterable); + foreach ($this->countingStack as $fn) { + $multiplier += call_user_func($fn, $key, $value); + } + } + return count($this->iterable) * $multiplier; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $finalResult = Result::success($this); + $this->startProgressIndicator(); + foreach ($this->iterable as $key => $value) { + $this->showIterationMessage($key, $value); + try { + foreach ($this->functionStack as $fn) { + $result = call_user_func($fn, $key, $value); + $this->advanceProgressIndicator(); + if (!isset($result)) { + $result = Result::success($this); + } + // If the function returns a result, it must either return + // a \Robo\Result or an exit code. In the later case, we + // convert it to a \Robo\Result. + if (!$result instanceof Result) { + $result = new Result($this, $result); + } + if (!$result->wasSuccessful()) { + return $result; + } + $finalResult = $result->merge($finalResult); + } + } catch (\Exception $e) { + return Result::fromException($result, $e); + } + } + $this->stopProgressIndicator(); + return $finalResult; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Temporary.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Temporary.php new file mode 100644 index 00000000..dad25e34 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/Temporary.php @@ -0,0 +1,57 @@ +get('collection'); + register_shutdown_function(function () { + static::complete(); + }); + } + + return static::$collection; + } + + /** + * Call the complete method of all of the registered objects. + */ + public static function complete() + { + // Run the collection of tasks. This will also run the + // completion tasks. + $collection = static::getCollection(); + $collection->run(); + // Make sure that our completion functions do not run twice. + $collection->reset(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/loadTasks.php new file mode 100644 index 00000000..03f68823 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Collection/loadTasks.php @@ -0,0 +1,17 @@ +task(TaskForEach::class, $collection); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/BuilderAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/BuilderAwareTrait.php new file mode 100644 index 00000000..915ff008 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/BuilderAwareTrait.php @@ -0,0 +1,45 @@ +builder = $builder; + + return $this; + } + + /** + * @see \Robo\Contract\BuilderAwareInterface::getBuilder() + * + * @return \Robo\Collection\CollectionBuilder + */ + public function getBuilder() + { + return $this->builder; + } + + /** + * @return \Robo\Collection\CollectionBuilder + */ + protected function collectionBuilder() + { + return $this->getBuilder()->newBuilder(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/CommandArguments.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/CommandArguments.php new file mode 100644 index 00000000..12c2e89f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/CommandArguments.php @@ -0,0 +1,130 @@ +args($arg); + } + + /** + * Pass methods parameters as arguments to executable. Argument values + * are automatically escaped. + * + * @param string|string[] $args + * + * @return $this + */ + public function args($args) + { + if (!is_array($args)) { + $args = func_get_args(); + } + $this->arguments .= ' ' . implode(' ', array_map('static::escape', $args)); + return $this; + } + + /** + * Pass the provided string in its raw (as provided) form as an argument to executable. + * + * @param string $arg + * + * @return $this + */ + public function rawArg($arg) + { + $this->arguments .= " $arg"; + + return $this; + } + + /** + * Escape the provided value, unless it contains only alphanumeric + * plus a few other basic characters. + * + * @param string $value + * + * @return string + */ + public static function escape($value) + { + if (preg_match('/^[a-zA-Z0-9\/\.@~_-]+$/', $value)) { + return $value; + } + return ProcessUtils::escapeArgument($value); + } + + /** + * Pass option to executable. Options are prefixed with `--` , value can be provided in second parameter. + * Option values are automatically escaped. + * + * @param string $option + * @param string $value + * @param string $separator + * + * @return $this + */ + public function option($option, $value = null, $separator = ' ') + { + if ($option !== null and strpos($option, '-') !== 0) { + $option = "--$option"; + } + $this->arguments .= null == $option ? '' : " " . $option; + $this->arguments .= null == $value ? '' : $separator . static::escape($value); + return $this; + } + + /** + * Pass multiple options to executable. The associative array contains + * the key:value pairs that become `--key value`, for each item in the array. + * Values are automatically escaped. + */ + public function options(array $options, $separator = ' ') + { + foreach ($options as $option => $value) { + $this->option($option, $value, $separator); + } + return $this; + } + + /** + * Pass an option with multiple values to executable. Value can be a string or array. + * Option values are automatically escaped. + * + * @param string $option + * @param string|array $value + * @param string $separator + * + * @return $this + */ + public function optionList($option, $value = array(), $separator = ' ') + { + if (is_array($value)) { + foreach ($value as $item) { + $this->optionList($option, $item, $separator); + } + } else { + $this->option($option, $value, $separator); + } + + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/CommandReceiver.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/CommandReceiver.php new file mode 100644 index 00000000..03b20fce --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/CommandReceiver.php @@ -0,0 +1,30 @@ +getCommand(); + } else { + throw new TaskException($this, get_class($command) . " does not implement CommandInterface, so can't be passed into this task"); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ConfigAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ConfigAwareTrait.php new file mode 100644 index 00000000..d6d45788 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ConfigAwareTrait.php @@ -0,0 +1,109 @@ +config = $config; + + return $this; + } + + /** + * Get the config management object. + * + * @return ConfigInterface + * + * @see \Robo\Contract\ConfigAwareInterface::getConfig() + */ + public function getConfig() + { + return $this->config; + } + + /** + * Any class that uses ConfigAwareTrait SHOULD override this method + * , and define a prefix for its configuration items. This is usually + * done in a base class. When used, this method should return a string + * that ends with a "."; see BaseTask::configPrefix(). + * + * @return string + */ + protected static function configPrefix() + { + return ''; + } + + protected static function configClassIdentifier($classname) + { + $configIdentifier = strtr($classname, '\\', '.'); + $configIdentifier = preg_replace('#^(.*\.Task\.|\.)#', '', $configIdentifier); + + return $configIdentifier; + } + + protected static function configPostfix() + { + return ''; + } + + /** + * @param string $key + * + * @return string + */ + private static function getClassKey($key) + { + $configPrefix = static::configPrefix(); // task. + $configClass = static::configClassIdentifier(get_called_class()); // PARTIAL_NAMESPACE.CLASSNAME + $configPostFix = static::configPostfix(); // .settings + + return sprintf('%s%s%s.%s', $configPrefix, $configClass, $configPostFix, $key); + } + + /** + * @param string $key + * @param mixed $value + * @param Config|null $config + */ + public static function configure($key, $value, $config = null) + { + if (!$config) { + $config = Robo::config(); + } + $config->setDefault(static::getClassKey($key), $value); + } + + /** + * @param string $key + * @param mixed|null $default + * + * @return mixed|null + */ + protected function getConfigValue($key, $default = null) + { + if (!$this->getConfig()) { + return $default; + } + return $this->getConfig()->get(static::getClassKey($key), $default); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/DynamicParams.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/DynamicParams.php new file mode 100644 index 00000000..28a1d150 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/DynamicParams.php @@ -0,0 +1,45 @@ +$property))) { + $this->$property = !$this->$property; + return $this; + } + + // append item to array + if (is_array($this->$property)) { + if (is_array($args[0])) { + $this->$property = $args[0]; + } else { + array_push($this->$property, $args[0]); + } + return $this; + } + + $this->$property = $args[0]; + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecCommand.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecCommand.php new file mode 100644 index 00000000..c3e6c3af --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecCommand.php @@ -0,0 +1,148 @@ +execTimer)) { + $this->execTimer = new TimeKeeper(); + } + return $this->execTimer; + } + + /** + * Look for a "{$cmd}.phar" in the current working + * directory; return a string to exec it if it is + * found. Otherwise, look for an executable command + * of the same name via findExecutable. + * + * @param string $cmd + * + * @return bool|string + */ + protected function findExecutablePhar($cmd) + { + if (file_exists("{$cmd}.phar")) { + return "php {$cmd}.phar"; + } + return $this->findExecutable($cmd); + } + + /** + * Return the best path to the executable program + * with the provided name. Favor vendor/bin in the + * current project. If not found there, use + * whatever is on the $PATH. + * + * @param string $cmd + * + * @return bool|string + */ + protected function findExecutable($cmd) + { + $pathToCmd = $this->searchForExecutable($cmd); + if ($pathToCmd) { + return $this->useCallOnWindows($pathToCmd); + } + return false; + } + + /** + * @param string $cmd + * + * @return string + */ + private function searchForExecutable($cmd) + { + $projectBin = $this->findProjectBin(); + + $localComposerInstallation = $projectBin . DIRECTORY_SEPARATOR . $cmd; + if (file_exists($localComposerInstallation)) { + return $localComposerInstallation; + } + $finder = new ExecutableFinder(); + return $finder->find($cmd, null, []); + } + + /** + * @return bool|string + */ + protected function findProjectBin() + { + $cwd = getcwd(); + $candidates = [ __DIR__ . '/../../vendor/bin', __DIR__ . '/../../bin', $cwd . '/vendor/bin' ]; + + // If this project is inside a vendor directory, give highest priority + // to that directory. + $vendorDirContainingUs = realpath(__DIR__ . '/../../../..'); + if (is_dir($vendorDirContainingUs) && (basename($vendorDirContainingUs) == 'vendor')) { + array_unshift($candidates, $vendorDirContainingUs . '/bin'); + } + + foreach ($candidates as $dir) { + if (is_dir("$dir")) { + return realpath($dir); + } + } + return false; + } + + /** + * Wrap Windows executables in 'call' per 7a88757d + * + * @param string $cmd + * + * @return string + */ + protected function useCallOnWindows($cmd) + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + if (file_exists("{$cmd}.bat")) { + $cmd = "{$cmd}.bat"; + } + return "call $cmd"; + } + return $cmd; + } + + protected function getCommandDescription() + { + return $this->process->getCommandLine(); + } + + /** + * @param string $command + * + * @return \Robo\Result + */ + protected function executeCommand($command) + { + // TODO: Symfony 4 requires that we supply the working directory. + $result_data = $this->execute(new Process($command, getcwd())); + return new Result( + $this, + $result_data->getExitCode(), + $result_data->getMessage(), + $result_data->getData() + ); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecOneCommand.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecOneCommand.php new file mode 100644 index 00000000..60137514 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ExecOneCommand.php @@ -0,0 +1,12 @@ +interactive() based on posix_isatty(). + * + * @return $this + */ + public function detectInteractive() + { + // If the caller did not explicity set the 'interactive' mode, + // and output should be produced by this task (verbosityMeetsThreshold), + // then we will automatically set interactive mode based on whether + // or not output was redirected when robo was executed. + if (!isset($this->interactive) && function_exists('posix_isatty') && $this->verbosityMeetsThreshold()) { + $this->interactive = posix_isatty(STDOUT); + } + + return $this; + } + + /** + * Executes command in background mode (asynchronously) + * + * @return $this + */ + public function background($arg = true) + { + $this->background = $arg; + return $this; + } + + /** + * Stop command if it runs longer then $timeout in seconds + * + * @param int $timeout + * + * @return $this + */ + public function timeout($timeout) + { + $this->timeout = $timeout; + return $this; + } + + /** + * Stops command if it does not output something for a while + * + * @param int $timeout + * + * @return $this + */ + public function idleTimeout($timeout) + { + $this->idleTimeout = $timeout; + return $this; + } + + /** + * Set a single environment variable, or multiple. + */ + public function env($env, $value = null) + { + if (!is_array($env)) { + $env = [$env => ($value ? $value : true)]; + } + return $this->envVars($env); + } + + /** + * Sets the environment variables for the command + * + * @param array $env + * + * @return $this + */ + public function envVars(array $env) + { + $this->env = $env; + return $this; + } + + /** + * Pass an input to the process. Can be resource created with fopen() or string + * + * @param resource|string $input + * + * @return $this + */ + public function setInput($input) + { + $this->input = $input; + return $this; + } + + /** + * Attach tty to process for interactive input + * + * @param $interactive bool + * + * @return $this + */ + public function interactive($interactive = true) + { + $this->interactive = $interactive; + return $this; + } + + + /** + * Is command printing its output to screen + * + * @return bool + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * Changes working directory of command + * + * @param string $dir + * + * @return $this + */ + public function dir($dir) + { + $this->workingDirectory = $dir; + return $this; + } + + /** + * Shortcut for setting isPrinted() and isMetadataPrinted() to false. + * + * @param bool $arg + * + * @return $this + */ + public function silent($arg) + { + if (is_bool($arg)) { + $this->isPrinted = !$arg; + $this->isMetadataPrinted = !$arg; + } + return $this; + } + + /** + * Should command output be printed + * + * @param bool $arg + * + * @return $this + * + * @deprecated + */ + public function printed($arg) + { + $this->logger->warning("printed() is deprecated. Please use printOutput()."); + return $this->printOutput($arg); + } + + /** + * Should command output be printed + * + * @param bool $arg + * + * @return $this + */ + public function printOutput($arg) + { + if (is_bool($arg)) { + $this->isPrinted = $arg; + } + return $this; + } + + /** + * Should command metadata be printed. I,e., command and timer. + * + * @param bool $arg + * + * @return $this + */ + public function printMetadata($arg) + { + if (is_bool($arg)) { + $this->isMetadataPrinted = $arg; + } + return $this; + } + + /** + * @param Process $process + * @param callable $output_callback + * + * @return \Robo\ResultData + */ + protected function execute($process, $output_callback = null) + { + $this->process = $process; + + if (!$output_callback) { + $output_callback = function ($type, $buffer) { + $progressWasVisible = $this->hideTaskProgress(); + $this->writeMessage($buffer); + $this->showTaskProgress($progressWasVisible); + }; + } + + $this->detectInteractive(); + + if ($this->isMetadataPrinted) { + $this->printAction(); + } + $this->process->setTimeout($this->timeout); + $this->process->setIdleTimeout($this->idleTimeout); + if ($this->workingDirectory) { + $this->process->setWorkingDirectory($this->workingDirectory); + } + if ($this->input) { + $this->process->setInput($this->input); + } + + if ($this->interactive && $this->isPrinted) { + $this->process->setTty(true); + } + + if (isset($this->env)) { + $this->process->setEnv($this->env); + } + + if (!$this->background && !$this->isPrinted) { + $this->startTimer(); + $this->process->run(); + $this->stopTimer(); + $output = rtrim($this->process->getOutput()); + return new ResultData( + $this->process->getExitCode(), + $output, + $this->getResultData() + ); + } + + if (!$this->background && $this->isPrinted) { + $this->startTimer(); + $this->process->run($output_callback); + $this->stopTimer(); + return new ResultData( + $this->process->getExitCode(), + $this->process->getOutput(), + $this->getResultData() + ); + } + + try { + $this->process->start(); + } catch (\Exception $e) { + return new ResultData( + $this->process->getExitCode(), + $e->getMessage(), + $this->getResultData() + ); + } + return new ResultData($this->process->getExitCode()); + } + + /** + * + */ + protected function stop() + { + if ($this->background && isset($this->process) && $this->process->isRunning()) { + $this->process->stop(); + $this->printTaskInfo( + "Stopped {command}", + ['command' => $this->getCommandDescription()] + ); + } + } + + /** + * @param array $context + */ + protected function printAction($context = []) + { + $command = $this->getCommandDescription(); + $formatted_command = $this->formatCommandDisplay($command); + + $dir = $this->workingDirectory ? " in {dir}" : ""; + $this->printTaskInfo("Running {command}$dir", [ + 'command' => $formatted_command, + 'dir' => $this->workingDirectory + ] + $context); + } + + /** + * @param $command + * + * @return mixed + */ + protected function formatCommandDisplay($command) + { + $formatted_command = str_replace("&&", "&&\n", $command); + $formatted_command = str_replace("||", "||\n", $formatted_command); + + return $formatted_command; + } + + /** + * Gets the data array to be passed to Result(). + * + * @return array + * The data array passed to Result(). + */ + protected function getResultData() + { + if ($this->isMetadataPrinted) { + return ['time' => $this->getExecutionTime()]; + } + + return []; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/IO.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/IO.php new file mode 100644 index 00000000..d6c77bff --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/IO.php @@ -0,0 +1,171 @@ +io) { + $this->io = new SymfonyStyle($this->input(), $this->output()); + } + return $this->io; + } + + /** + * @param string $nonDecorated + * @param string $decorated + * + * @return string + */ + protected function decorationCharacter($nonDecorated, $decorated) + { + if (!$this->output()->isDecorated() || (strncasecmp(PHP_OS, 'WIN', 3) == 0)) { + return $nonDecorated; + } + return $decorated; + } + + /** + * @param string $text + */ + protected function say($text) + { + $char = $this->decorationCharacter('>', '➜'); + $this->writeln("$char $text"); + } + + /** + * @param string $text + * @param int $length + * @param string $color + */ + protected function yell($text, $length = 40, $color = 'green') + { + $char = $this->decorationCharacter(' ', '➜'); + $format = "$char %s"; + $this->formattedOutput($text, $length, $format); + } + + /** + * @param string $text + * @param int $length + * @param string $format + */ + protected function formattedOutput($text, $length, $format) + { + $lines = explode("\n", trim($text, "\n")); + $maxLineLength = array_reduce(array_map('strlen', $lines), 'max'); + $length = max($length, $maxLineLength); + $len = $length + 2; + $space = str_repeat(' ', $len); + $this->writeln(sprintf($format, $space)); + foreach ($lines as $line) { + $line = str_pad($line, $length, ' ', STR_PAD_BOTH); + $this->writeln(sprintf($format, " $line ")); + } + $this->writeln(sprintf($format, $space)); + } + + /** + * @param string $question + * @param bool $hideAnswer + * + * @return string + */ + protected function ask($question, $hideAnswer = false) + { + if ($hideAnswer) { + return $this->askHidden($question); + } + return $this->doAsk(new Question($this->formatQuestion($question))); + } + + /** + * @param string $question + * + * @return string + */ + protected function askHidden($question) + { + $question = new Question($this->formatQuestion($question)); + $question->setHidden(true); + return $this->doAsk($question); + } + + /** + * @param string $question + * @param string $default + * + * @return string + */ + protected function askDefault($question, $default) + { + return $this->doAsk(new Question($this->formatQuestion("$question [$default]"), $default)); + } + + /** + * @param string $question + * + * @return string + */ + protected function confirm($question) + { + return $this->doAsk(new ConfirmationQuestion($this->formatQuestion($question . ' (y/n)'), false)); + } + + /** + * @param \Symfony\Component\Console\Question\Question $question + * + * @return string + */ + protected function doAsk(Question $question) + { + return $this->getDialog()->ask($this->input(), $this->output(), $question); + } + + /** + * @param string $message + * + * @return string + */ + protected function formatQuestion($message) + { + return "? $message "; + } + + /** + * @return \Symfony\Component\Console\Helper\QuestionHelper + */ + protected function getDialog() + { + return new QuestionHelper(); + } + + /** + * @param $text + */ + protected function writeln($text) + { + $this->output()->writeln($text); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/InflectionTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/InflectionTrait.php new file mode 100644 index 00000000..8bc4e831 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/InflectionTrait.php @@ -0,0 +1,21 @@ +injectDependencies($this); + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/InputAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/InputAwareTrait.php new file mode 100644 index 00000000..bae58c17 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/InputAwareTrait.php @@ -0,0 +1,51 @@ +input = $input; + + return $this; + } + + /** + * @return \Symfony\Component\Console\Input\InputInterface + */ + protected function input() + { + if (!isset($this->input)) { + $this->setInput(new ArgvInput()); + } + return $this->input; + } + + /** + * Backwards compatibility. + * + * @return \Symfony\Component\Console\Input\InputInterface + * + * @deprecated + */ + protected function getInput() + { + return $this->input(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/OutputAdapter.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/OutputAdapter.php new file mode 100644 index 00000000..b8e795f2 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/OutputAdapter.php @@ -0,0 +1,38 @@ + OutputInterface::VERBOSITY_NORMAL, + VerbosityThresholdInterface::VERBOSITY_VERBOSE => OutputInterface::VERBOSITY_VERBOSE, + VerbosityThresholdInterface::VERBOSITY_VERY_VERBOSE => OutputInterface::VERBOSITY_VERY_VERBOSE, + VerbosityThresholdInterface::VERBOSITY_DEBUG => OutputInterface::VERBOSITY_DEBUG, + ]; + + public function verbosityMeetsThreshold($verbosityThreshold) + { + if (!isset($this->verbosityMap[$verbosityThreshold])) { + return true; + } + $verbosityThreshold = $this->verbosityMap[$verbosityThreshold]; + $verbosity = $this->output()->getVerbosity(); + + return $verbosity >= $verbosityThreshold; + } + + public function writeMessage($message) + { + $this->output()->write($message); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/OutputAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/OutputAwareTrait.php new file mode 100644 index 00000000..48082cb3 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/OutputAwareTrait.php @@ -0,0 +1,51 @@ +output = $output; + + return $this; + } + + /** + * @return \Symfony\Component\Console\Output\OutputInterface + */ + protected function output() + { + if (!isset($this->output)) { + $this->setOutput(new NullOutput()); + } + return $this->output; + } + + /** + * Backwards compatibility + * + * @return \Symfony\Component\Console\Output\OutputInterface + * + * @deprecated + */ + protected function getOutput() + { + return $this->output(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProcessExecutor.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProcessExecutor.php new file mode 100644 index 00000000..f78a4775 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProcessExecutor.php @@ -0,0 +1,51 @@ +process = $process; + } + + public static function create($container, $process) + { + $processExecutor = new self($process); + + $processExecutor->setLogger($container->get('logger')); + $processExecutor->setProgressIndicator($container->get('progressIndicator')); + $processExecutor->setConfig($container->get('config')); + $processExecutor->setOutputAdapter($container->get('outputAdapter')); + + return $processExecutor; + } + + /** + * @return string + */ + protected function getCommandDescription() + { + return $this->process->getCommandLine(); + } + + public function run() + { + return $this->execute($this->process); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProcessUtils.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProcessUtils.php new file mode 100644 index 00000000..7dc4e553 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProcessUtils.php @@ -0,0 +1,79 @@ + + */ + +namespace Robo\Common; + +use Symfony\Component\Process\Exception\InvalidArgumentException; + +/** + * ProcessUtils is a bunch of utility methods. We want to allow Robo 1.x + * to work with Symfony 4.x while remaining backwards compatibility. This + * requires us to replace some deprecated functionality removed in Symfony. + */ +class ProcessUtils +{ + /** + * This class should not be instantiated. + */ + private function __construct() + { + } + + /** + * Escapes a string to be used as a shell argument. + * + * @param string $argument The argument that will be escaped + * + * @return string The escaped argument + * + * @deprecated since version 3.3, to be removed in 4.0. Use a command line array or give env vars to the `Process::start/run()` method instead. + */ + public static function escapeArgument($argument) + { + @trigger_error('The '.__METHOD__.'() method is a copy of a method that was deprecated by Symfony 3.3 and removed in Symfony 4; it will be removed in Robo 2.0.', E_USER_DEPRECATED); + + //Fix for PHP bug #43784 escapeshellarg removes % from given string + //Fix for PHP bug #49446 escapeshellarg doesn't work on Windows + //@see https://bugs.php.net/bug.php?id=43784 + //@see https://bugs.php.net/bug.php?id=49446 + if ('\\' === DIRECTORY_SEPARATOR) { + if ('' === $argument) { + return escapeshellarg($argument); + } + + $escapedArgument = ''; + $quote = false; + foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) { + if ('"' === $part) { + $escapedArgument .= '\\"'; + } elseif (self::isSurroundedBy($part, '%')) { + // Avoid environment variable expansion + $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%'; + } else { + // escape trailing backslash + if ('\\' === substr($part, -1)) { + $part .= '\\'; + } + $quote = true; + $escapedArgument .= $part; + } + } + if ($quote) { + $escapedArgument = '"'.$escapedArgument.'"'; + } + + return $escapedArgument; + } + + return "'".str_replace("'", "'\\''", $argument)."'"; + } + + private static function isSurroundedBy($arg, $char) + { + return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1]; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProgressIndicator.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProgressIndicator.php new file mode 100644 index 00000000..050250e5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProgressIndicator.php @@ -0,0 +1,201 @@ +progressBar = $progressBar; + $this->output = $output; + } + + /** + * @param int $interval + */ + public function setProgressBarAutoDisplayInterval($interval) + { + if ($this->progressIndicatorRunning) { + return; + } + $this->autoDisplayInterval = $interval; + } + + /** + * @return bool + */ + public function hideProgressIndicator() + { + $result = $this->progressBarDisplayed; + if ($this->progressIndicatorRunning && $this->progressBarDisplayed) { + $this->progressBar->clear(); + // Hack: progress indicator does not reset cursor to beginning of line on 'clear' + $this->output->write("\x0D"); + $this->progressBarDisplayed = false; + } + return $result; + } + + public function showProgressIndicator() + { + if ($this->progressIndicatorRunning && !$this->progressBarDisplayed && isset($this->progressBar)) { + $this->progressBar->display(); + $this->progressBarDisplayed = true; + $this->advanceProgressIndicatorCachedSteps(); + } + } + + /** + * @param bool $visible + */ + public function restoreProgressIndicator($visible) + { + if ($visible) { + $this->showProgressIndicator(); + } + } + + /** + * @param int $totalSteps + * @param \Robo\Contract\TaskInterface $owner + */ + public function startProgressIndicator($totalSteps, $owner) + { + if (!isset($this->progressBar)) { + return; + } + + $this->progressIndicatorRunning = true; + if (!isset($this->owner)) { + $this->owner = $owner; + $this->startTimer(); + $this->totalSteps = $totalSteps; + $this->autoShowProgressIndicator(); + } + } + + public function autoShowProgressIndicator() + { + if (($this->autoDisplayInterval < 0) || !isset($this->progressBar) || !$this->output->isDecorated()) { + return; + } + if ($this->autoDisplayInterval <= $this->getExecutionTime()) { + $this->autoDisplayInterval = -1; + $this->progressBar->start($this->totalSteps); + $this->showProgressIndicator(); + } + } + + /** + * @return bool + */ + public function inProgress() + { + return $this->progressIndicatorRunning; + } + + /** + * @param \Robo\Contract\TaskInterface $owner + */ + public function stopProgressIndicator($owner) + { + if ($this->progressIndicatorRunning && ($this->owner === $owner)) { + $this->cleanup(); + } + } + + protected function cleanup() + { + $this->progressIndicatorRunning = false; + $this->owner = null; + if ($this->progressBarDisplayed) { + $this->progressBar->finish(); + // Hack: progress indicator does not always finish cleanly + $this->output->writeln(''); + $this->progressBarDisplayed = false; + } + $this->stopTimer(); + } + + /** + * Erase progress indicator and ensure it never returns. Used + * only during error handlers. + */ + public function disableProgressIndicator() + { + $this->cleanup(); + // ProgressIndicator is shared, so this permanently removes + // the program's ability to display progress bars. + $this->progressBar = null; + } + + /** + * @param int $steps + */ + public function advanceProgressIndicator($steps = 1) + { + $this->cachedSteps += $steps; + if ($this->progressIndicatorRunning) { + $this->autoShowProgressIndicator(); + // We only want to call `advance` if the progress bar is visible, + // because it always displays itself when it is advanced. + if ($this->progressBarDisplayed) { + return $this->advanceProgressIndicatorCachedSteps(); + } + } + } + + protected function advanceProgressIndicatorCachedSteps() + { + $this->progressBar->advance($this->cachedSteps); + $this->cachedSteps = 0; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProgressIndicatorAwareTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProgressIndicatorAwareTrait.php new file mode 100644 index 00000000..060e039a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ProgressIndicatorAwareTrait.php @@ -0,0 +1,135 @@ +progressIndicator = $progressIndicator; + + return $this; + } + + /** + * @return null|bool + */ + protected function hideProgressIndicator() + { + if (!$this->progressIndicator) { + return; + } + return $this->progressIndicator->hideProgressIndicator(); + } + + protected function showProgressIndicator() + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->showProgressIndicator(); + } + + /** + * @param bool $visible + */ + protected function restoreProgressIndicator($visible) + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->restoreProgressIndicator($visible); + } + + /** + * @return int + */ + protected function getTotalExecutionTime() + { + if (!$this->progressIndicator) { + return 0; + } + return $this->progressIndicator->getExecutionTime(); + } + + protected function startProgressIndicator() + { + $this->startTimer(); + if ($this instanceof VerbosityThresholdInterface + && !$this->verbosityMeetsThreshold()) { + return; + } + if (!$this->progressIndicator) { + return; + } + $totalSteps = $this->progressIndicatorSteps(); + $this->progressIndicator->startProgressIndicator($totalSteps, $this); + } + + /** + * @return bool + */ + protected function inProgress() + { + if (!$this->progressIndicator) { + return false; + } + return $this->progressIndicator->inProgress(); + } + + protected function stopProgressIndicator() + { + $this->stopTimer(); + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->stopProgressIndicator($this); + } + + protected function disableProgressIndicator() + { + $this->stopTimer(); + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->disableProgressIndicator(); + } + + protected function detatchProgressIndicator() + { + $this->setProgressIndicator(null); + } + + /** + * @param int $steps + */ + protected function advanceProgressIndicator($steps = 1) + { + if (!$this->progressIndicator) { + return; + } + $this->progressIndicator->advanceProgressIndicator($steps); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ResourceExistenceChecker.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ResourceExistenceChecker.php new file mode 100644 index 00000000..233f90a9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/ResourceExistenceChecker.php @@ -0,0 +1,116 @@ +printTaskError(sprintf('Invalid glob "%s"!', $resource), $this); + $success = false; + continue; + } + foreach ($glob as $resource) { + if (!$this->checkResource($resource, $type)) { + $success = false; + } + } + } + return $success; + } + + /** + * Checks a single resource, file or directory. + * + * It will print an error as well on the console. + * + * @param string $resource File or folder. + * @param string $type "file", "dir", "fileAndDir" + * + * @return bool + */ + protected function checkResource($resource, $type) + { + switch ($type) { + case 'file': + if (!$this->isFile($resource)) { + $this->printTaskError(sprintf('File "%s" does not exist!', $resource), $this); + return false; + } + return true; + case 'dir': + if (!$this->isDir($resource)) { + $this->printTaskError(sprintf('Directory "%s" does not exist!', $resource), $this); + return false; + } + return true; + case 'fileAndDir': + if (!$this->isDir($resource) && !$this->isFile($resource)) { + $this->printTaskError(sprintf('File or directory "%s" does not exist!', $resource), $this); + return false; + } + return true; + } + } + + /** + * Convenience method to check the often uses "source => target" file / folder arrays. + * + * @param string|array $resources + */ + protected function checkSourceAndTargetResource($resources) + { + if (is_string($resources)) { + $resources = [$resources]; + } + $sources = []; + $targets = []; + foreach ($resources as $source => $target) { + $sources[] = $source; + $target[] = $target; + } + $this->checkResources($sources); + $this->checkResources($targets); + } + + /** + * Wrapper method around phps is_dir() + * + * @param string $directory + * + * @return bool + */ + protected function isDir($directory) + { + return is_dir($directory); + } + + /** + * Wrapper method around phps file_exists() + * + * @param string $file + * + * @return bool + */ + protected function isFile($file) + { + return file_exists($file); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/TaskIO.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/TaskIO.php new file mode 100644 index 00000000..49b5ccd8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/TaskIO.php @@ -0,0 +1,237 @@ +logger should always be set in Robo core tasks. + if ($this->logger) { + return $this->logger; + } + + // TODO: Remove call to Robo::logger() once maintaining backwards + // compatibility with legacy external Robo tasks is no longer desired. + if (!Robo::logger()) { + return null; + } + + static $gaveDeprecationWarning = false; + if (!$gaveDeprecationWarning) { + trigger_error('No logger set for ' . get_class($this) . '. Use $this->task(Foo::class) rather than new Foo() in loadTasks to ensure the builder can initialize task the task, or use $this->collectionBuilder()->taskFoo() if creating one task from within another.', E_USER_DEPRECATED); + $gaveDeprecationWarning = true; + } + return Robo::logger(); + } + + /** + * Print information about a task in progress. + * + * With the Symfony Console logger, NOTICE is displayed at VERBOSITY_VERBOSE + * and INFO is displayed at VERBOSITY_VERY_VERBOSE. + * + * Robo overrides the default such that NOTICE is displayed at + * VERBOSITY_NORMAL and INFO is displayed at VERBOSITY_VERBOSE. + * + * n.b. We should probably have printTaskNotice for our ordinary + * output, and use printTaskInfo for less interesting messages. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskInfo($text, $context = null) + { + // The 'note' style is used for both 'notice' and 'info' log levels; + // However, 'notice' is printed at VERBOSITY_NORMAL, whereas 'info' + // is only printed at VERBOSITY_VERBOSE. + $this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that some part of the task succeeded. + * + * With the Symfony Console logger, success messages are remapped to NOTICE, + * and displayed in VERBOSITY_VERBOSE. When used with the Robo logger, + * success messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskSuccess($text, $context = null) + { + // Not all loggers will recognize ConsoleLogLevel::SUCCESS. + // We therefore log as LogLevel::NOTICE, and apply a '_level' + // override in the context so that this message will be + // logged as SUCCESS if that log level is recognized. + $context['_level'] = ConsoleLogLevel::SUCCESS; + $this->printTaskOutput(LogLevel::NOTICE, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that there is something wrong, but + * execution can continue. + * + * Warning messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskWarning($text, $context = null) + { + $this->printTaskOutput(LogLevel::WARNING, $text, $this->getTaskContext($context)); + } + + /** + * Provide notification that some operation in the task failed, + * and the task cannot continue. + * + * Error messages are displayed at VERBOSITY_NORMAL. + * + * @param string $text + * @param null|array $context + */ + protected function printTaskError($text, $context = null) + { + $this->printTaskOutput(LogLevel::ERROR, $text, $this->getTaskContext($context)); + } + + /** + * Provide debugging notification. These messages are only + * displayed if the log level is VERBOSITY_DEBUG. + * + * @param string$text + * @param null|array $context + */ + protected function printTaskDebug($text, $context = null) + { + $this->printTaskOutput(LogLevel::DEBUG, $text, $this->getTaskContext($context)); + } + + /** + * @param string $level + * One of the \Psr\Log\LogLevel constant + * @param string $text + * @param null|array $context + */ + protected function printTaskOutput($level, $text, $context) + { + if (!$this->verbosityMeetsThreshold()) { + return; + } + $logger = $this->logger(); + if (!$logger) { + return; + } + // Hide the progress indicator, if it is visible. + $inProgress = $this->hideTaskProgress(); + $logger->log($level, $text, $this->getTaskContext($context)); + // After we have printed our log message, redraw the progress indicator. + $this->showTaskProgress($inProgress); + } + + /** + * @return bool + */ + protected function hideTaskProgress() + { + $inProgress = false; + if ($this instanceof ProgressIndicatorAwareInterface) { + $inProgress = $this->inProgress(); + } + + // If a progress indicator is running on this task, then we mush + // hide it before we print anything, or its display will be overwritten. + if ($inProgress) { + $inProgress = $this->hideProgressIndicator(); + } + return $inProgress; + } + + /** + * @param $inProgress + */ + protected function showTaskProgress($inProgress) + { + if ($inProgress) { + $this->restoreProgressIndicator($inProgress); + } + } + + /** + * Format a quantity of bytes. + * + * @param int $size + * @param int $precision + * + * @return string + */ + protected function formatBytes($size, $precision = 2) + { + if ($size === 0) { + return 0; + } + $base = log($size, 1024); + $suffixes = array('', 'k', 'M', 'G', 'T'); + return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)]; + } + + /** + * Get the formatted task name for use in task output. + * This is placed in the task context under 'name', and + * used as the log label by Robo\Common\RoboLogStyle, + * which is inserted at the head of log messages by + * Robo\Common\CustomLogStyle::formatMessage(). + * + * @param null|object $task + * + * @return string + */ + protected function getPrintedTaskName($task = null) + { + if (!$task) { + $task = $this; + } + return TaskInfo::formatTaskName($task); + } + + /** + * @param null|array $context + * + * @return array with context information + */ + protected function getTaskContext($context = null) + { + if (!$context) { + $context = []; + } + if (!is_array($context)) { + $context = ['task' => $context]; + } + if (!array_key_exists('task', $context)) { + $context['task'] = $this; + } + + return $context + TaskInfo::getTaskContext($context['task']); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/TimeKeeper.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/TimeKeeper.php new file mode 100644 index 00000000..1cd3e334 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/TimeKeeper.php @@ -0,0 +1,69 @@ +startedAt) { + return; + } + // Get time in seconds as a float, accurate to the microsecond. + $this->startedAt = microtime(true); + } + + public function stop() + { + $this->finishedAt = microtime(true); + } + + /** + * @return float|null + */ + public function elapsed() + { + $finished = $this->finishedAt ? $this->finishedAt : microtime(true); + if ($finished - $this->startedAt <= 0) { + return null; + } + return $finished - $this->startedAt; + } + + /** + * Format a duration into a human-readable time + * + * @param float $duration Duration in seconds, with fractional component + * + * @return string + */ + public static function formatDuration($duration) + { + if ($duration >= self::DAY * 2) { + return gmdate('z \d\a\y\s H:i:s', $duration); + } + if ($duration > self::DAY) { + return gmdate('\1 \d\a\y H:i:s', $duration); + } + if ($duration > self::HOUR) { + return gmdate("H:i:s", $duration); + } + if ($duration > self::MINUTE) { + return gmdate("i:s", $duration); + } + return round($duration, 3).'s'; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/Timer.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/Timer.php new file mode 100644 index 00000000..955eb5bb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/Timer.php @@ -0,0 +1,37 @@ +timer)) { + $this->timer = new TimeKeeper(); + } + $this->timer->start(); + } + + protected function stopTimer() + { + if (!isset($this->timer)) { + return; + } + $this->timer->stop(); + } + + /** + * @return float|null + */ + protected function getExecutionTime() + { + if (!isset($this->timer)) { + return null; + } + return $this->timer->elapsed(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/VerbosityThresholdTrait.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/VerbosityThresholdTrait.php new file mode 100644 index 00000000..2fc51c22 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Common/VerbosityThresholdTrait.php @@ -0,0 +1,79 @@ +verbosityThreshold = $verbosityThreshold; + return $this; + } + + public function verbosityThreshold() + { + return $this->verbosityThreshold; + } + + public function setOutputAdapter(OutputAdapterInterface $outputAdapter) + { + $this->outputAdapter = $outputAdapter; + } + + /** + * @return OutputAdapterInterface + */ + public function outputAdapter() + { + return $this->outputAdapter; + } + + public function hasOutputAdapter() + { + return isset($this->outputAdapter); + } + + public function verbosityMeetsThreshold() + { + if ($this->hasOutputAdapter()) { + return $this->outputAdapter()->verbosityMeetsThreshold($this->verbosityThreshold()); + } + return true; + } + + /** + * Print a message if the selected verbosity level is over this task's + * verbosity threshhold. + */ + public function writeMessage($message) + { + if (!$this->verbosityMeetsThreshold()) { + return; + } + $this->outputAdapter()->writeMessage($message); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config.php new file mode 100644 index 00000000..9e9370d8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config.php @@ -0,0 +1,9 @@ +defaults = $this->getGlobalOptionDefaultValues(); + } + + /** + * Return an associative array containing all of the global configuration + * options and their default values. + * + * @return array + */ + public function getGlobalOptionDefaultValues() + { + $globalOptions = + [ + self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL => self::DEFAULT_PROGRESS_DELAY, + self::SIMULATE => false, + ]; + return $this->trimPrefixFromGlobalOptions($globalOptions); + } + + /** + * Remove the 'options.' prefix from the global options list. + */ + protected function trimPrefixFromGlobalOptions($globalOptions) + { + $result = []; + foreach ($globalOptions as $option => $value) { + $option = str_replace('options.', '', $option); + $result[$option] = $value; + } + return $result; + } + + /** + * @deprecated Use $config->get(Config::SIMULATE) + * + * @return bool + */ + public function isSimulated() + { + return $this->get(self::SIMULATE); + } + + /** + * @deprecated Use $config->set(Config::SIMULATE, true) + * + * @param bool $simulated + * + * @return $this + */ + public function setSimulated($simulated = true) + { + return $this->set(self::SIMULATE, $simulated); + } + + /** + * @deprecated Use $config->get(Config::INTERACTIVE) + * + * @return bool + */ + public function isInteractive() + { + return $this->get(self::INTERACTIVE); + } + + /** + * @deprecated Use $config->set(Config::INTERACTIVE, true) + * + * @param bool $interactive + * + * @return $this + */ + public function setInteractive($interactive = true) + { + return $this->set(self::INTERACTIVE, $interactive); + } + + /** + * @deprecated Use $config->get(Config::DECORATED) + * + * @return bool + */ + public function isDecorated() + { + return $this->get(self::DECORATED); + } + + /** + * @deprecated Use $config->set(Config::DECORATED, true) + * + * @param bool $decorated + * + * @return $this + */ + public function setDecorated($decorated = true) + { + return $this->set(self::DECORATED, $decorated); + } + + /** + * @deprecated Use $config->set(Config::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL, $interval) + * + * @param int $interval + * + * @return $this + */ + public function setProgressBarAutoDisplayInterval($interval) + { + return $this->set(self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL, $interval); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config/GlobalOptionDefaultValuesInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config/GlobalOptionDefaultValuesInterface.php new file mode 100644 index 00000000..f7639455 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Config/GlobalOptionDefaultValuesInterface.php @@ -0,0 +1,17 @@ +inflect($this) + * ->initializer() + * ->... + * + * Instead of: + * + * (new SomeTask($args)) + * ->setLogger($this->logger) + * ->initializer() + * ->... + * + * The reason `inflect` is better than the more explicit alternative is + * that subclasses of BaseTask that implement a new FooAwareInterface + * can override injectDependencies() as explained below, and add more + * dependencies that can be injected as needed. + * + * @param \Robo\Contract\InflectionInterface $parent + */ + public function inflect(InflectionInterface $parent); + + /** + * Take all dependencies availble to this task and inject any that are + * needed into the provided task. The general pattern is that, for every + * FooAwareInterface that this class implements, it should test to see + * if the child also implements the same interface, and if so, should call + * $child->setFoo($this->foo). + * + * The benefits of this are pretty large. Any time an object that implements + * InflectionInterface is created, just call `$child->inflect($this)`, and + * any available optional dependencies will be hooked up via setter injection. + * + * The required dependencies of an object should be provided via constructor + * injection, not inflection. + * + * @param InflectionInterface $child An object created by this class that + * should have its dependencies injected. + * + * @see https://mwop.net/blog/2016-04-26-on-locators.html + */ + public function injectDependencies(InflectionInterface $child); +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/OutputAdapterInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/OutputAdapterInterface.php new file mode 100644 index 00000000..948d384c --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Contract/OutputAdapterInterface.php @@ -0,0 +1,11 @@ +prefix = 'options'; + } + + /** + * Add a reference to the Symfony Console application object. + */ + public function setApplication($application) + { + $this->application = $application; + return $this; + } + + /** + * Stipulate the prefix to use for option injection. + * @param string $prefix + */ + public function setGlobalOptionsPrefix($prefix) + { + $this->prefix = $prefix; + return $this; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return [ConsoleEvents::COMMAND => 'handleCommandEvent']; + } + + /** + * Run all of our individual operations when a command event is received. + */ + public function handleCommandEvent(ConsoleCommandEvent $event) + { + $this->setGlobalOptions($event); + $this->setConfigurationValues($event); + } + + /** + * Before a Console command runs, examine the global + * commandline options from the event Input, and set + * configuration values as appropriate. + * + * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event + */ + public function setGlobalOptions(ConsoleCommandEvent $event) + { + $config = $this->getConfig(); + $input = $event->getInput(); + + $globalOptions = $config->get($this->prefix, []); + if ($config instanceof \Consolidation\Config\GlobalOptionDefaultValuesInterface) { + $globalOptions += $config->getGlobalOptionDefaultValues(); + } + + $globalOptions += $this->applicationOptionDefaultValues(); + + // Set any config value that has a defined global option (e.g. --simulate) + foreach ($globalOptions as $option => $default) { + $value = $input->hasOption($option) ? $input->getOption($option) : null; + // Unfortunately, the `?:` operator does not differentate between `0` and `null` + if (!isset($value)) { + $value = $default; + } + $config->set($this->prefix . '.' . $option, $value); + } + } + + /** + * Examine the commandline --define / -D options, and apply the provided + * values to the active configuration. + * + * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event + */ + public function setConfigurationValues(ConsoleCommandEvent $event) + { + $config = $this->getConfig(); + $input = $event->getInput(); + + // Also set any `-D config.key=value` options from the commandline. + if ($input->hasOption('define')) { + $configDefinitions = $input->getOption('define'); + foreach ($configDefinitions as $value) { + list($key, $value) = $this->splitConfigKeyValue($value); + $config->set($key, $value); + } + } + } + + /** + * Split up the key=value config setting into its component parts. If + * the input string contains no '=' character, then the value will be 'true'. + * + * @param string $value + * @return array + */ + protected function splitConfigKeyValue($value) + { + $parts = explode('=', $value, 2); + $parts[] = true; + return $parts; + } + + /** + * Get default option values from the Symfony Console application, if + * it is available. + */ + protected function applicationOptionDefaultValues() + { + if (!$this->application) { + return []; + } + + $result = []; + foreach ($this->application->getDefinition()->getOptions() as $key => $option) { + $result[$key] = $option->acceptValue() ? $option->getDefault() : null; + } + return $result; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/LoadAllTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/LoadAllTasks.php new file mode 100644 index 00000000..3183d5b6 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/LoadAllTasks.php @@ -0,0 +1,39 @@ +getTask(); + if ($task instanceof VerbosityThresholdInterface && !$task->verbosityMeetsThreshold()) { + return; + } + if (!$result->wasSuccessful()) { + return $this->printError($result); + } else { + return $this->printSuccess($result); + } + } + + /** + * Log that we are about to abort due to an error being encountered + * in 'stop on fail' mode. + * + * @param \Robo\Result $result + */ + public function printStopOnFail($result) + { + $this->printMessage(LogLevel::NOTICE, 'Stopping on fail. Exiting....'); + $this->printMessage(LogLevel::ERROR, 'Exit Code: {code}', ['code' => $result->getExitCode()]); + } + + /** + * Log the result of a Robo task that returned an error. + * + * @param \Robo\Result $result + * + * @return bool + */ + protected function printError(Result $result) + { + $task = $result->getTask(); + $context = $result->getContext() + ['timer-label' => 'Time', '_style' => []]; + $context['_style']['message'] = ''; + + $printOutput = true; + if ($task instanceof PrintedInterface) { + $printOutput = !$task->getPrinted(); + } + if ($printOutput) { + $this->printMessage(LogLevel::ERROR, "{message}", $context); + } + $this->printMessage(LogLevel::ERROR, 'Exit code {code}', $context); + return true; + } + + /** + * Log the result of a Robo task that was successful. + * + * @param \Robo\Result $result + * + * @return bool + */ + protected function printSuccess(Result $result) + { + $task = $result->getTask(); + $context = $result->getContext() + ['timer-label' => 'in']; + $time = $result->getExecutionTime(); + if ($time) { + $this->printMessage(ConsoleLogLevel::SUCCESS, 'Done', $context); + } + return false; + } + + /** + * @param string $level + * @param string $message + * @param array $context + */ + protected function printMessage($level, $message, $context = []) + { + $inProgress = $this->hideProgressIndicator(); + $this->logger->log($level, $message, $context); + if ($inProgress) { + $this->restoreProgressIndicator($inProgress); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogLevel.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogLevel.php new file mode 100644 index 00000000..d7d5eb0a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogLevel.php @@ -0,0 +1,11 @@ +labelStyles += [ + RoboLogLevel::SIMULATED_ACTION => self::TASK_STYLE_SIMULATED, + ]; + $this->messageStyles += [ + RoboLogLevel::SIMULATED_ACTION => '', + ]; + } + + /** + * Log style customization for Robo: replace the log level with + * the task name. + * + * @param string $level + * @param string $message + * @param array $context + * + * @return string + */ + protected function formatMessageByLevel($level, $message, $context) + { + $label = $level; + if (array_key_exists('name', $context)) { + $label = $context['name']; + } + return $this->formatMessage($label, $message, $context, $this->labelStyles[$level], $this->messageStyles[$level]); + } + + /** + * Log style customization for Robo: add the time indicator to the + * end of the log message if it exists in the context. + * + * @param string $label + * @param string $message + * @param array $context + * @param string $taskNameStyle + * @param string $messageStyle + * + * @return string + */ + protected function formatMessage($label, $message, $context, $taskNameStyle, $messageStyle = '') + { + $message = parent::formatMessage($label, $message, $context, $taskNameStyle, $messageStyle); + + if (array_key_exists('time', $context) && !empty($context['time']) && array_key_exists('timer-label', $context)) { + $duration = TimeKeeper::formatDuration($context['time']); + $message .= ' ' . $context['timer-label'] . ' ' . $this->wrapFormatString($duration, 'fg=yellow'); + } + + return $message; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogger.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogger.php new file mode 100644 index 00000000..75cf23f7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Log/RoboLogger.php @@ -0,0 +1,29 @@ + OutputInterface::VERBOSITY_NORMAL, // Default is "verbose" + LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL, // Default is "verbose" + LogLevel::INFO => OutputInterface::VERBOSITY_VERBOSE, // Default is "very verbose" + ]; + parent::__construct($output, $roboVerbosityOverrides); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Result.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Result.php new file mode 100644 index 00000000..7d779352 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Result.php @@ -0,0 +1,258 @@ +task = $task; + $this->printResult(); + + if (self::$stopOnFail) { + $this->stopOnFail(); + } + } + + /** + * Tasks should always return a Result. However, they are also + * allowed to return NULL or an array to indicate success. + */ + public static function ensureResult($task, $result) + { + if ($result instanceof Result) { + return $result; + } + if (!isset($result)) { + return static::success($task); + } + if ($result instanceof Data) { + return static::success($task, $result->getMessage(), $result->getData()); + } + if ($result instanceof ResultData) { + return new Result($task, $result->getExitCode(), $result->getMessage(), $result->getData()); + } + if (is_array($result)) { + return static::success($task, '', $result); + } + throw new \Exception(sprintf('Task %s returned a %s instead of a \Robo\Result.', get_class($task), get_class($result))); + } + + protected function printResult() + { + // For historic reasons, the Result constructor is responsible + // for printing task results. + // TODO: Make IO the responsibility of some other class. Maintaining + // existing behavior for backwards compatibility. This is undesirable + // in the long run, though, as it can result in unwanted repeated input + // in task collections et. al. + $resultPrinter = Robo::resultPrinter(); + if ($resultPrinter) { + if ($resultPrinter->printResult($this)) { + $this->alreadyPrinted(); + } + } + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $extension + * @param string $service + * + * @return \Robo\Result + */ + public static function errorMissingExtension(TaskInterface $task, $extension, $service) + { + $messageTpl = 'PHP extension required for %s. Please enable %s'; + $message = sprintf($messageTpl, $service, $extension); + + return self::error($task, $message); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $class + * @param string $package + * + * @return \Robo\Result + */ + public static function errorMissingPackage(TaskInterface $task, $class, $package) + { + $messageTpl = 'Class %s not found. Please install %s Composer package'; + $message = sprintf($messageTpl, $class, $package); + + return self::error($task, $message); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $message + * @param array $data + * + * @return \Robo\Result + */ + public static function error(TaskInterface $task, $message, $data = []) + { + return new self($task, self::EXITCODE_ERROR, $message, $data); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param \Exception $e + * @param array $data + * + * @return \Robo\Result + */ + public static function fromException(TaskInterface $task, \Exception $e, $data = []) + { + $exitCode = $e->getCode(); + if (!$exitCode) { + $exitCode = self::EXITCODE_ERROR; + } + return new self($task, $exitCode, $e->getMessage(), $data); + } + + /** + * @param \Robo\Contract\TaskInterface $task + * @param string $message + * @param array $data + * + * @return \Robo\Result + */ + public static function success(TaskInterface $task, $message = '', $data = []) + { + return new self($task, self::EXITCODE_OK, $message, $data); + } + + /** + * Return a context useful for logging messages. + * + * @return array + */ + public function getContext() + { + $task = $this->getTask(); + + return TaskInfo::getTaskContext($task) + [ + 'code' => $this->getExitCode(), + 'data' => $this->getArrayCopy(), + 'time' => $this->getExecutionTime(), + 'message' => $this->getMessage(), + ]; + } + + /** + * Add the results from the most recent task to the accumulated + * results from all tasks that have run so far, merging data + * as necessary. + * + * @param int|string $key + * @param \Robo\Result $taskResult + */ + public function accumulate($key, Result $taskResult) + { + // If the task is unnamed, then all of its data elements + // just get merged in at the top-level of the final Result object. + if (static::isUnnamed($key)) { + $this->merge($taskResult); + } elseif (isset($this[$key])) { + // There can only be one task with a given name; however, if + // there are tasks added 'before' or 'after' the named task, + // then the results from these will be stored under the same + // name unless they are given a name of their own when added. + $current = $this[$key]; + $this[$key] = $taskResult->merge($current); + } else { + $this[$key] = $taskResult; + } + } + + /** + * We assume that named values (e.g. for associative array keys) + * are non-numeric; numeric keys are presumed to simply be the + * index of an array, and therefore insignificant. + * + * @param int|string $key + * + * @return bool + */ + public static function isUnnamed($key) + { + return is_numeric($key); + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function getTask() + { + return $this->task; + } + + /** + * @return \Robo\Contract\TaskInterface + */ + public function cloneTask() + { + $reflect = new \ReflectionClass(get_class($this->task)); + return $reflect->newInstanceArgs(func_get_args()); + } + + /** + * @return bool + * + * @deprecated since 1.0. + * + * @see wasSuccessful() + */ + public function __invoke() + { + trigger_error(__METHOD__ . ' is deprecated: use wasSuccessful() instead.', E_USER_DEPRECATED); + return $this->wasSuccessful(); + } + + /** + * @return $this + */ + public function stopOnFail() + { + if (!$this->wasSuccessful()) { + $resultPrinter = Robo::resultPrinter(); + if ($resultPrinter) { + $resultPrinter->printStopOnFail($this); + } + $this->exitEarly($this->getExitCode()); + } + return $this; + } + + /** + * @param int $status + * + * @throws \Robo\Exception\TaskExitException + */ + private function exitEarly($status) + { + throw new TaskExitException($this->getTask(), $this->getMessage(), $status); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/ResultData.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/ResultData.php new file mode 100644 index 00000000..90baf6e9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/ResultData.php @@ -0,0 +1,110 @@ +exitCode = $exitCode; + parent::__construct($message, $data); + } + + /** + * @param string $message + * @param array $data + * + * @return \Robo\ResultData + */ + public static function message($message, $data = []) + { + return new self(self::EXITCODE_OK, $message, $data); + } + + /** + * @param string $message + * @param array $data + * + * @return \Robo\ResultData + */ + public static function cancelled($message = '', $data = []) + { + return new ResultData(self::EXITCODE_USER_CANCEL, $message, $data); + } + + /** + * @return int + */ + public function getExitCode() + { + return $this->exitCode; + } + + /** + * @return null|string + */ + public function getOutputData() + { + if (!empty($this->message) && !isset($this['already-printed']) && isset($this['provide-outputdata'])) { + return $this->message; + } + } + + /** + * Indicate that the message in this data has already been displayed. + */ + public function alreadyPrinted() + { + $this['already-printed'] = true; + } + + /** + * Opt-in to providing the result message as the output data + */ + public function provideOutputdata() + { + $this['provide-outputdata'] = true; + } + + /** + * @return bool + */ + public function wasSuccessful() + { + return $this->exitCode === self::EXITCODE_OK; + } + + /** + * @return bool + */ + public function wasCancelled() + { + return $this->exitCode == self::EXITCODE_USER_CANCEL; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Robo.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Robo.php new file mode 100644 index 00000000..0f427707 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Robo.php @@ -0,0 +1,394 @@ +setSelfUpdateRepository($repository); + $statusCode = $runner->execute($argv, $appName, $appVersion, $output); + return $statusCode; + } + + /** + * Sets a new global container. + * + * @param ContainerInterface $container + * A new container instance to replace the current. + */ + public static function setContainer(ContainerInterface $container) + { + static::$container = $container; + } + + /** + * Unsets the global container. + */ + public static function unsetContainer() + { + static::$container = null; + } + + /** + * Returns the currently active global container. + * + * @return \League\Container\ContainerInterface + * + * @throws \RuntimeException + */ + public static function getContainer() + { + if (static::$container === null) { + throw new \RuntimeException('container is not initialized yet. \Robo\Robo::setContainer() must be called with a real container.'); + } + return static::$container; + } + + /** + * Returns TRUE if the container has been initialized, FALSE otherwise. + * + * @return bool + */ + public static function hasContainer() + { + return static::$container !== null; + } + + /** + * Create a config object and load it from the provided paths. + */ + public static function createConfiguration($paths) + { + $config = new \Robo\Config\Config(); + static::loadConfiguration($paths, $config); + return $config; + } + + /** + * Use a simple config loader to load configuration values from specified paths + */ + public static function loadConfiguration($paths, $config = null) + { + if ($config == null) { + $config = static::config(); + } + $loader = new YamlConfigLoader(); + $processor = new ConfigProcessor(); + $processor->add($config->export()); + foreach ($paths as $path) { + $processor->extend($loader->load($path)); + } + $config->import($processor->export()); + } + + /** + * Create a container and initiailze it. If you wish to *change* + * anything defined in the container, then you should call + * \Robo::configureContainer() instead of this function. + * + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * @param null|\Robo\Application $app + * @param null|ConfigInterface $config + * + * @return \League\Container\Container|\League\Container\ContainerInterface + */ + public static function createDefaultContainer($input = null, $output = null, $app = null, $config = null) + { + // Do not allow this function to be called more than once. + if (static::hasContainer()) { + return static::getContainer(); + } + + if (!$app) { + $app = static::createDefaultApplication(); + } + + if (!$config) { + $config = new \Robo\Config\Config(); + } + + // Set up our dependency injection container. + $container = new Container(); + static::configureContainer($container, $app, $config, $input, $output); + + // Set the application dispatcher + $app->setDispatcher($container->get('eventDispatcher')); + + return $container; + } + + /** + * Initialize a container with all of the default Robo services. + * IMPORTANT: after calling this method, clients MUST call: + * + * $dispatcher = $container->get('eventDispatcher'); + * $app->setDispatcher($dispatcher); + * + * Any modification to the container should be done prior to fetching + * objects from it. + * + * It is recommended to use \Robo::createDefaultContainer() + * instead, which does all required setup for the caller, but has + * the limitation that the container it creates can only be + * extended, not modified. + * + * @param \League\Container\ContainerInterface $container + * @param \Symfony\Component\Console\Application $app + * @param ConfigInterface $config + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + */ + public static function configureContainer(ContainerInterface $container, SymfonyApplication $app, ConfigInterface $config, $input = null, $output = null) + { + // Self-referential container refernce for the inflector + $container->add('container', $container); + static::setContainer($container); + + // Create default input and output objects if they were not provided + if (!$input) { + $input = new StringInput(''); + } + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + $config->set(Config::DECORATED, $output->isDecorated()); + $config->set(Config::INTERACTIVE, $input->isInteractive()); + + $container->share('application', $app); + $container->share('config', $config); + $container->share('input', $input); + $container->share('output', $output); + $container->share('outputAdapter', \Robo\Common\OutputAdapter::class); + + // Register logging and related services. + $container->share('logStyler', \Robo\Log\RoboLogStyle::class); + $container->share('logger', \Robo\Log\RoboLogger::class) + ->withArgument('output') + ->withMethodCall('setLogOutputStyler', ['logStyler']); + $container->add('progressBar', \Symfony\Component\Console\Helper\ProgressBar::class) + ->withArgument('output'); + $container->share('progressIndicator', \Robo\Common\ProgressIndicator::class) + ->withArgument('progressBar') + ->withArgument('output'); + $container->share('resultPrinter', \Robo\Log\ResultPrinter::class); + $container->add('simulator', \Robo\Task\Simulator::class); + $container->share('globalOptionsEventListener', \Robo\GlobalOptionsEventListener::class) + ->withMethodCall('setApplication', ['application']); + $container->share('injectConfigEventListener', \Consolidation\Config\Inject\ConfigForCommand::class) + ->withArgument('config') + ->withMethodCall('setApplication', ['application']); + $container->share('collectionProcessHook', \Robo\Collection\CollectionProcessHook::class); + $container->share('alterOptionsCommandEvent', \Consolidation\AnnotatedCommand\Options\AlterOptionsCommandEvent::class) + ->withArgument('application'); + $container->share('hookManager', \Consolidation\AnnotatedCommand\Hooks\HookManager::class) + ->withMethodCall('addCommandEvent', ['alterOptionsCommandEvent']) + ->withMethodCall('addCommandEvent', ['injectConfigEventListener']) + ->withMethodCall('addCommandEvent', ['globalOptionsEventListener']) + ->withMethodCall('addResultProcessor', ['collectionProcessHook', '*']); + $container->share('eventDispatcher', \Symfony\Component\EventDispatcher\EventDispatcher::class) + ->withMethodCall('addSubscriber', ['hookManager']); + $container->share('formatterManager', \Consolidation\OutputFormatters\FormatterManager::class) + ->withMethodCall('addDefaultFormatters', []) + ->withMethodCall('addDefaultSimplifiers', []); + $container->share('prepareTerminalWidthOption', \Consolidation\AnnotatedCommand\Options\PrepareTerminalWidthOption::class) + ->withMethodCall('setApplication', ['application']); + $container->share('commandProcessor', \Consolidation\AnnotatedCommand\CommandProcessor::class) + ->withArgument('hookManager') + ->withMethodCall('setFormatterManager', ['formatterManager']) + ->withMethodCall('addPrepareFormatter', ['prepareTerminalWidthOption']) + ->withMethodCall( + 'setDisplayErrorFunction', + [ + function ($output, $message) use ($container) { + $logger = $container->get('logger'); + $logger->error($message); + } + ] + ); + $container->share('commandFactory', \Consolidation\AnnotatedCommand\AnnotatedCommandFactory::class) + ->withMethodCall('setCommandProcessor', ['commandProcessor']); + + // Deprecated: favor using collection builders to direct use of collections. + $container->add('collection', \Robo\Collection\Collection::class); + // Deprecated: use CollectionBuilder::create() instead -- or, better + // yet, BuilderAwareInterface::collectionBuilder() if available. + $container->add('collectionBuilder', \Robo\Collection\CollectionBuilder::class); + + static::addInflectors($container); + + // Make sure the application is appropriately initialized. + $app->setAutoExit(false); + } + + /** + * @param null|string $appName + * @param null|string $appVersion + * + * @return \Robo\Application + */ + public static function createDefaultApplication($appName = null, $appVersion = null) + { + $appName = $appName ?: self::APPLICATION_NAME; + $appVersion = $appVersion ?: self::VERSION; + + $app = new \Robo\Application($appName, $appVersion); + $app->setAutoExit(false); + return $app; + } + + /** + * Add the Robo League\Container inflectors to the container + * + * @param \League\Container\ContainerInterface $container + */ + public static function addInflectors($container) + { + // Register our various inflectors. + $container->inflector(\Robo\Contract\ConfigAwareInterface::class) + ->invokeMethod('setConfig', ['config']); + $container->inflector(\Psr\Log\LoggerAwareInterface::class) + ->invokeMethod('setLogger', ['logger']); + $container->inflector(\League\Container\ContainerAwareInterface::class) + ->invokeMethod('setContainer', ['container']); + $container->inflector(\Symfony\Component\Console\Input\InputAwareInterface::class) + ->invokeMethod('setInput', ['input']); + $container->inflector(\Robo\Contract\OutputAwareInterface::class) + ->invokeMethod('setOutput', ['output']); + $container->inflector(\Robo\Contract\ProgressIndicatorAwareInterface::class) + ->invokeMethod('setProgressIndicator', ['progressIndicator']); + $container->inflector(\Consolidation\AnnotatedCommand\Events\CustomEventAwareInterface::class) + ->invokeMethod('setHookManager', ['hookManager']); + $container->inflector(\Robo\Contract\VerbosityThresholdInterface::class) + ->invokeMethod('setOutputAdapter', ['outputAdapter']); + } + + /** + * Retrieves a service from the container. + * + * Use this method if the desired service is not one of those with a dedicated + * accessor method below. If it is listed below, those methods are preferred + * as they can return useful type hints. + * + * @param string $id + * The ID of the service to retrieve. + * + * @return mixed + * The specified service. + */ + public static function service($id) + { + return static::getContainer()->get($id); + } + + /** + * Indicates if a service is defined in the container. + * + * @param string $id + * The ID of the service to check. + * + * @return bool + * TRUE if the specified service exists, FALSE otherwise. + */ + public static function hasService($id) + { + // Check hasContainer() first in order to always return a Boolean. + return static::hasContainer() && static::getContainer()->has($id); + } + + /** + * Return the result printer object. + * + * @return \Robo\Log\ResultPrinter + */ + public static function resultPrinter() + { + return static::service('resultPrinter'); + } + + /** + * @return ConfigInterface + */ + public static function config() + { + return static::service('config'); + } + + /** + * @return \Consolidation\Log\Logger + */ + public static function logger() + { + return static::service('logger'); + } + + /** + * @return \Robo\Application + */ + public static function application() + { + return static::service('application'); + } + + /** + * Return the output object. + * + * @return \Symfony\Component\Console\Output\OutputInterface + */ + public static function output() + { + return static::service('output'); + } + + /** + * Return the input object. + * + * @return \Symfony\Component\Console\Input\InputInterface + */ + public static function input() + { + return static::service('input'); + } + + public static function process(Process $process) + { + return ProcessExecutor::create(static::getContainer(), $process); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Runner.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Runner.php new file mode 100644 index 00000000..800ad281 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Runner.php @@ -0,0 +1,465 @@ +roboClass = $roboClass ? $roboClass : self::ROBOCLASS ; + $this->roboFile = $roboFile ? $roboFile : self::ROBOFILE; + $this->dir = getcwd(); + } + + protected function errorCondtion($msg, $errorType) + { + $this->errorConditions[$msg] = $errorType; + } + + /** + * @param \Symfony\Component\Console\Output\OutputInterface $output + * + * @return bool + */ + protected function loadRoboFile($output) + { + // If we have not been provided an output object, make a temporary one. + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + + // If $this->roboClass is a single class that has not already + // been loaded, then we will try to obtain it from $this->roboFile. + // If $this->roboClass is an array, we presume all classes requested + // are available via the autoloader. + if (is_array($this->roboClass) || class_exists($this->roboClass)) { + return true; + } + if (!file_exists($this->dir)) { + $this->errorCondtion("Path `{$this->dir}` is invalid; please provide a valid absolute path to the Robofile to load.", 'red'); + return false; + } + + $realDir = realpath($this->dir); + + $roboFilePath = $realDir . DIRECTORY_SEPARATOR . $this->roboFile; + if (!file_exists($roboFilePath)) { + $requestedRoboFilePath = $this->dir . DIRECTORY_SEPARATOR . $this->roboFile; + $this->errorCondtion("Requested RoboFile `$requestedRoboFilePath` is invalid, please provide valid absolute path to load Robofile.", 'red'); + return false; + } + require_once $roboFilePath; + + if (!class_exists($this->roboClass)) { + $this->errorCondtion("Class {$this->roboClass} was not loaded.", 'red'); + return false; + } + return true; + } + + /** + * @param array $argv + * @param null|string $appName + * @param null|string $appVersion + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * + * @return int + */ + public function execute($argv, $appName = null, $appVersion = null, $output = null) + { + $argv = $this->shebang($argv); + $argv = $this->processRoboOptions($argv); + $app = null; + if ($appName && $appVersion) { + $app = Robo::createDefaultApplication($appName, $appVersion); + } + $commandFiles = $this->getRoboFileCommands($output); + return $this->run($argv, $output, $app, $commandFiles); + } + + /** + * @param null|\Symfony\Component\Console\Input\InputInterface $input + * @param null|\Symfony\Component\Console\Output\OutputInterface $output + * @param null|\Robo\Application $app + * @param array[] $commandFiles + * + * @return int + */ + public function run($input = null, $output = null, $app = null, $commandFiles = []) + { + // Create default input and output objects if they were not provided + if (!$input) { + $input = new StringInput(''); + } + if (is_array($input)) { + $input = new ArgvInput($input); + } + if (!$output) { + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + } + $this->setInput($input); + $this->setOutput($output); + + // If we were not provided a container, then create one + if (!$this->getContainer()) { + $userConfig = 'robo.yml'; + $roboAppConfig = dirname(__DIR__) . '/robo.yml'; + $config = Robo::createConfiguration([$userConfig, $roboAppConfig]); + $container = Robo::createDefaultContainer($input, $output, $app, $config); + $this->setContainer($container); + // Automatically register a shutdown function and + // an error handler when we provide the container. + $this->installRoboHandlers(); + } + + if (!$app) { + $app = Robo::application(); + } + if ($app instanceof \Robo\Application) { + $app->addSelfUpdateCommand($this->getSelfUpdateRepository()); + if (!isset($commandFiles)) { + $this->errorCondtion("Robo is not initialized here. Please run `robo init` to create a new RoboFile.", 'yellow'); + $app->addInitRoboFileCommand($this->roboFile, $this->roboClass); + $commandFiles = []; + } + } + $this->registerCommandClasses($app, $commandFiles); + + try { + $statusCode = $app->run($input, $output); + } catch (TaskExitException $e) { + $statusCode = $e->getCode() ?: 1; + } + + // If there were any error conditions in bootstrapping Robo, + // print them only if the requested command did not complete + // successfully. + if ($statusCode) { + foreach ($this->errorConditions as $msg => $color) { + $this->yell($msg, 40, $color); + } + } + return $statusCode; + } + + /** + * @param \Symfony\Component\Console\Output\OutputInterface $output + * + * @return null|string + */ + protected function getRoboFileCommands($output) + { + if (!$this->loadRoboFile($output)) { + return; + } + return $this->roboClass; + } + + /** + * @param \Robo\Application $app + * @param array $commandClasses + */ + public function registerCommandClasses($app, $commandClasses) + { + foreach ((array)$commandClasses as $commandClass) { + $this->registerCommandClass($app, $commandClass); + } + } + + /** + * @param \Robo\Application $app + * @param string|BuilderAwareInterface|ContainerAwareInterface $commandClass + * + * @return mixed|void + */ + public function registerCommandClass($app, $commandClass) + { + $container = Robo::getContainer(); + $roboCommandFileInstance = $this->instantiateCommandClass($commandClass); + if (!$roboCommandFileInstance) { + return; + } + + // Register commands for all of the public methods in the RoboFile. + $commandFactory = $container->get('commandFactory'); + $commandList = $commandFactory->createCommandsFromClass($roboCommandFileInstance); + foreach ($commandList as $command) { + $app->add($command); + } + return $roboCommandFileInstance; + } + + /** + * @param string|BuilderAwareInterface|ContainerAwareInterface $commandClass + * + * @return null|object + */ + protected function instantiateCommandClass($commandClass) + { + $container = Robo::getContainer(); + + // Register the RoboFile with the container and then immediately + // fetch it; this ensures that all of the inflectors will run. + // If the command class is already an instantiated object, then + // just use it exactly as it was provided to us. + if (is_string($commandClass)) { + if (!class_exists($commandClass)) { + return; + } + $reflectionClass = new \ReflectionClass($commandClass); + if ($reflectionClass->isAbstract()) { + return; + } + + $commandFileName = "{$commandClass}Commands"; + $container->share($commandFileName, $commandClass); + $commandClass = $container->get($commandFileName); + } + // If the command class is a Builder Aware Interface, then + // ensure that it has a builder. Every command class needs + // its own collection builder, as they have references to each other. + if ($commandClass instanceof BuilderAwareInterface) { + $builder = CollectionBuilder::create($container, $commandClass); + $commandClass->setBuilder($builder); + } + if ($commandClass instanceof ContainerAwareInterface) { + $commandClass->setContainer($container); + } + return $commandClass; + } + + public function installRoboHandlers() + { + register_shutdown_function(array($this, 'shutdown')); + set_error_handler(array($this, 'handleError')); + } + + /** + * Process a shebang script, if one was used to launch this Runner. + * + * @param array $args + * + * @return array $args with shebang script removed + */ + protected function shebang($args) + { + // Option 1: Shebang line names Robo, but includes no parameters. + // #!/bin/env robo + // The robo class may contain multiple commands; the user may + // select which one to run, or even get a list of commands or + // run 'help' on any of the available commands as usual. + if ((count($args) > 1) && $this->isShebangFile($args[1])) { + return array_merge([$args[0]], array_slice($args, 2)); + } + // Option 2: Shebang line stipulates which command to run. + // #!/bin/env robo mycommand + // The robo class must contain a public method named 'mycommand'. + // This command will be executed every time. Arguments and options + // may be provided on the commandline as usual. + if ((count($args) > 2) && $this->isShebangFile($args[2])) { + return array_merge([$args[0]], explode(' ', $args[1]), array_slice($args, 3)); + } + return $args; + } + + /** + * Determine if the specified argument is a path to a shebang script. + * If so, load it. + * + * @param string $filepath file to check + * + * @return bool Returns TRUE if shebang script was processed + */ + protected function isShebangFile($filepath) + { + if (!is_file($filepath)) { + return false; + } + $fp = fopen($filepath, "r"); + if ($fp === false) { + return false; + } + $line = fgets($fp); + $result = $this->isShebangLine($line); + if ($result) { + while ($line = fgets($fp)) { + $line = trim($line); + if ($line == 'roboClass = $matches[1]; + eval($script); + $result = true; + } + } + } + } + fclose($fp); + + return $result; + } + + /** + * Test to see if the provided line is a robo 'shebang' line. + * + * @param string $line + * + * @return bool + */ + protected function isShebangLine($line) + { + return ((substr($line, 0, 2) == '#!') && (strstr($line, 'robo') !== false)); + } + + /** + * Check for Robo-specific arguments such as --load-from, process them, + * and remove them from the array. We have to process --load-from before + * we set up Symfony Console. + * + * @param array $argv + * + * @return array + */ + protected function processRoboOptions($argv) + { + // loading from other directory + $pos = $this->arraySearchBeginsWith('--load-from', $argv) ?: array_search('-f', $argv); + if ($pos === false) { + return $argv; + } + + $passThru = array_search('--', $argv); + if (($passThru !== false) && ($passThru < $pos)) { + return $argv; + } + + if (substr($argv[$pos], 0, 12) == '--load-from=') { + $this->dir = substr($argv[$pos], 12); + } elseif (isset($argv[$pos +1])) { + $this->dir = $argv[$pos +1]; + unset($argv[$pos +1]); + } + unset($argv[$pos]); + // Make adjustments if '--load-from' points at a file. + if (is_file($this->dir) || (substr($this->dir, -4) == '.php')) { + $this->roboFile = basename($this->dir); + $this->dir = dirname($this->dir); + $className = basename($this->roboFile, '.php'); + if ($className != $this->roboFile) { + $this->roboClass = $className; + } + } + // Convert directory to a real path, but only if the + // path exists. We do not want to lose the original + // directory if the user supplied a bad value. + $realDir = realpath($this->dir); + if ($realDir) { + chdir($realDir); + $this->dir = $realDir; + } + + return $argv; + } + + /** + * @param string $needle + * @param string[] $haystack + * + * @return bool|int + */ + protected function arraySearchBeginsWith($needle, $haystack) + { + for ($i = 0; $i < count($haystack); ++$i) { + if (substr($haystack[$i], 0, strlen($needle)) == $needle) { + return $i; + } + } + return false; + } + + public function shutdown() + { + $error = error_get_last(); + if (!is_array($error)) { + return; + } + $this->writeln(sprintf("ERROR: %s \nin %s:%d\n", $error['message'], $error['file'], $error['line'])); + } + + /** + * This is just a proxy error handler that checks the current error_reporting level. + * In case error_reporting is disabled the error is marked as handled, otherwise + * the normal internal error handling resumes. + * + * @return bool + */ + public function handleError() + { + if (error_reporting() === 0) { + return true; + } + return false; + } + + /** + * @return string + */ + public function getSelfUpdateRepository() + { + return $this->selfUpdateRepository; + } + + /** + * @param string $selfUpdateRepository + */ + public function setSelfUpdateRepository($selfUpdateRepository) + { + $this->selfUpdateRepository = $selfUpdateRepository; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/SelfUpdateCommand.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/SelfUpdateCommand.php new file mode 100644 index 00000000..d07ee71f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/SelfUpdateCommand.php @@ -0,0 +1,152 @@ + + */ +class SelfUpdateCommand extends Command +{ + const SELF_UPDATE_COMMAND_NAME = 'self:update'; + + protected $gitHubRepository; + + protected $currentVersion; + + protected $applicationName; + + public function __construct($applicationName = null, $currentVersion = null, $gitHubRepository = null) + { + parent::__construct(self::SELF_UPDATE_COMMAND_NAME); + + $this->applicationName = $applicationName; + $this->currentVersion = $currentVersion; + $this->gitHubRepository = $gitHubRepository; + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setAliases(array('update')) + ->setDescription('Updates the robo.phar to the latest version.') + ->setHelp( + <<self-update command checks github for newer +versions of robo and if found, installs the latest. +EOT + ); + } + + protected function getLatestReleaseFromGithub() + { + $opts = [ + 'http' => [ + 'method' => 'GET', + 'header' => [ + 'User-Agent: ' . $this->applicationName . ' (' . $this->gitHubRepository . ')' . ' Self-Update (PHP)' + ] + ] + ]; + + $context = stream_context_create($opts); + + $releases = file_get_contents('https://api.github.com/repos/' . $this->gitHubRepository . '/releases', false, $context); + $releases = json_decode($releases); + + if (! isset($releases[0])) { + throw new \Exception('API error - no release found at GitHub repository ' . $this->gitHubRepository); + } + + $version = $releases[0]->tag_name; + $url = $releases[0]->assets[0]->browser_download_url; + + return [ $version, $url ]; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + if (empty(\Phar::running())) { + throw new \Exception(self::SELF_UPDATE_COMMAND_NAME . ' only works when running the phar version of ' . $this->applicationName . '.'); + } + + $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0]; + $programName = basename($localFilename); + $tempFilename = dirname($localFilename) . '/' . basename($localFilename, '.phar') . '-temp.phar'; + + // check for permissions in local filesystem before start connection process + if (! is_writable($tempDirectory = dirname($tempFilename))) { + throw new \Exception( + $programName . ' update failed: the "' . $tempDirectory . + '" directory used to download the temp file could not be written' + ); + } + + if (! is_writable($localFilename)) { + throw new \Exception( + $programName . ' update failed: the "' . $localFilename . '" file could not be written (execute with sudo)' + ); + } + + list( $latest, $downloadUrl ) = $this->getLatestReleaseFromGithub(); + + + if ($this->currentVersion == $latest) { + $output->writeln('No update available'); + return; + } + + $fs = new sfFilesystem(); + + $output->writeln('Downloading ' . $this->applicationName . ' (' . $this->gitHubRepository . ') ' . $latest); + + $fs->copy($downloadUrl, $tempFilename); + + $output->writeln('Download finished'); + + try { + \error_reporting(E_ALL); // supress notices + + @chmod($tempFilename, 0777 & ~umask()); + // test the phar validity + $phar = new \Phar($tempFilename); + // free the variable to unlock the file + unset($phar); + @rename($tempFilename, $localFilename); + $output->writeln('Successfully updated ' . $programName . ''); + $this->_exit(); + } catch (\Exception $e) { + @unlink($tempFilename); + if (! $e instanceof \UnexpectedValueException && ! $e instanceof \PharException) { + throw $e; + } + $output->writeln('The download is corrupted (' . $e->getMessage() . ').'); + $output->writeln('Please re-run the self-update command to try again.'); + } + } + + /** + * Stop execution + * + * This is a workaround to prevent warning of dispatcher after replacing + * the phar file. + * + * @return void + */ + protected function _exit() + { + exit; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/Consumer.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/Consumer.php new file mode 100644 index 00000000..ab9c0e27 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/Consumer.php @@ -0,0 +1,12 @@ +message = $message; + parent::__construct($data); + } + + /** + * @return array + */ + public function getData() + { + return $this->getArrayCopy(); + } + + /** + * @return string + */ + public function getMessage() + { + return $this->message; + } + + /** + * @param string message + */ + public function setMessage($message) + { + $this->message = $message; + } + + /** + * Merge another result into this result. Data already + * existing in this result takes precedence over the + * data in the Result being merged. + * + * @param \Robo\ResultData $result + * + * @return $this + */ + public function merge(Data $result) + { + $mergedData = $this->getArrayCopy() + $result->getArrayCopy(); + $this->exchangeArray($mergedData); + return $this; + } + + /** + * Update the current data with the data provided in the parameter. + * Provided data takes precedence. + * + * @param \ArrayObject $update + * + * @return $this + */ + public function update(\ArrayObject $update) + { + $iterator = $update->getIterator(); + + while ($iterator->valid()) { + $this[$iterator->key()] = $iterator->current(); + $iterator->next(); + } + + return $this; + } + + /** + * Merge another result into this result. Data already + * existing in this result takes precedence over the + * data in the Result being merged. + * + * $data['message'] is handled specially, and is appended + * to $this->message if set. + * + * @param array $data + * + * @return array + */ + public function mergeData(array $data) + { + $mergedData = $this->getArrayCopy() + $data; + $this->exchangeArray($mergedData); + return $mergedData; + } + + /** + * @return bool + */ + public function hasExecutionTime() + { + return isset($this['time']); + } + + /** + * @return null|float + */ + public function getExecutionTime() + { + if (!$this->hasExecutionTime()) { + return null; + } + return $this['time']; + } + + /** + * Accumulate execution time + */ + public function accumulateExecutionTime($duration) + { + // Convert data arrays to scalar + if (is_array($duration)) { + $duration = isset($duration['time']) ? $duration['time'] : 0; + } + $this['time'] = $this->getExecutionTime() + $duration; + return $this->getExecutionTime(); + } + + /** + * Accumulate the message. + */ + public function accumulateMessage($message) + { + if (!empty($this->message)) { + $this->message .= "\n"; + } + $this->message .= $message; + return $this->getMessage(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/StateAwareInterface.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/StateAwareInterface.php new file mode 100644 index 00000000..f86bccb8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/State/StateAwareInterface.php @@ -0,0 +1,30 @@ +state; + } + + /** + * {@inheritdoc} + */ + public function setState(Data $state) + { + $this->state = $state; + } + + /** + * {@inheritdoc} + */ + public function setStateValue($key, $value) + { + $this->state[$key] = $value; + } + + /** + * {@inheritdoc} + */ + public function updateState(Data $update) + { + $this->state->update($update); + } + + /** + * {@inheritdoc} + */ + public function resetState() + { + $this->state = new Data(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/ApiGen/ApiGen.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/ApiGen/ApiGen.php new file mode 100644 index 00000000..11ff764c --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/ApiGen/ApiGen.php @@ -0,0 +1,518 @@ +taskApiGen('./vendor/apigen/apigen.phar') + * ->config('./apigen.neon') + * ->templateConfig('vendor/apigen/apigen/templates/bootstrap/config.neon') + * ->wipeout(true) + * ->run(); + * ?> + * ``` + */ +class ApiGen extends BaseTask implements CommandInterface +{ + use \Robo\Common\ExecOneCommand; + + const BOOL_NO = 'no'; + const BOOL_YES = 'yes'; + + /** + * @var string + */ + protected $command; + protected $operation = 'generate'; + + /** + * @param null|string $pathToApiGen + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToApiGen = null) + { + $this->command = $pathToApiGen; + $command_parts = []; + preg_match('/((?:.+)?apigen(?:\.phar)?) ?( \w+)? ?(.+)?/', $this->command, $command_parts); + if (count($command_parts) === 3) { + list(, $this->command, $this->operation) = $command_parts; + } + if (count($command_parts) === 4) { + list(, $this->command, $this->operation, $arg) = $command_parts; + $this->arg($arg); + } + if (!$this->command) { + $this->command = $this->findExecutablePhar('apigen'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "No apigen installation found"); + } + } + + /** + * Pass methods parameters as arguments to executable. Argument values + * are automatically escaped. + * + * @param string|string[] $args + * + * @return $this + */ + public function args($args) + { + if (!is_array($args)) { + $args = func_get_args(); + } + $args = array_map(function ($arg) { + if (preg_match('/^\w+$/', trim($arg)) === 1) { + $this->operation = $arg; + return null; + } + return $arg; + }, $args); + $args = array_filter($args); + $this->arguments .= ' ' . implode(' ', array_map('static::escape', $args)); + return $this; + } + + /** + * @param array|Traversable|string $arg a single object or something traversable + * + * @return array|Traversable the provided argument if it was already traversable, or the given + * argument returned as a one-element array + */ + protected static function forceTraversable($arg) + { + $traversable = $arg; + if (!is_array($traversable) && !($traversable instanceof \Traversable)) { + $traversable = array($traversable); + } + return $traversable; + } + + /** + * @param array|string $arg a single argument or an array of multiple string values + * + * @return string a comma-separated string of all of the provided arguments, suitable + * as a command-line "list" type argument for ApiGen + */ + protected static function asList($arg) + { + $normalized = is_array($arg) ? $arg : array($arg); + return implode(',', $normalized); + } + + /** + * @param bool|string $val an argument to be normalized + * @param string $default one of self::BOOL_YES or self::BOOK_NO if the provided + * value could not deterministically be converted to a + * yes or no value + * + * @return string the given value as a command-line "yes|no" type of argument for ApiGen, + * or the default value if none could be determined + */ + protected static function asTextBool($val, $default) + { + if ($val === self::BOOL_YES || $val === self::BOOL_NO) { + return $val; + } + if (!$val) { + return self::BOOL_NO; + } + if ($val === true) { + return self::BOOL_YES; + } + if (is_numeric($val) && $val != 0) { + return self::BOOL_YES; + } + if (strcasecmp($val[0], 'y') === 0) { + return self::BOOL_YES; + } + if (strcasecmp($val[0], 'n') === 0) { + return self::BOOL_NO; + } + // meh, good enough, let apigen sort it out + return $default; + } + + /** + * @param string $config + * + * @return $this + */ + public function config($config) + { + $this->option('config', $config); + return $this; + } + + /** + * @param array|string|Traversable $src one or more source values + * + * @return $this + */ + public function source($src) + { + foreach (self::forceTraversable($src) as $source) { + $this->option('source', $source); + } + return $this; + } + + /** + * @param string $dest + * + * @return $this + */ + public function destination($dest) + { + $this->option('destination', $dest); + return $this; + } + + /** + * @param array|string $exts one or more extensions + * + * @return $this + */ + public function extensions($exts) + { + $this->option('extensions', self::asList($exts)); + return $this; + } + + /** + * @param array|string $exclude one or more exclusions + * + * @return $this + */ + public function exclude($exclude) + { + foreach (self::forceTraversable($exclude) as $excl) { + $this->option('exclude', $excl); + } + return $this; + } + + /** + * @param array|string|Traversable $path one or more skip-doc-path values + * + * @return $this + */ + public function skipDocPath($path) + { + foreach (self::forceTraversable($path) as $skip) { + $this->option('skip-doc-path', $skip); + } + return $this; + } + + /** + * @param array|string|Traversable $prefix one or more skip-doc-prefix values + * + * @return $this + */ + public function skipDocPrefix($prefix) + { + foreach (self::forceTraversable($prefix) as $skip) { + $this->option('skip-doc-prefix', $skip); + } + return $this; + } + + /** + * @param array|string $charset one or more charsets + * + * @return $this + */ + public function charset($charset) + { + $this->option('charset', self::asList($charset)); + return $this; + } + + /** + * @param string $name + * + * @return $this + */ + public function mainProjectNamePrefix($name) + { + $this->option('main', $name); + return $this; + } + + /** + * @param string $title + * + * @return $this + */ + public function title($title) + { + $this->option('title', $title); + return $this; + } + + /** + * @param string $baseUrl + * + * @return $this + */ + public function baseUrl($baseUrl) + { + $this->option('base-url', $baseUrl); + return $this; + } + + /** + * @param string $id + * + * @return $this + */ + public function googleCseId($id) + { + $this->option('google-cse-id', $id); + return $this; + } + + /** + * @param string $trackingCode + * + * @return $this + */ + public function googleAnalytics($trackingCode) + { + $this->option('google-analytics', $trackingCode); + return $this; + } + + /** + * @param mixed $templateConfig + * + * @return $this + */ + public function templateConfig($templateConfig) + { + $this->option('template-config', $templateConfig); + return $this; + } + + /** + * @param array|string $tags one or more supported html tags + * + * @return $this + */ + public function allowedHtml($tags) + { + $this->option('allowed-html', self::asList($tags)); + return $this; + } + + /** + * @param string $groups + * + * @return $this + */ + public function groups($groups) + { + $this->option('groups', $groups); + return $this; + } + + /** + * @param array|string $types or more supported autocomplete types + * + * @return $this + */ + public function autocomplete($types) + { + $this->option('autocomplete', self::asList($types)); + return $this; + } + + /** + * @param array|string $levels one or more access levels + * + * @return $this + */ + public function accessLevels($levels) + { + $this->option('access-levels', self::asList($levels)); + return $this; + } + + /** + * @param boolean|string $internal 'yes' or true if internal, 'no' or false if not + * + * @return $this + */ + public function internal($internal) + { + $this->option('internal', self::asTextBool($internal, self::BOOL_NO)); + return $this; + } + + /** + * @param boolean|string $php 'yes' or true to generate documentation for internal php classes, + * 'no' or false otherwise + * + * @return $this + */ + public function php($php) + { + $this->option('php', self::asTextBool($php, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $tree 'yes' or true to generate a tree view of classes, 'no' or false otherwise + * + * @return $this + */ + public function tree($tree) + { + $this->option('tree', self::asTextBool($tree, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $dep 'yes' or true to generate documentation for deprecated classes, 'no' or false otherwise + * + * @return $this + */ + public function deprecated($dep) + { + $this->option('deprecated', self::asTextBool($dep, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $todo 'yes' or true to document tasks, 'no' or false otherwise + * + * @return $this + */ + public function todo($todo) + { + $this->option('todo', self::asTextBool($todo, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $src 'yes' or true to generate highlighted source code, 'no' or false otherwise + * + * @return $this + */ + public function sourceCode($src) + { + $this->option('source-code', self::asTextBool($src, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $zipped 'yes' or true to generate downloadable documentation, 'no' or false otherwise + * + * @return $this + */ + public function download($zipped) + { + $this->option('download', self::asTextBool($zipped, self::BOOL_NO)); + return $this; + } + + public function report($path) + { + $this->option('report', $path); + return $this; + } + + /** + * @param bool|string $wipeout 'yes' or true to clear out the destination directory, 'no' or false otherwise + * + * @return $this + */ + public function wipeout($wipeout) + { + $this->option('wipeout', self::asTextBool($wipeout, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $quiet 'yes' or true for quiet, 'no' or false otherwise + * + * @return $this + */ + public function quiet($quiet) + { + $this->option('quiet', self::asTextBool($quiet, self::BOOL_NO)); + return $this; + } + + /** + * @param bool|string $bar 'yes' or true to display a progress bar, 'no' or false otherwise + * + * @return $this + */ + public function progressbar($bar) + { + $this->option('progressbar', self::asTextBool($bar, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $colors 'yes' or true colorize the output, 'no' or false otherwise + * + * @return $this + */ + public function colors($colors) + { + $this->option('colors', self::asTextBool($colors, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $check 'yes' or true to check for updates, 'no' or false otherwise + * + * @return $this + */ + public function updateCheck($check) + { + $this->option('update-check', self::asTextBool($check, self::BOOL_YES)); + return $this; + } + + /** + * @param bool|string $debug 'yes' or true to enable debug mode, 'no' or false otherwise + * + * @return $this + */ + public function debug($debug) + { + $this->option('debug', self::asTextBool($debug, self::BOOL_NO)); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return "$this->command $this->operation$this->arguments"; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running ApiGen {args}', ['args' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/ApiGen/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/ApiGen/loadTasks.php new file mode 100644 index 00000000..e8cd372a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/ApiGen/loadTasks.php @@ -0,0 +1,15 @@ +task(ApiGen::class, $pathToApiGen); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/Extract.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/Extract.php new file mode 100644 index 00000000..a00a0baf --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/Extract.php @@ -0,0 +1,279 @@ +taskExtract($archivePath) + * ->to($destination) + * ->preserveTopDirectory(false) // the default + * ->run(); + * ?> + * ``` + */ +class Extract extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $filename; + + /** + * @var string + */ + protected $to; + + /** + * @var bool + */ + private $preserveTopDirectory = false; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * Location to store extracted files. + * + * @param string $to + * + * @return $this + */ + public function to($to) + { + $this->to = $to; + return $this; + } + + /** + * @param bool $preserve + * + * @return $this + */ + public function preserveTopDirectory($preserve = true) + { + $this->preserveTopDirectory = $preserve; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!file_exists($this->filename)) { + $this->printTaskError("File {filename} does not exist", ['filename' => $this->filename]); + + return false; + } + if (!($mimetype = static::archiveType($this->filename))) { + $this->printTaskError("Could not determine type of archive for {filename}", ['filename' => $this->filename]); + + return false; + } + + // We will first extract to $extractLocation and then move to $this->to + $extractLocation = static::getTmpDir(); + @mkdir($extractLocation); + @mkdir(dirname($this->to)); + + $this->startTimer(); + + $this->printTaskInfo("Extracting {filename}", ['filename' => $this->filename]); + + $result = $this->extractAppropriateType($mimetype, $extractLocation); + if ($result->wasSuccessful()) { + $this->printTaskInfo("{filename} extracted", ['filename' => $this->filename]); + // Now, we want to move the extracted files to $this->to. There + // are two possibilities that we must consider: + // + // (1) Archived files were encapsulated in a folder with an arbitrary name + // (2) There was no encapsulating folder, and all the files in the archive + // were extracted into $extractLocation + // + // In the case of (1), we want to move and rename the encapsulating folder + // to $this->to. + // + // In the case of (2), we will just move and rename $extractLocation. + $filesInExtractLocation = glob("$extractLocation/*"); + $hasEncapsulatingFolder = ((count($filesInExtractLocation) == 1) && is_dir($filesInExtractLocation[0])); + if ($hasEncapsulatingFolder && !$this->preserveTopDirectory) { + $result = (new FilesystemStack()) + ->inflect($this) + ->rename($filesInExtractLocation[0], $this->to) + ->run(); + (new DeleteDir($extractLocation)) + ->inflect($this) + ->run(); + } else { + $result = (new FilesystemStack()) + ->inflect($this) + ->rename($extractLocation, $this->to) + ->run(); + } + } + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * @param string $mimetype + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractAppropriateType($mimetype, $extractLocation) + { + // Perform the extraction of a zip file. + if (($mimetype == 'application/zip') || ($mimetype == 'application/x-zip')) { + return $this->extractZip($extractLocation); + } + return $this->extractTar($extractLocation); + } + + /** + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractZip($extractLocation) + { + if (!extension_loaded('zlib')) { + return Result::errorMissingExtension($this, 'zlib', 'zip extracting'); + } + + $zip = new \ZipArchive(); + if (($status = $zip->open($this->filename)) !== true) { + return Result::error($this, "Could not open zip archive {$this->filename}"); + } + if (!$zip->extractTo($extractLocation)) { + return Result::error($this, "Could not extract zip archive {$this->filename}"); + } + $zip->close(); + + return Result::success($this); + } + + /** + * @param string $extractLocation + * + * @return \Robo\Result + */ + protected function extractTar($extractLocation) + { + if (!class_exists('Archive_Tar')) { + return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar'); + } + $tar_object = new \Archive_Tar($this->filename); + if (!$tar_object->extract($extractLocation)) { + return Result::error($this, "Could not extract tar archive {$this->filename}"); + } + + return Result::success($this); + } + + /** + * @param string $filename + * + * @return bool|string + */ + protected static function archiveType($filename) + { + $content_type = false; + if (class_exists('finfo')) { + $finfo = new \finfo(FILEINFO_MIME_TYPE); + $content_type = $finfo->file($filename); + // If finfo cannot determine the content type, then we will try other methods + if ($content_type == 'application/octet-stream') { + $content_type = false; + } + } + // Examing the file's magic header bytes. + if (!$content_type) { + if ($file = fopen($filename, 'rb')) { + $first = fread($file, 2); + fclose($file); + if ($first !== false) { + // Interpret the two bytes as a little endian 16-bit unsigned int. + $data = unpack('v', $first); + switch ($data[1]) { + case 0x8b1f: + // First two bytes of gzip files are 0x1f, 0x8b (little-endian). + // See http://www.gzip.org/zlib/rfc-gzip.html#header-trailer + $content_type = 'application/x-gzip'; + break; + + case 0x4b50: + // First two bytes of zip files are 0x50, 0x4b ('PK') (little-endian). + // See http://en.wikipedia.org/wiki/Zip_(file_format)#File_headers + $content_type = 'application/zip'; + break; + + case 0x5a42: + // First two bytes of bzip2 files are 0x5a, 0x42 ('BZ') (big-endian). + // See http://en.wikipedia.org/wiki/Bzip2#File_format + $content_type = 'application/x-bzip2'; + break; + } + } + } + } + // 3. Lastly if above methods didn't work, try to guess the mime type from + // the file extension. This is useful if the file has no identificable magic + // header bytes (for example tarballs). + if (!$content_type) { + // Remove querystring from the filename, if present. + $filename = basename(current(explode('?', $filename, 2))); + $extension_mimetype = array( + '.tar.gz' => 'application/x-gzip', + '.tgz' => 'application/x-gzip', + '.tar' => 'application/x-tar', + ); + foreach ($extension_mimetype as $extension => $ct) { + if (substr($filename, -strlen($extension)) === $extension) { + $content_type = $ct; + break; + } + } + } + + return $content_type; + } + + /** + * @return string + */ + protected static function getTmpDir() + { + return getcwd().'/tmp'.rand().time(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/Pack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/Pack.php new file mode 100644 index 00000000..0970f8e8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/Pack.php @@ -0,0 +1,257 @@ +taskPack( + * ) + * ->add('README') // Puts file 'README' in archive at the root + * ->add('project') // Puts entire contents of directory 'project' in archinve inside 'project' + * ->addFile('dir/file.txt', 'file.txt') // Takes 'file.txt' from cwd and puts it in archive inside 'dir'. + * ->run(); + * ?> + * ``` + */ +class Pack extends BaseTask implements PrintedInterface +{ + /** + * The list of items to be packed into the archive. + * + * @var array + */ + private $items = []; + + /** + * The full path to the archive to be created. + * + * @var string + */ + private $archiveFile; + + /** + * Construct the class. + * + * @param string $archiveFile The full path and name of the archive file to create. + * + * @since 1.0 + */ + public function __construct($archiveFile) + { + $this->archiveFile = $archiveFile; + } + + /** + * Satisfy the parent requirement. + * + * @return bool Always returns true. + * + * @since 1.0 + */ + public function getPrinted() + { + return true; + } + + /** + * @param string $archiveFile + * + * @return $this + */ + public function archiveFile($archiveFile) + { + $this->archiveFile = $archiveFile; + return $this; + } + + /** + * Add an item to the archive. Like file_exists(), the parameter + * may be a file or a directory. + * + * @var string + * Relative path and name of item to store in archive + * @var string + * Absolute or relative path to file or directory's location in filesystem + * + * @return $this + */ + public function addFile($placementLocation, $filesystemLocation) + { + $this->items[$placementLocation] = $filesystemLocation; + + return $this; + } + + /** + * Alias for addFile, in case anyone has angst about using + * addFile with a directory. + * + * @var string + * Relative path and name of directory to store in archive + * @var string + * Absolute or relative path to directory or directory's location in filesystem + * + * @return $this + */ + public function addDir($placementLocation, $filesystemLocation) + { + $this->addFile($placementLocation, $filesystemLocation); + + return $this; + } + + /** + * Add a file or directory, or list of same to the archive. + * + * @var string|array + * If given a string, should contain the relative filesystem path to the + * the item to store in archive; this will also be used as the item's + * path in the archive, so absolute paths should not be used here. + * If given an array, the key of each item should be the path to store + * in the archive, and the value should be the filesystem path to the + * item to store. + * @return $this + */ + public function add($item) + { + if (is_array($item)) { + $this->items = array_merge($this->items, $item); + } else { + $this->addFile($item, $item); + } + + return $this; + } + + /** + * Create a zip archive for distribution. + * + * @return \Robo\Result + * + * @since 1.0 + */ + public function run() + { + $this->startTimer(); + + // Use the file extension to determine what kind of archive to create. + $fileInfo = new \SplFileInfo($this->archiveFile); + $extension = strtolower($fileInfo->getExtension()); + if (empty($extension)) { + return Result::error($this, "Archive filename must use an extension (e.g. '.zip') to specify the kind of archive to create."); + } + + try { + // Inform the user which archive we are creating + $this->printTaskInfo("Creating archive {filename}", ['filename' => $this->archiveFile]); + if ($extension == 'zip') { + $result = $this->archiveZip($this->archiveFile, $this->items); + } else { + $result = $this->archiveTar($this->archiveFile, $this->items); + } + $this->printTaskSuccess("{filename} created.", ['filename' => $this->archiveFile]); + } catch (\Exception $e) { + $this->printTaskError("Could not create {filename}. {exception}", ['filename' => $this->archiveFile, 'exception' => $e->getMessage(), '_style' => ['exception' => '']]); + $result = Result::error($this, sprintf('Could not create %s. %s', $this->archiveFile, $e->getMessage())); + } + $this->stopTimer(); + $result['time'] = $this->getExecutionTime(); + + return $result; + } + + /** + * @param string $archiveFile + * @param array $items + * + * @return \Robo\Result + */ + protected function archiveTar($archiveFile, $items) + { + if (!class_exists('Archive_Tar')) { + return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar'); + } + + $tar_object = new \Archive_Tar($archiveFile); + foreach ($items as $placementLocation => $filesystemLocation) { + $p_remove_dir = $filesystemLocation; + $p_add_dir = $placementLocation; + if (is_file($filesystemLocation)) { + $p_remove_dir = dirname($filesystemLocation); + $p_add_dir = dirname($placementLocation); + if (basename($filesystemLocation) != basename($placementLocation)) { + return Result::error($this, "Tar archiver does not support renaming files during extraction; could not add $filesystemLocation as $placementLocation."); + } + } + + if (!$tar_object->addModify([$filesystemLocation], $p_add_dir, $p_remove_dir)) { + return Result::error($this, "Could not add $filesystemLocation to the archive."); + } + } + + return Result::success($this); + } + + /** + * @param string $archiveFile + * @param array $items + * + * @return \Robo\Result + */ + protected function archiveZip($archiveFile, $items) + { + if (!extension_loaded('zlib')) { + return Result::errorMissingExtension($this, 'zlib', 'zip packing'); + } + + $zip = new \ZipArchive($archiveFile, \ZipArchive::CREATE); + if (!$zip->open($archiveFile, \ZipArchive::CREATE)) { + return Result::error($this, "Could not create zip archive {$archiveFile}"); + } + $result = $this->addItemsToZip($zip, $items); + $zip->close(); + + return $result; + } + + /** + * @param \ZipArchive $zip + * @param array $items + * + * @return \Robo\Result + */ + protected function addItemsToZip($zip, $items) + { + foreach ($items as $placementLocation => $filesystemLocation) { + if (is_dir($filesystemLocation)) { + $finder = new Finder(); + $finder->files()->in($filesystemLocation)->ignoreDotFiles(false); + + foreach ($finder as $file) { + // Replace Windows slashes or resulting zip will have issues on *nixes. + $relativePathname = str_replace('\\', '/', $file->getRelativePathname()); + + if (!$zip->addFile($file->getRealpath(), "{$placementLocation}/{$relativePathname}")) { + return Result::error($this, "Could not add directory $filesystemLocation to the archive; error adding {$file->getRealpath()}."); + } + } + } elseif (is_file($filesystemLocation)) { + if (!$zip->addFile($filesystemLocation, $placementLocation)) { + return Result::error($this, "Could not add file $filesystemLocation to the archive."); + } + } else { + return Result::error($this, "Could not find $filesystemLocation for the archive."); + } + } + + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/loadTasks.php new file mode 100644 index 00000000..cf846fdf --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Archive/loadTasks.php @@ -0,0 +1,25 @@ +task(Pack::class, $filename); + } + + /** + * @param $filename + * + * @return Extract + */ + protected function taskExtract($filename) + { + return $this->task(Extract::class, $filename); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/CssPreprocessor.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/CssPreprocessor.php new file mode 100644 index 00000000..a15d2078 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/CssPreprocessor.php @@ -0,0 +1,214 @@ +files = $input; + + $this->setDefaultCompiler(); + } + + protected function setDefaultCompiler() + { + if (isset($this->compilers[0])) { + //set first compiler as default + $this->compiler = $this->compilers[0]; + } + } + + /** + * Sets import directories + * Alias for setImportPaths + * @see CssPreprocessor::setImportPaths + * + * @param array|string $dirs + * + * @return $this + */ + public function importDir($dirs) + { + return $this->setImportPaths($dirs); + } + + /** + * Adds import directory + * + * @param string $dir + * + * @return $this + */ + public function addImportPath($dir) + { + if (!isset($this->compilerOptions['importDirs'])) { + $this->compilerOptions['importDirs'] = []; + } + + if (!in_array($dir, $this->compilerOptions['importDirs'], true)) { + $this->compilerOptions['importDirs'][] = $dir; + } + + return $this; + } + + /** + * Sets import directories + * + * @param array|string $dirs + * + * @return $this + */ + public function setImportPaths($dirs) + { + if (!is_array($dirs)) { + $dirs = [$dirs]; + } + + $this->compilerOptions['importDirs'] = $dirs; + + return $this; + } + + /** + * @param string $formatterName + * + * @return $this + */ + public function setFormatter($formatterName) + { + $this->compilerOptions['formatter'] = $formatterName; + + return $this; + } + + /** + * Sets the compiler. + * + * @param string $compiler + * @param array $options + * + * @return $this + */ + public function compiler($compiler, array $options = []) + { + $this->compiler = $compiler; + $this->compilerOptions = array_merge($this->compilerOptions, $options); + + return $this; + } + + /** + * Compiles file + * + * @param $file + * + * @return bool|mixed + */ + protected function compile($file) + { + if (is_callable($this->compiler)) { + return call_user_func($this->compiler, $file, $this->compilerOptions); + } + + if (method_exists($this, $this->compiler)) { + return $this->{$this->compiler}($file); + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!in_array($this->compiler, $this->compilers, true) + && !is_callable($this->compiler) + ) { + $message = sprintf('Invalid ' . static::FORMAT_NAME . ' compiler %s!', $this->compiler); + + return Result::error($this, $message); + } + + foreach ($this->files as $in => $out) { + if (!file_exists($in)) { + $message = sprintf('File %s not found.', $in); + + return Result::error($this, $message); + } + if (file_exists($out) && !is_writable($out)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + } + + foreach ($this->files as $in => $out) { + $css = $this->compile($in); + + if ($css instanceof Result) { + return $css; + } elseif (false === $css) { + $message = sprintf( + ucfirst(static::FORMAT_NAME) . ' compilation failed for %s.', + $in + ); + + return Result::error($this, $message); + } + + $dst = $out . '.part'; + $write_result = file_put_contents($dst, $css); + + if (false === $write_result) { + $message = sprintf('File write failed: %s', $out); + + @unlink($dst); + return Result::error($this, $message); + } + + // Cannot be cross-volume: should always succeed + @rename($dst, $out); + + $this->printTaskSuccess('Wrote CSS to {filename}', ['filename' => $out]); + } + + return Result::success($this, 'All ' . static::FORMAT_NAME . ' files compiled.'); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/ImageMinify.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/ImageMinify.php new file mode 100644 index 00000000..1aa62593 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/ImageMinify.php @@ -0,0 +1,716 @@ +taskImageMinify('assets/images/*') + * ->to('dist/images/') + * ->run(); + * ``` + * + * This will use the following minifiers: + * + * - PNG: optipng + * - GIF: gifsicle + * - JPG, JPEG: jpegtran + * - SVG: svgo + * + * When the minifier is specified the task will use that for all the input files. In that case + * it is useful to filter the files with the extension: + * + * ```php + * $this->taskImageMinify('assets/images/*.png') + * ->to('dist/images/') + * ->minifier('pngcrush'); + * ->run(); + * ``` + * + * The task supports the following minifiers: + * + * - optipng + * - pngquant + * - advpng + * - pngout + * - zopflipng + * - pngcrush + * - gifsicle + * - jpegoptim + * - jpeg-recompress + * - jpegtran + * - svgo (only minification, no downloading) + * + * You can also specifiy extra options for the minifiers: + * + * ```php + * $this->taskImageMinify('assets/images/*.jpg') + * ->to('dist/images/') + * ->minifier('jpegtran', ['-progressive' => null, '-copy' => 'none']) + * ->run(); + * ``` + * + * This will execute as: + * `jpegtran -copy none -progressive -optimize -outfile "dist/images/test.jpg" "/var/www/test/assets/images/test.jpg"` + */ +class ImageMinify extends BaseTask +{ + /** + * Destination directory for the minified images. + * + * @var string + */ + protected $to; + + /** + * Array of the source files. + * + * @var array + */ + protected $dirs = []; + + /** + * Symfony 2 filesystem. + * + * @var sfFilesystem + */ + protected $fs; + + /** + * Target directory for the downloaded binary executables. + * + * @var string + */ + protected $executableTargetDir; + + /** + * Array for the downloaded binary executables. + * + * @var array + */ + protected $executablePaths = []; + + /** + * Array for the individual results of all the files. + * + * @var array + */ + protected $results = []; + + /** + * Default minifier to use. + * + * @var string + */ + protected $minifier; + + /** + * Array for minifier options. + * + * @var array + */ + protected $minifierOptions = []; + + /** + * Supported minifiers. + * + * @var array + */ + protected $minifiers = [ + // Default 4 + 'optipng', + 'gifsicle', + 'jpegtran', + 'svgo', + // PNG + 'pngquant', + 'advpng', + 'pngout', + 'zopflipng', + 'pngcrush', + // JPG + 'jpegoptim', + 'jpeg-recompress', + ]; + + /** + * Binary repositories of Imagemin. + * + * @link https://github.com/imagemin + * + * @var array + */ + protected $imageminRepos = [ + // PNG + 'optipng' => 'https://github.com/imagemin/optipng-bin', + 'pngquant' => 'https://github.com/imagemin/pngquant-bin', + 'advpng' => 'https://github.com/imagemin/advpng-bin', + 'pngout' => 'https://github.com/imagemin/pngout-bin', + 'zopflipng' => 'https://github.com/imagemin/zopflipng-bin', + 'pngcrush' => 'https://github.com/imagemin/pngcrush-bin', + // Gif + 'gifsicle' => 'https://github.com/imagemin/gifsicle-bin', + // JPG + 'jpegtran' => 'https://github.com/imagemin/jpegtran-bin', + 'jpegoptim' => 'https://github.com/imagemin/jpegoptim-bin', + 'cjpeg' => 'https://github.com/imagemin/mozjpeg-bin', // note: we do not support this minifier because it creates JPG from non-JPG files + 'jpeg-recompress' => 'https://github.com/imagemin/jpeg-recompress-bin', + // WebP + 'cwebp' => 'https://github.com/imagemin/cwebp-bin', // note: we do not support this minifier because it creates WebP from non-WebP files + ]; + + public function __construct($dirs) + { + is_array($dirs) + ? $this->dirs = $dirs + : $this->dirs[] = $dirs; + + $this->fs = new sfFilesystem(); + + // guess the best path for the executables based on __DIR__ + if (($pos = strpos(__DIR__, 'consolidation/robo')) !== false) { + // the executables should be stored in vendor/bin + $this->executableTargetDir = substr(__DIR__, 0, $pos).'bin'; + } + + // check if the executables are already available + foreach ($this->imageminRepos as $exec => $url) { + $path = $this->executableTargetDir.'/'.$exec; + // if this is Windows add a .exe extension + if (substr($this->getOS(), 0, 3) == 'win') { + $path .= '.exe'; + } + if (is_file($path)) { + $this->executablePaths[$exec] = $path; + } + } + } + + /** + * {@inheritdoc} + */ + public function run() + { + // find the files + $files = $this->findFiles($this->dirs); + + // minify the files + $result = $this->minify($files); + // check if there was an error + if ($result instanceof Result) { + return $result; + } + + $amount = (count($files) == 1 ? 'image' : 'images'); + $message = "Minified {filecount} out of {filetotal} $amount into {destination}"; + $context = ['filecount' => count($this->results['success']), 'filetotal' => count($files), 'destination' => $this->to]; + + if (count($this->results['success']) == count($files)) { + $this->printTaskSuccess($message, $context); + + return Result::success($this, $message, $context); + } else { + return Result::error($this, $message, $context); + } + } + + /** + * Sets the target directory where the files will be copied to. + * + * @param string $target + * + * @return $this + */ + public function to($target) + { + $this->to = rtrim($target, '/'); + + return $this; + } + + /** + * Sets the minifier. + * + * @param string $minifier + * @param array $options + * + * @return $this + */ + public function minifier($minifier, array $options = []) + { + $this->minifier = $minifier; + $this->minifierOptions = array_merge($this->minifierOptions, $options); + + return $this; + } + + /** + * @param array $dirs + * + * @return array|\Robo\Result + * + * @throws \Robo\Exception\TaskException + */ + protected function findFiles($dirs) + { + $files = array(); + + // find the files + foreach ($dirs as $k => $v) { + // reset finder + $finder = new Finder(); + + $dir = $k; + $to = $v; + // check if target was given with the to() method instead of key/value pairs + if (is_int($k)) { + $dir = $v; + if (isset($this->to)) { + $to = $this->to; + } else { + throw new TaskException($this, 'target directory is not defined'); + } + } + + try { + $finder->files()->in($dir); + } catch (\InvalidArgumentException $e) { + // if finder cannot handle it, try with in()->name() + if (strpos($dir, '/') === false) { + $dir = './'.$dir; + } + $parts = explode('/', $dir); + $new_dir = implode('/', array_slice($parts, 0, -1)); + try { + $finder->files()->in($new_dir)->name(array_pop($parts)); + } catch (\InvalidArgumentException $e) { + return Result::fromException($this, $e); + } + } + + foreach ($finder as $file) { + // store the absolute path as key and target as value in the files array + $files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to); + } + $fileNoun = count($finder) == 1 ? ' file' : ' files'; + $this->printTaskInfo("Found {filecount} $fileNoun in {dir}", ['filecount' => count($finder), 'dir' => $dir]); + } + + return $files; + } + + /** + * @param string $file + * @param string $to + * + * @return string + */ + protected function getTarget($file, $to) + { + $target = $to.'/'.basename($file); + + return $target; + } + + /** + * @param array $files + * + * @return \Robo\Result + */ + protected function minify($files) + { + // store the individual results into the results array + $this->results = [ + 'success' => [], + 'error' => [], + ]; + + // loop through the files + foreach ($files as $from => $to) { + if (!isset($this->minifier)) { + // check filetype based on the extension + $extension = strtolower(pathinfo($from, PATHINFO_EXTENSION)); + + // set the default minifiers based on the extension + switch ($extension) { + case 'png': + $minifier = 'optipng'; + break; + case 'jpg': + case 'jpeg': + $minifier = 'jpegtran'; + break; + case 'gif': + $minifier = 'gifsicle'; + break; + case 'svg': + $minifier = 'svgo'; + break; + } + } else { + if (!in_array($this->minifier, $this->minifiers, true) + && !is_callable(strtr($this->minifier, '-', '_')) + ) { + $message = sprintf('Invalid minifier %s!', $this->minifier); + + return Result::error($this, $message); + } + $minifier = $this->minifier; + } + + // Convert minifier name to camelCase (e.g. jpeg-recompress) + $funcMinifier = $this->camelCase($minifier); + + // call the minifier method which prepares the command + if (is_callable($funcMinifier)) { + $command = call_user_func($funcMinifier, $from, $to, $this->minifierOptions); + } elseif (method_exists($this, $funcMinifier)) { + $command = $this->{$funcMinifier}($from, $to); + } else { + $message = sprintf('Minifier method %s cannot be found!', $funcMinifier); + + return Result::error($this, $message); + } + + // launch the command + $this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]); + $result = $this->executeCommand($command); + + // check the return code + if ($result->getExitCode() == 127) { + $this->printTaskError('The {minifier} executable cannot be found', ['minifier' => $minifier]); + // try to install from imagemin repository + if (array_key_exists($minifier, $this->imageminRepos)) { + $result = $this->installFromImagemin($minifier); + if ($result instanceof Result) { + if ($result->wasSuccessful()) { + $this->printTaskSuccess($result->getMessage()); + // retry the conversion with the downloaded executable + if (is_callable($minifier)) { + $command = call_user_func($minifier, $from, $to, $minifierOptions); + } elseif (method_exists($this, $minifier)) { + $command = $this->{$minifier}($from, $to); + } + // launch the command + $this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]); + $result = $this->executeCommand($command); + } else { + $this->printTaskError($result->getMessage()); + // the download was not successful + return $result; + } + } + } else { + return $result; + } + } + + // check the success of the conversion + if ($result->getExitCode() !== 0) { + $this->results['error'][] = $from; + } else { + $this->results['success'][] = $from; + } + } + } + + /** + * @return string + */ + protected function getOS() + { + $os = php_uname('s'); + $os .= '/'.php_uname('m'); + // replace x86_64 to x64, because the imagemin repo uses that + $os = str_replace('x86_64', 'x64', $os); + // replace i386, i686, etc to x86, because of imagemin + $os = preg_replace('/i[0-9]86/', 'x86', $os); + // turn info to lowercase, because of imagemin + $os = strtolower($os); + + return $os; + } + + /** + * @param string $command + * + * @return \Robo\Result + */ + protected function executeCommand($command) + { + // insert the options into the command + $a = explode(' ', $command); + $executable = array_shift($a); + foreach ($this->minifierOptions as $key => $value) { + // first prepend the value + if (!empty($value)) { + array_unshift($a, $value); + } + // then add the key + if (!is_numeric($key)) { + array_unshift($a, $key); + } + } + // check if the executable can be replaced with the downloaded one + if (array_key_exists($executable, $this->executablePaths)) { + $executable = $this->executablePaths[$executable]; + } + array_unshift($a, $executable); + $command = implode(' ', $a); + + // execute the command + $exec = new Exec($command); + + return $exec->inflect($this)->printed(false)->run(); + } + + /** + * @param string $executable + * + * @return \Robo\Result + */ + protected function installFromImagemin($executable) + { + // check if there is an url defined for the executable + if (!array_key_exists($executable, $this->imageminRepos)) { + $message = sprintf('The executable %s cannot be found in the defined imagemin repositories', $executable); + + return Result::error($this, $message); + } + $this->printTaskInfo('Downloading the {executable} executable from the imagemin repository', ['executable' => $executable]); + + $os = $this->getOS(); + $url = $this->imageminRepos[$executable].'/blob/master/vendor/'.$os.'/'.$executable.'?raw=true'; + if (substr($os, 0, 3) == 'win') { + // if it is win, add a .exe extension + $url = $this->imageminRepos[$executable].'/blob/master/vendor/'.$os.'/'.$executable.'.exe?raw=true'; + } + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is something wrong with the url, try it without the version info + $url = preg_replace('/x[68][64]\//', '', $url); + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is still something wrong with the url if it is win, try with win32 + if (substr($os, 0, 3) == 'win') { + $url = preg_replace('win/', 'win32/', $url); + $data = @file_get_contents($url, false, null); + if ($data === false) { + // there is nothing more we can do + $message = sprintf('Could not download the executable %s', $executable); + + return Result::error($this, $message); + } + } + // if it is not windows there is nothing we can do + $message = sprintf('Could not download the executable %s', $executable); + + return Result::error($this, $message); + } + } + // check if target directory exists + if (!is_dir($this->executableTargetDir)) { + mkdir($this->executableTargetDir); + } + // save the executable into the target dir + $path = $this->executableTargetDir.'/'.$executable; + if (substr($os, 0, 3) == 'win') { + // if it is win, add a .exe extension + $path = $this->executableTargetDir.'/'.$executable.'.exe'; + } + $result = file_put_contents($path, $data); + if ($result === false) { + $message = sprintf('Could not copy the executable %s to %s', $executable, $target_dir); + + return Result::error($this, $message); + } + // set the binary to executable + chmod($path, 0755); + + // if everything successful, store the executable path + $this->executablePaths[$executable] = $this->executableTargetDir.'/'.$executable; + // if it is win, add a .exe extension + if (substr($os, 0, 3) == 'win') { + $this->executablePaths[$executable] .= '.exe'; + } + + $message = sprintf('Executable %s successfully downloaded', $executable); + + return Result::success($this, $message); + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function optipng($from, $to) + { + $command = sprintf('optipng -quiet -out "%s" -- "%s"', $to, $from); + if ($from != $to && is_file($to)) { + // earlier versions of optipng do not overwrite the target without a backup + // http://sourceforge.net/p/optipng/bugs/37/ + unlink($to); + } + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegtran($from, $to) + { + $command = sprintf('jpegtran -optimize -outfile "%s" "%s"', $to, $from); + + return $command; + } + + protected function gifsicle($from, $to) + { + $command = sprintf('gifsicle -o "%s" "%s"', $to, $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function svgo($from, $to) + { + $command = sprintf('svgo "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngquant($from, $to) + { + $command = sprintf('pngquant --force --output "%s" "%s"', $to, $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function advpng($from, $to) + { + // advpng does not have any output parameters, copy the file and then compress the copy + $command = sprintf('advpng --recompress --quiet "%s"', $to); + $this->fs->copy($from, $to, true); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngout($from, $to) + { + $command = sprintf('pngout -y -q "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function zopflipng($from, $to) + { + $command = sprintf('zopflipng -y "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function pngcrush($from, $to) + { + $command = sprintf('pngcrush -q -ow "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegoptim($from, $to) + { + // jpegoptim only takes the destination directory as an argument + $command = sprintf('jpegoptim --quiet -o --dest "%s" "%s"', dirname($to), $from); + + return $command; + } + + /** + * @param string $from + * @param string $to + * + * @return string + */ + protected function jpegRecompress($from, $to) + { + $command = sprintf('jpeg-recompress --quiet "%s" "%s"', $from, $to); + + return $command; + } + + /** + * @param string $text + * + * @return string + */ + public static function camelCase($text) + { + // non-alpha and non-numeric characters become spaces + $text = preg_replace('/[^a-z0-9]+/i', ' ', $text); + $text = trim($text); + // uppercase the first character of each word + $text = ucwords($text); + $text = str_replace(" ", "", $text); + $text = lcfirst($text); + + return $text; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Less.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Less.php new file mode 100644 index 00000000..4cfa0978 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Less.php @@ -0,0 +1,108 @@ +taskLess([ + * 'less/default.less' => 'css/default.css' + * ]) + * ->run(); + * ?> + * ``` + * + * Use one of both less compilers in your project: + * + * ``` + * "leafo/lessphp": "~0.5", + * "oyejorge/less.php": "~1.5" + * ``` + * + * Specify directory (string or array) for less imports lookup: + * + * ```php + * taskLess([ + * 'less/default.less' => 'css/default.css' + * ]) + * ->importDir('less') + * ->compiler('lessphp') + * ->run(); + * ?> + * ``` + * + * You can implement additional compilers by extending this task and adding a + * method named after them and overloading the lessCompilers() method to + * inject the name there. + */ +class Less extends CssPreprocessor +{ + const FORMAT_NAME = 'less'; + + /** + * @var string[] + */ + protected $compilers = [ + 'less', // https://github.com/oyejorge/less.php + 'lessphp', //https://github.com/leafo/lessphp + ]; + + /** + * lessphp compiler + * @link https://github.com/leafo/lessphp + * + * @param string $file + * + * @return string + */ + protected function lessphp($file) + { + if (!class_exists('\lessc')) { + return Result::errorMissingPackage($this, 'lessc', 'leafo/lessphp'); + } + + $lessCode = file_get_contents($file); + + $less = new \lessc(); + if (isset($this->compilerOptions['importDirs'])) { + $less->setImportDir($this->compilerOptions['importDirs']); + } + + return $less->compile($lessCode); + } + + /** + * less compiler + * @link https://github.com/oyejorge/less.php + * + * @param string $file + * + * @return string + */ + protected function less($file) + { + if (!class_exists('\Less_Parser')) { + return Result::errorMissingPackage($this, 'Less_Parser', 'oyejorge/less.php'); + } + + $lessCode = file_get_contents($file); + + $parser = new \Less_Parser(); + $parser->SetOptions($this->compilerOptions); + if (isset($this->compilerOptions['importDirs'])) { + $importDirs = []; + foreach ($this->compilerOptions['importDirs'] as $dir) { + $importDirs[$dir] = $dir; + } + $parser->SetImportDirs($importDirs); + } + + $parser->parse($lessCode); + + return $parser->getCss(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Minify.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Minify.php new file mode 100644 index 00000000..3187714e --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Minify.php @@ -0,0 +1,297 @@ +taskMinify( 'web/assets/theme.css' ) + * ->run() + * ?> + * ``` + * Please install additional dependencies to use: + * + * ``` + * "patchwork/jsqueeze": "~1.0", + * "natxet/CssMin": "~3.0" + * ``` + */ +class Minify extends BaseTask +{ + /** + * @var array + */ + protected $types = ['css', 'js']; + + /** + * @var string + */ + protected $text; + + /** + * @var string + */ + protected $dst; + + /** + * @var string + */ + protected $type; + + /** + * @var array + */ + protected $squeezeOptions = [ + 'singleLine' => true, + 'keepImportantComments' => true, + 'specialVarRx' => false, + ]; + + /** + * Constructor. Accepts asset file path or string source. + * + * @param string $input + */ + public function __construct($input) + { + if (file_exists($input)) { + $this->fromFile($input); + return; + } + + $this->fromText($input); + } + + /** + * Sets destination. Tries to guess type from it. + * + * @param string $dst + * + * @return $this + */ + public function to($dst) + { + $this->dst = $dst; + + if (!empty($this->dst) && empty($this->type)) { + $this->type($this->getExtension($this->dst)); + } + + return $this; + } + + /** + * Sets type with validation. + * + * @param string $type css|js + * + * @return $this + */ + public function type($type) + { + $type = strtolower($type); + + if (in_array($type, $this->types)) { + $this->type = $type; + } + + return $this; + } + + /** + * Sets text from string source. + * + * @param string $text + * + * @return $this + */ + protected function fromText($text) + { + $this->text = (string)$text; + unset($this->type); + + return $this; + } + + /** + * Sets text from asset file path. Tries to guess type and set default destination. + * + * @param string $path + * + * @return $this + */ + protected function fromFile($path) + { + $this->text = file_get_contents($path); + + unset($this->type); + $this->type($this->getExtension($path)); + + if (empty($this->dst) && !empty($this->type)) { + $ext_length = strlen($this->type) + 1; + $this->dst = substr($path, 0, -$ext_length) . '.min.' . $this->type; + } + + return $this; + } + + /** + * Gets file extension from path. + * + * @param string $path + * + * @return string + */ + protected function getExtension($path) + { + return pathinfo($path, PATHINFO_EXTENSION); + } + + /** + * Minifies and returns text. + * + * @return string|bool + */ + protected function getMinifiedText() + { + switch ($this->type) { + case 'css': + if (!class_exists('\CssMin')) { + return Result::errorMissingPackage($this, 'CssMin', 'natxet/CssMin'); + } + + return \CssMin::minify($this->text); + break; + + case 'js': + if (!class_exists('\JSqueeze') && !class_exists('\Patchwork\JSqueeze')) { + return Result::errorMissingPackage($this, 'Patchwork\JSqueeze', 'patchwork/jsqueeze'); + } + + if (class_exists('\JSqueeze')) { + $jsqueeze = new \JSqueeze(); + } else { + $jsqueeze = new \Patchwork\JSqueeze(); + } + + return $jsqueeze->squeeze( + $this->text, + $this->squeezeOptions['singleLine'], + $this->squeezeOptions['keepImportantComments'], + $this->squeezeOptions['specialVarRx'] + ); + break; + } + + return false; + } + + /** + * Single line option for the JS minimisation. + * + * @param bool $singleLine + * + * @return $this + */ + public function singleLine($singleLine) + { + $this->squeezeOptions['singleLine'] = (bool)$singleLine; + return $this; + } + + /** + * keepImportantComments option for the JS minimisation. + * + * @param bool $keepImportantComments + * + * @return $this + */ + public function keepImportantComments($keepImportantComments) + { + $this->squeezeOptions['keepImportantComments'] = (bool)$keepImportantComments; + return $this; + } + + /** + * specialVarRx option for the JS minimisation. + * + * @param bool $specialVarRx + * + * @return $this ; + */ + public function specialVarRx($specialVarRx) + { + $this->squeezeOptions['specialVarRx'] = (bool)$specialVarRx; + return $this; + } + + /** + * @return string + */ + public function __toString() + { + return (string) $this->getMinifiedText(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->type)) { + return Result::error($this, 'Unknown asset type.'); + } + + if (empty($this->dst)) { + return Result::error($this, 'Unknown file destination.'); + } + + if (file_exists($this->dst) && !is_writable($this->dst)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + + $size_before = strlen($this->text); + $minified = $this->getMinifiedText(); + + if ($minified instanceof Result) { + return $minified; + } elseif (false === $minified) { + return Result::error($this, 'Minification failed.'); + } + + $size_after = strlen($minified); + + // Minification did not reduce file size, so use original file. + if ($size_after > $size_before) { + $minified = $this->text; + $size_after = $size_before; + } + + $dst = $this->dst . '.part'; + $write_result = file_put_contents($dst, $minified); + + if (false === $write_result) { + @unlink($dst); + return Result::error($this, 'File write failed.'); + } + // Cannot be cross-volume; should always succeed. + @rename($dst, $this->dst); + if ($size_before === 0) { + $minified_percent = 0; + } else { + $minified_percent = number_format(100 - ($size_after / $size_before * 100), 1); + } + $this->printTaskSuccess('Wrote {filepath}', ['filepath' => $this->dst]); + $context = [ + 'bytes' => $this->formatBytes($size_after), + 'reduction' => $this->formatBytes(($size_before - $size_after)), + 'percentage' => $minified_percent, + ]; + $this->printTaskSuccess('Wrote {bytes} (reduced by {reduction} / {percentage})', $context); + return Result::success($this, 'Asset minified.'); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Scss.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Scss.php new file mode 100644 index 00000000..ffd39345 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/Scss.php @@ -0,0 +1,93 @@ +taskScss([ + * 'scss/default.scss' => 'css/default.css' + * ]) + * ->importDir('assets/styles') + * ->run(); + * ?> + * ``` + * + * Use the following scss compiler in your project: + * + * ``` + * "leafo/scssphp": "~0.1", + * ``` + * + * You can implement additional compilers by extending this task and adding a + * method named after them and overloading the scssCompilers() method to + * inject the name there. + */ +class Scss extends CssPreprocessor +{ + const FORMAT_NAME = 'scss'; + + /** + * @var string[] + */ + protected $compilers = [ + 'scssphp', // https://github.com/leafo/scssphp + ]; + + /** + * scssphp compiler + * @link https://github.com/leafo/scssphp + * + * @param string $file + * + * @return string + */ + protected function scssphp($file) + { + if (!class_exists('\Leafo\ScssPhp\Compiler')) { + return Result::errorMissingPackage($this, 'scssphp', 'leafo/scssphp'); + } + + $scssCode = file_get_contents($file); + $scss = new \Leafo\ScssPhp\Compiler(); + + // set options for the scssphp compiler + if (isset($this->compilerOptions['importDirs'])) { + $scss->setImportPaths($this->compilerOptions['importDirs']); + } + + if (isset($this->compilerOptions['formatter'])) { + $scss->setFormatter($this->compilerOptions['formatter']); + } + + return $scss->compile($scssCode); + } + + /** + * Sets the formatter for scssphp + * + * The method setFormatter($formatterName) sets the current formatter to $formatterName, + * the name of a class as a string that implements the formatting interface. See the source + * for Leafo\ScssPhp\Formatter\Expanded for an example. + * + * Five formatters are included with leafo/scssphp: + * - Leafo\ScssPhp\Formatter\Expanded + * - Leafo\ScssPhp\Formatter\Nested (default) + * - Leafo\ScssPhp\Formatter\Compressed + * - Leafo\ScssPhp\Formatter\Compact + * - Leafo\ScssPhp\Formatter\Crunched + * + * @link http://leafo.github.io/scssphp/docs/#output-formatting + * + * @param string $formatterName + * + * @return $this + */ + public function setFormatter($formatterName) + { + return parent::setFormatter($formatterName); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/loadTasks.php new file mode 100644 index 00000000..12192dd8 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Assets/loadTasks.php @@ -0,0 +1,45 @@ +task(Minify::class, $input); + } + + /** + * @param string|string[] $input + * + * @return \Robo\Task\Assets\ImageMinify + */ + protected function taskImageMinify($input) + { + return $this->task(ImageMinify::class, $input); + } + + /** + * @param array $input + * + * @return \Robo\Task\Assets\Less + */ + protected function taskLess($input) + { + return $this->task(Less::class, $input); + } + + /** + * @param array $input + * + * @return \Robo\Task\Assets\Scss + */ + protected function taskScss($input) + { + return $this->task(Scss::class, $input); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/Exec.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/Exec.php new file mode 100644 index 00000000..c3e47917 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/Exec.php @@ -0,0 +1,125 @@ +taskExec('compass')->arg('watch')->run(); + * // or use shortcut + * $this->_exec('compass watch'); + * + * $this->taskExec('compass watch')->background()->run(); + * + * if ($this->taskExec('phpunit .')->run()->wasSuccessful()) { + * $this->say('tests passed'); + * } + * + * ?> + * ``` + */ +class Exec extends BaseTask implements CommandInterface, PrintedInterface, SimulatedInterface +{ + use \Robo\Common\CommandReceiver; + use \Robo\Common\ExecOneCommand; + + /** + * @var static[] + */ + protected static $instances = []; + + /** + * @var string|\Robo\Contract\CommandInterface + */ + protected $command; + + /** + * @param string|\Robo\Contract\CommandInterface $command + */ + public function __construct($command) + { + $this->command = $this->receiveCommand($command); + } + + /** + * + */ + public function __destruct() + { + $this->stop(); + } + + /** + * Executes command in background mode (asynchronously) + * + * @return $this + */ + public function background($arg = true) + { + self::$instances[] = $this; + $this->background = $arg; + return $this; + } + + /** + * {@inheritdoc} + */ + protected function getCommandDescription() + { + return $this->getCommand(); + } + /** + * {@inheritdoc} + */ + public function getCommand() + { + return trim($this->command . $this->arguments); + } + + /** + * {@inheritdoc} + */ + public function simulate($context) + { + $this->printAction($context); + } + + public static function stopRunningJobs() + { + foreach (self::$instances as $instance) { + if ($instance) { + unset($instance); + } + } + } + + /** + * {@inheritdoc} + */ + public function run() + { + // TODO: Symfony 4 requires that we supply the working directory. + $result_data = $this->execute(new Process($this->getCommand(), getcwd())); + return new Result( + $this, + $result_data->getExitCode(), + $result_data->getMessage(), + $result_data->getData() + ); + } +} + +if (function_exists('pcntl_signal')) { + pcntl_signal(SIGTERM, ['Robo\Task\Base\Exec', 'stopRunningJobs']); +} + +register_shutdown_function(['Robo\Task\Base\Exec', 'stopRunningJobs']); diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/ExecStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/ExecStack.php new file mode 100644 index 00000000..51b39ef1 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/ExecStack.php @@ -0,0 +1,23 @@ +taskExecStack() + * ->stopOnFail() + * ->exec('mkdir site') + * ->exec('cd site') + * ->run(); + * + * ?> + * ``` + */ +class ExecStack extends CommandStack +{ +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/ParallelExec.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/ParallelExec.php new file mode 100644 index 00000000..c98b7841 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/ParallelExec.php @@ -0,0 +1,199 @@ +taskParallelExec() + * ->process('php ~/demos/script.php hey') + * ->process('php ~/demos/script.php hoy') + * ->process('php ~/demos/script.php gou') + * ->run(); + * ?> + * ``` + */ +class ParallelExec extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\CommandReceiver; + + /** + * @var Process[] + */ + protected $processes = []; + + /** + * @var null|int + */ + protected $timeout = null; + + /** + * @var null|int + */ + protected $idleTimeout = null; + + /** + * @var null|int + */ + protected $waitInterval = 0; + + /** + * @var bool + */ + protected $isPrinted = false; + + /** + * {@inheritdoc} + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * @param bool $isPrinted + * + * @return $this + */ + public function printed($isPrinted = true) + { + $this->isPrinted = $isPrinted; + return $this; + } + + /** + * @param string|\Robo\Contract\CommandInterface $command + * + * @return $this + */ + public function process($command) + { + // TODO: Symfony 4 requires that we supply the working directory. + $this->processes[] = new Process($this->receiveCommand($command), getcwd()); + return $this; + } + + /** + * Stops process if it runs longer then `$timeout` (seconds). + * + * @param int $timeout + * + * @return $this + */ + public function timeout($timeout) + { + $this->timeout = $timeout; + return $this; + } + + /** + * Stops process if it does not output for time longer then `$timeout` (seconds). + * + * @param int $idleTimeout + * + * @return $this + */ + public function idleTimeout($idleTimeout) + { + $this->idleTimeout = $idleTimeout; + return $this; + } + + /** + * Parallel processing will wait `$waitInterval` seconds after launching each process and before + * the next one. + * + * @param int $waitInterval + * + * @return $this + */ + public function waitInterval($waitInterval) + { + $this->waitInterval = $waitInterval; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return implode(' && ', $this->processes); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + return count($this->processes); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->startProgressIndicator(); + $running = []; + $queue = $this->processes; + $nextTime = time(); + while (true) { + if (($nextTime <= time()) && !empty($queue)) { + $process = array_shift($queue); + $process->setIdleTimeout($this->idleTimeout); + $process->setTimeout($this->timeout); + $process->start(); + $this->printTaskInfo($process->getCommandLine()); + $running[] = $process; + $nextTime = time() + $this->waitInterval; + } + foreach ($running as $k => $process) { + try { + $process->checkTimeout(); + } catch (ProcessTimedOutException $e) { + $this->printTaskWarning("Process timed out for {command}", ['command' => $process->getCommandLine(), '_style' => ['command' => 'fg=white;bg=magenta']]); + } + if (!$process->isRunning()) { + $this->advanceProgressIndicator(); + if ($this->isPrinted) { + $this->printTaskInfo("Output for {command}:\n\n{output}", ['command' => $process->getCommandLine(), 'output' => $process->getOutput(), '_style' => ['command' => 'fg=white;bg=magenta']]); + $errorOutput = $process->getErrorOutput(); + if ($errorOutput) { + $this->printTaskError(rtrim($errorOutput)); + } + } + unset($running[$k]); + } + } + if (empty($running) && empty($queue)) { + break; + } + usleep(1000); + } + $this->stopProgressIndicator(); + + $errorMessage = ''; + $exitCode = 0; + foreach ($this->processes as $p) { + if ($p->getExitCode() === 0) { + continue; + } + $errorMessage .= "'" . $p->getCommandLine() . "' exited with code ". $p->getExitCode()." \n"; + $exitCode = max($exitCode, $p->getExitCode()); + } + if (!$errorMessage) { + $this->printTaskSuccess('{process-count} processes finished running', ['process-count' => count($this->processes)]); + } + + return new Result($this, $exitCode, $errorMessage, ['time' => $this->getExecutionTime()]); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/SymfonyCommand.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/SymfonyCommand.php new file mode 100644 index 00000000..708ea845 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/SymfonyCommand.php @@ -0,0 +1,75 @@ +taskSymfonyCommand(new \Codeception\Command\Run('run')) + * ->arg('suite','acceptance') + * ->opt('debug') + * ->run(); + * + * // Artisan Command + * $this->taskSymfonyCommand(new ModelGeneratorCommand()) + * ->arg('name', 'User') + * ->run(); + * ?> + * ``` + */ +class SymfonyCommand extends BaseTask +{ + /** + * @var \Symfony\Component\Console\Command\Command + */ + protected $command; + + /** + * @var string[] + */ + protected $input; + + public function __construct(Command $command) + { + $this->command = $command; + $this->input = []; + } + + /** + * @param string $arg + * @param string $value + * + * @return $this + */ + public function arg($arg, $value) + { + $this->input[$arg] = $value; + return $this; + } + + public function opt($option, $value = null) + { + $this->input["--$option"] = $value; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running command {command}', ['command' => $this->command->getName()]); + return new Result( + $this, + $this->command->run(new ArrayInput($this->input), Robo::output()) + ); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/Watch.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/Watch.php new file mode 100644 index 00000000..d7940ac9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/Watch.php @@ -0,0 +1,89 @@ +taskWatch() + * ->monitor('composer.json', function() { + * $this->taskComposerUpdate()->run(); + * })->monitor('src', function() { + * $this->taskExec('phpunit')->run(); + * })->run(); + * ?> + * ``` + */ +class Watch extends BaseTask +{ + /** + * @var \Closure + */ + protected $closure; + + /** + * @var array + */ + protected $monitor = []; + + /** + * @var object + */ + protected $bindTo; + + /** + * @param $bindTo + */ + public function __construct($bindTo) + { + $this->bindTo = $bindTo; + } + + /** + * @param string|string[] $paths + * @param \Closure $callable + * + * @return $this + */ + public function monitor($paths, \Closure $callable) + { + if (!is_array($paths)) { + $paths = [$paths]; + } + $this->monitor[] = [$paths, $callable]; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!class_exists('Lurker\\ResourceWatcher')) { + return Result::errorMissingPackage($this, 'ResourceWatcher', 'henrikbjorn/lurker'); + } + + $watcher = new ResourceWatcher(); + + foreach ($this->monitor as $k => $monitor) { + /** @var \Closure $closure */ + $closure = $monitor[1]; + $closure->bindTo($this->bindTo); + foreach ($monitor[0] as $i => $dir) { + $watcher->track("fs.$k.$i", $dir, FilesystemEvent::MODIFY); + $this->printTaskInfo('Watching {dir} for changes...', ['dir' => $dir]); + $watcher->addListener("fs.$k.$i", $closure); + } + } + + $watcher->start(); + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/loadShortcuts.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/loadShortcuts.php new file mode 100644 index 00000000..dba0af66 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/loadShortcuts.php @@ -0,0 +1,17 @@ +taskExec($command)->run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/loadTasks.php new file mode 100644 index 00000000..ab5301bb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Base/loadTasks.php @@ -0,0 +1,48 @@ +task(Exec::class, $command); + } + + /** + * @return ExecStack + */ + protected function taskExecStack() + { + return $this->task(ExecStack::class); + } + + /** + * @return ParallelExec + */ + protected function taskParallelExec() + { + return $this->task(ParallelExec::class); + } + + /** + * @param $command + * @return SymfonyCommand + */ + protected function taskSymfonyCommand($command) + { + return $this->task(SymfonyCommand::class, $command); + } + + /** + * @return Watch + */ + protected function taskWatch() + { + return $this->task(Watch::class, $this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/BaseTask.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/BaseTask.php new file mode 100644 index 00000000..66155c09 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/BaseTask.php @@ -0,0 +1,60 @@ +logger) { + $child->setLogger($this->logger); + } + if ($child instanceof ProgressIndicatorAwareInterface && $this->progressIndicator) { + $child->setProgressIndicator($this->progressIndicator); + } + if ($child instanceof ConfigAwareInterface && $this->getConfig()) { + $child->setConfig($this->getConfig()); + } + if ($child instanceof VerbosityThresholdInterface && $this->outputAdapter()) { + $child->setOutputAdapter($this->outputAdapter()); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Base.php new file mode 100644 index 00000000..9bc614c6 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Base.php @@ -0,0 +1,88 @@ +option('allow-root'); + return $this; + } + + /** + * adds `force-latest` option to bower + * + * @return $this + */ + public function forceLatest() + { + $this->option('force-latest'); + return $this; + } + + /** + * adds `production` option to bower + * + * @return $this + */ + public function noDev() + { + $this->option('production'); + return $this; + } + + /** + * adds `offline` option to bower + * + * @return $this + */ + public function offline() + { + $this->option('offline'); + return $this; + } + + /** + * Base constructor. + * + * @param null|string $pathToBower + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToBower = null) + { + $this->command = $pathToBower; + if (!$this->command) { + $this->command = $this->findExecutable('bower'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Bower executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Install.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Install.php new file mode 100644 index 00000000..c3c0ce75 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Install.php @@ -0,0 +1,36 @@ +taskBowerInstall()->run(); + * + * // prefer dist with custom path + * $this->taskBowerInstall('path/to/my/bower') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Install extends Base implements CommandInterface +{ + /** + * {@inheritdoc} + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Install Bower packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Update.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Update.php new file mode 100644 index 00000000..f0dfa94e --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/Update.php @@ -0,0 +1,34 @@ +taskBowerUpdate->run(); + * + * // prefer dist with custom path + * $this->taskBowerUpdate('path/to/my/bower') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Update Bower packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/loadTasks.php new file mode 100644 index 00000000..6e33f8ac --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Bower/loadTasks.php @@ -0,0 +1,25 @@ +task(Install::class, $pathToBower); + } + + /** + * @param null|string $pathToBower + * + * @return Update + */ + protected function taskBowerUpdate($pathToBower = null) + { + return $this->task(Update::class, $pathToBower); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/CommandStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/CommandStack.php new file mode 100644 index 00000000..f1cb4492 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/CommandStack.php @@ -0,0 +1,134 @@ +exec); + } + + /** + * @param string $executable + * + * @return $this + */ + public function executable($executable) + { + $this->executable = $executable; + return $this; + } + + /** + * @param string|string[] $command + * + * @return $this + */ + public function exec($command) + { + if (is_array($command)) { + $command = implode(' ', array_filter($command)); + } + + $command = $this->executable . ' ' . $this->stripExecutableFromCommand($command); + $this->exec[] = trim($command); + return $this; + } + + /** + * @param bool $stopOnFail + * + * @return $this + */ + public function stopOnFail($stopOnFail = true) + { + $this->stopOnFail = $stopOnFail; + return $this; + } + + public function result($result) + { + $this->result = $result; + return $this; + } + + /** + * @param string $command + * + * @return string + */ + protected function stripExecutableFromCommand($command) + { + $command = trim($command); + $executable = $this->executable . ' '; + if (strpos($command, $executable) === 0) { + $command = substr($command, strlen($executable)); + } + return $command; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->exec)) { + throw new TaskException($this, 'You must add at least one command'); + } + // If 'stopOnFail' is not set, or if there is only one command to run, + // then execute the single command to run. + if (!$this->stopOnFail || (count($this->exec) == 1)) { + $this->printTaskInfo('{command}', ['command' => $this->getCommand()]); + return $this->executeCommand($this->getCommand()); + } + + // When executing multiple commands in 'stopOnFail' mode, run them + // one at a time so that the result will have the exact command + // that failed available to the caller. This is at the expense of + // losing the output from all successful commands. + $data = []; + $message = ''; + $result = null; + foreach ($this->exec as $command) { + $this->printTaskInfo("Executing {command}", ['command' => $command]); + $result = $this->executeCommand($command); + $result->accumulateExecutionTime($data); + $message = $result->accumulateMessage($message); + $data = $result->mergeData($data); + if (!$result->wasSuccessful()) { + return $result; + } + } + + return $result; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Base.php new file mode 100644 index 00000000..de3fe217 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Base.php @@ -0,0 +1,248 @@ +command = $pathToComposer; + if (!$this->command) { + $this->command = $this->findExecutablePhar('composer'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Neither local composer.phar nor global composer installation could be found."); + } + } + + /** + * adds `prefer-dist` option to composer + * + * @return $this + */ + public function preferDist($preferDist = true) + { + if (!$preferDist) { + return $this->preferSource(); + } + $this->prefer = '--prefer-dist'; + return $this; + } + + /** + * adds `prefer-source` option to composer + * + * @return $this + */ + public function preferSource() + { + $this->prefer = '--prefer-source'; + return $this; + } + + /** + * adds `dev` option to composer + * + * @return $this + */ + public function dev($dev = true) + { + if (!$dev) { + return $this->noDev(); + } + $this->dev = '--dev'; + return $this; + } + + /** + * adds `no-dev` option to composer + * + * @return $this + */ + public function noDev() + { + $this->dev = '--no-dev'; + return $this; + } + + /** + * adds `ansi` option to composer + * + * @return $this + */ + public function ansi($ansi = true) + { + if (!$ansi) { + return $this->noAnsi(); + } + $this->ansi = '--ansi'; + return $this; + } + + /** + * adds `no-ansi` option to composer + * + * @return $this + */ + public function noAnsi() + { + $this->ansi = '--no-ansi'; + return $this; + } + + public function interaction($interaction = true) + { + if (!$interaction) { + return $this->noInteraction(); + } + return $this; + } + + /** + * adds `no-interaction` option to composer + * + * @return $this + */ + public function noInteraction() + { + $this->nointeraction = '--no-interaction'; + return $this; + } + + /** + * adds `optimize-autoloader` option to composer + * + * @return $this + */ + public function optimizeAutoloader($optimize = true) + { + if ($optimize) { + $this->option('--optimize-autoloader'); + } + return $this; + } + + /** + * adds `ignore-platform-reqs` option to composer + * + * @return $this + */ + public function ignorePlatformRequirements($ignore = true) + { + $this->option('--ignore-platform-reqs'); + return $this; + } + + /** + * disable plugins + * + * @return $this + */ + public function disablePlugins($disable = true) + { + if ($disable) { + $this->option('--no-plugins'); + } + return $this; + } + + /** + * skip scripts + * + * @return $this + */ + public function noScripts($disable = true) + { + if ($disable) { + $this->option('--no-scripts'); + } + return $this; + } + + /** + * adds `--working-dir $dir` option to composer + * + * @return $this + */ + public function workingDir($dir) + { + $this->option("--working-dir", $dir); + return $this; + } + + /** + * Copy class fields into command options as directed. + */ + public function buildCommand() + { + if (!isset($this->ansi) && $this->getConfig()->get(\Robo\Config\Config::DECORATED)) { + $this->ansi(); + } + if (!isset($this->nointeraction) && !$this->getConfig()->get(\Robo\Config\Config::INTERACTIVE)) { + $this->noInteraction(); + } + $this->option($this->prefer) + ->option($this->dev) + ->option($this->nointeraction) + ->option($this->ansi); + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + if (!$this->built) { + $this->buildCommand(); + $this->built = true; + } + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Config.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Config.php new file mode 100644 index 00000000..b5a6bbff --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Config.php @@ -0,0 +1,93 @@ +taskComposerConfig()->set('bin-dir', 'bin/')->run(); + * ?> + * ``` + */ +class Config extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'config'; + + /** + * Set a configuration value + * @return $this + */ + public function set($key, $value) + { + $this->arg($key); + $this->arg($value); + return $this; + } + + /** + * Operate on the global repository + * @return $this + */ + public function useGlobal($useGlobal = true) + { + if ($useGlobal) { + $this->option('global'); + } + return $this; + } + + /** + * @return $this + */ + public function repository($id, $uri, $repoType = 'vcs') + { + $this->arg("repositories.$id"); + $this->arg($repoType); + $this->arg($uri); + return $this; + } + + /** + * @return $this + */ + public function removeRepository($id) + { + $this->option('unset', "repositories.$id"); + return $this; + } + + /** + * @return $this + */ + public function disableRepository($id) + { + $this->arg("repositories.$id"); + $this->arg('false'); + return $this; + } + + /** + * @return $this + */ + public function enableRepository($id) + { + $this->arg("repositories.$id"); + $this->arg('true'); + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Configuring composer.json: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/CreateProject.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/CreateProject.php new file mode 100644 index 00000000..5f979a64 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/CreateProject.php @@ -0,0 +1,112 @@ +taskComposerCreateProject()->source('foo/bar')->target('myBar')->run(); + * ?> + * ``` + */ +class CreateProject extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'create-project'; + + protected $source; + protected $target = ''; + protected $version = ''; + + /** + * @return $this + */ + public function source($source) + { + $this->source = $source; + return $this; + } + + /** + * @return $this + */ + public function target($target) + { + $this->target = $target; + return $this; + } + + /** + * @return $this + */ + public function version($version) + { + $this->version = $version; + return $this; + } + + public function keepVcs($keep = true) + { + if ($keep) { + $this->option('--keep-vcs'); + } + return $this; + } + + public function noInstall($noInstall = true) + { + if ($noInstall) { + $this->option('--no-install'); + } + return $this; + } + + /** + * @return $this + */ + public function repository($repository) + { + if (!empty($repository)) { + $this->option('repository', $repository); + } + return $this; + } + + /** + * @return $this + */ + public function stability($stability) + { + if (!empty($stability)) { + $this->option('stability', $stability); + } + return $this; + } + + public function buildCommand() + { + $this->arg($this->source); + if (!empty($this->target)) { + $this->arg($this->target); + } + if (!empty($this->version)) { + $this->arg($this->version); + } + + return parent::buildCommand(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Creating project: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/DumpAutoload.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/DumpAutoload.php new file mode 100644 index 00000000..55b1ea00 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/DumpAutoload.php @@ -0,0 +1,62 @@ +taskComposerDumpAutoload()->run(); + * + * // dump auto loader with custom path + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader dump with custom path + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->optimize() + * ->run(); + * + * // optimize autoloader dump with custom path and no dev + * $this->taskComposerDumpAutoload('path/to/my/composer.phar') + * ->optimize() + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class DumpAutoload extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'dump-autoload'; + + /** + * @var string + */ + protected $optimize; + + /** + * @return $this + */ + public function optimize($optimize = true) + { + if ($optimize) { + $this->option("--optimize"); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Dumping Autoloader: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Init.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Init.php new file mode 100644 index 00000000..c841299d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Init.php @@ -0,0 +1,115 @@ +taskComposerInit()->run(); + * ?> + * ``` + */ +class Init extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'init'; + + /** + * @return $this + */ + public function projectName($projectName) + { + $this->option('name', $projectName); + return $this; + } + + /** + * @return $this + */ + public function description($description) + { + $this->option('description', $description); + return $this; + } + + /** + * @return $this + */ + public function author($author) + { + $this->option('author', $author); + return $this; + } + + /** + * @return $this + */ + public function projectType($type) + { + $this->option('type', $type); + return $this; + } + + /** + * @return $this + */ + public function homepage($homepage) + { + $this->option('homepage', $homepage); + return $this; + } + + /** + * 'require' is a keyword, so it cannot be a method name. + * @return $this + */ + public function dependency($project, $version = null) + { + if (isset($version)) { + $project .= ":$version"; + } + $this->option('require', $project); + return $this; + } + + /** + * @return $this + */ + public function stability($stability) + { + $this->option('stability', $stability); + return $this; + } + + /** + * @return $this + */ + public function license($license) + { + $this->option('license', $license); + return $this; + } + + /** + * @return $this + */ + public function repository($repository) + { + $this->option('repository', $repository); + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Creating composer.json: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Install.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Install.php new file mode 100644 index 00000000..76cb9861 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Install.php @@ -0,0 +1,40 @@ +taskComposerInstall()->run(); + * + * // prefer dist with custom path + * $this->taskComposerInstall('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader with custom path + * $this->taskComposerInstall('path/to/my/composer.phar') + * ->optimizeAutoloader() + * ->run(); + * ?> + * ``` + */ +class Install extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Installing Packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Remove.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Remove.php new file mode 100644 index 00000000..b0316f05 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Remove.php @@ -0,0 +1,85 @@ +taskComposerRemove()->run(); + * ?> + * ``` + */ +class Remove extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'remove'; + + /** + * @return $this + */ + public function dev($dev = true) + { + if ($dev) { + $this->option('--dev'); + } + return $this; + } + + /** + * @return $this + */ + public function noProgress($noProgress = true) + { + if ($noProgress) { + $this->option('--no-progress'); + } + return $this; + } + + /** + * @return $this + */ + public function noUpdate($noUpdate = true) + { + if ($noUpdate) { + $this->option('--no-update'); + } + return $this; + } + + /** + * @return $this + */ + public function updateNoDev($updateNoDev = true) + { + if ($updateNoDev) { + $this->option('--update-no-dev'); + } + return $this; + } + + /** + * @return $this + */ + public function noUpdateWithDependencies($updateWithDependencies = true) + { + if ($updateWithDependencies) { + $this->option('--no-update-with-dependencies'); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Removing packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/RequireDependency.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/RequireDependency.php new file mode 100644 index 00000000..6cdbf613 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/RequireDependency.php @@ -0,0 +1,50 @@ +taskComposerRequire()->dependency('foo/bar', '^.2.4.8')->run(); + * ?> + * ``` + */ +class RequireDependency extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'require'; + + /** + * 'require' is a keyword, so it cannot be a method name. + * @return $this + */ + public function dependency($project, $version = null) + { + $project = (array)$project; + + if (isset($version)) { + $project = array_map( + function ($item) use ($version) { + return "$item:$version"; + }, + $project + ); + } + $this->args($project); + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Requiring packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Update.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Update.php new file mode 100644 index 00000000..3a0a64af --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Update.php @@ -0,0 +1,40 @@ +taskComposerUpdate()->run(); + * + * // prefer dist with custom path + * $this->taskComposerUpdate('path/to/my/composer.phar') + * ->preferDist() + * ->run(); + * + * // optimize autoloader with custom path + * $this->taskComposerUpdate('path/to/my/composer.phar') + * ->optimizeAutoloader() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Updating Packages: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Validate.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Validate.php new file mode 100644 index 00000000..adb15854 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/Validate.php @@ -0,0 +1,85 @@ +taskComposerValidate()->run(); + * ?> + * ``` + */ +class Validate extends Base +{ + /** + * {@inheritdoc} + */ + protected $action = 'validate'; + + /** + * @return $this + */ + public function noCheckAll($noCheckAll = true) + { + if ($noCheckAll) { + $this->option('--no-check-all'); + } + return $this; + } + + /** + * @return $this + */ + public function noCheckLock($noCheckLock = true) + { + if ($noCheckLock) { + $this->option('--no-check-lock'); + } + return $this; + } + + /** + * @return $this + */ + public function noCheckPublish($noCheckPublish = true) + { + if ($noCheckPublish) { + $this->option('--no-check-publish'); + } + return $this; + } + + /** + * @return $this + */ + public function withDependencies($withDependencies = true) + { + if ($withDependencies) { + $this->option('--with-dependencies'); + } + return $this; + } + + /** + * @return $this + */ + public function strict($strict = true) + { + if ($strict) { + $this->option('--strict'); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Validating composer.json: {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/loadTasks.php new file mode 100644 index 00000000..6b074ba3 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Composer/loadTasks.php @@ -0,0 +1,95 @@ +task(Install::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Update + */ + protected function taskComposerUpdate($pathToComposer = null) + { + return $this->task(Update::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return DumpAutoload + */ + protected function taskComposerDumpAutoload($pathToComposer = null) + { + return $this->task(DumpAutoload::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Init + */ + protected function taskComposerInit($pathToComposer = null) + { + return $this->task(Init::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Init + */ + protected function taskComposerConfig($pathToComposer = null) + { + return $this->task(Config::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Validate + */ + protected function taskComposerValidate($pathToComposer = null) + { + return $this->task(Validate::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Remove + */ + protected function taskComposerRemove($pathToComposer = null) + { + return $this->task(Remove::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Remove + */ + protected function taskComposerRequire($pathToComposer = null) + { + return $this->task(RequireDependency::class, $pathToComposer); + } + + /** + * @param null|string $pathToComposer + * + * @return Remove + */ + protected function taskComposerCreateProject($pathToComposer = null) + { + return $this->task(CreateProject::class, $pathToComposer); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/Changelog.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/Changelog.php new file mode 100644 index 00000000..44af6d82 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/Changelog.php @@ -0,0 +1,246 @@ +taskChangelog() + * ->version($version) + * ->change("released to github") + * ->run(); + * ?> + * ``` + * + * Changes can be asked from Console + * + * ``` php + * taskChangelog() + * ->version($version) + * ->askForChanges() + * ->run(); + * ?> + * ``` + */ +class Changelog extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $filename; + + /** + * @var array + */ + protected $log = []; + + /** + * @var string + */ + protected $anchor = "# Changelog"; + + /** + * @var string + */ + protected $version = ""; + + /** + * @var string + */ + protected $body = ""; + + /** + * @var string + */ + protected $header = ""; + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * Sets the changelog body text. + * + * This method permits the raw changelog text to be set directly If this is set, $this->log changes will be ignored. + * + * @param string $body + * + * @return $this + */ + public function setBody($body) + { + $this->body = $body; + return $this; + } + + /** + * @param string $header + * + * @return $this + */ + public function setHeader($header) + { + $this->header = $header; + return $this; + } + + /** + * @param string $item + * + * @return $this + */ + public function log($item) + { + $this->log[] = $item; + return $this; + } + + /** + * @param string $anchor + * + * @return $this + */ + public function anchor($anchor) + { + $this->anchor = $anchor; + return $this; + } + + /** + * @param string $version + * + * @return $this + */ + public function version($version) + { + $this->version = $version; + return $this; + } + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param array $data + * + * @return $this + */ + public function changes(array $data) + { + $this->log = array_merge($this->log, $data); + return $this; + } + + /** + * @param string $change + * + * @return $this + */ + public function change($change) + { + $this->log[] = $change; + return $this; + } + + /** + * @return array + */ + public function getChanges() + { + return $this->log; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (empty($this->body)) { + if (empty($this->log)) { + return Result::error($this, "Changelog is empty"); + } + $this->body = $this->generateBody(); + } + if (empty($this->header)) { + $this->header = $this->generateHeader(); + } + + $text = $this->header . $this->body; + + if (!file_exists($this->filename)) { + $this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]); + $res = file_put_contents($this->filename, $this->anchor); + if ($res === false) { + return Result::error($this, "File {filename} cant be created", ['filename' => $this->filename]); + } + } + + /** @var \Robo\Result $result */ + // trying to append to changelog for today + $result = $this->collectionBuilder()->taskReplaceInFile($this->filename) + ->from($this->header) + ->to($text) + ->run(); + + if (!isset($result['replaced']) || !$result['replaced']) { + $result = $this->collectionBuilder()->taskReplaceInFile($this->filename) + ->from($this->anchor) + ->to($this->anchor . "\n\n" . $text) + ->run(); + } + + return new Result($this, $result->getExitCode(), $result->getMessage(), $this->log); + } + + /** + * @return \Robo\Result|string + */ + protected function generateBody() + { + $text = implode("\n", array_map([$this, 'processLogRow'], $this->log)); + $text .= "\n"; + + return $text; + } + + /** + * @return string + */ + protected function generateHeader() + { + return "#### {$this->version}\n\n"; + } + + /** + * @param $i + * + * @return string + */ + public function processLogRow($i) + { + return "* $i *" . date('Y-m-d') . "*"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GenerateMarkdownDoc.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GenerateMarkdownDoc.php new file mode 100644 index 00000000..0c3ec26c --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GenerateMarkdownDoc.php @@ -0,0 +1,782 @@ +taskGenDoc('models.md') + * ->docClass('Model\User') // take class Model\User + * ->docClass('Model\Post') // take class Model\Post + * ->filterMethods(function(\ReflectionMethod $r) { + * return $r->isPublic() or $r->isProtected(); // process public and protected methods + * })->processClass(function(\ReflectionClass $r, $text) { + * return "Class ".$r->getName()."\n\n$text\n\n###Methods\n"; + * })->run(); + * ``` + * + * By default this task generates a documentation for each public method of a class. + * It combines method signature with a docblock. Both can be post-processed. + * + * ``` php + * taskGenDoc('models.md') + * ->docClass('Model\User') + * ->processClassSignature(false) // false can be passed to not include class signature + * ->processClassDocBlock(function(\ReflectionClass $r, $text) { + * return "[This is part of application model]\n" . $text; + * })->processMethodSignature(function(\ReflectionMethod $r, $text) { + * return "#### {$r->name}()"; + * })->processMethodDocBlock(function(\ReflectionMethod $r, $text) { + * return strpos($r->name, 'save')===0 ? "[Saves to the database]\n" . $text : $text; + * })->run(); + * ``` + */ +class GenerateMarkdownDoc extends BaseTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string[] + */ + protected $docClass = []; + + /** + * @var callable + */ + protected $filterMethods; + + /** + * @var callable + */ + protected $filterClasses; + + /** + * @var callable + */ + protected $filterProperties; + + /** + * @var callable + */ + protected $processClass; + + /** + * @var callable|false + */ + protected $processClassSignature; + + /** + * @var callable|false + */ + protected $processClassDocBlock; + + /** + * @var callable|false + */ + protected $processMethod; + + /** + * @var callable|false + */ + protected $processMethodSignature; + + /** + * @var callable|false + */ + protected $processMethodDocBlock; + + /** + * @var callable|false + */ + protected $processProperty; + + /** + * @var callable|false + */ + protected $processPropertySignature; + + /** + * @var callable|false + */ + protected $processPropertyDocBlock; + + /** + * @var callable + */ + protected $reorder; + + /** + * @var callable + */ + protected $reorderMethods; + + /** + * @todo Unused property. + * + * @var callable + */ + protected $reorderProperties; + + /** + * @var string + */ + protected $filename; + + /** + * @var string + */ + protected $prepend = ""; + + /** + * @var string + */ + protected $append = ""; + + /** + * @var string + */ + protected $text; + + /** + * @var string[] + */ + protected $textForClass = []; + + /** + * @param string $filename + * + * @return static + */ + public static function init($filename) + { + return new static($filename); + } + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * Put a class you want to be documented. + * + * @param string $item + * + * @return $this + */ + public function docClass($item) + { + $this->docClass[] = $item; + return $this; + } + + /** + * Using a callback function filter out methods that won't be documented. + * + * @param callable $filterMethods + * + * @return $this + */ + public function filterMethods($filterMethods) + { + $this->filterMethods = $filterMethods; + return $this; + } + + /** + * Using a callback function filter out classes that won't be documented. + * + * @param callable $filterClasses + * + * @return $this + */ + public function filterClasses($filterClasses) + { + $this->filterClasses = $filterClasses; + return $this; + } + + /** + * Using a callback function filter out properties that won't be documented. + * + * @param callable $filterProperties + * + * @return $this + */ + public function filterProperties($filterProperties) + { + $this->filterProperties = $filterProperties; + return $this; + } + + /** + * Post-process class documentation. + * + * @param callable $processClass + * + * @return $this + */ + public function processClass($processClass) + { + $this->processClass = $processClass; + return $this; + } + + /** + * Post-process class signature. Provide *false* to skip. + * + * @param callable|false $processClassSignature + * + * @return $this + */ + public function processClassSignature($processClassSignature) + { + $this->processClassSignature = $processClassSignature; + return $this; + } + + /** + * Post-process class docblock contents. Provide *false* to skip. + * + * @param callable|false $processClassDocBlock + * + * @return $this + */ + public function processClassDocBlock($processClassDocBlock) + { + $this->processClassDocBlock = $processClassDocBlock; + return $this; + } + + /** + * Post-process method documentation. Provide *false* to skip. + * + * @param callable|false $processMethod + * + * @return $this + */ + public function processMethod($processMethod) + { + $this->processMethod = $processMethod; + return $this; + } + + /** + * Post-process method signature. Provide *false* to skip. + * + * @param callable|false $processMethodSignature + * + * @return $this + */ + public function processMethodSignature($processMethodSignature) + { + $this->processMethodSignature = $processMethodSignature; + return $this; + } + + /** + * Post-process method docblock contents. Provide *false* to skip. + * + * @param callable|false $processMethodDocBlock + * + * @return $this + */ + public function processMethodDocBlock($processMethodDocBlock) + { + $this->processMethodDocBlock = $processMethodDocBlock; + return $this; + } + + /** + * Post-process property documentation. Provide *false* to skip. + * + * @param callable|false $processProperty + * + * @return $this + */ + public function processProperty($processProperty) + { + $this->processProperty = $processProperty; + return $this; + } + + /** + * Post-process property signature. Provide *false* to skip. + * + * @param callable|false $processPropertySignature + * + * @return $this + */ + public function processPropertySignature($processPropertySignature) + { + $this->processPropertySignature = $processPropertySignature; + return $this; + } + + /** + * Post-process property docblock contents. Provide *false* to skip. + * + * @param callable|false $processPropertyDocBlock + * + * @return $this + */ + public function processPropertyDocBlock($processPropertyDocBlock) + { + $this->processPropertyDocBlock = $processPropertyDocBlock; + return $this; + } + + /** + * Use a function to reorder classes. + * + * @param callable $reorder + * + * @return $this + */ + public function reorder($reorder) + { + $this->reorder = $reorder; + return $this; + } + + /** + * Use a function to reorder methods in class. + * + * @param callable $reorderMethods + * + * @return $this + */ + public function reorderMethods($reorderMethods) + { + $this->reorderMethods = $reorderMethods; + return $this; + } + + /** + * @param callable $reorderProperties + * + * @return $this + */ + public function reorderProperties($reorderProperties) + { + $this->reorderProperties = $reorderProperties; + return $this; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * Inserts text at the beginning of markdown file. + * + * @param string $prepend + * + * @return $this + */ + public function prepend($prepend) + { + $this->prepend = $prepend; + return $this; + } + + /** + * Inserts text at the end of markdown file. + * + * @param string $append + * + * @return $this + */ + public function append($append) + { + $this->append = $append; + return $this; + } + + /** + * @param string $text + * + * @return $this + */ + public function text($text) + { + $this->text = $text; + return $this; + } + + /** + * @param string $item + * + * @return $this + */ + public function textForClass($item) + { + $this->textForClass[] = $item; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + foreach ($this->docClass as $class) { + $this->printTaskInfo("Processing {class}", ['class' => $class]); + $this->textForClass[$class] = $this->documentClass($class); + } + + if (is_callable($this->reorder)) { + $this->printTaskInfo("Applying reorder function"); + call_user_func_array($this->reorder, [$this->textForClass]); + } + + $this->text = implode("\n", $this->textForClass); + + /** @var \Robo\Result $result */ + $result = $this->collectionBuilder()->taskWriteToFile($this->filename) + ->line($this->prepend) + ->text($this->text) + ->line($this->append) + ->run(); + + $this->printTaskSuccess('{filename} created. {class-count} classes documented', ['filename' => $this->filename, 'class-count' => count($this->docClass)]); + + return new Result($this, $result->getExitCode(), $result->getMessage(), $this->textForClass); + } + + /** + * @param string $class + * + * @return null|string + */ + protected function documentClass($class) + { + if (!class_exists($class)) { + return ""; + } + $refl = new \ReflectionClass($class); + + if (is_callable($this->filterClasses)) { + $ret = call_user_func($this->filterClasses, $refl); + if (!$ret) { + return; + } + } + $doc = $this->documentClassSignature($refl); + $doc .= "\n" . $this->documentClassDocBlock($refl); + $doc .= "\n"; + + if (is_callable($this->processClass)) { + $doc = call_user_func($this->processClass, $refl, $doc); + } + + $properties = []; + foreach ($refl->getProperties() as $reflProperty) { + $properties[] = $this->documentProperty($reflProperty); + } + + $properties = array_filter($properties); + $doc .= implode("\n", $properties); + + $methods = []; + foreach ($refl->getMethods() as $reflMethod) { + $methods[$reflMethod->name] = $this->documentMethod($reflMethod); + } + if (is_callable($this->reorderMethods)) { + call_user_func_array($this->reorderMethods, [&$methods]); + } + + $methods = array_filter($methods); + + $doc .= implode("\n", $methods)."\n"; + + return $doc; + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return string + */ + protected function documentClassSignature(\ReflectionClass $reflectionClass) + { + if ($this->processClassSignature === false) { + return ""; + } + + $signature = "## {$reflectionClass->name}\n\n"; + + if ($parent = $reflectionClass->getParentClass()) { + $signature .= "* *Extends* `{$parent->name}`"; + } + $interfaces = $reflectionClass->getInterfaceNames(); + if (count($interfaces)) { + $signature .= "\n* *Implements* `" . implode('`, `', $interfaces) . '`'; + } + $traits = $reflectionClass->getTraitNames(); + if (count($traits)) { + $signature .= "\n* *Uses* `" . implode('`, `', $traits) . '`'; + } + if (is_callable($this->processClassSignature)) { + $signature = call_user_func($this->processClassSignature, $reflectionClass, $signature); + } + + return $signature; + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return string + */ + protected function documentClassDocBlock(\ReflectionClass $reflectionClass) + { + if ($this->processClassDocBlock === false) { + return ""; + } + $doc = self::indentDoc($reflectionClass->getDocComment()); + if (is_callable($this->processClassDocBlock)) { + $doc = call_user_func($this->processClassDocBlock, $reflectionClass, $doc); + } + return $doc; + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethod(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethod === false) { + return ""; + } + if (is_callable($this->filterMethods)) { + $ret = call_user_func($this->filterMethods, $reflectedMethod); + if (!$ret) { + return ""; + } + } else { + if (!$reflectedMethod->isPublic()) { + return ""; + } + } + + $signature = $this->documentMethodSignature($reflectedMethod); + $docblock = $this->documentMethodDocBlock($reflectedMethod); + $methodDoc = "$signature $docblock"; + if (is_callable($this->processMethod)) { + $methodDoc = call_user_func($this->processMethod, $reflectedMethod, $methodDoc); + } + return $methodDoc; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentProperty(\ReflectionProperty $reflectedProperty) + { + if ($this->processProperty === false) { + return ""; + } + if (is_callable($this->filterProperties)) { + $ret = call_user_func($this->filterProperties, $reflectedProperty); + if (!$ret) { + return ""; + } + } else { + if (!$reflectedProperty->isPublic()) { + return ""; + } + } + $signature = $this->documentPropertySignature($reflectedProperty); + $docblock = $this->documentPropertyDocBlock($reflectedProperty); + $propertyDoc = $signature . $docblock; + if (is_callable($this->processProperty)) { + $propertyDoc = call_user_func($this->processProperty, $reflectedProperty, $propertyDoc); + } + return $propertyDoc; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentPropertySignature(\ReflectionProperty $reflectedProperty) + { + if ($this->processPropertySignature === false) { + return ""; + } + $modifiers = implode(' ', \Reflection::getModifierNames($reflectedProperty->getModifiers())); + $signature = "#### *$modifiers* {$reflectedProperty->name}"; + if (is_callable($this->processPropertySignature)) { + $signature = call_user_func($this->processPropertySignature, $reflectedProperty, $signature); + } + return $signature; + } + + /** + * @param \ReflectionProperty $reflectedProperty + * + * @return string + */ + protected function documentPropertyDocBlock(\ReflectionProperty $reflectedProperty) + { + if ($this->processPropertyDocBlock === false) { + return ""; + } + $propertyDoc = $reflectedProperty->getDocComment(); + // take from parent + if (!$propertyDoc) { + $parent = $reflectedProperty->getDeclaringClass(); + while ($parent = $parent->getParentClass()) { + if ($parent->hasProperty($reflectedProperty->name)) { + $propertyDoc = $parent->getProperty($reflectedProperty->name)->getDocComment(); + } + } + } + $propertyDoc = self::indentDoc($propertyDoc, 7); + $propertyDoc = preg_replace("~^@(.*?)([$\s])~", ' * `$1` $2', $propertyDoc); // format annotations + if (is_callable($this->processPropertyDocBlock)) { + $propertyDoc = call_user_func($this->processPropertyDocBlock, $reflectedProperty, $propertyDoc); + } + return ltrim($propertyDoc); + } + + /** + * @param \ReflectionParameter $param + * + * @return string + */ + protected function documentParam(\ReflectionParameter $param) + { + $text = ""; + if ($param->isArray()) { + $text .= 'array '; + } + if ($param->isCallable()) { + $text .= 'callable '; + } + $text .= '$' . $param->name; + if ($param->isDefaultValueAvailable()) { + if ($param->allowsNull()) { + $text .= ' = null'; + } else { + $text .= ' = ' . str_replace("\n", ' ', print_r($param->getDefaultValue(), true)); + } + } + + return $text; + } + + /** + * @param string $doc + * @param int $indent + * + * @return string + */ + public static function indentDoc($doc, $indent = 3) + { + if (!$doc) { + return $doc; + } + return implode( + "\n", + array_map( + function ($line) use ($indent) { + return substr($line, $indent); + }, + explode("\n", $doc) + ) + ); + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethodSignature(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethodSignature === false) { + return ""; + } + $modifiers = implode(' ', \Reflection::getModifierNames($reflectedMethod->getModifiers())); + $params = implode( + ', ', + array_map( + function ($p) { + return $this->documentParam($p); + }, + $reflectedMethod->getParameters() + ) + ); + $signature = "#### *$modifiers* {$reflectedMethod->name}($params)"; + if (is_callable($this->processMethodSignature)) { + $signature = call_user_func($this->processMethodSignature, $reflectedMethod, $signature); + } + return $signature; + } + + /** + * @param \ReflectionMethod $reflectedMethod + * + * @return string + */ + protected function documentMethodDocBlock(\ReflectionMethod $reflectedMethod) + { + if ($this->processMethodDocBlock === false) { + return ""; + } + $methodDoc = $reflectedMethod->getDocComment(); + // take from parent + if (!$methodDoc) { + $parent = $reflectedMethod->getDeclaringClass(); + while ($parent = $parent->getParentClass()) { + if ($parent->hasMethod($reflectedMethod->name)) { + $methodDoc = $parent->getMethod($reflectedMethod->name)->getDocComment(); + } + } + } + // take from interface + if (!$methodDoc) { + $interfaces = $reflectedMethod->getDeclaringClass()->getInterfaces(); + foreach ($interfaces as $interface) { + $i = new \ReflectionClass($interface->name); + if ($i->hasMethod($reflectedMethod->name)) { + $methodDoc = $i->getMethod($reflectedMethod->name)->getDocComment(); + break; + } + } + } + + $methodDoc = self::indentDoc($methodDoc, 7); + $methodDoc = preg_replace("~^@(.*?) ([$\s])~m", ' * `$1` $2', $methodDoc); // format annotations + if (is_callable($this->processMethodDocBlock)) { + $methodDoc = call_user_func($this->processMethodDocBlock, $reflectedMethod, $methodDoc); + } + + return $methodDoc; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GenerateTask.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GenerateTask.php new file mode 100644 index 00000000..9d7a698e --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GenerateTask.php @@ -0,0 +1,107 @@ +taskGenerateTask('Symfony\Component\Filesystem\Filesystem', 'FilesystemStack') + * ->run(); + * ``` + */ +class GenerateTask extends BaseTask +{ + /** + * @var string + */ + protected $className; + + /** + * @var string + */ + protected $wrapperClassName; + + /** + * @param string $className + * @param string $wrapperClassName + */ + public function __construct($className, $wrapperClassName = '') + { + $this->className = $className; + $this->wrapperClassName = $wrapperClassName; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $delegate = new \ReflectionClass($this->className); + $replacements = []; + + $leadingCommentChars = " * "; + $methodDescriptions = []; + $methodImplementations = []; + $immediateMethods = []; + foreach ($delegate->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + $methodName = $method->name; + $getter = preg_match('/^(get|has|is)/', $methodName); + $setter = preg_match('/^(set|unset)/', $methodName); + $argPrototypeList = []; + $argNameList = []; + $needsImplementation = false; + foreach ($method->getParameters() as $arg) { + $argDescription = '$' . $arg->name; + $argNameList[] = $argDescription; + if ($arg->isOptional()) { + $argDescription = $argDescription . ' = ' . str_replace("\n", "", var_export($arg->getDefaultValue(), true)); + // We will create wrapper methods for any method that + // has default parameters. + $needsImplementation = true; + } + $argPrototypeList[] = $argDescription; + } + $argPrototypeString = implode(', ', $argPrototypeList); + $argNameListString = implode(', ', $argNameList); + + if ($methodName[0] != '_') { + $methodDescriptions[] = "@method $methodName($argPrototypeString)"; + + if ($getter) { + $immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n return \$this->delegate->$methodName($argNameListString);\n }"; + } elseif ($setter) { + $immediateMethods[] = " public function $methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n return \$this;\n }"; + } elseif ($needsImplementation) { + // Include an implementation for the wrapper method if necessary + $methodImplementations[] = " protected function _$methodName($argPrototypeString)\n {\n \$this->delegate->$methodName($argNameListString);\n }"; + } + } + } + + $classNameParts = explode('\\', $this->className); + $delegate = array_pop($classNameParts); + $delegateNamespace = implode('\\', $classNameParts); + + if (empty($this->wrapperClassName)) { + $this->wrapperClassName = $delegate; + } + + $replacements['{delegateNamespace}'] = $delegateNamespace; + $replacements['{delegate}'] = $delegate; + $replacements['{wrapperClassName}'] = $this->wrapperClassName; + $replacements['{taskname}'] = "task$delegate"; + $replacements['{methodList}'] = $leadingCommentChars . implode("\n$leadingCommentChars", $methodDescriptions); + $replacements['{immediateMethods}'] = "\n\n" . implode("\n\n", $immediateMethods); + $replacements['{methodImplementations}'] = "\n\n" . implode("\n\n", $methodImplementations); + + $template = file_get_contents(__DIR__ . '/../../../data/Task/Development/GeneratedWrapper.tmpl'); + $template = str_replace(array_keys($replacements), array_values($replacements), $template); + + // Returning data in the $message will cause it to be printed. + return Result::success($this, $template); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GitHub.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GitHub.php new file mode 100644 index 00000000..9fc9909d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GitHub.php @@ -0,0 +1,157 @@ +repo = $repo; + return $this; + } + + /** + * @param string $owner + * + * @return $this + */ + public function owner($owner) + { + $this->owner = $owner; + return $this; + } + + /** + * @param string $uri + * + * @return $this + */ + public function uri($uri) + { + list($this->owner, $this->repo) = explode('/', $uri); + return $this; + } + + /** + * @return string + */ + protected function getUri() + { + return $this->owner . '/' . $this->repo; + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + $this->user = $user; + return $this; + } + + /** + * @param $password + * + * @return $this + */ + public function password($password) + { + $this->password = $password; + return $this; + } + + /** + * @param $accessToken + * + * @return $this + */ + public function accessToken($token) + { + $this->accessToken = $token; + return $this; + } + + /** + * @param string $uri + * @param array $params + * @param string $method + * + * @return array + * + * @throws \Robo\Exception\TaskException + */ + protected function sendRequest($uri, $params = [], $method = 'POST') + { + if (!$this->owner or !$this->repo) { + throw new TaskException($this, 'Repo URI is not set'); + } + + $ch = curl_init(); + $url = sprintf('%s/repos/%s/%s', self::GITHUB_URL, $this->getUri(), $uri); + $this->printTaskInfo($url); + $this->printTaskInfo('{method} {url}', ['method' => $method, 'url' => $url]); + + if (!empty($this->user)) { + curl_setopt($ch, CURLOPT_USERPWD, $this->user . ':' . $this->password); + } + + if (!empty($this->accessToken)) { + $url .= "?access_token=" . $this->accessToken; + } + + curl_setopt_array( + $ch, + array( + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => $method != 'GET', + CURLOPT_POSTFIELDS => json_encode($params), + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_USERAGENT => "Robo" + ) + ); + + $output = curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $response = json_decode($output); + + $this->printTaskInfo($output); + return [$code, $response]; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GitHubRelease.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GitHubRelease.php new file mode 100644 index 00000000..bf7a4889 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/GitHubRelease.php @@ -0,0 +1,208 @@ +taskGitHubRelease('0.1.0') + * ->uri('consolidation-org/Robo') + * ->description('Add stuff people need.') + * ->change('Fix #123') + * ->change('Add frobulation method to all widgets') + * ->run(); + * ?> + * ``` + */ +class GitHubRelease extends GitHub +{ + /** + * @var string + */ + protected $tag; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $description = ''; + + /** + * @var string[] + */ + protected $changes = []; + + /** + * @var bool + */ + protected $draft = false; + + /** + * @var bool + */ + protected $prerelease = false; + + /** + * @var string + */ + protected $comittish = 'master'; + + /** + * @param string $tag + */ + public function __construct($tag) + { + $this->tag = $tag; + } + + /** + * @param string $tag + * + * @return $this + */ + public function tag($tag) + { + $this->tag = $tag; + return $this; + } + + /** + * @param bool $draft + * + * @return $this + */ + public function draft($draft) + { + $this->draft = $draft; + return $this; + } + + /** + * @param string $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this; + } + + /** + * @param string $description + * + * @return $this + */ + public function description($description) + { + $this->description = $description; + return $this; + } + + /** + * @param bool $prerelease + * + * @return $this + */ + public function prerelease($prerelease) + { + $this->prerelease = $prerelease; + return $this; + } + + /** + * @param string $comittish + * + * @return $this + */ + public function comittish($comittish) + { + $this->comittish = $comittish; + return $this; + } + + /** + * @param string $description + * + * @return $this + */ + public function appendDescription($description) + { + if (!empty($this->description)) { + $this->description .= "\n\n"; + } + $this->description .= $description; + return $this; + } + + public function changes(array $changes) + { + $this->changes = array_merge($this->changes, $changes); + return $this; + } + + /** + * @param string $change + * + * @return $this + */ + public function change($change) + { + $this->changes[] = $change; + return $this; + } + + /** + * @return string + */ + protected function getBody() + { + $body = $this->description; + if (!empty($this->changes)) { + $changes = array_map( + function ($line) { + return "* $line"; + }, + $this->changes + ); + $changesText = implode("\n", $changes); + $body .= "### Changelog \n\n$changesText"; + } + return $body; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Releasing {tag}', ['tag' => $this->tag]); + $this->startTimer(); + list($code, $data) = $this->sendRequest( + 'releases', + [ + "tag_name" => $this->tag, + "target_commitish" => $this->comittish, + "name" => $this->name, + "body" => $this->getBody(), + "draft" => $this->draft, + "prerelease" => $this->prerelease + ] + ); + $this->stopTimer(); + + return new Result( + $this, + in_array($code, [200, 201]) ? 0 : 1, + isset($data->message) ? $data->message : '', + ['response' => $data, 'time' => $this->getExecutionTime()] + ); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/OpenBrowser.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/OpenBrowser.php new file mode 100644 index 00000000..ea01b326 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/OpenBrowser.php @@ -0,0 +1,80 @@ +taskOpenBrowser('http://localhost') + * ->run(); + * + * // open two browser windows + * $this->taskOpenBrowser([ + * 'http://localhost/mysite', + * 'http://localhost/mysite2' + * ]) + * ->run(); + * ``` + */ +class OpenBrowser extends BaseTask +{ + /** + * @var string[] + */ + protected $urls = []; + + /** + * @param string|array $url + */ + public function __construct($url) + { + $this->urls = (array) $url; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $openCommand = $this->getOpenCommand(); + + if (empty($openCommand)) { + return Result::error($this, 'no suitable browser opening command found'); + } + + foreach ($this->urls as $url) { + passthru(sprintf($openCommand, ProcessUtils::escapeArgument($url))); + $this->printTaskInfo('Opened {url}', ['url' => $url]); + } + + return Result::success($this); + } + + /** + * @return null|string + */ + private function getOpenCommand() + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + return 'start "web" explorer "%s"'; + } + + passthru('which xdg-open', $linux); + passthru('which open', $osx); + + if (0 === $linux) { + return 'xdg-open %s'; + } + + if (0 === $osx) { + return 'open %s'; + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/PackPhar.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/PackPhar.php new file mode 100644 index 00000000..6d0a04d7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/PackPhar.php @@ -0,0 +1,252 @@ +taskPackPhar('package/codecept.phar') + * ->compress() + * ->stub('package/stub.php'); + * + * $finder = Finder::create() + * ->name('*.php') + * ->in('src'); + * + * foreach ($finder as $file) { + * $pharTask->addFile('src/'.$file->getRelativePathname(), $file->getRealPath()); + * } + * + * $finder = Finder::create()->files() + * ->name('*.php') + * ->in('vendor'); + * + * foreach ($finder as $file) { + * $pharTask->addStripped('vendor/'.$file->getRelativePathname(), $file->getRealPath()); + * } + * $pharTask->run(); + * + * // verify Phar is packed correctly + * $code = $this->_exec('php package/codecept.phar'); + * ?> + * ``` + */ +class PackPhar extends BaseTask implements PrintedInterface, ProgressIndicatorAwareInterface +{ + /** + * @var \Phar + */ + protected $phar; + + /** + * @var null|string + */ + protected $compileDir = null; + + /** + * @var string + */ + protected $filename; + + /** + * @var bool + */ + protected $compress = false; + + protected $stub; + + protected $bin; + + /** + * @var string + */ + protected $stubTemplate = <<filename = $filename; + if (file_exists($file->getRealPath())) { + @unlink($file->getRealPath()); + } + $this->phar = new \Phar($file->getPathname(), 0, $file->getFilename()); + } + + /** + * @param bool $compress + * + * @return $this + */ + public function compress($compress = true) + { + $this->compress = $compress; + return $this; + } + + /** + * @param string $stub + * + * @return $this + */ + public function stub($stub) + { + $this->phar->setStub(file_get_contents($stub)); + return $this; + } + + /** + * {@inheritdoc} + */ + public function progressIndicatorSteps() + { + // run() will call advanceProgressIndicator() once for each + // file, one after calling stopBuffering, and again after compression. + return count($this->files)+2; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Creating {filename}', ['filename' => $this->filename]); + $this->phar->setSignatureAlgorithm(\Phar::SHA1); + $this->phar->startBuffering(); + + $this->printTaskInfo('Packing {file-count} files into phar', ['file-count' => count($this->files)]); + + $this->startProgressIndicator(); + foreach ($this->files as $path => $content) { + $this->phar->addFromString($path, $content); + $this->advanceProgressIndicator(); + } + $this->phar->stopBuffering(); + $this->advanceProgressIndicator(); + + if ($this->compress and in_array('GZ', \Phar::getSupportedCompression())) { + if (count($this->files) > 1000) { + $this->printTaskInfo('Too many files. Compression DISABLED'); + } else { + $this->printTaskInfo('{filename} compressed', ['filename' => $this->filename]); + $this->phar = $this->phar->compressFiles(\Phar::GZ); + } + } + $this->advanceProgressIndicator(); + $this->stopProgressIndicator(); + $this->printTaskSuccess('{filename} produced', ['filename' => $this->filename]); + return Result::success($this, '', ['time' => $this->getExecutionTime()]); + } + + /** + * @param string $path + * @param string $file + * + * @return $this + */ + public function addStripped($path, $file) + { + $this->files[$path] = $this->stripWhitespace(file_get_contents($file)); + return $this; + } + + /** + * @param string $path + * @param string $file + * + * @return $this + */ + public function addFile($path, $file) + { + $this->files[$path] = file_get_contents($file); + return $this; + } + + /** + * @param \Symfony\Component\Finder\SplFileInfo[] $files + */ + public function addFiles($files) + { + foreach ($files as $file) { + $this->addFile($file->getRelativePathname(), $file->getRealPath()); + } + } + + /** + * @param string $file + * + * @return $this + */ + public function executable($file) + { + $source = file_get_contents($file); + if (strpos($source, '#!/usr/bin/env php') === 0) { + $source = substr($source, strpos($source, 'phar->setStub(sprintf($this->stubTemplate, $source)); + return $this; + } + + /** + * Strips whitespace from source. Taken from composer + * + * @param string $source + * + * @return string + */ + private function stripWhitespace($source) + { + if (!function_exists('token_get_all')) { + return $source; + } + + $output = ''; + foreach (token_get_all($source) as $token) { + if (is_string($token)) { + $output .= $token; + } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { + // $output .= $token[1]; + $output .= str_repeat("\n", substr_count($token[1], "\n")); + } elseif (T_WHITESPACE === $token[0]) { + // reduce wide spaces + $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]); + // normalize newlines to \n + $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace); + // trim leading spaces + $whitespace = preg_replace('{\n +}', "\n", $whitespace); + $output .= $whitespace; + } else { + $output .= $token[1]; + } + } + + return $output; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/PhpServer.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/PhpServer.php new file mode 100644 index 00000000..6dd36680 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/PhpServer.php @@ -0,0 +1,86 @@ +taskServer(8000) + * ->dir('public') + * ->run(); + * + * // run with IP 0.0.0.0 + * $this->taskServer(8000) + * ->host('0.0.0.0') + * ->run(); + * + * // execute server in background + * $this->taskServer(8000) + * ->background() + * ->run(); + * ?> + * ``` + */ +class PhpServer extends Exec +{ + /** + * @var int + */ + protected $port; + + /** + * @var string + */ + protected $host = '127.0.0.1'; + + /** + * {@inheritdoc} + */ + protected $command = 'php -S %s:%d '; + + /** + * @param int $port + */ + public function __construct($port) + { + $this->port = $port; + + if (strtolower(PHP_OS) === 'linux') { + $this->command = 'exec php -S %s:%d '; + } + } + + /** + * @param string $host + * + * @return $this + */ + public function host($host) + { + $this->host = $host; + return $this; + } + + /** + * @param string $path + * + * @return $this + */ + public function dir($path) + { + $this->command .= "-t $path"; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return sprintf($this->command . $this->arguments, $this->host, $this->port); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/SemVer.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/SemVer.php new file mode 100644 index 00000000..6c807d89 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/SemVer.php @@ -0,0 +1,255 @@ +taskSemVer('.semver') + * ->increment() + * ->run(); + * ?> + * ``` + * + */ +class SemVer implements TaskInterface +{ + const SEMVER = "---\n:major: %d\n:minor: %d\n:patch: %d\n:special: '%s'\n:metadata: '%s'"; + + const REGEX = "/^\-\-\-\n:major:\s(0|[1-9]\d*)\n:minor:\s(0|[1-9]\d*)\n:patch:\s(0|[1-9]\d*)\n:special:\s'([a-zA-z0-9]*\.?(?:0|[1-9]\d*)?)'\n:metadata:\s'((?:0|[1-9]\d*)?(?:\.[a-zA-z0-9\.]*)?)'/"; + + const REGEX_STRING = '/^(?[0-9]+)\.(?[0-9]+)\.(?[0-9]+)(|-(?[0-9a-zA-Z.]+))(|\+(?[0-9a-zA-Z.]+))$/'; + + /** + * @var string + */ + protected $format = 'v%M.%m.%p%s'; + + /** + * @var string + */ + protected $specialSeparator = '-'; + + /** + * @var string + */ + protected $metadataSeparator = '+'; + + /** + * @var string + */ + protected $path; + + /** + * @var array + */ + protected $version = [ + 'major' => 0, + 'minor' => 0, + 'patch' => 0, + 'special' => '', + 'metadata' => '' + ]; + + /** + * @param string $filename + */ + public function __construct($filename = '') + { + $this->path = $filename; + + if (file_exists($this->path)) { + $semverFileContents = file_get_contents($this->path); + $this->parseFile($semverFileContents); + } + } + + /** + * @return string + */ + public function __toString() + { + $search = ['%M', '%m', '%p', '%s']; + $replace = $this->version + ['extra' => '']; + + foreach (['special', 'metadata'] as $key) { + if (!empty($replace[$key])) { + $separator = $key . 'Separator'; + $replace['extra'] .= $this->{$separator} . $replace[$key]; + } + unset($replace[$key]); + } + + return str_replace($search, $replace, $this->format); + } + + public function version($version) + { + $this->parseString($version); + return $this; + } + + /** + * @param string $format + * + * @return $this + */ + public function setFormat($format) + { + $this->format = $format; + return $this; + } + + /** + * @param string $separator + * + * @return $this + */ + public function setMetadataSeparator($separator) + { + $this->metadataSeparator = $separator; + return $this; + } + + /** + * @param string $separator + * + * @return $this + */ + public function setPrereleaseSeparator($separator) + { + $this->specialSeparator = $separator; + return $this; + } + + /** + * @param string $what + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function increment($what = 'patch') + { + switch ($what) { + case 'major': + $this->version['major']++; + $this->version['minor'] = 0; + $this->version['patch'] = 0; + break; + case 'minor': + $this->version['minor']++; + $this->version['patch'] = 0; + break; + case 'patch': + $this->version['patch']++; + break; + default: + throw new TaskException( + $this, + 'Bad argument, only one of the following is allowed: major, minor, patch' + ); + } + return $this; + } + + /** + * @param string $tag + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function prerelease($tag = 'RC') + { + if (!is_string($tag)) { + throw new TaskException($this, 'Bad argument, only strings allowed.'); + } + + $number = 0; + + if (!empty($this->version['special'])) { + list($current, $number) = explode('.', $this->version['special']); + if ($tag != $current) { + $number = 0; + } + } + + $number++; + + $this->version['special'] = implode('.', [$tag, $number]); + return $this; + } + + /** + * @param array|string $data + * + * @return $this + */ + public function metadata($data) + { + if (is_array($data)) { + $data = implode('.', $data); + } + + $this->version['metadata'] = $data; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $written = $this->dump(); + return new Result($this, (int)($written === false), $this->__toString()); + } + + /** + * @return bool + * + * @throws \Robo\Exception\TaskException + */ + protected function dump() + { + if (empty($this->path)) { + return true; + } + extract($this->version); + $semver = sprintf(self::SEMVER, $major, $minor, $patch, $special, $metadata); + if (is_writeable($this->path) === false || file_put_contents($this->path, $semver) === false) { + throw new TaskException($this, 'Failed to write semver file.'); + } + return true; + } + + protected function parseString($semverString) + { + if (!preg_match_all(self::REGEX_STRING, $semverString, $matches)) { + throw new TaskException($this, 'Bad semver value: ' . $semverString); + } + + $this->version = array_intersect_key($matches, $this->version); + $this->version = array_map(function ($item) { + return $item[0]; + }, $this->version); + } + + /** + * @throws \Robo\Exception\TaskException + */ + protected function parseFile($semverFileContents) + { + if (!preg_match_all(self::REGEX, $semverFileContents, $matches)) { + throw new TaskException($this, 'Bad semver file.'); + } + + list(, $major, $minor, $patch, $special, $metadata) = array_map('current', $matches); + $this->version = compact('major', 'minor', 'patch', 'special', 'metadata'); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/loadTasks.php new file mode 100644 index 00000000..e3dc49a3 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Development/loadTasks.php @@ -0,0 +1,86 @@ +task(Changelog::class, $filename); + } + + /** + * @param string $filename + * + * @return GenerateMarkdownDoc + */ + protected function taskGenDoc($filename) + { + return $this->task(GenerateMarkdownDoc::class, $filename); + } + + /** + * @param string $className + * @param string $wrapperClassName + * + * @return \Robo\Task\Development\GenerateTask + */ + protected function taskGenTask($className, $wrapperClassName = '') + { + return $this->task(GenerateTask::class, $className, $wrapperClassName); + } + + /** + * @param string $pathToSemVer + * + * @return SemVer + */ + protected function taskSemVer($pathToSemVer = '.semver') + { + return $this->task(SemVer::class, $pathToSemVer); + } + + /** + * @param int $port + * + * @return PhpServer + */ + protected function taskServer($port = 8000) + { + return $this->task(PhpServer::class, $port); + } + + /** + * @param string $filename + * + * @return PackPhar + */ + protected function taskPackPhar($filename) + { + return $this->task(PackPhar::class, $filename); + } + + /** + * @param string $tag + * + * @return GitHubRelease + */ + protected function taskGitHubRelease($tag) + { + return $this->task(GitHubRelease::class, $tag); + } + + /** + * @param string|array $url + * + * @return OpenBrowser + */ + protected function taskOpenBrowser($url) + { + return $this->task(OpenBrowser::class, $url); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Base.php new file mode 100644 index 00000000..135f39e7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Base.php @@ -0,0 +1,28 @@ +getCommand(); + return $this->executeCommand($command); + } + + abstract public function getCommand(); +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Build.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Build.php new file mode 100644 index 00000000..11eb92ab --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Build.php @@ -0,0 +1,55 @@ +taskDockerBuild()->run(); + * + * $this->taskDockerBuild('path/to/dir') + * ->tag('database') + * ->run(); + * + * ?> + * + * ``` + * + * Class Build + * @package Robo\Task\Docker + */ +class Build extends Base +{ + /** + * @var string + */ + protected $path; + + /** + * @param string $path + */ + public function __construct($path = '.') + { + $this->command = "docker build"; + $this->path = $path; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->path; + } + + /** + * @param string $tag + * + * @return $this + */ + public function tag($tag) + { + return $this->option('-t', $tag); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Commit.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Commit.php new file mode 100644 index 00000000..302f1920 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Commit.php @@ -0,0 +1,66 @@ +taskDockerCommit($containerId) + * ->name('my/database') + * ->run(); + * + * // alternatively you can take the result from DockerRun task: + * + * $result = $this->taskDockerRun('db') + * ->exec('./prepare_database.sh') + * ->run(); + * + * $task->dockerCommit($result) + * ->name('my/database') + * ->run(); + * ``` + */ +class Commit extends Base +{ + /** + * @var string + */ + protected $command = "docker commit"; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->cid . ' ' . $this->name . ' ' . $this->arguments; + } + + /** + * @param $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Exec.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Exec.php new file mode 100644 index 00000000..fa67c8da --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Exec.php @@ -0,0 +1,95 @@ +taskDockerRun('test_env') + * ->detached() + * ->run(); + * + * $this->taskDockerExec($test) + * ->interactive() + * ->exec('./runtests') + * ->run(); + * + * // alternatively use commands from other tasks + * + * $this->taskDockerExec($test) + * ->interactive() + * ->exec($this->taskCodecept()->suite('acceptance')) + * ->run(); + * ?> + * ``` + * + */ +class Exec extends Base +{ + use CommandReceiver; + + /** + * @var string + */ + protected $command = "docker exec"; + + /** + * @var string + */ + protected $cid; + + /** + * @var string + */ + protected $run = ''; + + /** + * @param string|\Robo\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * @return $this + */ + public function detached() + { + $this->option('-d'); + return $this; + } + + /** + * {@inheritdoc)} + */ + public function interactive($interactive = true) + { + if ($interactive) { + $this->option('-i'); + } + return parent::interactive($interactive); + } + + /** + * @param string|\Robo\Contract\CommandInterface $command + * + * @return $this + */ + public function exec($command) + { + $this->run = $this->receiveCommand($command); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid.' '.$this->run; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Pull.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Pull.php new file mode 100644 index 00000000..32ba5b40 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Pull.php @@ -0,0 +1,33 @@ +taskDockerPull('wordpress') + * ->run(); + * + * ?> + * ``` + * + */ +class Pull extends Base +{ + /** + * @param string $image + */ + public function __construct($image) + { + $this->command = "docker pull $image "; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Remove.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Remove.php new file mode 100644 index 00000000..0a8c0ac6 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Remove.php @@ -0,0 +1,32 @@ +taskDockerRemove($container) + * ->run(); + * ?> + * ``` + * + */ +class Remove extends Base +{ + /** + * @param string $container + */ + public function __construct($container) + { + $this->command = "docker rm $container "; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Result.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Result.php new file mode 100644 index 00000000..0533159a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Result.php @@ -0,0 +1,35 @@ +taskDockerRun('mysql')->run(); + * + * $result = $this->taskDockerRun('my_db_image') + * ->env('DB', 'database_name') + * ->volume('/path/to/data', '/data') + * ->detached() + * ->publish(3306) + * ->name('my_mysql') + * ->run(); + * + * // retrieve container's cid: + * $this->say("Running container ".$result->getCid()); + * + * // execute script inside container + * $result = $this->taskDockerRun('db') + * ->exec('prepare_test_data.sh') + * ->run(); + * + * $this->taskDockerCommit($result) + * ->name('test_db') + * ->run(); + * + * // link containers + * $mysql = $this->taskDockerRun('mysql') + * ->name('wp_db') // important to set name for linked container + * ->env('MYSQL_ROOT_PASSWORD', '123456') + * ->run(); + * + * $this->taskDockerRun('wordpress') + * ->link($mysql) + * ->publish(80, 8080) + * ->detached() + * ->run(); + * + * ?> + * ``` + * + */ +class Run extends Base +{ + use CommandReceiver; + + /** + * @var string + */ + protected $image = ''; + + /** + * @var string + */ + protected $run = ''; + + /** + * @var string + */ + protected $cidFile; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $dir; + + /** + * @param string $image + */ + public function __construct($image) + { + $this->image = $image; + } + + /** + * {@inheritdoc} + */ + public function getPrinted() + { + return $this->isPrinted; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + if ($this->isPrinted) { + $this->option('-i'); + } + if ($this->cidFile) { + $this->option('cidfile', $this->cidFile); + } + return trim('docker run ' . $this->arguments . ' ' . $this->image . ' ' . $this->run); + } + + /** + * @return $this + */ + public function detached() + { + $this->option('-d'); + return $this; + } + + /** + * {@inheritdoc)} + */ + public function interactive($interactive = true) + { + if ($interactive) { + $this->option('-i'); + } + return parent::interactive($interactive); + } + + /** + * @param string|\Robo\Contract\CommandInterface $run + * + * @return $this + */ + public function exec($run) + { + $this->run = $this->receiveCommand($run); + return $this; + } + + /** + * @param string $from + * @param null|string $to + * + * @return $this + */ + public function volume($from, $to = null) + { + $volume = $to ? "$from:$to" : $from; + $this->option('-v', $volume); + return $this; + } + + /** + * Set environment variables. + * n.b. $this->env($variable, $value) also available here, + * inherited from ExecTrait. + * + * @param array $env + * @return type + */ + public function envVars(array $env) + { + foreach ($env as $variable => $value) { + $this->setDockerEnv($variable, $value); + } + return $this; + } + + /** + * @param string $variable + * @param null|string $value + * + * @return $this + */ + protected function setDockerEnv($variable, $value = null) + { + $env = $value ? "$variable=$value" : $variable; + return $this->option("-e", $env); + } + + /** + * @param null|int $port + * @param null|int $portTo + * + * @return $this + */ + public function publish($port = null, $portTo = null) + { + if (!$port) { + return $this->option('-P'); + } + if ($portTo) { + $port = "$port:$portTo"; + } + return $this->option('-p', $port); + } + + /** + * @param string $dir + * + * @return $this + */ + public function containerWorkdir($dir) + { + return $this->option('-w', $dir); + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + return $this->option('-u', $user); + } + + /** + * @return $this + */ + public function privileged() + { + return $this->option('--privileged'); + } + + /** + * @param string $name + * + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this->option('name', $name); + } + + /** + * @param string|\Robo\Task\Docker\Result $name + * @param string $alias + * + * @return $this + */ + public function link($name, $alias) + { + if ($name instanceof Result) { + $name = $name->getContainerName(); + } + $this->option('link', "$name:$alias"); + return $this; + } + + /** + * @param string $dir + * + * @return $this + */ + public function tmpDir($dir) + { + $this->dir = $dir; + return $this; + } + + /** + * @return string + */ + public function getTmpDir() + { + return $this->dir ? $this->dir : sys_get_temp_dir(); + } + + /** + * @return string + */ + public function getUniqId() + { + return uniqid(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->cidFile = $this->getTmpDir() . '/docker_' . $this->getUniqId() . '.cid'; + $result = parent::run(); + $result['cid'] = $this->getCid(); + return $result; + } + + /** + * @return null|string + */ + protected function getCid() + { + if (!$this->cidFile || !file_exists($this->cidFile)) { + return null; + } + $cid = trim(file_get_contents($this->cidFile)); + @unlink($this->cidFile); + return $cid; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Start.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Start.php new file mode 100644 index 00000000..ef19d74d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Start.php @@ -0,0 +1,41 @@ +taskDockerStart($cidOrResult) + * ->run(); + * ?> + * ``` + */ +class Start extends Base +{ + /** + * @var string + */ + protected $command = "docker start"; + + /** + * @var null|string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Stop.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Stop.php new file mode 100644 index 00000000..4d0d436d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/Stop.php @@ -0,0 +1,41 @@ +taskDockerStop($cidOrResult) + * ->run(); + * ?> + * ``` + */ +class Stop extends Base +{ + /** + * @var string + */ + protected $command = "docker stop"; + + /** + * @var null|string + */ + protected $cid; + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + */ + public function __construct($cidOrResult) + { + $this->cid = $cidOrResult instanceof Result ? $cidOrResult->getCid() : $cidOrResult; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . ' ' . $this->arguments . ' ' . $this->cid; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/loadTasks.php new file mode 100644 index 00000000..e58f5ef0 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Docker/loadTasks.php @@ -0,0 +1,85 @@ +task(Run::class, $image); + } + + /** + * @param string $image + * + * @return \Robo\Task\Docker\Pull + */ + protected function taskDockerPull($image) + { + return $this->task(Pull::class, $image); + } + + /** + * @param string $path + * + * @return \Robo\Task\Docker\Build + */ + protected function taskDockerBuild($path = '.') + { + return $this->task(Build::class, $path); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Stop + */ + protected function taskDockerStop($cidOrResult) + { + return $this->task(Stop::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Commit + */ + protected function taskDockerCommit($cidOrResult) + { + return $this->task(Commit::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Start + */ + protected function taskDockerStart($cidOrResult) + { + return $this->task(Start::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Remove + */ + protected function taskDockerRemove($cidOrResult) + { + return $this->task(Remove::class, $cidOrResult); + } + + /** + * @param string|\Robo\Task\Docker\Result $cidOrResult + * + * @return \Robo\Task\Docker\Exec + */ + protected function taskDockerExec($cidOrResult) + { + return $this->task(Exec::class, $cidOrResult); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Concat.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Concat.php new file mode 100644 index 00000000..12b1eca0 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Concat.php @@ -0,0 +1,101 @@ +taskConcat([ + * 'web/assets/screen.css', + * 'web/assets/print.css', + * 'web/assets/theme.css' + * ]) + * ->to('web/assets/style.css') + * ->run() + * ?> + * ``` + */ +class Concat extends BaseTask +{ + use ResourceExistenceChecker; + + /** + * @var array|Iterator + */ + protected $files; + + /** + * @var string + */ + protected $dst; + + /** + * Constructor. + * + * @param array|Iterator $files + */ + public function __construct($files) + { + $this->files = $files; + } + + /** + * set the destination file + * + * @param string $dst + * + * @return $this + */ + public function to($dst) + { + $this->dst = $dst; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (is_null($this->dst) || "" === $this->dst) { + return Result::error($this, 'You must specify a destination file with to() method.'); + } + + if (!$this->checkResources($this->files, 'file')) { + return Result::error($this, 'Source files are missing!'); + } + + if (file_exists($this->dst) && !is_writable($this->dst)) { + return Result::error($this, 'Destination already exists and cannot be overwritten.'); + } + + $dump = ''; + + foreach ($this->files as $path) { + foreach (glob($path) as $file) { + $dump .= file_get_contents($file) . "\n"; + } + } + + $this->printTaskInfo('Writing {destination}', ['destination' => $this->dst]); + + $dst = $this->dst . '.part'; + $write_result = file_put_contents($dst, $dump); + + if (false === $write_result) { + @unlink($dst); + return Result::error($this, 'File write failed.'); + } + // Cannot be cross-volume; should always succeed. + @rename($dst, $this->dst); + + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Replace.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Replace.php new file mode 100644 index 00000000..0107df13 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Replace.php @@ -0,0 +1,141 @@ +taskReplaceInFile('VERSION') + * ->from('0.2.0') + * ->to('0.3.0') + * ->run(); + * + * $this->taskReplaceInFile('README.md') + * ->from(date('Y')-1) + * ->to(date('Y')) + * ->run(); + * + * $this->taskReplaceInFile('config.yml') + * ->regex('~^service:~') + * ->to('services:') + * ->run(); + * + * $this->taskReplaceInFile('box/robo.txt') + * ->from(array('##dbname##', '##dbhost##')) + * ->to(array('robo', 'localhost')) + * ->run(); + * ?> + * ``` + */ +class Replace extends BaseTask +{ + /** + * @var string + */ + protected $filename; + + /** + * @var string|string[] + */ + protected $from; + + /** + * @var string|string[] + */ + protected $to; + + /** + * @var string + */ + protected $regex; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * String(s) to be replaced. + * + * @param string|string[] $from + * + * @return $this + */ + public function from($from) + { + $this->from = $from; + return $this; + } + + /** + * Value(s) to be set as a replacement. + * + * @param string|string[] $to + * + * @return $this + */ + public function to($to) + { + $this->to = $to; + return $this; + } + + /** + * Regex to match string to be replaced. + * + * @param string $regex + * + * @return $this + */ + public function regex($regex) + { + $this->regex = $regex; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + if (!file_exists($this->filename)) { + $this->printTaskError('File {filename} does not exist', ['filename' => $this->filename]); + return false; + } + + $text = file_get_contents($this->filename); + if ($this->regex) { + $text = preg_replace($this->regex, $this->to, $text, -1, $count); + } else { + $text = str_replace($this->from, $this->to, $text, $count); + } + if ($count > 0) { + $res = file_put_contents($this->filename, $text); + if ($res === false) { + return Result::error($this, "Error writing to file {filename}.", ['filename' => $this->filename]); + } + $this->printTaskSuccess("{filename} updated. {count} items replaced", ['filename' => $this->filename, 'count' => $count]); + } else { + $this->printTaskInfo("{filename} unchanged. {count} items replaced", ['filename' => $this->filename, 'count' => $count]); + } + return Result::success($this, '', ['replaced' => $count]); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/TmpFile.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/TmpFile.php new file mode 100644 index 00000000..4a18691d --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/TmpFile.php @@ -0,0 +1,72 @@ +collectionBuilder(); + * $tmpFilePath = $collection->taskTmpFile() + * ->line('-----') + * ->line(date('Y-m-d').' '.$title) + * ->line('----') + * ->getPath(); + * $collection->run(); + * ?> + * ``` + */ +class TmpFile extends Write implements CompletionInterface +{ + /** + * @param string $filename + * @param string $extension + * @param string $baseDir + * @param bool $includeRandomPart + */ + public function __construct($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true) + { + if (empty($baseDir)) { + $baseDir = sys_get_temp_dir(); + } + if ($includeRandomPart) { + $random = static::randomString(); + $filename = "{$filename}_{$random}"; + } + $filename .= $extension; + parent::__construct("{$baseDir}/{$filename}"); + } + + /** + * Generate a suitably random string to use as the suffix for our + * temporary file. + * + * @param int $length + * + * @return string + */ + private static function randomString($length = 12) + { + return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, $length); + } + + /** + * Delete this file when our collection completes. + * If this temporary file is not part of a collection, + * then it will be deleted when the program terminates, + * presuming that it was created by taskTmpFile() or _tmpFile(). + */ + public function complete() + { + unlink($this->getPath()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Write.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Write.php new file mode 100644 index 00000000..dc2199f9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/Write.php @@ -0,0 +1,335 @@ +taskWriteToFile('blogpost.md') + * ->line('-----') + * ->line(date('Y-m-d').' '.$title) + * ->line('----') + * ->run(); + * ?> + * ``` + */ +class Write extends BaseTask +{ + /** + * @var array + */ + protected $stack = []; + + /** + * @var string + */ + protected $filename; + + /** + * @var bool + */ + protected $append = false; + + /** + * @var null|string + */ + protected $originalContents = null; + + /** + * @param string $filename + */ + public function __construct($filename) + { + $this->filename = $filename; + } + + /** + * @param string $filename + * + * @return $this + */ + public function filename($filename) + { + $this->filename = $filename; + return $this; + } + + /** + * @param bool $append + * + * @return $this + */ + public function append($append = true) + { + $this->append = $append; + return $this; + } + + /** + * add a line. + * + * @param string $line + * + * @return $this The current instance + */ + public function line($line) + { + $this->text($line . "\n"); + return $this; + } + + /** + * add more lines. + * + * @param array $lines + * + * @return $this The current instance + */ + public function lines(array $lines) + { + $this->text(implode("\n", $lines) . "\n"); + return $this; + } + + /** + * add a text. + * + * @param string $text + * + * @return $this The current instance + */ + public function text($text) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * add a text from a file. + * + * Note that the file is read in the run() method of this task. + * To load text from the current state of a file (e.g. one that may + * be deleted or altered by other tasks prior the execution of this one), + * use: + * $task->text(file_get_contents($filename)); + * + * @param string $filename + * + * @return $this The current instance + */ + public function textFromFile($filename) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * substitute a placeholder with value, placeholder must be enclosed by `{}`. + * + * @param string $name + * @param string $val + * + * @return $this The current instance + */ + public function place($name, $val) + { + $this->replace('{'.$name.'}', $val); + + return $this; + } + + /** + * replace any string with value. + * + * @param string $string + * @param string $replacement + * + * @return $this The current instance + */ + public function replace($string, $replacement) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * replace any string with value using regular expression. + * + * @param string $pattern + * @param string $replacement + * + * @return $this The current instance + */ + public function regexReplace($pattern, $replacement) + { + $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args()); + return $this; + } + + /** + * Append the provided text to the end of the buffer if the provided + * regex pattern matches any text already in the buffer. + * + * @param string $pattern + * @param string $text + * + * @return $this + */ + public function appendIfMatches($pattern, $text) + { + $this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, true]); + return $this; + } + + /** + * Append the provided text to the end of the buffer unless the provided + * regex pattern matches any text already in the buffer. + * + * @param string $pattern + * @param string $text + * + * @return $this + */ + public function appendUnlessMatches($pattern, $text) + { + $this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, false]); + return $this; + } + + /** + * @param $contents string + * @param $filename string + * + * @return string + */ + protected function textFromFileCollect($contents, $filename) + { + if (file_exists($filename)) { + $contents .= file_get_contents($filename); + } + return $contents; + } + + /** + * @param string|string[] $contents + * @param string|string[] $string + * @param string|string[] $replacement + * + * @return string|string[] + */ + protected function replaceCollect($contents, $string, $replacement) + { + return str_replace($string, $replacement, $contents); + } + + /** + * @param string|string[] $contents + * @param string|string[] $pattern + * @param string|string[] $replacement + * + * @return string|string[] + */ + protected function regexReplaceCollect($contents, $pattern, $replacement) + { + return preg_replace($pattern, $replacement, $contents); + } + + /** + * @param string $contents + * @param string $text + * + * @return string + */ + protected function textCollect($contents, $text) + { + return $contents . $text; + } + + /** + * @param string $contents + * @param string $pattern + * @param string $text + * @param bool $shouldMatch + * + * @return string + */ + protected function appendIfMatchesCollect($contents, $pattern, $text, $shouldMatch) + { + if (preg_match($pattern, $contents) == $shouldMatch) { + $contents .= $text; + } + return $contents; + } + + /** + * @return string + */ + public function originalContents() + { + if (!isset($this->originalContents)) { + $this->originalContents = ''; + if (file_exists($this->filename)) { + $this->originalContents = file_get_contents($this->filename); + } + } + return $this->originalContents; + } + + /** + * @return bool + */ + public function wouldChange() + { + return $this->originalContents() != $this->getContentsToWrite(); + } + + /** + * @return string + */ + protected function getContentsToWrite() + { + $contents = ""; + if ($this->append) { + $contents = $this->originalContents(); + } + foreach ($this->stack as $action) { + $command = array_shift($action); + if (method_exists($this, $command)) { + array_unshift($action, $contents); + $contents = call_user_func_array([$this, $command], $action); + } + } + return $contents; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo("Writing to {filename}.", ['filename' => $this->filename]); + $contents = $this->getContentsToWrite(); + if (!file_exists(dirname($this->filename))) { + mkdir(dirname($this->filename), 0777, true); + } + $res = file_put_contents($this->filename, $contents); + if ($res === false) { + return Result::error($this, "File {$this->filename} couldn't be created"); + } + + return Result::success($this); + } + + /** + * @return string + */ + public function getPath() + { + return $this->filename; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/loadTasks.php new file mode 100644 index 00000000..c5f39c95 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/File/loadTasks.php @@ -0,0 +1,48 @@ +task(Concat::class, $files); + } + + /** + * @param string $file + * + * @return \Robo\Task\File\Replace + */ + protected function taskReplaceInFile($file) + { + return $this->task(Replace::class, $file); + } + + /** + * @param string $file + * + * @return \Robo\Task\File\Write + */ + protected function taskWriteToFile($file) + { + return $this->task(Write::class, $file); + } + + /** + * @param string $filename + * @param string $extension + * @param string $baseDir + * @param bool $includeRandomPart + * + * @return \Robo\Task\File\TmpFile + */ + protected function taskTmpFile($filename = 'tmp', $extension = '', $baseDir = '', $includeRandomPart = true) + { + return $this->task(TmpFile::class, $filename, $extension, $baseDir, $includeRandomPart); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/BaseDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/BaseDir.php new file mode 100644 index 00000000..434334d7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/BaseDir.php @@ -0,0 +1,30 @@ +dirs = $dirs + : $this->dirs[] = $dirs; + + $this->fs = new sfFilesystem(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/CleanDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/CleanDir.php new file mode 100644 index 00000000..762f8550 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/CleanDir.php @@ -0,0 +1,63 @@ +taskCleanDir(['tmp','logs'])->run(); + * // as shortcut + * $this->_cleanDir('app/cache'); + * ?> + * ``` + */ +class CleanDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $dir) { + $this->emptyDir($dir); + $this->printTaskInfo("Cleaned {dir}", ['dir' => $dir]); + } + return Result::success($this); + } + + /** + * @param string $path + */ + protected function emptyDir($path) + { + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ($iterator as $path) { + if ($path->isDir()) { + $dir = (string)$path; + if (basename($dir) === '.' || basename($dir) === '..') { + continue; + } + $this->fs->remove($dir); + } else { + $file = (string)$path; + if (basename($file) === '.gitignore' || basename($file) === '.gitkeep') { + continue; + } + $this->fs->remove($file); + } + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/CopyDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/CopyDir.php new file mode 100644 index 00000000..08482222 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/CopyDir.php @@ -0,0 +1,162 @@ +taskCopyDir(['dist/config' => 'config'])->run(); + * // as shortcut + * $this->_copyDir('dist/config', 'config'); + * ?> + * ``` + */ +class CopyDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * Explicitly declare our consturctor, so that + * our copyDir() method does not look like a php4 constructor. + */ + public function __construct($dirs) + { + parent::__construct($dirs); + } + + /** + * @var int + */ + protected $chmod = 0755; + + /** + * Files to exclude on copying. + * + * @var string[] + */ + protected $exclude = []; + + /** + * Overwrite destination files newer than source files. + */ + protected $overwrite = true; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $src => $dst) { + $this->copyDir($src, $dst); + $this->printTaskInfo('Copied from {source} to {destination}', ['source' => $src, 'destination' => $dst]); + } + return Result::success($this); + } + + /** + * Sets the default folder permissions for the destination if it doesn't exist + * + * @link http://en.wikipedia.org/wiki/Chmod + * @link http://php.net/manual/en/function.mkdir.php + * @link http://php.net/manual/en/function.chmod.php + * + * @param int $value + * + * @return $this + */ + public function dirPermissions($value) + { + $this->chmod = (int)$value; + return $this; + } + + /** + * List files to exclude. + * + * @param string[] $exclude + * + * @return $this + */ + public function exclude($exclude = []) + { + $this->exclude = $this->simplifyForCompare($exclude); + return $this; + } + + /** + * Destination files newer than source files are overwritten. + * + * @param bool $overwrite + * + * @return $this + */ + public function overwrite($overwrite) + { + $this->overwrite = $overwrite; + return $this; + } + + /** + * Copies a directory to another location. + * + * @param string $src Source directory + * @param string $dst Destination directory + * @param string $parent Parent directory + * + * @throws \Robo\Exception\TaskException + */ + protected function copyDir($src, $dst, $parent = '') + { + $dir = @opendir($src); + if (false === $dir) { + throw new TaskException($this, "Cannot open source directory '" . $src . "'"); + } + if (!is_dir($dst)) { + mkdir($dst, $this->chmod, true); + } + while (false !== ($file = readdir($dir))) { + // Support basename and full path exclusion. + if ($this->excluded($file, $src, $parent)) { + continue; + } + $srcFile = $src . '/' . $file; + $destFile = $dst . '/' . $file; + if (is_dir($srcFile)) { + $this->copyDir($srcFile, $destFile, $parent . $file . DIRECTORY_SEPARATOR); + } else { + $this->fs->copy($srcFile, $destFile, $this->overwrite); + } + } + closedir($dir); + } + + /** + * Check to see if the current item is excluded. + */ + protected function excluded($file, $src, $parent) + { + return + ($file == '.') || + ($file == '..') || + in_array($file, $this->exclude) || + in_array($this->simplifyForCompare($parent . $file), $this->exclude) || + in_array($this->simplifyForCompare($src . DIRECTORY_SEPARATOR . $file), $this->exclude); + } + + /** + * Avoid problems comparing paths on Windows that may have a + * combination of DIRECTORY_SEPARATOR and /. + */ + protected function simplifyForCompare($item) + { + return str_replace(DIRECTORY_SEPARATOR, '/', $item); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/DeleteDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/DeleteDir.php new file mode 100644 index 00000000..25cf007b --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/DeleteDir.php @@ -0,0 +1,36 @@ +taskDeleteDir('tmp')->run(); + * // as shortcut + * $this->_deleteDir(['tmp', 'log']); + * ?> + * ``` + */ +class DeleteDir extends BaseDir +{ + use ResourceExistenceChecker; + + /** + * {@inheritdoc} + */ + public function run() + { + if (!$this->checkResources($this->dirs, 'dir')) { + return Result::error($this, 'Source directories are missing!'); + } + foreach ($this->dirs as $dir) { + $this->fs->remove($dir); + $this->printTaskInfo("Deleted {dir}...", ['dir' => $dir]); + } + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/FilesystemStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/FilesystemStack.php new file mode 100644 index 00000000..8663e245 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/FilesystemStack.php @@ -0,0 +1,154 @@ +taskFilesystemStack() + * ->mkdir('logs') + * ->touch('logs/.gitignore') + * ->chgrp('www', 'www-data') + * ->symlink('/var/log/nginx/error.log', 'logs/error.log') + * ->run(); + * + * // one line + * $this->_touch('.gitignore'); + * $this->_mkdir('logs'); + * + * ?> + * ``` + * + * @method $this mkdir(string|array|\Traversable $dir, int $mode = 0777) + * @method $this touch(string|array|\Traversable $file, int $time = null, int $atime = null) + * @method $this copy(string $from, string $to, bool $force = false) + * @method $this chmod(string|array|\Traversable $file, int $permissions, int $umask = 0000, bool $recursive = false) + * @method $this chgrp(string|array|\Traversable $file, string $group, bool $recursive = false) + * @method $this chown(string|array|\Traversable $file, string $user, bool $recursive = false) + * @method $this remove(string|array|\Traversable $file) + * @method $this rename(string $from, string $to, bool $force = false) + * @method $this symlink(string $from, string $to, bool $copyOnWindows = false) + * @method $this mirror(string $from, string $to, \Traversable $iterator = null, array $options = []) + */ +class FilesystemStack extends StackBasedTask implements BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var \Symfony\Component\Filesystem\Filesystem + */ + protected $fs; + + public function __construct() + { + $this->fs = new sfFilesystem(); + } + + /** + * @return \Symfony\Component\Filesystem\Filesystem + */ + protected function getDelegate() + { + return $this->fs; + } + + /** + * @param string $from + * @param string $to + * @param bool $force + */ + protected function _copy($from, $to, $force = false) + { + $this->fs->copy($from, $to, $force); + } + + /** + * @param string|string[]|\Traversable $file + * @param int $permissions + * @param int $umask + * @param bool $recursive + */ + protected function _chmod($file, $permissions, $umask = 0000, $recursive = false) + { + $this->fs->chmod($file, $permissions, $umask, $recursive); + } + + /** + * @param string|string[]|\Traversable $file + * @param string $group + * @param bool $recursive + */ + protected function _chgrp($file, $group, $recursive = null) + { + $this->fs->chgrp($file, $group, $recursive); + } + + /** + * @param string|string[]|\Traversable $file + * @param string $user + * @param bool $recursive + */ + protected function _chown($file, $user, $recursive = null) + { + $this->fs->chown($file, $user, $recursive); + } + + /** + * @param string $origin + * @param string $target + * @param bool $overwrite + * + * @return null|true|\Robo\Result + */ + protected function _rename($origin, $target, $overwrite = false) + { + // we check that target does not exist + if ((!$overwrite && is_readable($target)) || (file_exists($target) && !is_writable($target))) { + throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target); + } + + // Due to a bug (limitation) in PHP, cross-volume renames do not work. + // See: https://bugs.php.net/bug.php?id=54097 + if (true !== @rename($origin, $target)) { + return $this->crossVolumeRename($origin, $target); + } + return true; + } + + /** + * @param string $origin + * @param string $target + * + * @return null|\Robo\Result + */ + protected function crossVolumeRename($origin, $target) + { + // First step is to try to get rid of the target. If there + // is a single, deletable file, then we will just unlink it. + if (is_file($target)) { + unlink($target); + } + // If the target still exists, we will try to delete it. + // TODO: Note that if this fails partway through, then we cannot + // adequately rollback. Perhaps we need to preflight the operation + // and determine if everything inside of $target is writable. + if (file_exists($target)) { + $this->fs->remove($target); + } + + /** @var \Robo\Result $result */ + $result = $this->collectionBuilder()->taskCopyDir([$origin => $target])->run(); + if (!$result->wasSuccessful()) { + return $result; + } + $this->fs->remove($origin); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/FlattenDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/FlattenDir.php new file mode 100644 index 00000000..6e885112 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/FlattenDir.php @@ -0,0 +1,294 @@ +taskFlattenDir(['assets/*.min.js' => 'dist'])->run(); + * // or use shortcut + * $this->_flattenDir('assets/*.min.js', 'dist'); + * ?> + * ``` + * + * You can also define the target directory with an additional method, instead of + * key/value pairs. More similar to the gulp-flatten syntax: + * + * ``` php + * taskFlattenDir(['assets/*.min.js']) + * ->to('dist') + * ->run(); + * ?> + * ``` + * + * You can also append parts of the parent directories to the target path. If you give + * the value `1` to the `includeParents()` method, then the top parent will be appended + * to the target directory resulting in a path such as `dist/assets/asset-library1.min.js`. + * + * If you give a negative number, such as `-1` (the same as specifying `array(0, 1)` then + * the bottom parent will be appended, resulting in a path such as + * `dist/asset-library1/asset-library1.min.js`. + * + * The top parent directory will always be starting from the relative path to the current + * directory. You can override that with the `parentDir()` method. If in the above example + * you would specify `assets`, then the top parent directory would be `asset-library1`. + * + * ``` php + * taskFlattenDir(['assets/*.min.js' => 'dist']) + * ->parentDir('assets') + * ->includeParents(1) + * ->run(); + * ?> + * ``` + */ +class FlattenDir extends BaseDir +{ + /** + * @var int + */ + protected $chmod = 0755; + + /** + * @var int[] + */ + protected $parents = array(0, 0); + + /** + * @var string + */ + protected $parentDir = ''; + + /** + * @var string + */ + protected $to; + + /** + * {@inheritdoc} + */ + public function __construct($dirs) + { + parent::__construct($dirs); + $this->parentDir = getcwd(); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // find the files + $files = $this->findFiles($this->dirs); + + // copy the files + $this->copyFiles($files); + + $fileNoun = count($files) == 1 ? ' file' : ' files'; + $this->printTaskSuccess("Copied {count} $fileNoun to {destination}", ['count' => count($files), 'destination' => $this->to]); + + return Result::success($this); + } + + /** + * Sets the default folder permissions for the destination if it does not exist. + * + * @link http://en.wikipedia.org/wiki/Chmod + * @link http://php.net/manual/en/function.mkdir.php + * @link http://php.net/manual/en/function.chmod.php + * + * @param int $permission + * + * @return $this + */ + public function dirPermissions($permission) + { + $this->chmod = (int) $permission; + + return $this; + } + + /** + * Sets the value from which direction and how much parent dirs should be included. + * Accepts a positive or negative integer or an array with two integer values. + * + * @param int|int[] $parents + * + * @return $this + * + * @throws TaskException + */ + public function includeParents($parents) + { + if (is_int($parents)) { + // if an integer is given check whether it is for top or bottom parent + if ($parents >= 0) { + $this->parents[0] = $parents; + return $this; + } + $this->parents[1] = 0 - $parents; + return $this; + } + + if (is_array($parents)) { + // check if the array has two values no more, no less + if (count($parents) == 2) { + $this->parents = $parents; + return $this; + } + } + + throw new TaskException($this, 'includeParents expects an integer or an array with two values'); + } + + /** + * Sets the parent directory from which the relative parent directories will be calculated. + * + * @param string $dir + * + * @return $this + */ + public function parentDir($dir) + { + if (!$this->fs->isAbsolutePath($dir)) { + // attach the relative path to current working directory + $dir = getcwd().'/'.$dir; + } + $this->parentDir = $dir; + + return $this; + } + + /** + * Sets the target directory where the files will be copied to. + * + * @param string $target + * + * @return $this + */ + public function to($target) + { + $this->to = rtrim($target, '/'); + + return $this; + } + + /** + * @param array $dirs + * + * @return array|\Robo\Result + * + * @throws \Robo\Exception\TaskException + */ + protected function findFiles($dirs) + { + $files = array(); + + // find the files + foreach ($dirs as $k => $v) { + // reset finder + $finder = new Finder(); + + $dir = $k; + $to = $v; + // check if target was given with the to() method instead of key/value pairs + if (is_int($k)) { + $dir = $v; + if (isset($this->to)) { + $to = $this->to; + } else { + throw new TaskException($this, 'target directory is not defined'); + } + } + + try { + $finder->files()->in($dir); + } catch (\InvalidArgumentException $e) { + // if finder cannot handle it, try with in()->name() + if (strpos($dir, '/') === false) { + $dir = './'.$dir; + } + $parts = explode('/', $dir); + $new_dir = implode('/', array_slice($parts, 0, -1)); + try { + $finder->files()->in($new_dir)->name(array_pop($parts)); + } catch (\InvalidArgumentException $e) { + return Result::fromException($this, $e); + } + } + + foreach ($finder as $file) { + // store the absolute path as key and target as value in the files array + $files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to); + } + $fileNoun = count($files) == 1 ? ' file' : ' files'; + $this->printTaskInfo("Found {count} $fileNoun in {dir}", ['count' => count($files), 'dir' => $dir]); + } + + return $files; + } + + /** + * @param string $file + * @param string $to + * + * @return string + */ + protected function getTarget($file, $to) + { + $target = $to.'/'.basename($file); + if ($this->parents !== array(0, 0)) { + // if the parent is set, create additional directories inside target + // get relative path to parentDir + $rel_path = $this->fs->makePathRelative(dirname($file), $this->parentDir); + // get top parents and bottom parents + $parts = explode('/', rtrim($rel_path, '/')); + $prefix_dir = ''; + $prefix_dir .= ($this->parents[0] > 0 ? implode('/', array_slice($parts, 0, $this->parents[0])).'/' : ''); + $prefix_dir .= ($this->parents[1] > 0 ? implode('/', array_slice($parts, (0 - $this->parents[1]), $this->parents[1])) : ''); + $prefix_dir = rtrim($prefix_dir, '/'); + $target = $to.'/'.$prefix_dir.'/'.basename($file); + } + + return $target; + } + + /** + * @param array $files + */ + protected function copyFiles($files) + { + // copy the files + foreach ($files as $from => $to) { + // check if target dir exists + if (!is_dir(dirname($to))) { + $this->fs->mkdir(dirname($to), $this->chmod); + } + $this->fs->copy($from, $to); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/MirrorDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/MirrorDir.php new file mode 100644 index 00000000..4eda9097 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/MirrorDir.php @@ -0,0 +1,40 @@ +taskMirrorDir(['dist/config/' => 'config/'])->run(); + * // or use shortcut + * $this->_mirrorDir('dist/config/', 'config/'); + * + * ?> + * ``` + */ +class MirrorDir extends BaseDir +{ + /** + * {@inheritdoc} + */ + public function run() + { + foreach ($this->dirs as $src => $dst) { + $this->fs->mirror( + $src, + $dst, + null, + [ + 'override' => true, + 'copy_on_windows' => true, + 'delete' => true + ] + ); + $this->printTaskInfo("Mirrored from {source} to {destination}", ['source' => $src, 'destination' => $dst]); + } + return Result::success($this); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/TmpDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/TmpDir.php new file mode 100644 index 00000000..104318de --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/TmpDir.php @@ -0,0 +1,173 @@ +run(). + * $collection = $this->collectionBuilder(); + * $tmpPath = $collection->tmpDir()->getPath(); + * $collection->taskFilesystemStack() + * ->mkdir("$tmpPath/log") + * ->touch("$tmpPath/log/error.txt"); + * $collection->run(); + * // as shortcut (deleted when program exits) + * $tmpPath = $this->_tmpDir(); + * ?> + * ``` + */ +class TmpDir extends BaseDir implements CompletionInterface +{ + /** + * @var string + */ + protected $base; + + /** + * @var string + */ + protected $prefix; + + /** + * @var bool + */ + protected $cwd; + + /** + * @var string + */ + protected $savedWorkingDirectory; + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + */ + public function __construct($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + if (empty($base)) { + $base = sys_get_temp_dir(); + } + $path = "{$base}/{$prefix}"; + if ($includeRandomPart) { + $path = static::randomLocation($path); + } + parent::__construct(["$path"]); + } + + /** + * Add a random part to a path, ensuring that the directory does + * not (currently) exist. + * + * @param string $path The base/prefix path to add a random component to + * @param int $length Number of digits in the random part + * + * @return string + */ + protected static function randomLocation($path, $length = 12) + { + $random = static::randomString($length); + while (is_dir("{$path}_{$random}")) { + $random = static::randomString($length); + } + return "{$path}_{$random}"; + } + + /** + * Generate a suitably random string to use as the suffix for our + * temporary directory. + * + * @param int $length + * + * @return string + */ + protected static function randomString($length = 12) + { + return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, max($length, 3)); + } + + /** + * Flag that we should cwd to the temporary directory when it is + * created, and restore the old working directory when it is deleted. + * + * @param bool $shouldChangeWorkingDirectory + * + * @return $this + */ + public function cwd($shouldChangeWorkingDirectory = true) + { + $this->cwd = $shouldChangeWorkingDirectory; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Save the current working directory + $this->savedWorkingDirectory = getcwd(); + foreach ($this->dirs as $dir) { + $this->fs->mkdir($dir); + $this->printTaskInfo("Created {dir}...", ['dir' => $dir]); + + // Change the current working directory, if requested + if ($this->cwd) { + chdir($dir); + } + } + + return Result::success($this, '', ['path' => $this->getPath()]); + } + + protected function restoreWorkingDirectory() + { + // Restore the current working directory, if we redirected it. + if ($this->cwd) { + chdir($this->savedWorkingDirectory); + } + } + + protected function deleteTmpDir() + { + foreach ($this->dirs as $dir) { + $this->fs->remove($dir); + } + } + + /** + * Delete this directory when our collection completes. + * If this temporary directory is not part of a collection, + * then it will be deleted when the program terminates, + * presuming that it was created by taskTmpDir() or _tmpDir(). + */ + public function complete() + { + $this->restoreWorkingDirectory(); + $this->deleteTmpDir(); + } + + /** + * Get a reference to the path to the temporary directory, so that + * it may be used to create other tasks. Note that the directory + * is not actually created until the task runs. + * + * @return string + */ + public function getPath() + { + return $this->dirs[0]; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/WorkDir.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/WorkDir.php new file mode 100644 index 00000000..4b75c6ed --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/WorkDir.php @@ -0,0 +1,126 @@ +collectionBuilder(); + * $workingPath = $collection->workDir("build")->getPath(); + * $collection->taskFilesystemStack() + * ->mkdir("$workingPath/log") + * ->touch("$workingPath/log/error.txt"); + * $collection->run(); + * ?> + * ``` + */ +class WorkDir extends TmpDir implements RollbackInterface, BuilderAwareInterface +{ + use BuilderAwareTrait; + + /** + * @var string + */ + protected $finalDestination; + + /** + * @param string $finalDestination + */ + public function __construct($finalDestination) + { + $this->finalDestination = $finalDestination; + + // Create a temporary directory to work in. We will place our + // temporary directory in the same location as the final destination + // directory, so that the work directory can be moved into place + // without having to be copied, e.g. in a cross-volume rename scenario. + parent::__construct(basename($finalDestination), dirname($finalDestination)); + } + + /** + * Create our working directory. + * + * @return \Robo\Result + */ + public function run() + { + // Destination cannot be empty + if (empty($this->finalDestination)) { + return Result::error($this, "Destination directory not specified."); + } + + // Before we do anything else, ensure that any directory in the + // final destination is writable, so that we can at a minimum + // move it out of the way before placing our results there. + if (is_dir($this->finalDestination)) { + if (!is_writable($this->finalDestination)) { + return Result::error($this, "Destination directory {dir} exists and cannot be overwritten.", ['dir' => $this->finalDestination]); + } + } + + return parent::run(); + } + + /** + * Move our working directory into its final destination once the + * collection it belongs to completes. + */ + public function complete() + { + $this->restoreWorkingDirectory(); + + // Delete the final destination, if it exists. + // Move it out of the way first, in case it cannot + // be completely deleted. + if (file_exists($this->finalDestination)) { + $temporaryLocation = static::randomLocation($this->finalDestination . '_TO_DELETE_'); + // This should always work, because we already created a temporary + // folder in the parent directory of the final destination, and we + // have already checked to confirm that the final destination is + // writable. + rename($this->finalDestination, $temporaryLocation); + // This may silently fail, leaving artifacts behind, if there + // are permissions problems with some items somewhere inside + // the folder being deleted. + $this->fs->remove($temporaryLocation); + } + + // Move our working directory over the final destination. + // This should never be a cross-volume rename, so this should + // always succeed. + $workDir = reset($this->dirs); + if (file_exists($workDir)) { + rename($workDir, $this->finalDestination); + } + } + + /** + * Delete our working directory + */ + public function rollback() + { + $this->restoreWorkingDirectory(); + $this->deleteTmpDir(); + } + + /** + * Get a reference to the path to the temporary directory, so that + * it may be used to create other tasks. Note that the directory + * is not actually created until the task runs. + * + * @return string + */ + public function getPath() + { + return $this->dirs[0]; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/loadShortcuts.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/loadShortcuts.php new file mode 100644 index 00000000..fe72ce5a --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/loadShortcuts.php @@ -0,0 +1,159 @@ +taskCopyDir([$src => $dst])->run(); + } + + /** + * @param string $src + * @param string $dst + * + * @return \Robo\Result + */ + protected function _mirrorDir($src, $dst) + { + return $this->taskMirrorDir([$src => $dst])->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _deleteDir($dir) + { + return $this->taskDeleteDir($dir)->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _cleanDir($dir) + { + return $this->taskCleanDir($dir)->run(); + } + + /** + * @param string $from + * @param string $to + * @param bool $overwrite + * + * @return \Robo\Result + */ + protected function _rename($from, $to, $overwrite = false) + { + return $this->taskFilesystemStack()->rename($from, $to, $overwrite)->run(); + } + + /** + * @param string|string[] $dir + * + * @return \Robo\Result + */ + protected function _mkdir($dir) + { + return $this->taskFilesystemStack()->mkdir($dir)->run(); + } + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return string + */ + protected function _tmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + $result = $this->taskTmpDir($prefix, $base, $includeRandomPart)->run(); + return isset($result['path']) ? $result['path'] : ''; + } + + /** + * @param string $file + * + * @return \Robo\Result + */ + protected function _touch($file) + { + return $this->taskFilesystemStack()->touch($file)->run(); + } + + /** + * @param string|string[] $file + * + * @return \Robo\Result + */ + protected function _remove($file) + { + return $this->taskFilesystemStack()->remove($file)->run(); + } + + /** + * @param string|string[] $file + * @param string $group + * + * @return \Robo\Result + */ + protected function _chgrp($file, $group) + { + return $this->taskFilesystemStack()->chgrp($file, $group)->run(); + } + + /** + * @param string|string[] $file + * @param int $permissions + * @param int $umask + * @param bool $recursive + * + * @return \Robo\Result + */ + protected function _chmod($file, $permissions, $umask = 0000, $recursive = false) + { + return $this->taskFilesystemStack()->chmod($file, $permissions, $umask, $recursive)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _symlink($from, $to) + { + return $this->taskFilesystemStack()->symlink($from, $to)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _copy($from, $to) + { + return $this->taskFilesystemStack()->copy($from, $to)->run(); + } + + /** + * @param string $from + * @param string $to + * + * @return \Robo\Result + */ + protected function _flattenDir($from, $to) + { + return $this->taskFlattenDir([$from => $to])->run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/loadTasks.php new file mode 100644 index 00000000..8fecaaff --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Filesystem/loadTasks.php @@ -0,0 +1,85 @@ +task(CleanDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\DeleteDir + */ + protected function taskDeleteDir($dirs) + { + return $this->task(DeleteDir::class, $dirs); + } + + /** + * @param string $prefix + * @param string $base + * @param bool $includeRandomPart + * + * @return \Robo\Task\Filesystem\WorkDir + */ + protected function taskTmpDir($prefix = 'tmp', $base = '', $includeRandomPart = true) + { + return $this->task(TmpDir::class, $prefix, $base, $includeRandomPart); + } + + /** + * @param string $finalDestination + * + * @return \Robo\Task\Filesystem\TmpDir + */ + protected function taskWorkDir($finalDestination) + { + return $this->task(WorkDir::class, $finalDestination); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\CopyDir + */ + protected function taskCopyDir($dirs) + { + return $this->task(CopyDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\MirrorDir + */ + protected function taskMirrorDir($dirs) + { + return $this->task(MirrorDir::class, $dirs); + } + + /** + * @param string|string[] $dirs + * + * @return \Robo\Task\Filesystem\FlattenDir + */ + protected function taskFlattenDir($dirs) + { + return $this->task(FlattenDir::class, $dirs); + } + + /** + * @return \Robo\Task\Filesystem\FilesystemStack + */ + protected function taskFilesystemStack() + { + return $this->task(FilesystemStack::class); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/Base.php new file mode 100644 index 00000000..42728673 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/Base.php @@ -0,0 +1,97 @@ +option('silent'); + return $this; + } + + /** + * adds `--no-color` option to gulp + * + * @return $this + */ + public function noColor() + { + $this->option('no-color'); + return $this; + } + + /** + * adds `--color` option to gulp + * + * @return $this + */ + public function color() + { + $this->option('color'); + return $this; + } + + /** + * adds `--tasks-simple` option to gulp + * + * @return $this + */ + public function simple() + { + $this->option('tasks-simple'); + return $this; + } + + /** + * @param string $task + * @param null|string $pathToGulp + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($task, $pathToGulp = null) + { + $this->task = $task; + $this->command = $pathToGulp; + if (!$this->command) { + $this->command = $this->findExecutable('gulp'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Gulp executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} " . ProcessUtils::escapeArgument($this->task) . "{$this->arguments}"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/Run.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/Run.php new file mode 100644 index 00000000..8f2077b5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/Run.php @@ -0,0 +1,35 @@ +taskGulpRun()->run(); + * + * // run task 'clean' with --silent option + * $this->taskGulpRun('clean') + * ->silent() + * ->run(); + * ?> + * ``` + */ +class Run extends Base implements CommandInterface +{ + /** + * {@inheritdoc} + */ + public function run() + { + if (strlen($this->arguments)) { + $this->printTaskInfo('Running Gulp task: {gulp_task} with arguments: {arguments}', ['gulp_task' => $this->task, 'arguments' => $this->arguments]); + } else { + $this->printTaskInfo('Running Gulp task: {gulp_task} without arguments', ['gulp_task' => $this->task]); + } + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/loadTasks.php new file mode 100644 index 00000000..6fdc6ca7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Gulp/loadTasks.php @@ -0,0 +1,16 @@ +task(Run::class, $task, $pathToGulp); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Base.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Base.php new file mode 100644 index 00000000..35ff9c48 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Base.php @@ -0,0 +1,60 @@ +option('production'); + return $this; + } + + /** + * @param null|string $pathToNpm + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToNpm = null) + { + $this->command = $pathToNpm; + if (!$this->command) { + $this->command = $this->findExecutable('npm'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Npm executable not found."); + } + } + + /** + * @return string + */ + public function getCommand() + { + return "{$this->command} {$this->action}{$this->arguments}"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Install.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Install.php new file mode 100644 index 00000000..65cbe618 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Install.php @@ -0,0 +1,36 @@ +taskNpmInstall()->run(); + * + * // prefer dist with custom path + * $this->taskNpmInstall('path/to/my/npm') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Install extends Base implements CommandInterface +{ + /** + * @var string + */ + protected $action = 'install'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Install Npm packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Update.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Update.php new file mode 100644 index 00000000..75421b30 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/Update.php @@ -0,0 +1,34 @@ +taskNpmUpdate()->run(); + * + * // prefer dist with custom path + * $this->taskNpmUpdate('path/to/my/npm') + * ->noDev() + * ->run(); + * ?> + * ``` + */ +class Update extends Base +{ + /** + * @var string + */ + protected $action = 'update'; + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Update Npm packages: {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/loadTasks.php new file mode 100644 index 00000000..4d9a26eb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Npm/loadTasks.php @@ -0,0 +1,25 @@ +task(Install::class, $pathToNpm); + } + + /** + * @param null|string $pathToNpm + * + * @return \Robo\Task\Npm\Update + */ + protected function taskNpmUpdate($pathToNpm = null) + { + return $this->task(Update::class, $pathToNpm); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/Rsync.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/Rsync.php new file mode 100644 index 00000000..5c334af4 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/Rsync.php @@ -0,0 +1,484 @@ +taskRsync() + * ->fromPath('src/') + * ->toHost('localhost') + * ->toUser('dev') + * ->toPath('/var/www/html/app/') + * ->remoteShell('ssh -i public_key') + * ->recursive() + * ->excludeVcs() + * ->checksum() + * ->wholeFile() + * ->verbose() + * ->progress() + * ->humanReadable() + * ->stats() + * ->run(); + * ``` + * + * You could also clone the task and do a dry-run first: + * + * ``` php + * $rsync = $this->taskRsync() + * ->fromPath('src/') + * ->toPath('example.com:/var/www/html/app/') + * ->archive() + * ->excludeVcs() + * ->progress() + * ->stats(); + * + * $dryRun = clone $rsync; + * $dryRun->dryRun()->run(); + * if ('y' === $this->ask('Do you want to run (y/n)')) { + * $rsync->run(); + * } + * ``` + */ +class Rsync extends BaseTask implements CommandInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string + */ + protected $fromUser; + + /** + * @var string + */ + protected $fromHost; + + /** + * @var string + */ + protected $fromPath; + + /** + * @var string + */ + protected $toUser; + + /** + * @var string + */ + protected $toHost; + + /** + * @var string + */ + protected $toPath; + + /** + * @return static + */ + public static function init() + { + return new static(); + } + + public function __construct() + { + $this->command = 'rsync'; + } + + /** + * This can either be a full rsync path spec (user@host:path) or just a path. + * In case of the former do not specify host and user. + * + * @param string|array $path + * + * @return $this + */ + public function fromPath($path) + { + $this->fromPath = $path; + + return $this; + } + + /** + * This can either be a full rsync path spec (user@host:path) or just a path. + * In case of the former do not specify host and user. + * + * @param string $path + * + * @return $this + */ + public function toPath($path) + { + $this->toPath = $path; + + return $this; + } + + /** + * @param string $fromUser + * + * @return $this + */ + public function fromUser($fromUser) + { + $this->fromUser = $fromUser; + return $this; + } + + /** + * @param string $fromHost + * + * @return $this + */ + public function fromHost($fromHost) + { + $this->fromHost = $fromHost; + return $this; + } + + /** + * @param string $toUser + * + * @return $this + */ + public function toUser($toUser) + { + $this->toUser = $toUser; + return $this; + } + + /** + * @param string $toHost + * + * @return $this + */ + public function toHost($toHost) + { + $this->toHost = $toHost; + return $this; + } + + /** + * @return $this + */ + public function progress() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function stats() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function recursive() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function verbose() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function checksum() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function archive() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function compress() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function owner() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function group() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function times() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @return $this + */ + public function delete() + { + $this->option(__FUNCTION__); + + return $this; + } + + /** + * @param int $seconds + * + * @return $this + */ + public function timeout($seconds) + { + $this->option(__FUNCTION__, $seconds); + + return $this; + } + + /** + * @return $this + */ + public function humanReadable() + { + $this->option('human-readable'); + + return $this; + } + + /** + * @return $this + */ + public function wholeFile() + { + $this->option('whole-file'); + + return $this; + } + + /** + * @return $this + */ + public function dryRun() + { + $this->option('dry-run'); + + return $this; + } + + /** + * @return $this + */ + public function itemizeChanges() + { + $this->option('itemize-changes'); + + return $this; + } + + /** + * Excludes .git, .svn and .hg items at any depth. + * + * @return $this + */ + public function excludeVcs() + { + return $this->exclude([ + '.git', + '.svn', + '.hg', + ]); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function exclude($pattern) + { + return $this->optionList(__FUNCTION__, $pattern); + } + + /** + * @param string $file + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function excludeFrom($file) + { + if (!is_readable($file)) { + throw new TaskException($this, "Exclude file $file is not readable"); + } + + return $this->option('exclude-from', $file); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function includeFilter($pattern) + { + return $this->optionList('include', $pattern); + } + + /** + * @param array|string $pattern + * + * @return $this + */ + public function filter($pattern) + { + return $this->optionList(__FUNCTION__, $pattern); + } + + /** + * @param string $file + * + * @return $this + * + * @throws \Robo\Exception\TaskException + */ + public function filesFrom($file) + { + if (!is_readable($file)) { + throw new TaskException($this, "Files-from file $file is not readable"); + } + + return $this->option('files-from', $file); + } + + /** + * @param string $command + * + * @return $this + */ + public function remoteShell($command) + { + $this->option('rsh', "'$command'"); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + + return $this->executeCommand($command); + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + foreach ((array)$this->fromPath as $from) { + $this->option(null, $this->getFromPathSpec($from)); + } + $this->option(null, $this->getToPathSpec()); + + return $this->command . $this->arguments; + } + + /** + * @return string + */ + protected function getFromPathSpec($from) + { + return $this->getPathSpec($this->fromHost, $this->fromUser, $from); + } + + /** + * @return string + */ + protected function getToPathSpec() + { + return $this->getPathSpec($this->toHost, $this->toUser, $this->toPath); + } + + /** + * @param string $host + * @param string $user + * @param string $path + * + * @return string + */ + protected function getPathSpec($host, $user, $path) + { + $spec = isset($path) ? $path : ''; + if (!empty($host)) { + $spec = "{$host}:{$spec}"; + } + if (!empty($user)) { + $spec = "{$user}@{$spec}"; + } + + return $spec; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/Ssh.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/Ssh.php new file mode 100644 index 00000000..69df9fe2 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/Ssh.php @@ -0,0 +1,273 @@ +taskSshExec('remote.example.com', 'user') + * ->remoteDir('/var/www/html') + * ->exec('ls -la') + * ->exec('chmod g+x logs') + * ->run(); + * + * ``` + * + * You can even exec other tasks (which implement CommandInterface): + * + * ```php + * $gitTask = $this->taskGitStack() + * ->checkout('master') + * ->pull(); + * + * $this->taskSshExec('remote.example.com') + * ->remoteDir('/var/www/html/site') + * ->exec($gitTask) + * ->run(); + * ``` + * + * You can configure the remote directory for all future calls: + * + * ```php + * \Robo\Task\Remote\Ssh::configure('remoteDir', '/some-dir'); + * ``` + */ +class Ssh extends BaseTask implements CommandInterface, SimulatedInterface +{ + use \Robo\Common\CommandReceiver; + use \Robo\Common\ExecOneCommand; + + /** + * @var null|string + */ + protected $hostname; + + /** + * @var null|string + */ + protected $user; + + /** + * @var bool + */ + protected $stopOnFail = true; + + /** + * @var array + */ + protected $exec = []; + + /** + * Changes to the given directory before running commands. + * + * @var string + */ + protected $remoteDir; + + /** + * @param null|string $hostname + * @param null|string $user + */ + public function __construct($hostname = null, $user = null) + { + $this->hostname = $hostname; + $this->user = $user; + } + + /** + * @param string $hostname + * + * @return $this + */ + public function hostname($hostname) + { + $this->hostname = $hostname; + return $this; + } + + /** + * @param string $user + * + * @return $this + */ + public function user($user) + { + $this->user = $user; + return $this; + } + + /** + * Whether or not to chain commands together with && and stop the chain if one command fails. + * + * @param bool $stopOnFail + * + * @return $this + */ + public function stopOnFail($stopOnFail = true) + { + $this->stopOnFail = $stopOnFail; + return $this; + } + + /** + * Changes to the given directory before running commands. + * + * @param string $remoteDir + * + * @return $this + */ + public function remoteDir($remoteDir) + { + $this->remoteDir = $remoteDir; + return $this; + } + + /** + * @param string $filename + * + * @return $this + */ + public function identityFile($filename) + { + $this->option('-i', $filename); + + return $this; + } + + /** + * @param int $port + * + * @return $this + */ + public function port($port) + { + $this->option('-p', $port); + + return $this; + } + + /** + * @return $this + */ + public function forcePseudoTty() + { + $this->option('-t'); + + return $this; + } + + /** + * @return $this + */ + public function quiet() + { + $this->option('-q'); + + return $this; + } + + /** + * @return $this + */ + public function verbose() + { + $this->option('-v'); + + return $this; + } + + /** + * @param string|string[]|CommandInterface $command + * + * @return $this + */ + public function exec($command) + { + if (is_array($command)) { + $command = implode(' ', array_filter($command)); + } + + $this->exec[] = $command; + + return $this; + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + $commands = []; + foreach ($this->exec as $command) { + $commands[] = $this->receiveCommand($command); + } + + $remoteDir = $this->remoteDir ? $this->remoteDir : $this->getConfigValue('remoteDir'); + if (!empty($remoteDir)) { + array_unshift($commands, sprintf('cd "%s"', $remoteDir)); + } + $command = implode($this->stopOnFail ? ' && ' : ' ; ', $commands); + + return $this->sshCommand($command); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->validateParameters(); + $command = $this->getCommand(); + return $this->executeCommand($command); + } + + /** + * {@inheritdoc} + */ + public function simulate($context) + { + $command = $this->getCommand(); + $this->printTaskInfo("Running {command}", ['command' => $command] + $context); + } + + protected function validateParameters() + { + if (empty($this->hostname)) { + throw new TaskException($this, 'Please set a hostname'); + } + if (empty($this->exec)) { + throw new TaskException($this, 'Please add at least one command'); + } + } + + /** + * Returns an ssh command string running $command on the remote. + * + * @param string|CommandInterface $command + * + * @return string + */ + protected function sshCommand($command) + { + $command = $this->receiveCommand($command); + $sshOptions = $this->arguments; + $hostSpec = $this->hostname; + if ($this->user) { + $hostSpec = $this->user . '@' . $hostSpec; + } + + return "ssh{$sshOptions} {$hostSpec} '{$command}'"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/loadTasks.php new file mode 100644 index 00000000..092d2a55 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Remote/loadTasks.php @@ -0,0 +1,24 @@ +task(Rsync::class); + } + + /** + * @param null|string $hostname + * @param null|string $user + * + * @return \Robo\Task\Remote\Ssh + */ + protected function taskSshExec($hostname = null, $user = null) + { + return $this->task(Ssh::class, $hostname, $user); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Simulator.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Simulator.php new file mode 100644 index 00000000..e69d23fa --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Simulator.php @@ -0,0 +1,168 @@ +task = ($task instanceof WrappedTaskInterface) ? $task->original() : $task; + $this->constructorParameters = $constructorParameters; + } + + /** + * @param string $function + * @param array $args + * + * @return \Robo\Result|\Robo\Task\Simulator + */ + public function __call($function, $args) + { + $this->stack[] = array_merge([$function], $args); + $result = call_user_func_array([$this->task, $function], $args); + return $result == $this->task ? $this : $result; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $callchain = ''; + foreach ($this->stack as $action) { + $command = array_shift($action); + $parameters = $this->formatParameters($action); + $callchain .= "\n ->$command($parameters)"; + } + $context = $this->getTaskContext( + [ + '_level' => RoboLogLevel::SIMULATED_ACTION, + 'simulated' => TaskInfo::formatTaskName($this->task), + 'parameters' => $this->formatParameters($this->constructorParameters), + '_style' => ['simulated' => 'fg=blue;options=bold'], + ] + ); + + // RoboLogLevel::SIMULATED_ACTION + $this->printTaskInfo( + "Simulating {simulated}({parameters})$callchain", + $context + ); + + $result = null; + if ($this->task instanceof SimulatedInterface) { + $result = $this->task->simulate($context); + } + if (!isset($result)) { + $result = Result::success($this); + } + + return $result; + } + + /** + * Danger: reach through the simulated wrapper and pull out the command + * to be executed. This is used when using a simulated task with another + * simulated task that runs commands, e.g. the Remote\Ssh task. Using + * a simulated CommandInterface task with a non-simulated task may produce + * unexpected results (e.g. execution!). + * + * @return string + * + * @throws \Robo\Exception\TaskException + */ + public function getCommand() + { + if (!$this->task instanceof CommandInterface) { + throw new TaskException($this->task, 'Simulated task that is not a CommandInterface used as a CommandInterface.'); + } + return $this->task->getCommand(); + } + + /** + * @param string $action + * + * @return string + */ + protected function formatParameters($action) + { + $parameterList = array_map([$this, 'convertParameter'], $action); + return implode(', ', $parameterList); + } + + /** + * @param mixed $item + * + * @return string + */ + protected function convertParameter($item) + { + if (is_callable($item)) { + return 'inline_function(...)'; + } + if (is_array($item)) { + return $this->shortenParameter(var_export($item, true)); + } + if (is_object($item)) { + return '[' . get_class($item). ' object]'; + } + if (is_string($item)) { + return $this->shortenParameter("'$item'"); + } + if (is_null($item)) { + return 'null'; + } + return $item; + } + + /** + * @param string $item + * @param string $shortForm + * + * @return string + */ + protected function shortenParameter($item, $shortForm = '') + { + $maxLength = 80; + $tailLength = 20; + if (strlen($item) < $maxLength) { + return $item; + } + if (!empty($shortForm)) { + return $shortForm; + } + $item = trim($item); + $tail = preg_replace("#.*\n#ms", '', substr($item, -$tailLength)); + $head = preg_replace("#\n.*#ms", '', substr($item, 0, $maxLength - (strlen($tail) + 5))); + return "$head ... $tail"; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/StackBasedTask.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/StackBasedTask.php new file mode 100644 index 00000000..91659f33 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/StackBasedTask.php @@ -0,0 +1,236 @@ +friz() + * ->fraz() + * ->frob(); + * + * We presume that the existing library throws an exception on error. + * + * You want: + * + * $result = $this->taskFrobinator($a, $b, $c) + * ->friz() + * ->fraz() + * ->frob() + * ->run(); + * + * Execution is deferred until run(), and a Robo\Result instance is + * returned. Additionally, using Robo will covert Exceptions + * into RoboResult objects. + * + * To create a new Robo task: + * + * - Make a new class that extends StackBasedTask + * - Give it a constructor that creates a new Frobinator + * - Override getDelegate(), and return the Frobinator instance + * + * Finally, add your new class to loadTasks.php as usual, + * and you are all done. + * + * If you need to add any methods to your task that should run + * immediately (e.g. to set parameters used at run() time), just + * implement them in your derived class. + * + * If you need additional methods that should run deferred, just + * define them as 'protected function _foo()'. Then, users may + * call $this->taskFrobinator()->foo() to get deferred execution + * of _foo(). + */ +abstract class StackBasedTask extends BaseTask +{ + /** + * @var array + */ + protected $stack = []; + + /** + * @var bool + */ + protected $stopOnFail = true; + + /** + * @param bool $stop + * + * @return $this + */ + public function stopOnFail($stop = true) + { + $this->stopOnFail = $stop; + return $this; + } + + /** + * Derived classes should override the getDelegate() method, and + * return an instance of the API class being wrapped. When this + * is done, any method of the delegate is available as a method of + * this class. Calling one of the delegate's methods will defer + * execution until the run() method is called. + * + * @return null + */ + protected function getDelegate() + { + return null; + } + + /** + * Derived classes that have more than one delegate may override + * getCommandList to add as many delegate commands as desired to + * the list of potential functions that __call() tried to find. + * + * @param string $function + * + * @return array + */ + protected function getDelegateCommandList($function) + { + return [[$this, "_$function"], [$this->getDelegate(), $function]]; + } + + /** + * Print progress about the commands being executed + * + * @param string $command + * @param string $action + */ + protected function printTaskProgress($command, $action) + { + $this->printTaskInfo('{command} {action}', ['command' => "{$command[1]}", 'action' => json_encode($action, JSON_UNESCAPED_SLASHES)]); + } + + /** + * Derived classes can override processResult to add more + * logic to result handling from functions. By default, it + * is assumed that if a function returns in int, then + * 0 == success, and any other value is the error code. + * + * @param int|\Robo\Result $function_result + * + * @return \Robo\Result + */ + protected function processResult($function_result) + { + if (is_int($function_result)) { + if ($function_result) { + return Result::error($this, $function_result); + } + } + return Result::success($this); + } + + /** + * Record a function to call later. + * + * @param string $command + * @param array $args + * + * @return $this + */ + protected function addToCommandStack($command, $args) + { + $this->stack[] = array_merge([$command], $args); + return $this; + } + + /** + * Any API function provided by the delegate that executes immediately + * may be handled by __call automatically. These operations will all + * be deferred until this task's run() method is called. + * + * @param string $function + * @param array $args + * + * @return $this + */ + public function __call($function, $args) + { + foreach ($this->getDelegateCommandList($function) as $command) { + if (method_exists($command[0], $command[1])) { + // Otherwise, we'll defer calling this function + // until run(), and return $this. + $this->addToCommandStack($command, $args); + return $this; + } + } + + $message = "Method $function does not exist.\n"; + throw new \BadMethodCallException($message); + } + + /** + * @return int + */ + public function progressIndicatorSteps() + { + // run() will call advanceProgressIndicator() once for each + // file, one after calling stopBuffering, and again after compression. + return count($this->stack); + } + + /** + * Run all of the queued objects on the stack + * + * @return \Robo\Result + */ + public function run() + { + $this->startProgressIndicator(); + $result = Result::success($this); + + foreach ($this->stack as $action) { + $command = array_shift($action); + $this->printTaskProgress($command, $action); + $this->advanceProgressIndicator(); + // TODO: merge data from the result on this call + // with data from the result on the previous call? + // For now, the result always comes from the last function. + $result = $this->callTaskMethod($command, $action); + if ($this->stopOnFail && $result && !$result->wasSuccessful()) { + break; + } + } + + $this->stopProgressIndicator(); + + // todo: add timing information to the result + return $result; + } + + /** + * Execute one task method + * + * @param string $command + * @param string $action + * + * @return \Robo\Result + */ + protected function callTaskMethod($command, $action) + { + try { + $function_result = call_user_func_array($command, $action); + return $this->processResult($function_result); + } catch (\Exception $e) { + $this->printTaskError($e->getMessage()); + return Result::fromException($this, $e); + } + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Atoum.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Atoum.php new file mode 100644 index 00000000..56b47d84 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Atoum.php @@ -0,0 +1,184 @@ +taskAtoum() + * ->files('path/to/test.php') + * ->configFile('config/dev.php') + * ->run() + * + * ?> + * ``` + */ +class Atoum extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * Atoum constructor. + * + * @param null|string $pathToAtoum + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToAtoum = null) + { + $this->command = $pathToAtoum; + if (!$this->command) { + $this->command = $this->findExecutable('atoum'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither local atoum nor global composer installation not found"); + } + } + + /** + * Tag or Tags to filter. + * + * @param string|array $tags + * + * @return $this + */ + public function tags($tags) + { + return $this->addMultipleOption('tags', $tags); + } + + /** + * Display result using the light reporter. + * + * @return $this + */ + public function lightReport() + { + $this->option("--use-light-report"); + + return $this; + } + + /** + * Display result using the tap reporter. + * + * @return $this + */ + public function tap() + { + $this->option("use-tap-report"); + + return $this; + } + + /** + * Path to the bootstrap file. + + * @param string $file + * + * @return $this + */ + public function bootstrap($file) + { + $this->option("bootstrap", $file); + + return $this; + } + + /** + * Path to the config file. + * + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option('-c', $file); + + return $this; + } + + /** + * Use atoum's debug mode. + * + * @return $this + */ + public function debug() + { + $this->option("debug"); + + return $this; + } + + /** + * Test file or test files to run. + * + * @param string|array + * + * @return $this + */ + public function files($files) + { + return $this->addMultipleOption('f', $files); + } + + /** + * Test directory or directories to run. + * + * @param string|array A single directory or a list of directories. + * + * @return $this + */ + public function directories($directories) + { + return $this->addMultipleOption('directories', $directories); + } + + /** + * @param string $option + * @param string|array $values + * + * @return $this + */ + protected function addMultipleOption($option, $values) + { + if (is_string($values)) { + $values = [$values]; + } + + foreach ($values as $value) { + $this->option($option, $value); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running atoum ' . $this->arguments); + + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Behat.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Behat.php new file mode 100644 index 00000000..7e4f1d41 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Behat.php @@ -0,0 +1,163 @@ +taskBehat() + * ->format('pretty') + * ->noInteraction() + * ->run(); + * ?> + * ``` + * + */ +class Behat extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string[] $formaters available formaters for format option + */ + protected $formaters = ['progress', 'pretty', 'junit']; + + /** + * @var string[] $verbose_levels available verbose levels + */ + protected $verbose_levels = ['v', 'vv']; + + /** + * Behat constructor. + * + * @param null|string $pathToBehat + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToBehat = null) + { + $this->command = $pathToBehat; + if (!$this->command) { + $this->command = $this->findExecutable('behat'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Behat found"); + } + } + + /** + * @return $this + */ + public function stopOnFail() + { + $this->option('stop-on-failure'); + return $this; + } + + /** + * @return $this + */ + public function noInteraction() + { + $this->option('no-interaction'); + return $this; + } + + /** + * @param $config_file + * + * @return $this + */ + public function config($config_file) + { + $this->option('config', $config_file); + return $this; + } + + /** + * @return $this + */ + public function colors() + { + $this->option('colors'); + return $this; + } + + /** + * @return $this + */ + public function noColors() + { + $this->option('no-colors'); + return $this; + } + + /** + * @param string $suite + * + * @return $this + */ + public function suite($suite) + { + $this->option('suite', $suite); + return $this; + } + + /** + * @param string $level + * + * @return $this + */ + public function verbose($level = 'v') + { + if (!in_array($level, $this->verbose_levels)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels)); + } + $this->option('-' . $level); + return $this; + } + + /** + * @param string $formater + * + * @return $this + */ + public function format($formater) + { + if (!in_array($formater, $this->formaters)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters)); + } + $this->option('format', $formater); + return $this; + } + + /** + * Returns command that can be executed. + * This method is used to pass generated command from one task to another. + * + * @return string + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running behat {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Codecept.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Codecept.php new file mode 100644 index 00000000..1f8cce70 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Codecept.php @@ -0,0 +1,271 @@ +taskCodecept() + * ->suite('acceptance') + * ->env('chrome') + * ->group('admin') + * ->xml() + * ->html() + * ->run(); + * + * ?> + * ``` + * + */ +class Codecept extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @param string $pathToCodeception + * + * @throws \Robo\Exception\TaskException + */ + public function __construct($pathToCodeception = '') + { + $this->command = $pathToCodeception; + if (!$this->command) { + $this->command = $this->findExecutable('codecept'); + } + if (!$this->command) { + throw new TaskException(__CLASS__, "Neither composer nor phar installation of Codeception found."); + } + $this->command .= ' run'; + } + + /** + * @param string $suite + * + * @return $this + */ + public function suite($suite) + { + $this->option(null, $suite); + return $this; + } + + /** + * @param string $testName + * + * @return $this + */ + public function test($testName) + { + $this->option(null, $testName); + return $this; + } + + /** + * set group option. Can be called multiple times + * + * @param string $group + * + * @return $this + */ + public function group($group) + { + $this->option("group", $group); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function excludeGroup($group) + { + $this->option("skip-group", $group); + return $this; + } + + /** + * generate json report + * + * @param string $file + * + * @return $this + */ + public function json($file = null) + { + $this->option("json", $file); + return $this; + } + + /** + * generate xml JUnit report + * + * @param string $file + * + * @return $this + */ + public function xml($file = null) + { + $this->option("xml", $file); + return $this; + } + + /** + * Generate html report + * + * @param string $dir + * + * @return $this + */ + public function html($dir = null) + { + $this->option("html", $dir); + return $this; + } + + /** + * generate tap report + * + * @param string $file + * + * @return $this + */ + public function tap($file = null) + { + $this->option("tap", $file); + return $this; + } + + /** + * provides config file other then default `codeception.yml` with `-c` option + * + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option("-c", $file); + return $this; + } + + /** + * collect codecoverage in raw format. You may pass name of cov file to save results + * + * @param null|string $cov + * + * @return $this + */ + public function coverage($cov = null) + { + $this->option("coverage", $cov); + return $this; + } + + /** + * execute in silent mode + * + * @return $this + */ + public function silent() + { + $this->option("silent"); + return $this; + } + + /** + * collect code coverage in xml format. You may pass name of xml file to save results + * + * @param string $xml + * + * @return $this + */ + public function coverageXml($xml = null) + { + $this->option("coverage-xml", $xml); + return $this; + } + + /** + * collect code coverage and generate html report. You may pass + * + * @param string $html + * + * @return $this + */ + public function coverageHtml($html = null) + { + $this->option("coverage-html", $html); + return $this; + } + + /** + * @param string $env + * + * @return $this + */ + public function env($env) + { + $this->option("env", $env); + return $this; + } + + /** + * @return $this + */ + public function debug() + { + $this->option("debug"); + return $this; + } + + /** + * @return $this + */ + public function noRebuild() + { + $this->option("no-rebuild"); + return $this; + } + + /** + * @param string $failGroup + * @return $this + */ + public function failGroup($failGroup) + { + $this->option('override', "extensions: config: Codeception\\Extension\\RunFailed: fail-group: {$failGroup}"); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $command = $this->getCommand(); + $this->printTaskInfo('Executing {command}', ['command' => $command]); + return $this->executeCommand($command); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/PHPUnit.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/PHPUnit.php new file mode 100644 index 00000000..df67e1c7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/PHPUnit.php @@ -0,0 +1,199 @@ +taskPHPUnit() + * ->group('core') + * ->bootstrap('test/bootstrap.php') + * ->run() + * + * ?> + * ``` + */ +class PHPUnit extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * Directory of test files or single test file to run. Appended to + * the command and arguments. + * + * @var string + */ + protected $files = ''; + + public function __construct($pathToPhpUnit = null) + { + $this->command = $pathToPhpUnit; + if (!$this->command) { + $this->command = $this->findExecutablePhar('phpunit'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither local phpunit nor global composer installation not found"); + } + } + + /** + * @param string $filter + * + * @return $this + */ + public function filter($filter) + { + $this->option('filter', $filter); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function group($group) + { + $this->option("group", $group); + return $this; + } + + /** + * @param string $group + * + * @return $this + */ + public function excludeGroup($group) + { + $this->option("exclude-group", $group); + return $this; + } + + /** + * adds `log-json` option to runner + * + * @param string $file + * + * @return $this + */ + public function json($file = null) + { + $this->option("log-json", $file); + return $this; + } + + /** + * adds `log-junit` option + * + * @param string $file + * + * @return $this + */ + public function xml($file = null) + { + $this->option("log-junit", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function tap($file = "") + { + $this->option("log-tap", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function bootstrap($file) + { + $this->option("bootstrap", $file); + return $this; + } + + /** + * @param string $file + * + * @return $this + */ + public function configFile($file) + { + $this->option('-c', $file); + return $this; + } + + /** + * @return $this + */ + public function debug() + { + $this->option("debug"); + return $this; + } + + /** + * Directory of test files or single test file to run. + * + * @param string $files A single test file or a directory containing test files. + * + * @return $this + * + * @throws \Robo\Exception\TaskException + * + * @deprecated Use file() or dir() method instead + */ + public function files($files) + { + if (!empty($this->files) || is_array($files)) { + throw new \Robo\Exception\TaskException(__CLASS__, "Only one file or directory may be provided."); + } + $this->files = ' ' . $files; + + return $this; + } + + /** + * Test the provided file. + * + * @param string $file path to file to test + * + * @return $this + */ + public function file($file) + { + return $this->files($file); + } + + /** + * {@inheritdoc} + */ + public function getCommand() + { + return $this->command . $this->arguments . $this->files; + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running PHPUnit {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Phpspec.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Phpspec.php new file mode 100644 index 00000000..dd6a5ae7 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/Phpspec.php @@ -0,0 +1,116 @@ +taskPhpspec() + * ->format('pretty') + * ->noInteraction() + * ->run(); + * ?> + * ``` + * + */ +class Phpspec extends BaseTask implements CommandInterface, PrintedInterface +{ + use \Robo\Common\ExecOneCommand; + + /** + * @var string + */ + protected $command; + + /** + * @var string[] $formaters available formaters for format option + */ + protected $formaters = ['progress', 'html', 'pretty', 'junit', 'dot', 'tap']; + + /** + * @var array $verbose_levels available verbose levels + */ + protected $verbose_levels = ['v', 'vv', 'vvv']; + + public function __construct($pathToPhpspec = null) + { + $this->command = $pathToPhpspec; + if (!$this->command) { + $this->command = $this->findExecutable('phpspec'); + } + if (!$this->command) { + throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Phpspec found"); + } + $this->arg('run'); + } + + public function stopOnFail() + { + $this->option('stop-on-failure'); + return $this; + } + + public function noCodeGeneration() + { + $this->option('no-code-generation'); + return $this; + } + + public function quiet() + { + $this->option('quiet'); + return $this; + } + + public function verbose($level = 'v') + { + if (!in_array($level, $this->verbose_levels)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels)); + } + $this->option('-' . $level); + return $this; + } + + public function noAnsi() + { + $this->option('no-ansi'); + return $this; + } + + public function noInteraction() + { + $this->option('no-interaction'); + return $this; + } + + public function config($config_file) + { + $this->option('config', $config_file); + return $this; + } + + public function format($formater) + { + if (!in_array($formater, $this->formaters)) { + throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters)); + } + $this->option('format', $formater); + return $this; + } + + public function getCommand() + { + return $this->command . $this->arguments; + } + + public function run() + { + $this->printTaskInfo('Running phpspec {arguments}', ['arguments' => $this->arguments]); + return $this->executeCommand($this->getCommand()); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/loadTasks.php new file mode 100644 index 00000000..43145b9b --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Testing/loadTasks.php @@ -0,0 +1,55 @@ +task(Codecept::class, $pathToCodeception); + } + + /** + * @param null|string $pathToPhpUnit + * + * @return \Robo\Task\Testing\PHPUnit + */ + protected function taskPhpUnit($pathToPhpUnit = null) + { + return $this->task(PHPUnit::class, $pathToPhpUnit); + } + + /** + * @param null $pathToPhpspec + * + * @return \Robo\Task\Testing\Phpspec + */ + protected function taskPhpspec($pathToPhpspec = null) + { + return $this->task(Phpspec::class, $pathToPhpspec); + } + + /** + * @param null $pathToAtoum + * + * @return \Robo\Task\Testing\Atoum + */ + protected function taskAtoum($pathToAtoum = null) + { + return $this->task(Atoum::class, $pathToAtoum); + } + + /** + * @param null $pathToBehat + * + * @return \Robo\Task\Testing\Behat + */ + protected function taskBehat($pathToBehat = null) + { + return $this->task(Behat::class, $pathToBehat); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/GitStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/GitStack.php new file mode 100644 index 00000000..6cb1783f --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/GitStack.php @@ -0,0 +1,177 @@ +taskGitStack() + * ->stopOnFail() + * ->add('-A') + * ->commit('adding everything') + * ->push('origin','master') + * ->tag('0.6.0') + * ->push('origin','0.6.0') + * ->run() + * + * $this->taskGitStack() + * ->stopOnFail() + * ->add('doc/*') + * ->commit('doc updated') + * ->push() + * ->run(); + * ?> + * ``` + */ +class GitStack extends CommandStack +{ + /** + * @param string $pathToGit + */ + public function __construct($pathToGit = 'git') + { + $this->executable = $pathToGit; + } + + /** + * Executes `git clone` + * + * @param string $repo + * @param string $to + * + * @return $this + */ + public function cloneRepo($repo, $to = "", $branch = "") + { + $cmd = ['clone', $repo, $to]; + if (!empty($branch)) { + $cmd[] = "--branch $branch"; + } + return $this->exec($cmd); + } + + /** + * Executes `git clone` with depth 1 as default + * + * @param string $repo + * @param string $to + * @param string $branch + * @param int $depth + * + * @return $this + */ + public function cloneShallow($repo, $to = '', $branch = "", $depth = 1) + { + $cmd = ["clone --depth $depth", $repo, $to]; + if (!empty($branch)) { + $cmd[] = "--branch $branch"; + } + + return $this->exec($cmd); + } + + /** + * Executes `git add` command with files to add pattern + * + * @param string $pattern + * + * @return $this + */ + public function add($pattern) + { + return $this->exec([__FUNCTION__, $pattern]); + } + + /** + * Executes `git commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = "") + { + $message = ProcessUtils::escapeArgument($message); + return $this->exec([__FUNCTION__, "-m $message", $options]); + } + + /** + * Executes `git pull` command. + * + * @param string $origin + * @param string $branch + * + * @return $this + */ + public function pull($origin = '', $branch = '') + { + return $this->exec([__FUNCTION__, $origin, $branch]); + } + + /** + * Executes `git push` command + * + * @param string $origin + * @param string $branch + * + * @return $this + */ + public function push($origin = '', $branch = '') + { + return $this->exec([__FUNCTION__, $origin, $branch]); + } + + /** + * Performs git merge + * + * @param string $branch + * + * @return $this + */ + public function merge($branch) + { + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `git checkout` command + * + * @param string $branch + * + * @return $this + */ + public function checkout($branch) + { + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `git tag` command + * + * @param string $tag_name + * @param string $message + * + * @return $this + */ + public function tag($tag_name, $message = "") + { + if ($message != "") { + $message = "-m '$message'"; + } + return $this->exec([__FUNCTION__, $message, $tag_name]); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo("Running git commands..."); + return parent::run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/HgStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/HgStack.php new file mode 100644 index 00000000..71cc0ca9 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/HgStack.php @@ -0,0 +1,153 @@ +hgStack + * ->cloneRepo('https://bitbucket.org/durin42/hgsubversion') + * ->pull() + * ->add() + * ->commit('changed') + * ->push() + * ->tag('0.6.0') + * ->push('0.6.0') + * ->run(); + * ?> + * ``` + */ +class HgStack extends CommandStack +{ + + /** + * @param string $pathToHg + */ + public function __construct($pathToHg = 'hg') + { + $this->executable = $pathToHg; + } + + /** + * Executes `hg clone` + * + * @param string $repo + * @param string $to + * + * @return $this + */ + public function cloneRepo($repo, $to = '') + { + return $this->exec(['clone', $repo, $to]); + } + + /** + * Executes `hg add` command with files to add by pattern + * + * @param string $include + * @param string $exclude + * + * @return $this + */ + public function add($include = '', $exclude = '') + { + if (strlen($include) > 0) { + $include = "-I {$include}"; + } + + if (strlen($exclude) > 0) { + $exclude = "-X {$exclude}"; + } + + return $this->exec([__FUNCTION__, $include, $exclude]); + } + + /** + * Executes `hg commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = '') + { + return $this->exec([__FUNCTION__, "-m '{$message}'", $options]); + } + + /** + * Executes `hg pull` command. + * + * @param string $branch + * + * @return $this + */ + public function pull($branch = '') + { + if (strlen($branch) > 0) { + $branch = "-b '{$branch}''"; + } + + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Executes `hg push` command + * + * @param string $branch + * + * @return $this + */ + public function push($branch = '') + { + if (strlen($branch) > 0) { + $branch = "-b '{$branch}'"; + } + + return $this->exec([__FUNCTION__, $branch]); + } + + /** + * Performs hg merge + * + * @param string $revision + * + * @return $this + */ + public function merge($revision = '') + { + if (strlen($revision) > 0) { + $revision = "-r {$revision}"; + } + + return $this->exec([__FUNCTION__, $revision]); + } + + /** + * Executes `hg tag` command + * + * @param string $tag_name + * @param string $message + * + * @return $this + */ + public function tag($tag_name, $message = '') + { + if ($message !== '') { + $message = "-m '{$message}'"; + } + return $this->exec([__FUNCTION__, $message, $tag_name]); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->printTaskInfo('Running hg commands...'); + return parent::run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/SvnStack.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/SvnStack.php new file mode 100644 index 00000000..ec719b53 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/SvnStack.php @@ -0,0 +1,106 @@ +taskSvnStack() + * ->checkout('http://svn.collab.net/repos/svn/trunk') + * ->run() + * + * // alternatively + * $this->_svnCheckout('http://svn.collab.net/repos/svn/trunk'); + * + * $this->taskSvnStack('username', 'password') + * ->stopOnFail() + * ->update() + * ->add('doc/*') + * ->commit('doc updated') + * ->run(); + * ?> + * ``` + */ +class SvnStack extends CommandStack implements CommandInterface +{ + /** + * @var bool + */ + protected $stopOnFail = false; + + /** + * @var \Robo\Result + */ + protected $result; + + /** + * @param string $username + * @param string $password + * @param string $pathToSvn + */ + public function __construct($username = '', $password = '', $pathToSvn = 'svn') + { + $this->executable = $pathToSvn; + if (!empty($username)) { + $this->executable .= " --username $username"; + } + if (!empty($password)) { + $this->executable .= " --password $password"; + } + $this->result = Result::success($this); + } + + /** + * Updates `svn update` command + * + * @param string $path + * + * @return $this; + */ + public function update($path = '') + { + return $this->exec("update $path"); + } + + /** + * Executes `svn add` command with files to add pattern + * + * @param string $pattern + * + * @return $this + */ + public function add($pattern = '') + { + return $this->exec("add $pattern"); + } + + /** + * Executes `svn commit` command with a message + * + * @param string $message + * @param string $options + * + * @return $this + */ + public function commit($message, $options = "") + { + return $this->exec("commit -m '$message' $options"); + } + + /** + * Executes `svn checkout` command + * + * @param string $branch + * + * @return $this + */ + public function checkout($branch) + { + return $this->exec("checkout $branch"); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/loadShortcuts.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/loadShortcuts.php new file mode 100644 index 00000000..7d64ab58 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/loadShortcuts.php @@ -0,0 +1,35 @@ +taskSvnStack()->checkout($url)->run(); + } + + /** + * @param string $url + * + * @return \Robo\Result + */ + protected function _gitClone($url) + { + return $this->taskGitStack()->cloneRepo($url)->run(); + } + + /** + * @param string $url + * + * @return \Robo\Result + */ + protected function _hgClone($url) + { + return $this->taskHgStack()->cloneRepo($url)->run(); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/loadTasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/loadTasks.php new file mode 100644 index 00000000..6dd06228 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Task/Vcs/loadTasks.php @@ -0,0 +1,37 @@ +task(SvnStack::class, $username, $password, $pathToSvn); + } + + /** + * @param string $pathToGit + * + * @return \Robo\Task\Vcs\GitStack + */ + protected function taskGitStack($pathToGit = 'git') + { + return $this->task(GitStack::class, $pathToGit); + } + + /** + * @param string $pathToHg + * + * @return \Robo\Task\Vcs\HgStack + */ + protected function taskHgStack($pathToHg = 'hg') + { + return $this->task(HgStack::class, $pathToHg); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/TaskAccessor.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/TaskAccessor.php new file mode 100644 index 00000000..e65cd3eb --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/TaskAccessor.php @@ -0,0 +1,47 @@ +task(Foo::class, $a, $b); + * + * instead of: + * + * $this->taskFoo($a, $b); + * + * The later form is preferred. + * + * @return \Robo\Collection\CollectionBuilder + */ + protected function task() + { + $args = func_get_args(); + $name = array_shift($args); + + $collectionBuilder = $this->collectionBuilder(); + return $collectionBuilder->build($name, $args); + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/TaskInfo.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/TaskInfo.php new file mode 100644 index 00000000..ce59c2d5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/TaskInfo.php @@ -0,0 +1,35 @@ + TaskInfo::formatTaskName($task), + 'task' => $task, + ]; + } + + /** + * @param object $task + * + * @return string + */ + public static function formatTaskName($task) + { + $name = get_class($task); + $name = preg_replace('~Stack^~', '', $name); + $name = str_replace('Robo\\Task\Base\\', '', $name); + $name = str_replace('Robo\\Task\\', '', $name); + $name = str_replace('Robo\\Collection\\', '', $name); + return $name; + } +} diff --git a/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Tasks.php b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Tasks.php new file mode 100644 index 00000000..2822d7d5 --- /dev/null +++ b/core/lib/composer/vendor/consolidation/robo/scenarios/symfony4/src/Tasks.php @@ -0,0 +1,23 @@ +export(); + } + + /** + * Performs the actual property expansion. + * + * @param Data $data + * A data object, containing the $array. + * @param array $array + * The original, unmodified array. + * @param string $parent_keys + * The parent keys of the current key in dot notation. This is used to + * track the absolute path to the current key in recursive cases. + * @param Data|null $reference_data + * A reference data object. This is not operated upon but is used as a + * reference to provide supplemental values for property expansion. + */ + protected static function doExpandArrayProperties( + $data, + $array, + $parent_keys = '', + $reference_data = null + ) { + foreach ($array as $key => $value) { + // Boundary condition(s). + if (is_null($value) || is_bool($value)) { + continue; + } + // Recursive case. + if (is_array($value)) { + self::doExpandArrayProperties($data, $value, $parent_keys . "$key.", $reference_data); + } // Base case. + else { + self::expandStringProperties($data, $parent_keys, $reference_data, $value, $key); + } + } + } + + /** + * Expand a single property. + * + * @param Data $data + * A data object, containing the $array. + * @param string $parent_keys + * The parent keys of the current key in dot notation. This is used to + * track the absolute path to the current key in recursive cases. + * @param Data|null $reference_data + * A reference data object. This is not operated upon but is used as a + * reference to provide supplemental values for property expansion. + * @param string $value + * The unexpanded property value. + * @param string $key + * The immediate key of the property. + * + * @return mixed + */ + protected static function expandStringProperties( + $data, + $parent_keys, + $reference_data, + $value, + $key + ) { + // We loop through all placeholders in a given string. + // E.g., '${placeholder1} ${placeholder2}' requires two replacements. + while (strpos($value, '${') !== false) { + $original_value = $value; + $value = preg_replace_callback( + '/\$\{([^\$}]+)\}/', + function ($matches) use ($data, $reference_data) { + return self::expandStringPropertiesCallback( + $matches, + $data, + $reference_data + ); + }, + $value + ); + + // If no replacement occurred at all, break to prevent + // infinite loop. + if ($original_value == $value) { + break; + } + + // Set value on $data object. + if ($parent_keys) { + $full_key = $parent_keys . "$key"; + } else { + $full_key = $key; + } + $data->set($full_key, $value); + } + return $value; + } + + /** + * Expansion callback used by preg_replace_callback() in expandProperty(). + * + * @param array $matches + * An array of matches created by preg_replace_callback(). + * @param Data $data + * A data object containing the complete array being operated upon. + * @param Data|null $reference_data + * A reference data object. This is not operated upon but is used as a + * reference to provide supplemental values for property expansion. + * + * @return mixed + */ + public static function expandStringPropertiesCallback( + $matches, + $data, + $reference_data = null + ) { + $property_name = $matches[1]; + $unexpanded_value = $matches[0]; + + // Use only values within the subject array's data. + if (!$reference_data) { + return self::expandProperty($property_name, $unexpanded_value, $data); + } // Search both the subject array's data and the reference data for a value. + else { + return self::expandPropertyWithReferenceData( + $property_name, + $unexpanded_value, + $data, + $reference_data + ); + } + } + + /** + * Searches both the subject data and the reference data for value. + * + * @param string $property_name + * The name of the value for which to search. + * @param string $unexpanded_value + * The original, unexpanded value, containing the placeholder. + * @param Data $data + * A data object containing the complete array being operated upon. + * @param Data|null $reference_data + * A reference data object. This is not operated upon but is used as a + * reference to provide supplemental values for property expansion. + * + * @return string + * The expanded string. + */ + public static function expandPropertyWithReferenceData( + $property_name, + $unexpanded_value, + $data, + $reference_data + ) { + $expanded_value = self::expandProperty( + $property_name, + $unexpanded_value, + $data + ); + // If the string was not changed using the subject data, try using + // the reference data. + if ($expanded_value == $unexpanded_value) { + $expanded_value = self::expandProperty( + $property_name, + $unexpanded_value, + $reference_data + ); + } + + return $expanded_value; + } + + /** + * Searches a data object for a value. + * + * @param string $property_name + * The name of the value for which to search. + * @param string $unexpanded_value + * The original, unexpanded value, containing the placeholder. + * @param Data $data + * A data object containing possible replacement values. + * + * @return mixed + */ + public static function expandProperty($property_name, $unexpanded_value, $data) + { + if (strpos($property_name, "env.") === 0 && + !$data->has($property_name)) { + $env_key = substr($property_name, 4); + if (getenv($env_key)) { + $data->set($property_name, getenv($env_key)); + } + } + + if (!$data->has($property_name)) { + self::log("Property \${'$property_name'} could not be expanded."); + return $unexpanded_value; + } else { + $expanded_value = $data->get($property_name); + if (is_array($expanded_value)) { + $expanded_value = Yaml::dump($expanded_value, 0); + return $expanded_value; + } + self::log("Expanding property \${'$property_name'} => $expanded_value."); + return $expanded_value; + } + } + + /** + * @param $message + */ + public static function log($message) + { + // print "$message\n"; + } +} diff --git a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests deleted file mode 120000 index c2ebfe53..00000000 --- a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests +++ /dev/null @@ -1 +0,0 @@ -../../tests \ No newline at end of file diff --git a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests/phpunit/ExpanderTest.php b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests/phpunit/ExpanderTest.php new file mode 100644 index 00000000..291d00cc --- /dev/null +++ b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests/phpunit/ExpanderTest.php @@ -0,0 +1,99 @@ +assertEquals('gomjabbar', $expanded['env-test']); + $this->assertEquals('Frank Herbert 1965', $expanded['book']['copyright']); + $this->assertEquals('Paul Atreides', $expanded['book']['protaganist']); + $this->assertEquals('Dune by Frank Herbert', $expanded['summary']); + $this->assertEquals('${book.media.1}, hardcover', $expanded['available-products']); + $this->assertEquals('Dune', $expanded['product-name']); + $this->assertEquals(Yaml::dump($array['inline-array'], 0), $expanded['expand-array']); + + $expanded = Expander::expandArrayProperties($array, $reference_array); + $this->assertEquals('Dune Messiah, and others.', $expanded['sequels']); + $this->assertEquals('Dune Messiah', $expanded['book']['nested-reference']); + } + + /** + * Tests Expander::parse(). + * + * @param string $filename + * @param array $reference_array + * + * @dataProvider providerYaml + */ + public function testParse($filename, $reference_array) + { + $yaml_string = file_get_contents(__DIR__ . "/../resources/$filename"); + $expanded = Expander::parse($yaml_string); + $this->assertEquals('Frank Herbert 1965', $expanded['book']['copyright']); + $this->assertEquals('Paul Atreides', $expanded['book']['protaganist']); + $this->assertEquals('Dune by Frank Herbert', $expanded['summary']); + $this->assertEquals('${book.media.1}, hardcover', $expanded['available-products']); + + $expanded = Expander::parse($yaml_string, $reference_array); + $this->assertEquals('Dune Messiah, and others.', $expanded['sequels']); + $this->assertEquals('Dune Messiah', $expanded['book']['nested-reference']); + } + + /** + * @return array + * An array of values to test. + */ + public function providerYaml() + { + return [ + ['valid.yml', [ + 'book' => [ + 'sequel' => 'Dune Messiah' + ] + ]], + ]; + } + + /** + * Tests Expander::expandProperty(). + * + * @dataProvider providerTestExpandProperty + */ + public function testExpandProperty($array, $property_name, $unexpanded_string, $expected) + { + $data = new Data($array); + $expanded_value = Expander::expandProperty($property_name, $unexpanded_string, $data); + + $this->assertEquals($expected, $expanded_value); + } + + /** + * @return array + */ + public function providerTestExpandProperty() + { + return [ + [ ['author' => 'Frank Herbert'], 'author', '${author}', 'Frank Herbert' ], + [ ['book' => ['author' => 'Frank Herbert' ]], 'book.author', '${book.author}', 'Frank Herbert' ], + ]; + } +} diff --git a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests/resources/valid.yml b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests/resources/valid.yml new file mode 100644 index 00000000..78e4bc61 --- /dev/null +++ b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony2/tests/resources/valid.yml @@ -0,0 +1,35 @@ +# This file should contain only valid YAML. +type: book +book: + title: Dune + author: Frank Herbert + copyright: ${book.author} 1965 + protaganist: ${characters.0.name} + media: + - hardcover + # Use a nested key to reference an external value. + nested-reference: ${book.sequel} +characters: + - name: Paul Atreides + occupation: Kwisatz Haderach + aliases: + - Usul + - Muad'Dib + - The Preacher + - name: Duncan Idaho + occupation: Swordmaster +summary: ${book.title} by ${book.author} +# This is a complete fake property. +publisher: ${not.real.property} +# series.books is not defined in this YAML file, but is passed in to the parser by the application. +sequels: ${book.sequel}, and others. +# Reference one real value and one fake value. +available-products: ${book.media.1}, ${book.media.0} +# Nested property, should resolve to ${book.title} and then 'Dune'. +product-name: ${${type}.title} +# Represent a few more data types and formats. +boolean-value: true +null-value: null +inline-array: [ one, two, three ] +expand-array: ${inline-array} +env-test: ${env.test} \ No newline at end of file diff --git a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/src b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/src deleted file mode 120000 index 929cb3dc..00000000 --- a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/src +++ /dev/null @@ -1 +0,0 @@ -../../src \ No newline at end of file diff --git a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/src/Expander.php b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/src/Expander.php new file mode 100644 index 00000000..d922db59 --- /dev/null +++ b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/src/Expander.php @@ -0,0 +1,273 @@ +export(); + } + + /** + * Performs the actual property expansion. + * + * @param Data $data + * A data object, containing the $array. + * @param array $array + * The original, unmodified array. + * @param string $parent_keys + * The parent keys of the current key in dot notation. This is used to + * track the absolute path to the current key in recursive cases. + * @param Data|null $reference_data + * A reference data object. This is not operated upon but is used as a + * reference to provide supplemental values for property expansion. + */ + protected static function doExpandArrayProperties( + $data, + $array, + $parent_keys = '', + $reference_data = null + ) { + foreach ($array as $key => $value) { + // Boundary condition(s). + if (is_null($value) || is_bool($value)) { + continue; + } + // Recursive case. + if (is_array($value)) { + self::doExpandArrayProperties($data, $value, $parent_keys . "$key.", $reference_data); + } // Base case. + else { + self::expandStringProperties($data, $parent_keys, $reference_data, $value, $key); + } + } + } + + /** + * Expand a single property. + * + * @param Data $data + * A data object, containing the $array. + * @param string $parent_keys + * The parent keys of the current key in dot notation. This is used to + * track the absolute path to the current key in recursive cases. + * @param Data|null $reference_data + * A reference data object. This is not operated upon but is used as a + * reference to provide supplemental values for property expansion. + * @param string $value + * The unexpanded property value. + * @param string $key + * The immediate key of the property. + * + * @return mixed + */ + protected static function expandStringProperties( + $data, + $parent_keys, + $reference_data, + $value, + $key + ) { + // We loop through all placeholders in a given string. + // E.g., '${placeholder1} ${placeholder2}' requires two replacements. + while (strpos($value, '${') !== false) { + $original_value = $value; + $value = preg_replace_callback( + '/\$\{([^\$}]+)\}/', + function ($matches) use ($data, $reference_data) { + return self::expandStringPropertiesCallback( + $matches, + $data, + $reference_data + ); + }, + $value + ); + + // If no replacement occurred at all, break to prevent + // infinite loop. + if ($original_value == $value) { + break; + } + + // Set value on $data object. + if ($parent_keys) { + $full_key = $parent_keys . "$key"; + } else { + $full_key = $key; + } + $data->set($full_key, $value); + } + return $value; + } + + /** + * Expansion callback used by preg_replace_callback() in expandProperty(). + * + * @param array $matches + * An array of matches created by preg_replace_callback(). + * @param Data $data + * A data object containing the complete array being operated upon. + * @param Data|null $reference_data + * A reference data object. This is not operated upon but is used as a + * reference to provide supplemental values for property expansion. + * + * @return mixed + */ + public static function expandStringPropertiesCallback( + $matches, + $data, + $reference_data = null + ) { + $property_name = $matches[1]; + $unexpanded_value = $matches[0]; + + // Use only values within the subject array's data. + if (!$reference_data) { + return self::expandProperty($property_name, $unexpanded_value, $data); + } // Search both the subject array's data and the reference data for a value. + else { + return self::expandPropertyWithReferenceData( + $property_name, + $unexpanded_value, + $data, + $reference_data + ); + } + } + + /** + * Searches both the subject data and the reference data for value. + * + * @param string $property_name + * The name of the value for which to search. + * @param string $unexpanded_value + * The original, unexpanded value, containing the placeholder. + * @param Data $data + * A data object containing the complete array being operated upon. + * @param Data|null $reference_data + * A reference data object. This is not operated upon but is used as a + * reference to provide supplemental values for property expansion. + * + * @return string + * The expanded string. + */ + public static function expandPropertyWithReferenceData( + $property_name, + $unexpanded_value, + $data, + $reference_data + ) { + $expanded_value = self::expandProperty( + $property_name, + $unexpanded_value, + $data + ); + // If the string was not changed using the subject data, try using + // the reference data. + if ($expanded_value == $unexpanded_value) { + $expanded_value = self::expandProperty( + $property_name, + $unexpanded_value, + $reference_data + ); + } + + return $expanded_value; + } + + /** + * Searches a data object for a value. + * + * @param string $property_name + * The name of the value for which to search. + * @param string $unexpanded_value + * The original, unexpanded value, containing the placeholder. + * @param Data $data + * A data object containing possible replacement values. + * + * @return mixed + */ + public static function expandProperty($property_name, $unexpanded_value, $data) + { + if (strpos($property_name, "env.") === 0 && + !$data->has($property_name)) { + $env_key = substr($property_name, 4); + if (getenv($env_key)) { + $data->set($property_name, getenv($env_key)); + } + } + + if (!$data->has($property_name)) { + self::log("Property \${'$property_name'} could not be expanded."); + return $unexpanded_value; + } else { + $expanded_value = $data->get($property_name); + if (is_array($expanded_value)) { + $expanded_value = Yaml::dump($expanded_value, 0); + return $expanded_value; + } + self::log("Expanding property \${'$property_name'} => $expanded_value."); + return $expanded_value; + } + } + + /** + * @param $message + */ + public static function log($message) + { + // print "$message\n"; + } +} diff --git a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests deleted file mode 120000 index c2ebfe53..00000000 --- a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests +++ /dev/null @@ -1 +0,0 @@ -../../tests \ No newline at end of file diff --git a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests/phpunit/ExpanderTest.php b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests/phpunit/ExpanderTest.php new file mode 100644 index 00000000..291d00cc --- /dev/null +++ b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests/phpunit/ExpanderTest.php @@ -0,0 +1,99 @@ +assertEquals('gomjabbar', $expanded['env-test']); + $this->assertEquals('Frank Herbert 1965', $expanded['book']['copyright']); + $this->assertEquals('Paul Atreides', $expanded['book']['protaganist']); + $this->assertEquals('Dune by Frank Herbert', $expanded['summary']); + $this->assertEquals('${book.media.1}, hardcover', $expanded['available-products']); + $this->assertEquals('Dune', $expanded['product-name']); + $this->assertEquals(Yaml::dump($array['inline-array'], 0), $expanded['expand-array']); + + $expanded = Expander::expandArrayProperties($array, $reference_array); + $this->assertEquals('Dune Messiah, and others.', $expanded['sequels']); + $this->assertEquals('Dune Messiah', $expanded['book']['nested-reference']); + } + + /** + * Tests Expander::parse(). + * + * @param string $filename + * @param array $reference_array + * + * @dataProvider providerYaml + */ + public function testParse($filename, $reference_array) + { + $yaml_string = file_get_contents(__DIR__ . "/../resources/$filename"); + $expanded = Expander::parse($yaml_string); + $this->assertEquals('Frank Herbert 1965', $expanded['book']['copyright']); + $this->assertEquals('Paul Atreides', $expanded['book']['protaganist']); + $this->assertEquals('Dune by Frank Herbert', $expanded['summary']); + $this->assertEquals('${book.media.1}, hardcover', $expanded['available-products']); + + $expanded = Expander::parse($yaml_string, $reference_array); + $this->assertEquals('Dune Messiah, and others.', $expanded['sequels']); + $this->assertEquals('Dune Messiah', $expanded['book']['nested-reference']); + } + + /** + * @return array + * An array of values to test. + */ + public function providerYaml() + { + return [ + ['valid.yml', [ + 'book' => [ + 'sequel' => 'Dune Messiah' + ] + ]], + ]; + } + + /** + * Tests Expander::expandProperty(). + * + * @dataProvider providerTestExpandProperty + */ + public function testExpandProperty($array, $property_name, $unexpanded_string, $expected) + { + $data = new Data($array); + $expanded_value = Expander::expandProperty($property_name, $unexpanded_string, $data); + + $this->assertEquals($expected, $expanded_value); + } + + /** + * @return array + */ + public function providerTestExpandProperty() + { + return [ + [ ['author' => 'Frank Herbert'], 'author', '${author}', 'Frank Herbert' ], + [ ['book' => ['author' => 'Frank Herbert' ]], 'book.author', '${book.author}', 'Frank Herbert' ], + ]; + } +} diff --git a/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests/resources/valid.yml b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests/resources/valid.yml new file mode 100644 index 00000000..78e4bc61 --- /dev/null +++ b/core/lib/composer/vendor/grasmash/yaml-expander/scenarios/symfony4/tests/resources/valid.yml @@ -0,0 +1,35 @@ +# This file should contain only valid YAML. +type: book +book: + title: Dune + author: Frank Herbert + copyright: ${book.author} 1965 + protaganist: ${characters.0.name} + media: + - hardcover + # Use a nested key to reference an external value. + nested-reference: ${book.sequel} +characters: + - name: Paul Atreides + occupation: Kwisatz Haderach + aliases: + - Usul + - Muad'Dib + - The Preacher + - name: Duncan Idaho + occupation: Swordmaster +summary: ${book.title} by ${book.author} +# This is a complete fake property. +publisher: ${not.real.property} +# series.books is not defined in this YAML file, but is passed in to the parser by the application. +sequels: ${book.sequel}, and others. +# Reference one real value and one fake value. +available-products: ${book.media.1}, ${book.media.0} +# Nested property, should resolve to ${book.title} and then 'Dune'. +product-name: ${${type}.title} +# Represent a few more data types and formats. +boolean-value: true +null-value: null +inline-array: [ one, two, three ] +expand-array: ${inline-array} +env-test: ${env.test} \ No newline at end of file diff --git a/core/login.php b/core/login.php index 9cf3dfe5..4fda0645 100644 --- a/core/login.php +++ b/core/login.php @@ -302,14 +302,13 @@ $csrfToken = sha1(rand(4500, 100000) . time(). CLIENT_BASE_URL); var password = $("#password").val(); var passwordValidation = function (str) { - var val = /^[a-zA-Z0-9]\w{6,}$/; - return str != null && val.test(str); + return str.length > 7; }; if(!passwordValidation(password)){ $("#newPasswordFormAlert").show(); - $("#newPasswordFormAlert").html("Password may contain only letters, numbers and should be longer than 6 characters"); + $("#newPasswordFormAlert").html("Password should be longer than 7 characters"); return; } @@ -331,6 +330,10 @@ $csrfToken = sha1(rand(4500, 100000) . time(). CLIENT_BASE_URL); $("#loginForm").submit(); } + function authGoogle() { + window.location.href = window.location.href.split('login.php')[0] + "login.php?google=1"; + } +
    diff --git a/core/migrations/list.php b/core/migrations/list.php index 8b1e9f03..c9f80b05 100644 --- a/core/migrations/list.php +++ b/core/migrations/list.php @@ -1,5 +1,12 @@ executeQuery($sql); + } + + public function down(){ + + } + +} diff --git a/core/migrations/v20180801_240003_asset_management.php b/core/migrations/v20180801_240003_asset_management.php new file mode 100644 index 00000000..18bb0668 --- /dev/null +++ b/core/migrations/v20180801_240003_asset_management.php @@ -0,0 +1,63 @@ +executeQuery($sql); + + + $sql = <<<'SQL' +create table `CompanyAssets` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `code` VARCHAR(30) NOT NULL, + `type` bigint(20) NULL, + `attachment` varchar(100) NULL, + `employee` bigint(20) NULL, + `department` bigint(20) NULL, + `description` TEXT NULL, + `created` DATETIME default '0000-00-00 00:00:00', + `updated` DATETIME default '0000-00-00 00:00:00', + primary key (`id`), + CONSTRAINT `Fk_CompanyAssets_AssetTypes` FOREIGN KEY (`type`) REFERENCES `AssetTypes` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `Fk_CompanyAssets_Employees` FOREIGN KEY (`employee`) REFERENCES `Employees` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `Fk_CompanyAssets_CompanyStructures` FOREIGN KEY (`department`) REFERENCES `CompanyStructures` (`id`) ON DELETE SET NULL ON UPDATE CASCADE +) engine=innodb default charset=utf8; +SQL; + $this->executeQuery($sql); + + + $report = new Report(); + $report->name = 'Company Asset Report'; + $report->parameters = '[["department", {"label":"Department","type":"select2","remote-source":["CompanyStructure","id","title"],"allow-null":true}],["type", {"label":"Asset Type","type":"select2","remote-source":["AssetType","id","name"],"allow-null":true}]]'; + $report->query = 'AssetUsageReport'; + $report->type = 'Class'; + $report->paramOrder = '["department","type"]'; + $report->report_group = 'Resources'; + $report->output = 'CSV'; + $report->details = 'List company assets assigned to employees and departments'; + $ok = $report->Save(); + + return true; + } + + public function down(){ + + return true; + } + +} diff --git a/core/migrations/v20180808_250004_add_languages.php b/core/migrations/v20180808_250004_add_languages.php new file mode 100644 index 00000000..98e5e488 --- /dev/null +++ b/core/migrations/v20180808_250004_add_languages.php @@ -0,0 +1,39 @@ +executeQuery($sql); + + $sql = <<<'SQL' + INSERT INTO `SupportedLanguages` (`name`, `description`) VALUES ('sv', 'Swedish'); +SQL; + $this->executeQuery($sql); + + $sql = <<<'SQL' + INSERT INTO `SupportedLanguages` (`name`, `description`) VALUES ('no', 'Norwegian'); +SQL; + $this->executeQuery($sql); + + $sql = <<<'SQL' + INSERT INTO `SupportedLanguages` (`name`, `description`) VALUES ('pt', 'Portuguese'); +SQL; + $this->executeQuery($sql); + + $sql = <<<'SQL' + INSERT INTO `SupportedLanguages` (`name`, `description`) VALUES ('nl', 'Dutch'); +SQL; + return $this->executeQuery($sql); + } + + public function down(){ + + return true; + } + +} diff --git a/core/migrations/v20180810_250005_performance_review.php b/core/migrations/v20180810_250005_performance_review.php new file mode 100644 index 00000000..b44c6491 --- /dev/null +++ b/core/migrations/v20180810_250005_performance_review.php @@ -0,0 +1,72 @@ +executeQuery($sql); + + + $sql = <<<'SQL' +create table `PerformanceReviews` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `name` varchar(150) NOT NULL, + `employee` bigint(20) NULL, + `coordinator` bigint(20) NULL, + `attendees` VARCHAR(50) NOT NULL, + `form` bigint(20) NULL, + `status` varchar(20) NOT NULL, + `review_date` DATETIME default '0000-00-00 00:00:00', + `review_period_start` DATETIME default '0000-00-00 00:00:00', + `review_period_end` DATETIME default '0000-00-00 00:00:00', + `self_assessment_due` DATETIME default '0000-00-00 00:00:00', + `notes` TEXT NULL, + `created` DATETIME default '0000-00-00 00:00:00', + `updated` DATETIME default '0000-00-00 00:00:00', + primary key (`id`), + CONSTRAINT `Fk_PerformanceReviews_ReviewTemplates` FOREIGN KEY (`form`) REFERENCES ReviewTemplates (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `Fk_PerformanceReviews_Employees1` FOREIGN KEY (`employee`) REFERENCES `Employees` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `Fk_PerformanceReviews_Employees2` FOREIGN KEY (`coordinator`) REFERENCES `Employees` (`id`) ON DELETE SET NULL ON UPDATE CASCADE +) engine=innodb default charset=utf8; +SQL; + $this->executeQuery($sql); + + $sql = <<<'SQL' +create table `ReviewFeedbacks` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `employee` bigint(20) NULL, + `review` bigint(20) NULL, + `subject` bigint(20) NULL, + `form` bigint(20) NULL, + `status` varchar(20) NOT NULL, + `dueon` DATETIME default '0000-00-00 00:00:00', + `created` DATETIME default '0000-00-00 00:00:00', + `updated` DATETIME default '0000-00-00 00:00:00', + primary key (`id`), + CONSTRAINT `Fk_ReviewFeedbacks_ReviewTemplates` FOREIGN KEY (`form`) REFERENCES ReviewTemplates (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `Fk_ReviewFeedbacks_PerformanceReviews` FOREIGN KEY (`review`) REFERENCES PerformanceReviews (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `Fk_ReviewFeedbacks_Employees1` FOREIGN KEY (`employee`) REFERENCES `Employees` (`id`) ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT `Fk_ReviewFeedbacks_Employees2` FOREIGN KEY (`subject`) REFERENCES `Employees` (`id`) ON DELETE SET NULL ON UPDATE CASCADE +) engine=innodb default charset=utf8; +SQL; + return $this->executeQuery($sql); + } + + public function down(){ + + return true; + } + +} diff --git a/core/migrations/v20180912_250006_remove_null_users.php b/core/migrations/v20180912_250006_remove_null_users.php new file mode 100644 index 00000000..27a3f1f2 --- /dev/null +++ b/core/migrations/v20180912_250006_remove_null_users.php @@ -0,0 +1,20 @@ +executeQuery($sql); + + } + + public function down(){ + + return true; + } + +} diff --git a/core/migrations/v20181025_260001_dept_based_leave_periods.php b/core/migrations/v20181025_260001_dept_based_leave_periods.php new file mode 100644 index 00000000..1be873e8 --- /dev/null +++ b/core/migrations/v20181025_260001_dept_based_leave_periods.php @@ -0,0 +1,26 @@ +executeQuery($sql); + + $sql = <<<'SQL' +Alter table LeavePeriods ADD COLUMN `country` bigint(20) DEFAULT NULL; +SQL; + return $this->executeQuery($sql); + + } + + public function down(){ + + return true; + } + +} diff --git a/core/migrations/v20181106_260002_add_arabic_lang.php b/core/migrations/v20181106_260002_add_arabic_lang.php new file mode 100644 index 00000000..9eb0ca3e --- /dev/null +++ b/core/migrations/v20181106_260002_add_arabic_lang.php @@ -0,0 +1,19 @@ +executeQuery($sql); + } + + public function down(){ + + return true; + } + +} diff --git a/core/migrations/v20190125_260003_attendance_with_map.php b/core/migrations/v20190125_260003_attendance_with_map.php new file mode 100644 index 00000000..60e84545 --- /dev/null +++ b/core/migrations/v20190125_260003_attendance_with_map.php @@ -0,0 +1,40 @@ +executeQuery($sql); + + $sql = <<<'SQL' + Alter table Attendance add column `map_lng` DECIMAL(10, 8) NULL; +SQL; + $this->executeQuery($sql); + + $sql = <<<'SQL' + Alter table Attendance add column `map_snapshot` longtext default null; +SQL; + return $this->executeQuery($sql); + } + + public function down(){ + $sql = <<<'SQL' + Alter table Attendance drop column `map_lat`; +SQL; + $this->executeQuery($sql); + + $sql = <<<'SQL' + Alter table Attendance drop column `map_lng`; +SQL; + $this->executeQuery($sql); + + $sql = <<<'SQL' + Alter table Attendance drop column `map_snapshot`; +SQL; + return $this->executeQuery($sql); + } +} diff --git a/core/modulejslibs.inc.php b/core/modulejslibs.inc.php index 8601c4e3..f932cdaa 100644 --- a/core/modulejslibs.inc.php +++ b/core/modulejslibs.inc.php @@ -3,8 +3,8 @@ if(isset($additionalJs)) { foreach ($additionalJs as $js) { ?> - - \ No newline at end of file + diff --git a/core/modules.php b/core/modules.php index 6dbf1425..684ae757 100644 --- a/core/modules.php +++ b/core/modules.php @@ -126,6 +126,7 @@ foreach ($ams as $am) { $dbModule->label = $arr['label']; $dbModule->menu = $arr['menu']; $dbModule->icon = $arr['icon']; + $dbModule->mod_order = $arr['order']; $dbModule->Save(); } @@ -194,6 +195,7 @@ foreach ($ams as $am) { $arr['label'] = $meta->label; $arr['icon'] = $meta->icon; $arr['menu'] = $meta->menu; + $arr['order'] = $meta->order; $arr['status'] = 'Enabled'; $arr['user_levels'] = $meta->user_levels; $arr['user_roles'] = isset($meta->user_roles) ? $meta->user_roles : ""; @@ -212,6 +214,7 @@ foreach ($ams as $am) { $dbModule->label = $arr['label']; $dbModule->menu = $arr['menu']; $dbModule->icon = $arr['icon']; + $dbModule->mod_order = $arr['order']; $dbModule->Save(); } diff --git a/core/modules/attendance/index.php b/core/modules/attendance/index.php index b23f039f..4bc3aeb3 100644 --- a/core/modules/attendance/index.php +++ b/core/modules/attendance/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'attendance'; diff --git a/core/modules/dashboard/index.php b/core/modules/dashboard/index.php index ce4139f5..c2eacd87 100644 --- a/core/modules/dashboard/index.php +++ b/core/modules/dashboard/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'dashboard'; diff --git a/core/modules/dependents/index.php b/core/modules/dependents/index.php index e3bc16a4..2b917a4d 100644 --- a/core/modules/dependents/index.php +++ b/core/modules/dependents/index.php @@ -1,43 +1,26 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ - + $moduleName = 'emergency_contact'; define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
    - + - +
    - +
    @@ -60,4 +43,4 @@ modJsList['tabEmployeeDependent'].setShowEdit(false); var modJs = modJsList['tabEmployeeDependent']; - + diff --git a/core/modules/emergency_contact/index.php b/core/modules/emergency_contact/index.php index 8ab935e7..7bd500dd 100644 --- a/core/modules/emergency_contact/index.php +++ b/core/modules/emergency_contact/index.php @@ -1,24 +1,7 @@ -. - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'emergency_contact'; @@ -26,18 +9,18 @@ define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
    - + - +
    - +
    @@ -61,4 +44,4 @@ modJsList['tabEmergencyContact'].setShowEdit(false); var modJs = modJsList['tabEmergencyContact']; - + diff --git a/core/modules/employees/index.php b/core/modules/employees/index.php index 01b269e0..57f258b5 100644 --- a/core/modules/employees/index.php +++ b/core/modules/employees/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'employees'; @@ -28,19 +11,26 @@ include APP_BASE_PATH.'modulejslibs.inc.php'; $fieldNameMap = \Classes\BaseService::getInstance()->getFieldNameMappings("Employee"); $customFields = \Classes\BaseService::getInstance()->getCustomFields("Employee"); -if (\Classes\SettingsManager::getInstance()->getSetting("Api: REST Api Enabled") == "1") { - $user = \Classes\BaseService::getInstance()->getCurrentUser(); - if (empty($user)) { - return; - } - $dbUser = new \Users\Common\Model\User(); - $dbUser->Load("id = ?", array($user->id)); - $resp = \Classes\RestApiManager::getInstance()->getAccessTokenForUser($dbUser); - if ($resp->getStatus() != \Classes\IceResponse::SUCCESS) { - \Utils\LogManager::getInstance()->error( - "Error occurred while creating REST Api access token for ".$user->username - ); - } +$restApiBase = ''; +$user = \Classes\BaseService::getInstance()->getCurrentUser(); +if (empty($user)) { + return; +} +$dbUser = new \Users\Common\Model\User(); +$dbUser->Load("id = ?", array($user->id)); +$resp = \Classes\RestApiManager::getInstance()->getAccessTokenForUser($dbUser); +if ($resp->getStatus() != \Classes\IceResponse::SUCCESS) { + \Utils\LogManager::getInstance()->error( + "Error occurred while creating REST Api access token for ".$user->username + ); +} + +if (defined('SYM_CLIENT')) { + $restApiBase = WEB_APP_BASE_URL.'/api/'.SYM_CLIENT.'/'; +} else if (defined('REST_API_BASE')){ + $restApiBase = REST_API_BASE; +} else { + $restApiBase = CLIENT_BASE_PATH.'api/'; } ?> @@ -93,11 +83,17 @@ path.link {

    Api Access Token

    -
    +
    getData()?>
    -
    -
    +
    +
    +

    Mobile Authentication Code

    +
    + +
    +
    +
    @@ -110,6 +106,9 @@ modJsList['tabEmployee'].setCustomFields(); modJsList['tabCompanyGraph'] = new CompanyGraphAdapter('CompanyStructure'); modJsList['tabApiAccess'] = new ApiAccessAdapter('ApiAccess'); +modJsList['tabApiAccess'].setApiUrl(''); +modJsList['tabApiAccess'].setToken('getData()?>'); + var modJs = modJsList['tabEmployee']; diff --git a/core/modules/loans/index.php b/core/modules/loans/index.php index 95fbe846..82147c22 100644 --- a/core/modules/loans/index.php +++ b/core/modules/loans/index.php @@ -1,43 +1,26 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ - + $moduleName = 'loans'; define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
    - + - +
    - +
    @@ -55,4 +38,4 @@ modJsList['tabEmployeeCompanyLoan'].setShowEdit(true); var modJs = modJsList['tabEmployeeCompanyLoan']; - + diff --git a/core/modules/meta.json b/core/modules/meta.json index b74e130c..e5e4fb40 100644 --- a/core/modules/meta.json +++ b/core/modules/meta.json @@ -6,6 +6,7 @@ "Documents":"fa-files-o", "Company":"fa-building", "Training":"fa-briefcase", +"Performance":"fa-crosshairs", "Travel Management":"fa-plane", "Finance":"fa-money", "User Reports":"fa-file-text" diff --git a/core/modules/overtime/index.php b/core/modules/overtime/index.php index 3c4a32cb..00ef4b78 100644 --- a/core/modules/overtime/index.php +++ b/core/modules/overtime/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'overtime'; @@ -33,7 +16,6 @@ $appModName = $moduleMainName.'Approval'; define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; $additionalJs = array(); -$additionalJs[] = BASE_URL.'admin/overtime/lib.js?v='.$jsVersion; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
    @@ -75,7 +57,7 @@ include APP_BASE_PATH.'modulejslibs.inc.php'; var modJsList = new Array(); modJsList['tab'] = new Adapter('',''); - + modJsList['tab'] = new ApproverAdapter('', ''); modJsList['tab'].setShowAddNew(false); @@ -91,4 +73,4 @@ include APP_BASE_PATH.'modulejslibs.inc.php'; var modJs = modJsList['tab']; - + diff --git a/core/modules/projects/index.php b/core/modules/projects/index.php index 34c7cdb7..cd9f502b 100644 --- a/core/modules/projects/index.php +++ b/core/modules/projects/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'projects'; @@ -26,18 +9,18 @@ define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
    - + - +
    - +
    @@ -61,4 +44,4 @@ modJsList['tabEmployeeProject'].setShowEdit(false); var modJs = modJsList['tabEmployeeProject']; - + diff --git a/core/modules/qualifications/index.php b/core/modules/qualifications/index.php index 1c8735c6..37d993cb 100644 --- a/core/modules/qualifications/index.php +++ b/core/modules/qualifications/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'qualifications'; diff --git a/core/modules/reports/index.php b/core/modules/reports/index.php index a7cff766..6e695ed5 100644 --- a/core/modules/reports/index.php +++ b/core/modules/reports/index.php @@ -4,7 +4,6 @@ $moduleName = 'Reports'; define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; $additionalJs = array(); -$additionalJs[] = BASE_URL.'admin/reports/lib.js?v='.$jsVersion; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
    diff --git a/core/modules/salary/index.php b/core/modules/salary/index.php index 82b88b63..26591181 100644 --- a/core/modules/salary/index.php +++ b/core/modules/salary/index.php @@ -1,43 +1,26 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ - + $moduleName = 'salary'; define('MODULE_PATH',dirname(__FILE__)); include APP_BASE_PATH.'header.php'; include APP_BASE_PATH.'modulejslibs.inc.php'; ?>
    - + - +
    - +
    @@ -61,4 +44,4 @@ modJsList['tabEmployeeSalary'].setShowEdit(false); var modJs = modJsList['tabEmployeeSalary']; - + diff --git a/core/modules/staffdirectory/customTemplates/element.html b/core/modules/staffdirectory/customTemplates/element.html new file mode 100644 index 00000000..97ace73e --- /dev/null +++ b/core/modules/staffdirectory/customTemplates/element.html @@ -0,0 +1,21 @@ +
    + +
    +
    +
    + User Avatar +
    + +

    #_first_name_# #_last_name_#

    +
    #_job_title_#
    +
    + +
    + +
    \ No newline at end of file diff --git a/core/modules/staffdirectory/index.php b/core/modules/staffdirectory/index.php new file mode 100644 index 00000000..c02cedad --- /dev/null +++ b/core/modules/staffdirectory/index.php @@ -0,0 +1,61 @@ +
    + + + +
    +
    +
    + + +
    +
    + +
    + +
    +
    +
    + +
    + + diff --git a/core/modules/staffdirectory/meta.json b/core/modules/staffdirectory/meta.json new file mode 100644 index 00000000..2d6cd397 --- /dev/null +++ b/core/modules/staffdirectory/meta.json @@ -0,0 +1,14 @@ +{ + "label":"Staff Directory", + "menu":"Company", + "order":"1", + "icon":"fa-user", + "user_levels":["Admin","Manager","Employee"], + + "permissions": + { + + }, + "model_namespace": "\\StaffDirectory\\Common\\Model", + "manager": "\\StaffDirectory\\User\\Api\\StaffDirectoryModulesManager" +} diff --git a/core/modules/time_sheets/index.php b/core/modules/time_sheets/index.php index a79d4519..053e1151 100644 --- a/core/modules/time_sheets/index.php +++ b/core/modules/time_sheets/index.php @@ -1,24 +1,7 @@ . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ $moduleName = 'employee_TimeSheet'; @@ -79,7 +62,7 @@ $startEndTimeNeeded = \Classes\SettingsManager::getInstance()->getSetting( -
    + ', - "validation":"none", - "sort-function":function (a,b){ - var t1 = Date.parse(a.date).getTime(); - var t2 = Date.parse(b.date).getTime(); - - return (t1'; - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - -EmployeeAdapter.method('getHelpLink', function () { - return 'https://thilinah.gitbooks.io/icehrm-guide/content/employee-information-setup.html'; -}); - -EmployeeAdapter.method('saveSuccessItemCallback', function(data) { - this.lastSavedEmployee = data; - if(this.currentId == null){ - $('#createUserModel').modal('show'); - } - -}); - -EmployeeAdapter.method('closeCreateUser', function() { - $('#createUserModel').modal('hide'); -}); - -EmployeeAdapter.method('createUser', function() { - var data = {}; - data['employee'] = this.lastSavedEmployee.id; - data['user_level'] = "Employee"; - data['email'] = this.lastSavedEmployee.work_email; - data['username'] = this.lastSavedEmployee.work_email.split("@")[0]; - var url = this.getCustomUrl('?g=admin&n=users&m=admin_Admin&action=new&object='+Base64.encodeURI(JSON.stringify(data))); - top.location.href = url; -}); - -EmployeeAdapter.method('deleteEmployee', function(id) { - - if (confirm('Are you sure you want to archive this employee? Data for this employee will be saved to an archive table. But you will not be able to covert the archived employee data into a normal employee.')) { - //Archive - } else { - return; - } - - var params = {}; - params['id'] = id; - var reqJson = JSON.stringify(params); - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'deleteEmployeeSuccessCallback'; - callBackData['callBackFail'] = 'deleteEmployeeFailCallback'; - - this.customAction('deleteEmployee','admin=employees',reqJson,callBackData); -}); - - -EmployeeAdapter.method('deleteEmployeeSuccessCallback', function(callBackData) { - this.showMessage("Delete Success","Employee deleted. You can find archived information for this employee in Archived Employees tab"); - this.get([]); -}); - - -EmployeeAdapter.method('deleteEmployeeFailCallback', function(callBackData) { - this.showMessage("Error occurred while deleting Employee", callBackData); -}); - - -EmployeeAdapter.method('terminateEmployee', function(id) { - - if (confirm('Are you sure you want to terminate this employee contract? You will still be able to access all details of this employee.')) { - //Terminate - } else { - return; - } - - var params = {}; - params['id'] = id; - var reqJson = JSON.stringify(params); - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'terminateEmployeeSuccessCallback'; - callBackData['callBackFail'] = 'terminateEmployeeFailCallback'; - - this.customAction('terminateEmployee','admin=employees',reqJson,callBackData); -}); - - -EmployeeAdapter.method('terminateEmployeeSuccessCallback', function(callBackData) { - this.showMessage("Success","Employee contract terminated. You can find terminated employee information under Terminated Employees menu."); - this.get([]); -}); - - -EmployeeAdapter.method('terminateEmployeeFailCallback', function(callBackData) { - this.showMessage("Error occured while terminating Employee", callBackData); -}); - - -EmployeeAdapter.method('activateEmployee', function(id) { - - if (confirm('Are you sure you want to re-activate this employee contract?')) { - //Terminate - } else { - return; - } - - var params = {}; - params['id'] = id; - var reqJson = JSON.stringify(params); - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'activateEmployeeSuccessCallback'; - callBackData['callBackFail'] = 'activateEmployeeFailCallback'; - - this.customAction('activateEmployee','admin=employees',reqJson,callBackData); -}); - - -EmployeeAdapter.method('activateEmployeeSuccessCallback', function(callBackData) { - this.showMessage("Success","Employee contract re-activated."); - this.get([]); -}); - - -EmployeeAdapter.method('activateEmployeeFailCallback', function(callBackData) { - this.showMessage("Error occured while activating Employee", callBackData); -}); - - -EmployeeAdapter.method('view', function(id) { - - var that = this; - this.currentId = id; - var sourceMappingJson = JSON.stringify(this.getSourceMapping()); - var object = {"id":id, "map":sourceMappingJson}; - var reqJson = JSON.stringify(object); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'renderEmployee'; - callBackData['callBackFail'] = 'viewFailCallBack'; - - this.customAction('get','modules=employees',reqJson,callBackData); -}); - - -EmployeeAdapter.method('viewFailCallBack', function(callBackData) { - this.showMessage("Error","Error Occured while retriving candidate"); -}); - -EmployeeAdapter.method('renderEmployee', function(data) { - var title; - var fields = this.getFormFields(); - var currentEmpId = data[1]; - var currentId = data[1]; - var userEmpId = data[2]; - data = data[0]; - this.currentEmployee = data; - var html = this.getCustomTemplate('myDetails.html'); - - - for(var i=0;i 0) { - - - var ct = '
    '; - var customFieldHtml; - for (index in data.customFields) { - - if(!data.customFields[index][1]){ - data.customFields[index][1] = this.gt('Other Details'); - } - - sectionId = data.customFields[index][1].toLocaleLowerCase(); - sectionId = sectionId.replace(' ','_'); - - if($("#cont_"+sectionId).length <= 0){ - //Add section - sectionHtml = sectionTemplate; - sectionHtml = sectionHtml.replace('#_section_#', sectionId); - sectionHtml = sectionHtml.replace('#_section.name_#', data.customFields[index][1]); - $("#customFieldsCont").append($(sectionHtml)); - } - - customFieldHtml = ct; - customFieldHtml = customFieldHtml.replace('#_label_#', ''); - if (data.customFields[index][2] === 'fileupload') { - customFieldHtml = customFieldHtml.replace( - '#_value_#', - '' - ); - } else { - customFieldHtml = customFieldHtml.replace('#_value_#', data.customFields[index][0]); - } - $("#cont_"+sectionId).append($(customFieldHtml)); - } - }else{ - $("#customFieldsCont").remove(); - } - - - this.cancel(); - - if(!this.isModuleInstalled("admin","documents")) { - $('#tabDocuments').remove(); - } - - - modJs = this; - modJs.subModJsList = new Array(); - - modJs.subModJsList['tabEmployeeSkillSubTab'] = new EmployeeSubSkillsAdapter('EmployeeSkill','EmployeeSkillSubTab',{"employee":data.id}); - modJs.subModJsList['tabEmployeeSkillSubTab'].parent = this; - - modJs.subModJsList['tabEmployeeEducationSubTab'] = new EmployeeSubEducationAdapter('EmployeeEducation','EmployeeEducationSubTab',{"employee":data.id}); - modJs.subModJsList['tabEmployeeEducationSubTab'].parent = this; - - modJs.subModJsList['tabEmployeeCertificationSubTab'] = new EmployeeSubCertificationAdapter('EmployeeCertification','EmployeeCertificationSubTab',{"employee":data.id}); - modJs.subModJsList['tabEmployeeCertificationSubTab'].parent = this; - - modJs.subModJsList['tabEmployeeLanguageSubTab'] = new EmployeeSubLanguageAdapter('EmployeeLanguage','EmployeeLanguageSubTab',{"employee":data.id}); - modJs.subModJsList['tabEmployeeLanguageSubTab'].parent = this; - - modJs.subModJsList['tabEmployeeDependentSubTab'] = new EmployeeSubDependentAdapter('EmployeeDependent','EmployeeDependentSubTab',{"employee":data.id}); - modJs.subModJsList['tabEmployeeDependentSubTab'].parent = this; - - modJs.subModJsList['tabEmployeeEmergencyContactSubTab'] = new EmployeeSubEmergencyContactAdapter('EmergencyContact','EmployeeEmergencyContactSubTab',{"employee":data.id}); - modJs.subModJsList['tabEmployeeEmergencyContactSubTab'].parent = this; - - if(this.isModuleInstalled("admin","documents")) { - modJs.subModJsList['tabEmployeeDocumentSubTab'] = new EmployeeSubDocumentAdapter('EmployeeDocument', 'EmployeeDocumentSubTab', {"employee": data.id}); - modJs.subModJsList['tabEmployeeDocumentSubTab'].parent = this; - } - for (var prop in modJs.subModJsList) { - if(modJs.subModJsList.hasOwnProperty(prop)){ - modJs.subModJsList[prop].setTranslationsSubModules(this.translations); - modJs.subModJsList[prop].setPermissions(this.permissions); - modJs.subModJsList[prop].setFieldTemplates(this.fieldTemplates); - modJs.subModJsList[prop].setTemplates(this.templates); - modJs.subModJsList[prop].setCustomTemplates(this.customTemplates); - modJs.subModJsList[prop].setEmailTemplates(this.emailTemplates); - modJs.subModJsList[prop].setUser(this.user); - modJs.subModJsList[prop].initFieldMasterData(); - modJs.subModJsList[prop].setBaseUrl(this.baseUrl); - modJs.subModJsList[prop].setCurrentProfile(this.currentProfile); - modJs.subModJsList[prop].setInstanceId(this.instanceId); - modJs.subModJsList[prop].setGoogleAnalytics(ga); - modJs.subModJsList[prop].setNoJSONRequests(this.noJSONRequests); - } - } - - modJs.subModJsList['tabEmployeeSkillSubTab'].setShowFormOnPopup(true); - modJs.subModJsList['tabEmployeeSkillSubTab'].setShowAddNew(false); - modJs.subModJsList['tabEmployeeSkillSubTab'].setShowCancel(false); - modJs.subModJsList['tabEmployeeSkillSubTab'].get([]); - - modJs.subModJsList['tabEmployeeEducationSubTab'].setShowFormOnPopup(true); - modJs.subModJsList['tabEmployeeEducationSubTab'].setShowAddNew(false); - modJs.subModJsList['tabEmployeeEducationSubTab'].setShowCancel(false); - modJs.subModJsList['tabEmployeeEducationSubTab'].get([]); - - modJs.subModJsList['tabEmployeeCertificationSubTab'].setShowFormOnPopup(true); - modJs.subModJsList['tabEmployeeCertificationSubTab'].setShowAddNew(false); - modJs.subModJsList['tabEmployeeCertificationSubTab'].setShowCancel(false); - modJs.subModJsList['tabEmployeeCertificationSubTab'].get([]); - - modJs.subModJsList['tabEmployeeLanguageSubTab'].setShowFormOnPopup(true); - modJs.subModJsList['tabEmployeeLanguageSubTab'].setShowAddNew(false); - modJs.subModJsList['tabEmployeeLanguageSubTab'].setShowCancel(false); - modJs.subModJsList['tabEmployeeLanguageSubTab'].get([]); - - modJs.subModJsList['tabEmployeeDependentSubTab'].setShowFormOnPopup(true); - modJs.subModJsList['tabEmployeeDependentSubTab'].setShowAddNew(false); - modJs.subModJsList['tabEmployeeDependentSubTab'].setShowCancel(false); - modJs.subModJsList['tabEmployeeDependentSubTab'].get([]); - - modJs.subModJsList['tabEmployeeEmergencyContactSubTab'].setShowFormOnPopup(true); - modJs.subModJsList['tabEmployeeEmergencyContactSubTab'].setShowAddNew(false); - modJs.subModJsList['tabEmployeeEmergencyContactSubTab'].setShowCancel(false); - modJs.subModJsList['tabEmployeeEmergencyContactSubTab'].get([]); - - if(this.isModuleInstalled("admin","documents")) { - modJs.subModJsList['tabEmployeeDocumentSubTab'].setShowFormOnPopup(true); - modJs.subModJsList['tabEmployeeDocumentSubTab'].setShowAddNew(false); - modJs.subModJsList['tabEmployeeDocumentSubTab'].setShowCancel(false); - modJs.subModJsList['tabEmployeeDocumentSubTab'].get([]); - } - - $('#subModTab a').off().on('click',function (e) { - e.preventDefault(); - $(this).tab('show'); - }); -}); - - -EmployeeAdapter.method('deleteProfileImage', function(empId) { - var that = this; - - var req = {"id":empId}; - var reqJson = JSON.stringify(req); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'modEmployeeDeleteProfileImageCallBack'; - callBackData['callBackFail'] = 'modEmployeeDeleteProfileImageCallBack'; - - this.customAction('deleteProfileImage','modules=employees',reqJson,callBackData); -}); - -EmployeeAdapter.method('modEmployeeDeleteProfileImageCallBack', function(data) { - //top.location.href = top.location.href; -}); - - -/* - * Terminated Employee - */ - -function TerminatedEmployeeAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -TerminatedEmployeeAdapter.inherits(EmployeeAdapter); - - - -TerminatedEmployeeAdapter.method('getDataMapping', function() { - return [ - "id", - "image", - "employee_id", - "first_name", - "last_name", - "mobile_phone", - "department", - "gender", - "supervisor" - ]; -}); - -TerminatedEmployeeAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" }, - { "sTitle": "","bSortable":false }, - { "sTitle": "Employee Number" }, - { "sTitle": "First Name" }, - { "sTitle": "Last Name"}, - { "sTitle": "Mobile"}, - { "sTitle": "Department"}, - { "sTitle": "Gender"}, - { "sTitle": "Supervisor"} - ]; -}); - -TerminatedEmployeeAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden","validation":""}], - [ "employee_id", {"label":"Employee Number","type":"text","validation":""}], - [ "first_name", {"label":"First Name","type":"text","validation":""}], - [ "middle_name", {"label":"Middle Name","type":"text","validation":"none"}], - [ "last_name", {"label":"Last Name","type":"text","validation":""}], - [ "nationality", {"label":"Nationality","type":"select2","remote-source":["Nationality","id","name"]}], - [ "birthday", {"label":"Date of Birth","type":"date","validation":""}], - [ "gender", {"label":"Gender","type":"select","source":[["Male","Male"],["Female","Female"]]}], - [ "marital_status", {"label":"Marital Status","type":"select","source":[["Married","Married"],["Single","Single"],["Divorced","Divorced"],["Widowed","Widowed"],["Other","Other"]]}], - [ "ssn_num", {"label":"SSN/NRIC","type":"text","validation":"none"}], - [ "nic_num", {"label":"NIC","type":"text","validation":"none"}], - [ "other_id", {"label":"Other ID","type":"text","validation":"none"}], - [ "driving_license", {"label":"Driving License No","type":"text","validation":"none"}], - /*[ "driving_license_exp_date", {"label":"License Exp Date","type":"date","validation":"none"}],*/ - [ "employment_status", {"label":"Employment Status","type":"select2","remote-source":["EmploymentStatus","id","name"]}], - [ "job_title", {"label":"Job Title","type":"select2","remote-source":["JobTitle","id","name"]}], - [ "pay_grade", {"label":"Pay Grade","type":"select2","allow-null":true,"remote-source":["PayGrade","id","name"]}], - [ "work_station_id", {"label":"Work Station Id","type":"text","validation":"none"}], - [ "address1", {"label":"Address Line 1","type":"text","validation":"none"}], - [ "address2", {"label":"Address Line 2","type":"text","validation":"none"}], - [ "city", {"label":"City","type":"text","validation":"none"}], - [ "country", {"label":"Country","type":"select2","remote-source":["Country","code","name"]}], - [ "province", {"label":"Province","type":"select2","allow-null":true,"remote-source":["Province","id","name"]}], - [ "postal_code", {"label":"Postal/Zip Code","type":"text","validation":"none"}], - [ "home_phone", {"label":"Home Phone","type":"text","validation":"none"}], - [ "mobile_phone", {"label":"Mobile Phone","type":"text","validation":"none"}], - [ "work_phone", {"label":"Work Phone","type":"text","validation":"none"}], - [ "work_email", {"label":"Work Email","type":"text","validation":"emailOrEmpty"}], - [ "private_email", {"label":"Private Email","type":"text","validation":"emailOrEmpty"}], - [ "joined_date", {"label":"Joined Date","type":"date","validation":""}], - [ "confirmation_date", {"label":"Confirmation Date","type":"date","validation":"none"}], - [ "termination_date", {"label":"Termination Date","type":"date","validation":"none"}], - [ "department", {"label":"Department","type":"select2","remote-source":["CompanyStructure","id","title"]}], - [ "supervisor", {"label":"Supervisor","type":"select2","allow-null":true,"remote-source":["Employee","id","first_name+last_name"]}], - [ "notes", {"label":"Notes","type":"datagroup", - "form":[ - [ "note", {"label":"Note","type":"textarea","validation":""}] - ], - "html":'
    #_delete_##_edit_#Date: #_date_#
    #_note_#
    ', - "validation":"none", - "sort-function":function (a,b){ - var t1 = Date.parse(a.date).getTime(); - var t2 = Date.parse(b.date).getTime(); - - return (t1'; - return addBtn + this.gt("Skills"); -}); - -EmployeeSubSkillsAdapter.method('getSubItemHtml', function(item, itemDelete, itemEdit) { - var itemHtml = $('
    '+item[2]+itemDelete+itemEdit+'

    '+nl2br(item[3])+'

    '); - return itemHtml; -}); - - - - -/** - * @class EmployeeSubEducationAdapter - * @param endPoint - * @param tab - * @param filter - * @param orderBy - * @returns - */ - - -function EmployeeSubEducationAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeSubEducationAdapter.inherits(SubAdapterBase); - - - -EmployeeSubEducationAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "education_id", - "institute", - "date_start", - "date_end" - ]; -}); - -EmployeeSubEducationAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID", "bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Qualification" }, - { "sTitle": "Institute"}, - { "sTitle": "Start Date"}, - { "sTitle": "Completed On"}, - ]; -}); - -EmployeeSubEducationAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"hidden"}], - [ "education_id", {"label":"Qualification","type":"select2","allow-null":false,"remote-source":["Education","id","name"]}], - [ "institute", {"label":"Institute","type":"text","validation":""}], - [ "date_start", {"label":"Start Date","type":"date","validation":"none"}], - [ "date_end", {"label":"Completed On","type":"date","validation":"none"}] - ]; -}); - - -EmployeeSubEducationAdapter.method('forceInjectValuesBeforeSave', function(params) { - params['employee'] = this.parent.currentId; - return params; -}); - -EmployeeSubEducationAdapter.method('getSubHeaderTitle', function() { - var addBtn = ''; - return addBtn + this.gt("Education"); -}); - -EmployeeSubEducationAdapter.method('getSubItemHtml', function(item, itemDelete, itemEdit) { - var start = ""; - try{ - stat = Date.parse(item[4]).toString('MMM d, yyyy'); - }catch(e){} - - var end = ""; - try{ - end = Date.parse(item[5]).toString('MMM d, yyyy'); - }catch(e){} - //var itemHtml = $('
    '+item[2]+itemDelete+itemEdit+'

    '+nl2br(item[3])+'

    '); - var itemHtml = $('
    '+item[2]+itemDelete+itemEdit+'

    Start: '+start+'

    '+' Completed: '+end+'

    '+' Institute: '+item[3]+'

    '); - return itemHtml; -}); - - -/** - * @class EmployeeSubCertificationAdapter - * @param endPoint - * @param tab - * @param filter - * @param orderBy - * @returns - */ - -function EmployeeSubCertificationAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeSubCertificationAdapter.inherits(SubAdapterBase); - - - -EmployeeSubCertificationAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "certification_id", - "institute", - "date_start", - "date_end" - ]; -}); - - -EmployeeSubCertificationAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID","bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Certification" }, - { "sTitle": "Institute"}, - { "sTitle": "Granted On"}, - { "sTitle": "Valid Thru"} - ]; -}); - -EmployeeSubCertificationAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"hidden"}], - [ "certification_id", {"label":"Certification","type":"select2","allow-null":false,"remote-source":["Certification","id","name"]}], - [ "institute", {"label":"Institute","type":"text","validation":""}], - [ "date_start", {"label":"Granted On","type":"date","validation":"none"}], - [ "date_end", {"label":"Valid Thru","type":"date","validation":"none"}] - ]; -}); - - -EmployeeSubCertificationAdapter.method('forceInjectValuesBeforeSave', function(params) { - params['employee'] = this.parent.currentId; - return params; -}); - -EmployeeSubCertificationAdapter.method('getSubHeaderTitle', function() { - var addBtn = ''; - return addBtn + this.gt("Certifications"); -}); - -EmployeeSubCertificationAdapter.method('getSubItemHtml', function(item, itemDelete, itemEdit) { - var start = ""; - try{ - start = Date.parse(item[4]).toString('MMM d, yyyy'); - }catch(e){} - - var end = ""; - try{ - end = Date.parse(item[5]).toString('MMM d, yyyy'); - }catch(e){} - var itemHtml = $('
    '+item[2]+itemDelete+itemEdit+'

    Granted On: '+start+'

    '+' Valid Thru: '+end+'

    '+' Institute: '+item[3]+'

    '); - return itemHtml; -}); - - - - -/** - * @class EmployeeSubLanguageAdapter - * @param endPoint - * @param tab - * @param filter - * @param orderBy - * @returns - */ - -function EmployeeSubLanguageAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeSubLanguageAdapter.inherits(SubAdapterBase); - - - -EmployeeSubLanguageAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "language_id", - "reading", - "speaking", - "writing", - "understanding" - ]; -}); - -EmployeeSubLanguageAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID", "bVisible":false }, - { "sTitle": "Employee" }, - { "sTitle": "Language" }, - { "sTitle": "Reading"}, - { "sTitle": "Speaking"}, - { "sTitle": "Writing"}, - { "sTitle": "Understanding"} - ]; -}); - -EmployeeSubLanguageAdapter.method('getFormFields', function() { - var compArray = [["Elementary Proficiency","Elementary Proficiency"], - ["Limited Working Proficiency","Limited Working Proficiency"], - ["Professional Working Proficiency","Professional Working Proficiency"], - ["Full Professional Proficiency","Full Professional Proficiency"], - ["Native or Bilingual Proficiency","Native or Bilingual Proficiency"]]; - - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"hidden"}], - [ "language_id", {"label":"Language","type":"select2","allow-null":false,"remote-source":["Language","id","name"]}], - [ "reading", {"label":"Reading","type":"select","source":compArray}], - [ "speaking", {"label":"Speaking","type":"select","source":compArray}], - [ "writing", {"label":"Writing","type":"select","source":compArray}], - [ "understanding", {"label":"Understanding","type":"select","source":compArray}] - ]; -}); - - -EmployeeSubLanguageAdapter.method('forceInjectValuesBeforeSave', function(params) { - params['employee'] = this.parent.currentId; - return params; -}); - -EmployeeSubLanguageAdapter.method('getSubHeaderTitle', function() { - var addBtn = ''; - return addBtn + this.gt("Languages"); -}); - -EmployeeSubLanguageAdapter.method('getSubItemHtml', function(item, itemDelete, itemEdit) { - var itemHtml = $('
    '+item[2]+itemDelete+itemEdit+'

    Reading: '+item[3]+'

    '+' Speaking: '+ item[4] +'

    '+' Writing: '+item[5]+'

    '+' Understanding: '+item[6]+'

    '); - return itemHtml; -}); - -EmployeeSubLanguageAdapter.method('isSubProfileTable', function() { - if(this.user.user_level == "Admin"){ - return false; - }else{ - return true; - } -}); - -/** - * @class EmployeeSubDependentAdapter - * @param endPoint - * @param tab - * @param filter - * @param orderBy - * @returns - */ - -function EmployeeSubDependentAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeSubDependentAdapter.inherits(SubAdapterBase); - - - -EmployeeSubDependentAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "name", - "relationship", - "dob", - "id_number" - ]; -}); - - -EmployeeSubDependentAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Name" }, - { "sTitle": "Relationship"}, - { "sTitle": "Date of Birth"}, - { "sTitle": "Id Number"} - ]; -}); - -EmployeeSubDependentAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "relationship", {"label":"Relationship","type":"select","source":[["Child","Child"],["Spouse","Spouse"],["Parent","Parent"],["Other","Other"]]}], - [ "dob", {"label":"Date of Birth","type":"date","validation":""}], - [ "id_number", {"label":"Id Number","type":"text","validation":"none"}] - ]; -}); - - -EmployeeSubDependentAdapter.method('forceInjectValuesBeforeSave', function(params) { - params['employee'] = this.parent.currentId; - return params; -}); - -EmployeeSubDependentAdapter.method('getSubHeaderTitle', function() { - var addBtn = ''; - return addBtn + this.gt("Dependents"); -}); - -EmployeeSubDependentAdapter.method('getSubItemHtml', function(item, itemDelete, itemEdit) { - - - var itemHtml = $('
    '+item[2]+itemDelete+itemEdit+'

    Relationship: '+item[3]+'

    '+' Name: '+item[2]+'

    '); - return itemHtml; -}); - - - -/** - * @class EmployeeSubEmergencyContactAdapter - * @param endPoint - * @param tab - * @param filter - * @param orderBy - * @returns - */ - -function EmployeeSubEmergencyContactAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeSubEmergencyContactAdapter.inherits(SubAdapterBase); - - - -EmployeeSubEmergencyContactAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "name", - "relationship", - "home_phone", - "work_phone", - "mobile_phone" - ]; -}); - - -EmployeeSubEmergencyContactAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Name" }, - { "sTitle": "Relationship"}, - { "sTitle": "Home Phone"}, - { "sTitle": "Work Phone"}, - { "sTitle": "Mobile Phone"} - ]; -}); - -EmployeeSubEmergencyContactAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "relationship", {"label":"Relationship","type":"text","validation":"none"}], - [ "home_phone", {"label":"Home Phone","type":"text","validation":"none"}], - [ "work_phone", {"label":"Work Phone","type":"text","validation":"none"}], - [ "mobile_phone", {"label":"Mobile Phone","type":"text","validation":"none"}] - ]; -}); - - -EmployeeSubEmergencyContactAdapter.method('forceInjectValuesBeforeSave', function(params) { - params['employee'] = this.parent.currentId; - return params; -}); - -EmployeeSubEmergencyContactAdapter.method('getSubHeaderTitle', function() { - var addBtn = ''; - return addBtn + this.gt("Emergency Contacts"); -}); - -EmployeeSubEmergencyContactAdapter.method('getSubItemHtml', function(item, itemDelete, itemEdit) { - - - var itemHtml = $('
    '+item[2]+itemDelete+itemEdit+'

    Relationship: '+item[3]+'

    '+' Name: '+item[2]+'

    Home Phone: '+item[4]+'

    Mobile Phone: '+item[6]+'

    '); - return itemHtml; -}); - - - - - - - -/** - * @class EmployeeSubDocumentAdapter - * @param endPoint - * @param tab - * @param filter - * @param orderBy - * @returns - */ - -function EmployeeSubDocumentAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeSubDocumentAdapter.inherits(SubAdapterBase); - - - -EmployeeSubDocumentAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "document", - "details", - "date_added", - "valid_until", - "status", - "attachment" - ]; -}); - -EmployeeSubDocumentAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Document" }, - { "sTitle": "Details" }, - { "sTitle": "Date Added"}, - { "sTitle": "Status"}, - { "sTitle": "Attachment","bVisible":false} - ]; -}); - -EmployeeSubDocumentAdapter.method('getFormFields', function() { - - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"hidden"}], - [ "document", {"label":"Document","type":"select2","remote-source":["Document","id","name"]}], - [ "date_added", {"label":"Date Added","type":"date","validation":""}], - [ "valid_until", {"label":"Valid Until","type":"date","validation":"none"}], - [ "status", {"label":"Status","type":"select","source":[["Active","Active"],["Inactive","Inactive"],["Draft","Draft"]]}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}], - [ "attachment", {"label":"Attachment","type":"fileupload","validation":"none"}] - ]; -}); - - -EmployeeSubDocumentAdapter.method('forceInjectValuesBeforeSave', function(params) { - params['employee'] = this.parent.currentId; - return params; -}); - -EmployeeSubDocumentAdapter.method('getSubHeaderTitle', function() { - var addBtn = ''; - return addBtn + this.gt("Documents"); -}); - -EmployeeSubDocumentAdapter.method('getSubItemHtml', function(item, itemDelete, itemEdit) { - var expire = ""; - try{ - expire = Date.parse(item[5]).toString('MMM d, yyyy'); - }catch(e){} - - var downloadButton = ''; - - var itemHtml = $('
    '+item[2]+downloadButton+itemDelete+itemEdit+'

    '+nl2br(item[3])+'

    '+' Expire On: '+expire+'

    '); - return itemHtml; -}); - - - -EmployeeSubDocumentAdapter.method('isSubProfileTable', function() { - if(this.user.user_level == "Admin"){ - return false; - }else{ - return true; - } -}); - - - -/** - * EmployeeDocumentAdapter - */ - - - -function EmployeeDocumentAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeDocumentAdapter.inherits(AdapterBase); - - - -EmployeeDocumentAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "document", - "details", - "date_added", - "status", - "attachment" - ]; -}); - -EmployeeDocumentAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Document" }, - { "sTitle": "Details" }, - { "sTitle": "Date Added"}, - { "sTitle": "Status"}, - { "sTitle": "Attachment","bVisible":false} - ]; -}); - -EmployeeDocumentAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - ["employee", { - "label": "Employee", - "type": "select2", - "sort": "none", - "allow-null": false, - "remote-source": ["Employee", "id", "first_name+last_name", "getActiveSubordinateEmployees"] - }], - [ "document", {"label":"Document","type":"select2","remote-source":["Document","id","name"]}], - [ "date_added", {"label":"Date Added","type":"date","validation":""}], - [ "valid_until", {"label":"Valid Until","type":"date","validation":"none"}], - [ "status", {"label":"Status","type":"select","source":[["Active","Active"],["Inactive","Inactive"],["Draft","Draft"]]}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}], - [ "attachment", {"label":"Attachment","type":"fileupload","validation":"none"}] - ]; -}); - - -EmployeeDocumentAdapter.method('getFilters', function() { - return [ - [ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}] - - ]; -}); - - -EmployeeDocumentAdapter.method('getActionButtonsHtml', function(id,data) { - var html = '
    '; - html = html.replace(/_id_/g,id); - html = html.replace(/_attachment_/g,data[6]); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - -EmployeeDocumentAdapter.method('isSubProfileTable', function() { - if(this.user.user_level == "Admin"){ - return false; - }else{ - return true; - } -}); - diff --git a/web/admin/fieldnames/lib.js b/web/admin/fieldnames/lib.js deleted file mode 100644 index e3b0ce2b..00000000 --- a/web/admin/fieldnames/lib.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * FieldNameAdapter - */ - -function FieldNameAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -FieldNameAdapter.inherits(AdapterBase); - - - -FieldNameAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "textOrig", - "textMapped", - "display" - ]; -}); - -FieldNameAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Original Text"}, - { "sTitle": "Mapped Text"}, - { "sTitle": "Display Status"} - ]; -}); - -FieldNameAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "type", {"label":"Type","type":"placeholder","validation":""}], - [ "name", {"label":"Name","type":"placeholder","validation":""}], - [ "textOrig", {"label":"Original Text","type":"placeholder","validation":""}], - [ "textMapped", {"label":"Mapped Text","type":"text","validation":""}], - [ "display", {"label":"Display Status","type":"select","source":[["Form","Show"],["Hidden","Hidden"]]}] - ]; -}); - - diff --git a/web/admin/jobs/lib.js b/web/admin/jobs/lib.js deleted file mode 100644 index 016ad20e..00000000 --- a/web/admin/jobs/lib.js +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * JobTitleAdapter - */ - -function JobTitleAdapter(endPoint) { - this.initAdapter(endPoint); -} - -JobTitleAdapter.inherits(AdapterBase); - - - -JobTitleAdapter.method('getDataMapping', function() { - return [ - "id", - "code", - "name" - ]; -}); - -JobTitleAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Code" }, - { "sTitle": "Name" } - ]; -}); - -JobTitleAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "code", {"label":"Job Title Code","type":"text"}], - [ "name", {"label":"Job Title","type":"text"}], - [ "description", {"label":"Description","type":"textarea"}], - [ "specification", {"label":"Specification","type":"textarea"}] - ]; -}); - -JobTitleAdapter.method('getHelpLink', function () { - return 'http://blog.icehrm.com/docs/jobdetails/'; -}); - - -/** - * PayGradeAdapter - */ - -function PayGradeAdapter(endPoint) { - this.initAdapter(endPoint); -} - -PayGradeAdapter.inherits(AdapterBase); - - - -PayGradeAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "currency", - "min_salary", - "max_salary" - ]; -}); - -PayGradeAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Currency"}, - { "sTitle": "Min Salary" }, - { "sTitle": "Max Salary"} - ]; -}); - -PayGradeAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Pay Grade Name","type":"text"}], - [ "currency", {"label":"Currency","type":"select2","remote-source":["CurrencyType","code","name"]}], - [ "min_salary", {"label":"Min Salary","type":"text","validation":"float"}], - [ "max_salary", {"label":"Max Salary","type":"text","validation":"float"}] - ]; -}); - -PayGradeAdapter.method('doCustomValidation', function(params) { - try{ - if(parseFloat(params.min_salary)>parseFloat(params.max_salary)){ - return "Min Salary should be smaller than Max Salary"; - } - }catch(e){ - - } - return null; -}); - - - -/** - * EmploymentStatusAdapter - */ - -function EmploymentStatusAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmploymentStatusAdapter.inherits(AdapterBase); - - - -EmploymentStatusAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "description" - ]; -}); - -EmploymentStatusAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" }, - { "sTitle": "Name" }, - { "sTitle": "Description"} - ]; -}); - -EmploymentStatusAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Employment Status","type":"text"}], - [ "description", {"label":"Description","type":"textarea","validation":""}] - ]; -}); - diff --git a/web/admin/loans/lib.js b/web/admin/loans/lib.js deleted file mode 100644 index fcd72542..00000000 --- a/web/admin/loans/lib.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * CompanyLoanAdapter - */ - -function CompanyLoanAdapter(endPoint) { - this.initAdapter(endPoint); -} - -CompanyLoanAdapter.inherits(AdapterBase); - - - -CompanyLoanAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "details" - ]; -}); - -CompanyLoanAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Details"} - ]; -}); - -CompanyLoanAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}] - ]; -}); - -/* - * EmployeeCompanyLoanAdapter - */ - -function EmployeeCompanyLoanAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeCompanyLoanAdapter.inherits(AdapterBase); - - - -EmployeeCompanyLoanAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "loan", - "start_date", - "period_months", - "currency", - "amount", - "status" - ]; -}); - -EmployeeCompanyLoanAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Loan Type" }, - { "sTitle": "Loan Start Date"}, - { "sTitle": "Loan Period (Months)"}, - { "sTitle": "Currency"}, - { "sTitle": "Amount"}, - { "sTitle": "Status"} - ]; -}); - -EmployeeCompanyLoanAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}], - [ "loan", {"label":"Loan Type","type":"select","remote-source":["CompanyLoan","id","name"]}], - [ "start_date", {"label":"Loan Start Date","type":"date","validation":""}], - [ "last_installment_date", {"label":"Last Installment Date","type":"date","validation":"none"}], - [ "period_months", {"label":"Loan Period (Months)","type":"text","validation":"number"}], - [ "currency", {"label":"Currency","type":"select2","remote-source":["CurrencyType","id","name"]}], - [ "amount", {"label":"Loan Amount","type":"text","validation":"float"}], - [ "monthly_installment", {"label":"Monthly Installment","type":"text","validation":"float"}], - [ "status", {"label":"Status","type":"select","source":[["Approved","Approved"],["Paid","Paid"],["Suspended","Suspended"]]}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}] - ]; -}); - -EmployeeCompanyLoanAdapter.method('getFilters', function() { - return [ - [ "employee", {"label":"Employee","type":"select2","allow-null":true,"null-label":"All Employees","remote-source":["Employee","id","first_name+last_name"]}], - [ "loan", {"label":"Loan Type","type":"select","allow-null":true,"null-label":"All Loan Types","remote-source":["CompanyLoan","id","name"]}], - - ]; -}); diff --git a/web/admin/metadata/lib.js b/web/admin/metadata/lib.js deleted file mode 100644 index c7d66274..00000000 --- a/web/admin/metadata/lib.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * CountryAdapter - */ - -function CountryAdapter(endPoint) { - this.initAdapter(endPoint); -} - -CountryAdapter.inherits(AdapterBase); - - - -CountryAdapter.method('getDataMapping', function() { - return [ - "id", - "code", - "name" - ]; -}); - -CountryAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Code" }, - { "sTitle": "Name"} - ]; -}); - -CountryAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "code", {"label":"Code","type":"text","validation":""}], - [ "name", {"label":"Name","type":"text","validation":""}] - ]; -}); - - -/** - * ProvinceAdapter - */ - -function ProvinceAdapter(endPoint) { - this.initAdapter(endPoint); -} - -ProvinceAdapter.inherits(AdapterBase); - - - -ProvinceAdapter.method('getDataMapping', function() { - return [ - "id", - "code", - "name", - "country" - ]; -}); - -ProvinceAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Code" }, - { "sTitle": "Name"}, - { "sTitle": "Country"}, - ]; -}); - -ProvinceAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "code", {"label":"Code","type":"text","validation":""}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "country", {"label":"Country","type":"select2","remote-source":["Country","code","name"]}] - ]; -}); - -ProvinceAdapter.method('getFilters', function() { - return [ - [ "country", {"label":"Country","type":"select2","remote-source":["Country","code","name"]}] - - ]; -}); - - -/** - * CurrencyTypeAdapter - */ - -function CurrencyTypeAdapter(endPoint) { - this.initAdapter(endPoint); -} - -CurrencyTypeAdapter.inherits(AdapterBase); - - - -CurrencyTypeAdapter.method('getDataMapping', function() { - return [ - "id", - "code", - "name" - ]; -}); - -CurrencyTypeAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Code" }, - { "sTitle": "Name"} - ]; -}); - -CurrencyTypeAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "code", {"label":"Code","type":"text","validation":""}], - [ "name", {"label":"Name","type":"text","validation":""}] - ]; -}); - -/** - * NationalityAdapter - */ - -function NationalityAdapter(endPoint) { - this.initAdapter(endPoint); -} - -NationalityAdapter.inherits(IdNameAdapter); - -/** - * ImmigrationStatusAdapter - */ - -function ImmigrationStatusAdapter(endPoint) { - this.initAdapter(endPoint); -} - -ImmigrationStatusAdapter.inherits(IdNameAdapter); - - -/** - * EthnicityAdapter - */ - -function EthnicityAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EthnicityAdapter.inherits(IdNameAdapter); - - - diff --git a/web/admin/modules/lib.js b/web/admin/modules/lib.js deleted file mode 100644 index 4785e70b..00000000 --- a/web/admin/modules/lib.js +++ /dev/null @@ -1,164 +0,0 @@ -/* - This file is part of iCE Hrm. - - iCE Hrm is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - iCE Hrm is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with iCE Hrm. If not, see . - - ------------------------------------------------------------------ - - Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] - Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - - -/** - * ModuleAdapter - */ - -function ModuleAdapter(endPoint) { - this.initAdapter(endPoint); -} - -ModuleAdapter.inherits(AdapterBase); - - - -ModuleAdapter.method('getDataMapping', function() { - return [ - "id", - "label", - "menu", - "mod_group", - "mod_order", - "status", - "version", - "update_path" - ]; -}); - -ModuleAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Menu" ,"bVisible":false}, - { "sTitle": "Group"}, - { "sTitle": "Order"}, - { "sTitle": "Status"}, - { "sTitle": "Version","bVisible":false}, - { "sTitle": "Path" ,"bVisible":false} - ]; -}); - -ModuleAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "label", {"label":"Label","type":"text","validation":""}], - [ "status", {"label":"Status","type":"select","source":[["Enabled","Enabled"],["Disabled","Disabled"]]}], - [ "user_levels", {"label":"User Levels","type":"select2multi","source":[["Admin","Admin"],["Manager","Manager"],["Employee","Employee"],["Other","Other"]]}], - [ "user_roles", {"label":"User Roles","type":"select2multi","remote-source":["UserRole","id","name"]}] - ]; -}); - - -ModuleAdapter.method('getActionButtonsHtml', function(id,data) { - - - var nonEditableFields = {}; - nonEditableFields["admin_Company Structure"] = 1; - nonEditableFields["admin_Employees"] = 1; - nonEditableFields["admin_Job Details Setup"] = 1; - nonEditableFields["admin_Leaves"] = 1; - nonEditableFields["admin_Manage Modules"] = 1; - nonEditableFields["admin_Projects"] = 1; - nonEditableFields["admin_Qualifications"] = 1; - nonEditableFields["admin_Settings"] = 1; - nonEditableFields["admin_Users"] = 1; - nonEditableFields["admin_Upgrade"] = 1; - nonEditableFields["admin_Dashboard"] = 1; - - nonEditableFields["user_Basic Information"] = 1; - nonEditableFields["user_Dashboard"] = 1; - - if(nonEditableFields[data[3]+"_"+data[1]] == 1){ - return ""; - } - var html = '
    '; - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - - - -function UsageAdapter(endPoint) { - this.initAdapter(endPoint); -} - -UsageAdapter.inherits(AdapterBase); - - - -UsageAdapter.method('getDataMapping', function() { - return []; -}); - -UsageAdapter.method('getHeaders', function() { - return []; -}); - -UsageAdapter.method('getFormFields', function() { - return []; -}); - - -UsageAdapter.method('get', function(callBackData) { -}); - - -UsageAdapter.method('saveUsage', function() { - var that = this; - var object = {}; - var arr = []; - $('.module-check').each(function(){ - if($(this).is(":checked")) { - arr.push($(this).val()); - } - - }); - - if(arr.length == 0){ - alert("Please select one or more module groups"); - return; - } - - object['groups'] = arr.join(","); - - var reqJson = JSON.stringify(object); - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'getInitDataSuccessCallBack'; - callBackData['callBackFail'] = 'getInitDataFailCallBack'; - - this.customAction('saveUsage','admin=modules',reqJson,callBackData); -}); - - - -UsageAdapter.method('saveUsageSuccessCallBack', function(data) { - - -}); - -UsageAdapter.method('saveUsageFailCallBack', function(callBackData) { - -}); diff --git a/web/admin/overtime/lib.js b/web/admin/overtime/lib.js deleted file mode 100644 index 0ac41d45..00000000 --- a/web/admin/overtime/lib.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * OvertimeCategoryAdapter - */ - -function OvertimeCategoryAdapter(endPoint) { - this.initAdapter(endPoint); -} - -OvertimeCategoryAdapter.inherits(AdapterBase); - - - -OvertimeCategoryAdapter.method('getDataMapping', function() { - return [ - "id", - "name" - ]; -}); - -OvertimeCategoryAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" } - ]; -}); - -OvertimeCategoryAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}] - ]; -}); - - - - -/** - * EmployeeOvertimeAdminAdapter - */ - - -function EmployeeOvertimeAdminAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); - this.itemName = 'OvertimeRequest'; - this.itemNameLower = 'overtimerequest'; - this.modulePathName = 'overtime'; -} - -EmployeeOvertimeAdminAdapter.inherits(ApproveAdminAdapter); - - - -EmployeeOvertimeAdminAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "category", - "start_time", - "end_time", - "project", - "status" - ]; -}); - -EmployeeOvertimeAdminAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Category" }, - { "sTitle": "Start Time" }, - { "sTitle": "End Time"}, - { "sTitle": "Project"}, - { "sTitle": "Status"} - ]; -}); - -EmployeeOvertimeAdminAdapter.method('getFormFields', function() { - return [ - ["id", {"label": "ID", "type": "hidden"}], - ["employee", { - "label": "Employee", - "type": "select2", - "sort": "none", - "allow-null": false, - "remote-source": ["Employee", "id", "first_name+last_name", "getActiveSubordinateEmployees"] - }], - ["category", {"label": "Category", "type": "select2", "allow-null":false, "remote-source": ["OvertimeCategory", "id", "name"]}], - ["start_time", {"label": "Start Time", "type": "datetime", "validation": ""}], - ["end_time", {"label": "End Time", "type": "datetime", "validation": ""}], - ["project", {"label": "Project", "type": "select2", "allow-null":true,"null=label":"none","remote-source": ["Project", "id", "name"]}], - ["notes", {"label": "Notes", "type": "textarea", "validation": "none"}] - ]; -}); - diff --git a/web/admin/payroll/lib.js b/web/admin/payroll/lib.js deleted file mode 100644 index 5a5752bd..00000000 --- a/web/admin/payroll/lib.js +++ /dev/null @@ -1,657 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * PaydayAdapter - */ - -function PaydayAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -PaydayAdapter.inherits(AdapterBase); - - - -PaydayAdapter.method('getDataMapping', function() { - return [ - "id", - "name" - ]; -}); - -PaydayAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Select Pay Frequency"} - ]; -}); - -PaydayAdapter.method('getFormFields', function() { - return [ - [ "name", {"label":"Name","type":"text","validation":""}] - ]; -}); - -/* - PaydayAdapter.method('showActionButtons' , function() { - return false; - }); - */ - -PaydayAdapter.method('getAddNewLabel', function() { - return "Run Payroll"; -}); - -PaydayAdapter.method('createTable', function(elementId) { - $("#payday_all").off(); - this.uber('createTable',elementId); - $("#payday_all").off().on('click',function(){ - if($(this).is(':checked')){ - $('.paydayCheck').prop('checked', true); - }else{ - $('.paydayCheck').prop('checked', false); - } - }) -}); - -PaydayAdapter.method('getActionButtonsHtml', function(id,data) { - var editButton = ''; - - var html = '
    _edit_
    '; - html = html.replace('_edit_',editButton); - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - -PaydayAdapter.method('getActionButtonHeader', function() { - return { "sTitle": '', "sClass": "center" }; -}); - - - - -/** - * PayrollAdapter - */ - -function PayrollAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -PayrollAdapter.inherits(AdapterBase); - - - -PayrollAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "pay_period", - "department", - "date_start", - "date_end", - "status" - - ]; -}); - -PayrollAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID","bVisible":false }, - { "sTitle": "Name" }, - { "sTitle": "Pay Frequency"}, - { "sTitle": "Department"}, - { "sTitle": "Date Start"}, - { "sTitle": "Date End"}, - { "sTitle": "Status"} - ]; -}); - -PayrollAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text"}], - [ "pay_period", {"label":"Pay Frequency","type":"select","remote-source":["PayFrequency","id","name"],"sort":"none"}], - [ "deduction_group", {"label":"Calculation Group","type":"select","remote-source":["DeductionGroup","id","name"],"sort":"none"}], - [ "payslipTemplate", {"label":"Payslip Template","type":"select","remote-source":["PayslipTemplate","id","name"]}], - [ "department", {"label":"Department","type":"select2","remote-source":["CompanyStructure","id","title"],"sort":"none"}], - [ "date_start", {"label":"Start Date","type":"date","validation":""}], - [ "date_end", {"label":"End Date","type":"date","validation":""}], - //[ "column_template", {"label":"Report Column Template","type":"select","remote-source":["PayrollColumnTemplate","id","name"]}], - [ "columns", {"label":"Payroll Columns","type":"select2multi","remote-source":["PayrollColumn","id","name"]}], - [ "status", {"label":"Status","type":"select","source":[["Draft","Draft"],["Completed","Completed"]],"sort":"none"}] - ]; -}); - -PayrollAdapter.method('postRenderForm', function(object, $tempDomObj) { - if(object != null && object != undefined && object.id != undefined && object.id != null){ - $tempDomObj.find("#pay_period").attr('disabled','disabled'); - $tempDomObj.find("#department").attr('disabled','disabled'); - //$tempDomObj.find("#date_start").attr('disabled','disabled'); - //$tempDomObj.find("#date_end").attr('disabled','disabled'); - //$tempDomObj.find("#column_template").attr('disabled','disabled'); - } - - -}); - -PayrollAdapter.method('process', function(id, status) { - modJs = modJsList['tabPayrollData']; - modJs.setCurrentPayroll(id); - $("#Payroll").hide(); - $("#PayrollData").show(); - $("#PayrollDataButtons").show(); - - if(status == 'Completed'){ - $(".completeBtnTable").hide(); - $(".saveBtnTable").hide(); - }else{ - $(".completeBtnTable").show(); - $(".saveBtnTable").show(); - } - - modJs.get([]); - - -}); - - -PayrollAdapter.method('getActionButtonsHtml', function(id,data) { - var editButton = ''; - var processButton = ''; - var deleteButton = ''; - var cloneButton = ''; - - var html = '
    _edit__process__clone__delete_
    '; - - - if(this.showAddNew){ - html = html.replace('_clone_',cloneButton); - }else{ - html = html.replace('_clone_',''); - } - - if(this.showDelete){ - html = html.replace('_delete_',deleteButton); - }else{ - html = html.replace('_delete_',''); - } - - if(this.showEdit){ - html = html.replace('_edit_',editButton); - }else{ - html = html.replace('_edit_',''); - } - - /* - if(data[6] != "Completed"){ - html = html.replace('_process_',processButton); - }else{ - html = html.replace('_process_',''); - } - */ - html = html.replace('_process_',processButton); - - - html = html.replace(/_id_/g,id); - html = html.replace(/_status_/g,data[6]); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - -PayrollAdapter.method('get', function(callBackData) { - $("#PayrollData").hide(); - $("#PayrollForm").hide(); - $("#PayrollDataButtons").hide(); - $("#Payroll").show(); - modJsList['tabPayrollData'].setCurrentPayroll(null); - this.uber('get',callBackData); -}); - - - -/** - * PayrollDataAdapter - */ - -function PayrollDataAdapter(endPoint) { - this.initAdapter(endPoint); - this.cellDataUpdates = {}; - this.payrollId = null; -} - -PayrollDataAdapter.inherits(TableEditAdapter); - -PayrollDataAdapter.method('validateCellValue', function(element, evt, newValue) { - modJs.addCellDataUpdate(element.data('colId'),element.data('rowId'),newValue); - return true; -}); - -PayrollDataAdapter.method('setCurrentPayroll', function(val) { - this.payrollId = val; -}); - - -PayrollDataAdapter.method('addAdditionalRequestData' , function(type, req) { - if(type == 'updateData'){ - req.payrollId = this.payrollId; - }else if(type == 'updateAllData'){ - req.payrollId = this.payrollId; - }else if(type == 'getAllData'){ - req.payrollId = this.payrollId; - } - - return req; -}); - -PayrollDataAdapter.method('modifyCSVHeader', function(header) { - header.unshift(""); - return header; -}); - -PayrollDataAdapter.method('getCSVData' , function() { - var csv = ""; - - for(var i=0;i#_delete_##_edit_#
    #_renderFunction_#
    ', - "validation":"none", - "render":function(item){ - var output = "Variable:"+item.name; - return output; - - } - - }]; - - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "calculation_hook", {"label":"Predefined Calculations","type":"select2","allow-null":true,"null-label":"None","remote-source":["CalculationHook","code","name"]}], - [ "deduction_group", {"label":"Calculation Group","type":"select2","allow-null":true,"null-label":"Common","remote-source":["DeductionGroup","id","name"]}], - [ "salary_components", {"label":"Salary Components","type":"select2multi","remote-source":["SalaryComponent","id","name"]}], - [ "deductions", {"label":"Calculation Method","type":"select2multi","remote-source":["Deduction","id","name"]}], - [ "add_columns", {"label":"Columns to Add","type":"select2multi","remote-source":["PayrollColumn","id","name"]}], - [ "sub_columns", {"label":"Columns to Subtract","type":"select2multi","remote-source":["PayrollColumn","id","name"]}], - [ "colorder", {"label":"Column Order","type":"text","validation":"number"}], - [ "editable", {"label":"Editable","type":"select","source":[["Yes","Yes"],["No","No"]]}], - [ "enabled", {"label":"Enabled","type":"select","source":[["Yes","Yes"],["No","No"]]}], - [ "default_value", {"label":"Default Value","type":"text","validation":""}], - fucntionColumnList, - [ "calculation_function", {"label":"Function","type":"text","validation":"none"}] - ]; -}); - -PayrollColumnAdapter.method('getFilters', function() { - return [ - [ "deduction_group", {"label":"Calculation Group","type":"select2","allow-null":true,"null-label":"Any","remote-source":["DeductionGroup","id","name"]}] - ]; -}); - - - - -/** - * PayrollColumnTemplateAdapter - */ - -function PayrollColumnTemplateAdapter(endPoint) { - this.initAdapter(endPoint); -} - -PayrollColumnTemplateAdapter.inherits(AdapterBase); - -PayrollColumnTemplateAdapter.method('getDataMapping', function() { - return [ - "id", - "name" - ]; -}); - -PayrollColumnTemplateAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":true}, - { "sTitle": "Name"} - ]; -}); - -PayrollColumnTemplateAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "columns", {"label":"Payroll Columns","type":"select2multi","remote-source":["PayrollColumn","id","name"]}] - ]; -}); - - -/* - * PayrollEmployeeAdapter - */ - -function PayrollEmployeeAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -PayrollEmployeeAdapter.inherits(AdapterBase); - - - -PayrollEmployeeAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "pay_frequency", - "deduction_group", - "currency" - ]; -}); - -PayrollEmployeeAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Pay Frequency"}, - { "sTitle": "Calculation Group"}, - { "sTitle": "Currency"}, - ]; -}); - -PayrollEmployeeAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}], - [ "pay_frequency", {"label":"Pay Frequency","type":"select2","remote-source":["PayFrequency","id","name"]}], - [ "currency", {"label":"Currency","type":"select2","remote-source":["CurrencyType","id","code"]}], - [ "deduction_group", {"label":"Calculation Group","type":"select2","allow-null":true,"null-label":"None","remote-source":["DeductionGroup","id","name"]}], - [ "deduction_exemptions", {"label":"Calculation Exemptions","type":"select2multi","remote-source":["Deduction","id","name"],"validation":"none"}], - [ "deduction_allowed", {"label":"Calculations Assigned","type":"select2multi","remote-source":["Deduction","id","name"],"validation":"none"}] - ]; -}); - -PayrollEmployeeAdapter.method('getFilters', function() { - return [ - [ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}] - ]; -}); - - -/** - * DeductionAdapter - */ - -function DeductionAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -DeductionAdapter.inherits(AdapterBase); - - - -DeductionAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "deduction_group" - ]; -}); - -DeductionAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Calculation Group"} - ]; -}); - -DeductionAdapter.method('getFormFields', function() { - - var rangeAmounts = [ "rangeAmounts", {"label":"Calculation Process","type":"datagroup", - "form":[ - [ "lowerCondition", {"label":"Lower Limit Condition","type":"select","source":[["No Lower Limit","No Lower Limit"],["gt","Greater than"],["gte","Greater than or Equal"]]}], - [ "lowerLimit", {"label":"Lower Limit","type":"text","validation":"float"}], - [ "upperCondition", {"label":"Upper Limit Condition","type":"select","source":[["No Upper Limit","No Upper Limit"],["lt","Less than"],["lte","Less than or Equal"]]}], - [ "upperLimit", {"label":"Upper Limit","type":"text","validation":"float"}], - [ "amount", {"label":"Value","type":"text","validation":""}] - ], - "html":'
    #_delete_##_edit_#
    #_renderFunction_#
    ', - "validation":"none", - "custom-validate-function":function (data){ - var res = {}; - res['valid'] = true; - if(data.lowerCondition == 'No Lower Limit'){ - data.lowerLimit = 0; - } - if(data.upperCondition == 'No Upper Limit'){ - data.upperLimit = 0; - } - res['params'] = data; - return res; - }, - "render":function(item){ - var output = ""; - var getSymbol = function(text){ - var map = {}; - map['gt'] = '>'; - map['gte'] = '>='; - map['lt'] = '<'; - map['lte'] = '<='; - - return map[text]; - } - if(item.lowerCondition != "No Lower Limit"){ - output += item.lowerLimit + " " + getSymbol(item.lowerCondition) + " "; - } - - if(item.upperCondition != "No Upper Limit"){ - output += " and "; - output += getSymbol(item.upperCondition) + " " + item.upperLimit + " "; - } - if(output == ""){ - return "Deduction is "+item.amount + " for all ranges"; - }else{ - return "If salary component "+output+ " deduction is "+item.amount; - } - - - return output; - - } - - }]; - - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "componentType", {"label":"Salary Component Type","type":"select2multi","allow-null":true,"remote-source":["SalaryComponentType","id","name"]}], - [ "component", {"label":"Salary Component","type":"select2multi","allow-null":true,"remote-source":["SalaryComponent","id","name"]}], - [ "payrollColumn", {"label":"Payroll Report Column","type":"select2","allow-null":true,"remote-source":["PayrollColumn","id","name"]}], - rangeAmounts, - [ "deduction_group", {"label":"Calculation Group","type":"select2","allow-null":true,"null-label":"None","remote-source":["DeductionGroup","id","name"]}] - - ]; -}); - - - - - -/* - * DeductionGroupAdapter - */ - -function DeductionGroupAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -DeductionGroupAdapter.inherits(AdapterBase); - - - -DeductionGroupAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "description" - ]; -}); - -DeductionGroupAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Details" } - ]; -}); - -DeductionGroupAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "description", {"label":"Details","type":"textarea","validation":"none"}] - ]; -}); - - -/* - * PayslipTemplateAdapter - */ - -function PayslipTemplateAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -PayslipTemplateAdapter.inherits(AdapterBase); - - - -PayslipTemplateAdapter.method('getDataMapping', function() { - return [ - "id", - "name" - ]; -}); - -PayslipTemplateAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" } - ]; -}); - -PayslipTemplateAdapter.method('getFormFields', function() { - - var payslipFields = [ "data", {"label":"Payslip Fields","type":"datagroup", - "form":[ - [ "type", {"label":"Type","type":"select","sort":"none","source":[["Payroll Column","Payroll Column"],["Text","Text"],["Company Name","Company Name"],["Company Logo","Company Logo"], ["Separators","Separators"]]}], - [ "payrollColumn", {"label":"Payroll Column","type":"select2","sort":"none","allow-null":true,"null-label":"None","remote-source":["PayrollColumn","id","name"]}], - - [ "label", {"label":"Label","type":"text","validation":"none"}], - [ "text", {"label":"Text","type":"textarea","validation":"none"}], - [ "status", {"label":"Status","type":"select","sort":"none","source":[["Show","Show"],["Hide","Hide"]]}] - ], - - //"html":'
    #_delete_##_edit_#
    Type#_type_#
    Label#_label_#
    Text#_text_#
    Font Size#_fontSize_#
    Font Style#_fontStyle_#
    Font Color#_fontColor_#
    Status#_status_#
    ', - "html":'
    #_delete_##_edit_#
    #_type_# #_label_#
    #_text_#
    ', - "validation":"none", - "custom-validate-function":function (data){ - var res = {}; - res['valid'] = true; - if(data.type == 'Payroll Column'){ - if(data.payrollColumn == "NULL"){ - res['valid'] = false; - res['message'] = "Please select payroll column"; - }else{ - data.payrollColumn == "NULL"; - } - }else if(data.type == 'Text'){ - if(data.text == ""){ - res['valid'] = false; - res['message'] = "Text can not be empty"; - } - } - - res['params'] = data; - return res; - } - }]; - - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - payslipFields - ]; -}); - - - - - - diff --git a/web/admin/permissions/lib.js b/web/admin/permissions/lib.js deleted file mode 100644 index 52b8c048..00000000 --- a/web/admin/permissions/lib.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * PermissionAdapter - */ - -function PermissionAdapter(endPoint) { - this.initAdapter(endPoint); -} - -PermissionAdapter.inherits(AdapterBase); - - - -PermissionAdapter.method('getDataMapping', function() { - return [ - "id", - "user_level", - "module_id", - "permission", - "value" - ]; -}); - -PermissionAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "User Level" }, - { "sTitle": "Module"}, - { "sTitle": "Permission"}, - { "sTitle": "Value"} - ]; -}); - -PermissionAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "user_level", {"label":"User Level","type":"placeholder","validation":"none"}], - [ "module_id", {"label":"Module","type":"placeholder","remote-source":["Module","id","menu+name"]}], - [ "permission", {"label":"Permission","type":"placeholder","validation":"none"}], - [ "value", {"label":"Value","type":"text","validation":"none"}] - ]; -}); - -PermissionAdapter.method('getFilters', function() { - return [ - [ "module_id", {"label":"Module","type":"select2","allow-null":true,"null-label":"All Modules","remote-source":["Module","id","menu+name"]}] - ]; -}); - -PermissionAdapter.method('getActionButtonsHtml', function(id,data) { - var html = '
    '; - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - - -PermissionAdapter.method('getMetaFieldForRendering', function(fieldName) { - if(fieldName == "value"){ - return "meta"; - } - return ""; -}); - - -PermissionAdapter.method('fillForm', function(object) { - this.uber('fillForm',object); - $("#helptext").html(object.description); -}); diff --git a/web/admin/projects/lib.js b/web/admin/projects/lib.js deleted file mode 100644 index 75fd5a0d..00000000 --- a/web/admin/projects/lib.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - -/** - * ClientAdapter - */ - -function ClientAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -ClientAdapter.inherits(AdapterBase); - - - -ClientAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "details", - "address", - "contact_number" - ]; -}); - -ClientAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID","bVisible":false }, - { "sTitle": "Name" }, - { "sTitle": "Details"}, - { "sTitle": "Address"}, - { "sTitle": "Contact Number"} - ]; -}); - -ClientAdapter.method('getFormFields', function() { - if(this.showSave){ - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text"}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}], - [ "address", {"label":"Address","type":"textarea","validation":"none"}], - [ "contact_number", {"label":"Contact Number","type":"text","validation":"none"}], - [ "contact_email", {"label":"Contact Email","type":"text","validation":"none"}], - [ "company_url", {"label":"Company Url","type":"text","validation":"none"}], - [ "status", {"label":"Status","type":"select","source":[["Active","Active"],["Inactive","Inactive"]]}], - [ "first_contact_date", {"label":"First Contact Date","type":"date","validation":"none"}] - ]; - }else{ - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"placeholder"}], - [ "details", {"label":"Details","type":"placeholder","validation":"none"}], - [ "address", {"label":"Address","type":"placeholder","validation":"none"}], - [ "contact_number", {"label":"Contact Number","type":"placeholder","validation":"none"}], - [ "contact_email", {"label":"Contact Email","type":"placeholder","validation":"none"}], - [ "company_url", {"label":"Company Url","type":"placeholder","validation":"none"}], - [ "status", {"label":"Status","type":"placeholder","source":[["Active","Active"],["Inactive","Inactive"]]}], - [ "first_contact_date", {"label":"First Contact Date","type":"placeholder","validation":"none"}] - ]; - } -}); - -ClientAdapter.method('getHelpLink', function () { - return 'http://blog.icehrm.com/docs/projects/'; -}); - -/** - * ProjectAdapter - */ - -function ProjectAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -ProjectAdapter.inherits(AdapterBase); - - - -ProjectAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "client" - ]; -}); - -ProjectAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID","bVisible":false }, - { "sTitle": "Name" }, - { "sTitle": "Client"}, - ]; -}); - -ProjectAdapter.method('getFormFields', function() { - - if(this.showSave){ - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text"}], - [ "client", {"label":"Client","type":"select2","allow-null":true,"remote-source":["Client","id","name"]}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}], - [ "status", {"label":"Status","type":"select","source":[["Active","Active"],["On Hold","On Hold"],["Completed","Completed"],["Dropped","Dropped"]]}] - ]; - }else{ - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"placeholder"}], - [ "client", {"label":"Client","type":"placeholder","allow-null":true,"remote-source":["Client","id","name"]}], - [ "details", {"label":"Details","type":"placeholder","validation":"none"}], - [ "status", {"label":"Status","type":"select","source":[["Active","Active"],["On Hold","On Hold"],["Completed","Completed"],["Dropped","Dropped"]]}] - ]; - } - -}); - -ProjectAdapter.method('getHelpLink', function () { - return 'http://blog.icehrm.com/docs/projects/'; -}); - - -/* - * EmployeeProjectAdapter - */ - - -function EmployeeProjectAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeProjectAdapter.inherits(AdapterBase); - - - -EmployeeProjectAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "project" - ]; -}); - -EmployeeProjectAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee" }, - { "sTitle": "Project" } - ]; -}); - -EmployeeProjectAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}], - [ "project", {"label":"Project","type":"select2","remote-source":["Project","id","name"]}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}] - ]; -}); - -EmployeeProjectAdapter.method('getFilters', function() { - return [ - [ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}] - - ]; -}); - -EmployeeProjectAdapter.method('getHelpLink', function () { - return 'http://blog.icehrm.com/docs/projects/'; -}); - diff --git a/web/admin/qualifications/lib.js b/web/admin/qualifications/lib.js deleted file mode 100644 index 9f79ff1a..00000000 --- a/web/admin/qualifications/lib.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * SkillAdapter - */ - -function SkillAdapter(endPoint) { - this.initAdapter(endPoint); -} - -SkillAdapter.inherits(AdapterBase); - - - -SkillAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "description" - ]; -}); - -SkillAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID","bVisible":false }, - { "sTitle": "Name" }, - { "sTitle": "Description"} - ]; -}); - -SkillAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text"}], - [ "description", {"label":"Description","type":"textarea","validation":""}] - ]; -}); - -SkillAdapter.method('getHelpLink', function () { - return 'http://blog.icehrm.com/docs/qualifications/'; -}); - - - -/** - * EducationAdapter - */ - -function EducationAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EducationAdapter.inherits(AdapterBase); - - - -EducationAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "description" - ]; -}); - -EducationAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID","bVisible":false }, - { "sTitle": "Name" }, - { "sTitle": "Description"} - ]; -}); - -EducationAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text"}], - [ "description", {"label":"Description","type":"textarea","validation":""}] - ]; -}); - - - - - -/** - * CertificationAdapter - */ - -function CertificationAdapter(endPoint) { - this.initAdapter(endPoint); -} - -CertificationAdapter.inherits(AdapterBase); - - - -CertificationAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "description" - ]; -}); - -CertificationAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Description"} - ]; -}); - -CertificationAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text"}], - [ "description", {"label":"Description","type":"textarea","validation":""}] - ]; -}); - - - -/** - * LanguageAdapter - */ - -function LanguageAdapter(endPoint) { - this.initAdapter(endPoint); -} - -LanguageAdapter.inherits(AdapterBase); - - - -LanguageAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "description" - ]; -}); - -LanguageAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Description"} - ]; -}); - -LanguageAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text"}], - [ "description", {"label":"Description","type":"textarea","validation":""}] - ]; -}); - diff --git a/web/admin/reports/lib.js b/web/admin/reports/lib.js deleted file mode 100644 index ccfdceac..00000000 --- a/web/admin/reports/lib.js +++ /dev/null @@ -1,396 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * ReportAdapter - */ - - -function ReportAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); - this._construct(); -} - -ReportAdapter.inherits(AdapterBase); - -ReportAdapter.method('_construct', function() { - this._formFileds = [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"label","validation":""}], - [ "parameters", {"label":"Parameters","type":"fieldset","validation":"none"}] - ]; - this.remoteFieldsExists = false; -}); - -ReportAdapter.method('_initLocalFormFields', function() { - this._formFileds = [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"label","validation":""}], - [ "parameters", {"label":"Parameters","type":"fieldset","validation":"none"}] - ]; -}); - -ReportAdapter.method('setRemoteFieldExists', function(val) { - this.remoteFieldsExists = val; -}); - -ReportAdapter.method('getDataMapping', function() { - return [ - "id", - "icon", - "name", - "details", - "parameters" - ]; -}); - -ReportAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "","bSortable":false,"sWidth":"22px"}, - { "sTitle": "Name","sWidth":"30%"}, - { "sTitle": "Details"}, - { "sTitle": "Parameters","bVisible":false}, - ]; -}); - - -ReportAdapter.method('getFormFields', function() { - return this._formFileds; -}); - -ReportAdapter.method('processFormFieldsWithObject', function(object) { - var that = this; - this._initLocalFormFields(); - var len = this._formFileds.length; - var fieldIDsToDelete = []; - var fieldsToDelete = []; - this.remoteFieldsExists = false; - for(var i=0;i
    '); - $tempDomObj.attr('id',randomFormId); - - } - - $tempDomObj.html(formHtml); - - - $tempDomObj.find('.datefield').datepicker({'viewMode':2}); - $tempDomObj.find('.timefield').datetimepicker({ - language: 'en', - pickDate: false - }); - $tempDomObj.find('.datetimefield').datetimepicker({ - language: 'en' - }); - - $tempDomObj.find('.colorpick').colorpicker(); - - //$tempDomObj.find('.select2Field').select2(); - $tempDomObj.find('.select2Field').each(function() { - $(this).select2().select2('val', $(this).find("option:eq(0)").val()); - - }); - - $tempDomObj.find('.select2Multi').each(function() { - $(this).select2().on("change",function(e){ - var parentRow = $(this).parents(".row"); - var height = parentRow.find(".select2-choices").height(); - parentRow.height(parseInt(height)); - }); - - }); - - - $tempDomObj.find('.signatureField').each(function() { - //$(this).data('signaturePad',new SignaturePad($(this))); - signatureIds.push($(this).attr('id')); - }); - - for(var i=0;i').parent().html(); - //this.showMessage("Edit",tHtml,null,null,true); - this.showMessage("Edit","",null,null,true); - - $("#plainMessageModel .modal-body").html(""); - $("#plainMessageModel .modal-body").append($tempDomObj); - - - for(var i=0;iDownload Report '; - }else{ - link = 'Download Report '; - } - link = link.replace(/_BASE_/g,this.baseUrl); - - if(this.currentReport.output == "PDF" || this.currentReport.output == "JSON"){ - - this.showMessage("Download Report",link); - - }else{ - if(serverData[1].length == 0){ - this.showMessage("Empty Report","There were no data for selected filters"); - return; - } - - - var tableHtml = link+'

    '; - - //Delete existing temp report table - $("#tempReportTable").remove(); - - //this.showMessage("Report",tableHtml); - - $("#"+this.table).html(tableHtml); - $("#"+this.table).show(); - $("#"+this.table+"Form").hide(); - - //Prepare headers - var headers = []; - for(title in serverData[1]){ - headers.push({ "sTitle": serverData[1][title]}); - } - - var data = serverData[2]; - - - var dataTableParams = { - "oLanguage": { - "sLengthMenu": "_MENU_ records per page" - }, - "aaData": data, - "aoColumns": headers, - "bSort": false, - "iDisplayLength": 15, - "iDisplayStart": 0 - }; - - $("#tempReportTable").dataTable( dataTableParams ); - - $(".dataTables_paginate ul").addClass("pagination"); - $(".dataTables_length").hide(); - $(".dataTables_filter input").addClass("form-control"); - $(".dataTables_filter input").attr("placeholder","Search"); - $(".dataTables_filter label").contents().filter(function(){ - return (this.nodeType == 3); - }).remove(); - $('.tableActionButton').tooltip(); - } - - - -}); - - -ReportAdapter.method('fillForm', function(object) { - var fields = this.getFormFields(); - for(var i=0;i 7; - }; - - var password = $('#adminUsersChangePwd #newpwd').val(); - - if(!passwordValidation(password)){ - $('#adminUsersChangePwd_error').html("Password should be longer than 7 characters"); - $('#adminUsersChangePwd_error').show(); - return; - } - - var conPassword = $('#adminUsersChangePwd #conpwd').val(); - - if(conPassword != password){ - $('#adminUsersChangePwd_error').html("Passwords don't match"); - $('#adminUsersChangePwd_error').show(); - return; - } - - var req = {"id":this.currentId,"pwd":conPassword}; - var reqJson = JSON.stringify(req); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'changePasswordSuccessCallBack'; - callBackData['callBackFail'] = 'changePasswordFailCallBack'; - - this.customAction('changePassword','admin=users',reqJson,callBackData); - -}); - -UserAdapter.method('closeChangePassword', function() { - $('#adminUsersModel').modal('hide'); -}); - -UserAdapter.method('changePasswordSuccessCallBack', function(callBackData,serverData) { - this.closeChangePassword(); - this.showMessage("Password Change","Password changed successfully"); -}); - -UserAdapter.method('changePasswordFailCallBack', function(callBackData,serverData) { - this.closeChangePassword(); - this.showMessage("Error",callBackData); -}); - - - - - -/** - * UserRoleAdapter - */ - -function UserRoleAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -UserRoleAdapter.inherits(AdapterBase); - - - -UserRoleAdapter.method('getDataMapping', function() { - return [ - "id", - "name" - ]; -}); - -UserRoleAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name"} - ]; -}); - - -UserRoleAdapter.method('postRenderForm', function(object, $tempDomObj) { - $tempDomObj.find("#changePasswordBtn").remove(); -}); - -UserRoleAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}] - ]; -}); diff --git a/web/api/AdapterBase.js b/web/api/AdapterBase.js index 88418058..66ca0ca8 100644 --- a/web/api/AdapterBase.js +++ b/web/api/AdapterBase.js @@ -1,1557 +1,465 @@ +/* global baseUrl, clientUrl */ /* - This file is part of Ice Framework. - - Ice Framework is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Ice Framework is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Ice Framework. If not, see . - - ------------------------------------------------------------------ - - Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] - Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ - -function AdapterBase(endPoint) { - -} - -this.moduleRelativeURL = null; -this.tableData = new Array(); -this.sourceData = new Array(); -this.filter = null; -this.origFilter = null; -this.orderBy = null; -this.currentElement = null; - -AdapterBase.inherits(IceHRMBase); - -AdapterBase.method('initAdapter' , function(endPoint,tab,filter,orderBy) { - this.moduleRelativeURL = baseUrl; - this.table = endPoint; - if(tab == undefined || tab == null){ - this.tab = endPoint; - }else{ - this.tab = tab; - } - - if(filter == undefined || filter == null){ - this.filter = null; - }else{ - this.filter = filter; - } - - this.origFilter = this.filter; - - if(orderBy == undefined || orderBy == null){ - this.orderBy = null; - }else{ - this.orderBy = orderBy; - } - - this.trackEvent("initAdapter",tab); - - this.requestCache = new RequestCache(); - -}); - -AdapterBase.method('setFilter', function(filter) { - this.filter = filter; -}); - -AdapterBase.method('preSetFilterExternal', function(filter) { - this.initialFilter = filter; -}); - -AdapterBase.method('setFilterExternal', function(filter) { - if(filter == undefined || filter == null){ - filter = this.initialFilter; - } - - if(filter == undefined || filter == null){ - return; - } - - this.setFilter(filter); - this.filtersAlreadySet = true; - $("#"+this.getTableName()+"_resetFilters").show(); - this.currentFilterString = this.getFilterString(filter); -}); - -AdapterBase.method('getFilter', function() { - return this.filter; -}); - -AdapterBase.method('setOrderBy', function(orderBy) { - this.orderBy = orderBy; -}); - -AdapterBase.method('getOrderBy', function() { - return this.orderBy; -}); - -/** - * @method add - * @param object {Array} object data to be added to database - * @param getFunctionCallBackData {Array} once a success is returned call get() function for this module with these parameters - * @param callGetFunction {Boolean} if false the get function of the module will not be called (default: true) - * @param successCallback {Function} this will get called after success response - */ - -AdapterBase.method('add', function(object,getFunctionCallBackData,callGetFunction,successCallback) { - var that = this; - if(callGetFunction == undefined || callGetFunction == null){ - callGetFunction = true; - } - $(object).attr('a','add'); - $(object).attr('t',this.table); - that.showLoader(); - this.requestCache.invalidateTable(this.table); - $.post(this.moduleRelativeURL, object, function(data) { - if(data.status == "SUCCESS"){ - that.addSuccessCallBack(getFunctionCallBackData,data.object, callGetFunction, successCallback, that); - }else{ - that.addFailCallBack(getFunctionCallBackData,data.object); - } - },"json").always(function() {that.hideLoader()}); - this.trackEvent("add",this.tab,this.table); -}); - -AdapterBase.method('addSuccessCallBack', function(callBackData,serverData, callGetFunction, successCallback, thisObject) { - if(callGetFunction){ - this.get(callBackData); - } - this.initFieldMasterData(); - if(successCallback != undefined && successCallback != null){ - successCallback.apply(thisObject,[serverData]); - } - this.trackEvent("addSuccess",this.tab,this.table); -}); - -AdapterBase.method('addFailCallBack', function(callBackData,serverData) { - try{ - this.closePlainMessage(); - }catch(e){} - this.showMessage("Error saving",serverData); - this.trackEvent("addFailed",this.tab,this.table); -}); - -AdapterBase.method('deleteObj', function(id,callBackData) { - var that = this; - that.showLoader(); - this.requestCache.invalidateTable(this.table); - $.post(this.moduleRelativeURL, {'t':this.table,'a':'delete','id':id}, function(data) { - if(data.status == "SUCCESS"){ - that.deleteSuccessCallBack(callBackData,data.object); - }else{ - that.deleteFailCallBack(callBackData,data.object); - } - },"json").always(function() {that.hideLoader()}); - this.trackEvent("delete",this.tab,this.table); -}); - -AdapterBase.method('deleteSuccessCallBack', function(callBackData,serverData) { - this.get(callBackData); - this.clearDeleteParams(); -}); - -AdapterBase.method('deleteFailCallBack', function(callBackData,serverData) { - this.clearDeleteParams(); - this.showMessage("Error Occurred while Deleting Item",serverData); -}); - -AdapterBase.method('get', function(callBackData) { - var that = this; - - if(this.getRemoteTable()){ - this.createTableServer(this.getTableName()); - $("#"+this.getTableName()+'Form').hide(); - $("#"+this.getTableName()).show(); - return; - } - - var sourceMappingJson = JSON.stringify(this.getSourceMapping()); - - var filterJson = ""; - if(this.getFilter() != null){ - filterJson = JSON.stringify(this.getFilter()); - } - - var orderBy = ""; - if(this.getOrderBy() != null){ - orderBy = this.getOrderBy(); - } - - sourceMappingJson = this.fixJSON(sourceMappingJson); - filterJson = this.fixJSON(filterJson); - - that.showLoader(); - $.post(this.moduleRelativeURL, {'t':this.table,'a':'get','sm':sourceMappingJson,'ft':filterJson,'ob':orderBy}, function(data) { - if(data.status == "SUCCESS"){ - that.getSuccessCallBack(callBackData,data.object); - }else{ - that.getFailCallBack(callBackData,data.object); - } - },"json").always(function() {that.hideLoader()}); - - that.initFieldMasterData(); - - this.trackEvent("get",this.tab,this.table); - //var url = this.getDataUrl(); - //console.log(url); -}); - - -AdapterBase.method('getDataUrl', function(columns) { - var that = this; - var sourceMappingJson = JSON.stringify(this.getSourceMapping()); - - var columns = JSON.stringify(columns); - - var filterJson = ""; - if(this.getFilter() != null){ - filterJson = JSON.stringify(this.getFilter()); - } - - var orderBy = ""; - if(this.getOrderBy() != null){ - orderBy = this.getOrderBy(); - } - - var url = this.moduleRelativeURL.replace("service.php","data.php"); - url = url+"?"+"t="+this.table; - url = url+"&"+"sm="+this.fixJSON(sourceMappingJson); - url = url+"&"+"cl="+this.fixJSON(columns); - url = url+"&"+"ft="+this.fixJSON(filterJson); - url = url+"&"+"ob="+orderBy; - - if(this.isSubProfileTable()){ - url = url+"&"+"type=sub"; - } - - if(this.remoteTableSkipProfileRestriction()){ - url = url+"&"+"skip=1"; - } - - return url; -}); - -AdapterBase.method('isSubProfileTable', function() { - return false; -}); - -AdapterBase.method('remoteTableSkipProfileRestriction', function() { - return false; -}); - -AdapterBase.method('preProcessTableData', function(row) { - return row; -}); - -AdapterBase.method('getSuccessCallBack', function(callBackData,serverData) { - var data = []; - var mapping = this.getDataMapping(); - for(var i=0;i
  • '; - var editButton = ''; - - var table = $('
    '); - - //add Header - var header = this.getSubHeader(); - table.append(header); - if(data.length == 0){ - table.append(''+this.getNoDataMessage()+''); - }else{ - for(var i=0;i

    '+this.getSubHeaderTitle()+'

    '); - return header; -}); - - - -/** - * IdNameAdapter - */ - -function IdNameAdapter(endPoint) { - this.initAdapter(endPoint); -} - -IdNameAdapter.inherits(AdapterBase); - - - -IdNameAdapter.method('getDataMapping', function() { - return [ - "id", - "name" - ]; -}); - -IdNameAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name"} - ]; -}); - -IdNameAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}] - ]; -}); - - -/** - * LogViewAdapter - */ - -function LogViewAdapter(endPoint,tab,filter,orderBy){ - this.initAdapter(endPoint,tab,filter,orderBy); -} - -LogViewAdapter.inherits(AdapterBase); - -LogViewAdapter.method('getLogs', function(id) { - var that = this; - var object = {"id":id}; - var reqJson = JSON.stringify(object); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'getLogsSuccessCallBack'; - callBackData['callBackFail'] = 'getLogsFailCallBack'; - - this.customAction('getLogs','admin='+this.modulePathName,reqJson,callBackData); -}); - -LogViewAdapter.method('getLogsSuccessCallBack', function(callBackData) { - - var tableLog = '_days_
    Notes
    '; - var rowLog = '_date_  _status_
    _note_'; - - var logs = callBackData.data; - var html = ""; - var rowsLogs = ""; - - - for(var i=0;i "+logs[i].status_to); - trow = trow.replace(/_note_/g,logs[i].note); - rowsLogs += trow; - } - - if(rowsLogs != ""){ - tableLog = tableLog.replace('_days_',rowsLogs); - html+= tableLog; - } - - this.showMessage("Logs",html); - - timeUtils.convertToRelativeTime($(".logTime")); -}); - -LogViewAdapter.method('getLogsFailCallBack', function(callBackData) { - this.showMessage("Error","Error occured while getting data"); -}); - -/** - * ApproveAdminAdapter - */ - -function ApproveAdminAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -ApproveAdminAdapter.inherits(LogViewAdapter); - -ApproveAdminAdapter.method('getStatusFieldPosition', function() { - var dm = this.getDataMapping(); - return dm.length - 1; -}); - -ApproveAdminAdapter.method('openStatus', function(id,status) { - $('#'+this.itemNameLower+'StatusModel').modal('show'); - $('#'+this.itemNameLower+'_status').html(this.getStatusOptions(status)); - $('#'+this.itemNameLower+'_status').val(status); - this.statusChangeId = id; -}); - -ApproveAdminAdapter.method('closeDialog', function() { - $('#'+this.itemNameLower+'StatusModel').modal('hide'); -}); - -ApproveAdminAdapter.method('changeStatus', function() { - var status = $('#'+this.itemNameLower+'_status').val(); - var reason = $('#'+this.itemNameLower+'_reason').val(); - - if(status == undefined || status == null || status == ""){ - this.showMessage("Error", "Please select "+this.itemNameLower+" status"); - return; - } - - var object = {"id":this.statusChangeId,"status":status,"reason":reason}; - - var reqJson = JSON.stringify(object); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'changeStatusSuccessCallBack'; - callBackData['callBackFail'] = 'changeStatusFailCallBack'; - - this.customAction('changeStatus','admin='+this.modulePathName,reqJson,callBackData); - - this.closeDialog(); - this.statusChangeId = null; -}); - -ApproveAdminAdapter.method('changeStatusSuccessCallBack', function(callBackData) { - this.showMessage("Successful", this.itemName + " Request status changed successfully"); - this.get([]); -}); - -ApproveAdminAdapter.method('changeStatusFailCallBack', function(callBackData) { - this.showMessage("Error", "Error occurred while changing "+this.itemName+" request status"); -}); - - - -ApproveAdminAdapter.method('getActionButtonsHtml', function(id,data) { - var editButton = ''; - var deleteButton = ''; - var statusChangeButton = ''; - var viewLogsButton = ''; - - var html = '
    _edit__delete__status__logs_
    '; - - var optiondata = this.getStatusOptionsData(data[this.getStatusFieldPosition()]); - if(Object.keys(optiondata).length > 0){ - html = html.replace('_status_',statusChangeButton); - }else{ - html = html.replace('_status_',''); - } - - html = html.replace('_logs_',viewLogsButton); - - if(this.showDelete){ - html = html.replace('_delete_',deleteButton); - - }else{ - html = html.replace('_delete_',''); - } - - if(this.showEdit){ - html = html.replace('_edit_',editButton); - }else{ - html = html.replace('_edit_',''); - } - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - html = html.replace(/_cstatus_/g,data[this.getStatusFieldPosition()]); - return html; -}); - -ApproveAdminAdapter.method('isSubProfileTable', function() { - if(this.user.user_level == "Admin"){ - return false; - }else{ - return true; - } -}); - -ApproveAdminAdapter.method('getStatusOptionsData', function(currentStatus) { - var data = {}; - if(currentStatus == 'Approved'){ - - }else if(currentStatus == 'Pending'){ - data["Approved"] = "Approved"; - data["Rejected"] = "Rejected"; - - }else if(currentStatus == 'Rejected'){ - - }else if(currentStatus == 'Cancelled'){ - - }else if(currentStatus == 'Processing'){ - - }else{ - data["Cancellation Requested"] = "Cancellation Requested"; - data["Cancelled"] = "Cancelled"; - } - - return data; -}); - -ApproveAdminAdapter.method('getStatusOptions', function(currentStatus) { - - return this.generateOptions(this.getStatusOptionsData(currentStatus)); -}); - - -/** - * ApproveModuleAdapter - */ - -function ApproveModuleAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -ApproveModuleAdapter.inherits(LogViewAdapter); - -ApproveModuleAdapter.method('cancelRequest', function(id) { - var that = this; - var object = {}; - object['id'] = id; - - var reqJson = JSON.stringify(object); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'cancelSuccessCallBack'; - callBackData['callBackFail'] = 'cancelFailCallBack'; - - this.customAction('cancel','modules='+this.modulePathName,reqJson,callBackData); -}); - -ApproveModuleAdapter.method('cancelSuccessCallBack', function(callBackData) { - this.showMessage("Successful", this.itemName + " cancellation request sent"); - this.get([]); -}); - -ApproveModuleAdapter.method('cancelFailCallBack', function(callBackData) { - this.showMessage("Error Occurred while cancelling "+this.itemName, callBackData); -}); - -ApproveModuleAdapter.method('getActionButtonsHtml', function(id,data) { - var editButton = ''; - var deleteButton = ''; - var requestCancellationButton = ''; - var viewLogsButton = ''; - - - var html = '
    _edit__logs__delete_
    '; - - html = html.replace('_logs_',viewLogsButton); - - if(this.showDelete){ - if (data[7] === "Approved") { - html = html.replace('_delete_',requestCancellationButton); - } else if(data[7] === "Pending" || this.user.user_level === "Admin") { - html = html.replace('_delete_',deleteButton); - } else { - html = html.replace('_delete_',''); - } - }else{ - html = html.replace('_delete_',''); - } - - if(this.showEdit){ - html = html.replace('_edit_',editButton); - }else{ - html = html.replace('_edit_',''); - } - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - -/** - * ApproveApproverAdapter - */ - -function ApproveApproverAdapter() { -} - -ApproveApproverAdapter.method('getActionButtonsHtml', function(id,data) { - var statusChangeButton = ''; - var viewLogsButton = ''; - - var html = '
    _status__logs_
    '; - - - html = html.replace('_logs_',viewLogsButton); - - - if(data[this.getStatusFieldPosition()] == 'Processing'){ - html = html.replace('_status_',statusChangeButton); - - }else{ - html = html.replace('_status_',''); - } - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - html = html.replace(/_cstatus_/g,data[this.getStatusFieldPosition()]); - return html; -}); - -ApproveApproverAdapter.method('getStatusOptionsData', function(currentStatus) { - var data = {}; - if(currentStatus != 'Processing'){ - - }else{ - data["Approved"] = "Approved"; - data["Rejected"] = "Rejected"; - - } - - return data; -}); - -ApproveApproverAdapter.method('getStatusOptions', function(currentStatus) { - return this.generateOptions(this.getStatusOptionsData(currentStatus)); -}); - - - - -/** - * TableEditAdapter - */ - -function TableEditAdapter(endPoint) { - this.initAdapter(endPoint); - this.cellDataUpdates = {}; - this.modulePath = ''; - this.rowFieldName = ''; - this.columnFieldName = ''; - this.rowTable = ''; - this.columnTable = ''; - this.valueTable = ''; - this.csvData = []; - this.columnIDMap = {}; -} - -TableEditAdapter.inherits(AdapterBase); - -TableEditAdapter.method('setModulePath', function(path) { - this.modulePath = path; -}); - -TableEditAdapter.method('setRowFieldName', function(name) { - this.rowFieldName = name; -}); - -TableEditAdapter.method('setTables', function(rowTable, columnTable, valueTable) { - this.rowTable = rowTable; - this.columnTable = columnTable; - this.valueTable = valueTable; -}); - -TableEditAdapter.method('setColumnFieldName', function(name) { - this.columnFieldName = name; -}); - -TableEditAdapter.method('getDataMapping', function() { - return [ - ]; -}); - - -TableEditAdapter.method('getFormFields', function() { - return [ - ]; -}); - -TableEditAdapter.method('get', function() { - this.getAllData(); -}); - -TableEditAdapter.method('getAllData', function(save) { - var req = {}; - req.rowTable = this.rowTable; - req.columnTable = this.columnTable; - req.valueTable = this.valueTable; - req = this.addAdditionalRequestData('getAllData', req); - req.save = (save == undefined || save == null || save == false)?0:1; - var reqJson = JSON.stringify(req); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'getAllDataSuccessCallBack'; - callBackData['callBackFail'] = 'getAllDataFailCallBack'; - - this.customAction('getAllData',this.modulePath,reqJson,callBackData); -}); - -TableEditAdapter.method('getDataItem', function(row,column,allData) { - var columnData = allData[1]; - var rowData = allData[0]; - var serverData = allData[2]; - - if(column == -1){ - return rowData[row].name; - }else{ - return this.getDataItemByKeyValues(this.rowFieldName, rowData[row].id, this.columnFieldName, columnData[column].id, serverData); - } -}); - -TableEditAdapter.method('getDataItemByKeyValues', function(rowKeyName, rowKeyVal, colKeyName, colKeyVal, data) { - for(var i=0;i
    '; - - //Find current page - var activePage = $('#'+elementId +" .dataTables_paginate .active a").html(); - var start = 0; - if(activePage != undefined && activePage != null){ - start = parseInt(activePage, 10)*15 - 15; - } - - $('#'+elementId).html(html); - - var dataTableParams = { - "oLanguage": { - "sLengthMenu": "_MENU_ records per page" - }, - "aaData": data, - "aoColumns": headers, - "bSort": false, - "iDisplayLength": 15, - "iDisplayStart": start - }; - - - var customTableParams = this.getCustomTableParams(); - - $.extend(dataTableParams, customTableParams); - - $('#'+elementId+' #grid').dataTable( dataTableParams ); - - $(".dataTables_paginate ul").addClass("pagination"); - $(".dataTables_length").hide(); - $(".dataTables_filter input").addClass("form-control"); - $(".dataTables_filter input").attr("placeholder","Search"); - $(".dataTables_filter label").contents().filter(function(){ - return (this.nodeType == 3); - }).remove(); - //$('.tableActionButton').tooltip(); - $('#'+elementId+' #grid').editableTableWidget(); - - $('#'+elementId+' #grid .editcell').on('validate', function(evt, newValue) { - - return modJs.validateCellValue($(this), evt, newValue); - - }); - - this.afterCreateTable(elementId); -}); - -TableEditAdapter.method('afterCreateTable', function(elementId) { - -}); - -TableEditAdapter.method('addCellDataUpdate' , function(colId, rowId, data) { - - this.cellDataUpdates[colId+"="+rowId] = [colId, rowId, data]; -}); - -TableEditAdapter.method('addAdditionalRequestData' , function(type, req) { - return req; -}); - -TableEditAdapter.method('sendCellDataUpdates' , function() { - var req = this.cellDataUpdates; - req.rowTable = this.rowTable; - req.columnTable = this.columnTable; - req.valueTable = this.valueTable; - req = this.addAdditionalRequestData('updateData', req); - var reqJson = JSON.stringify(req); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'updateDataSuccessCallBack'; - callBackData['callBackFail'] = 'updateDataFailCallBack'; - this.showLoader(); - this.customAction('updateData',this.modulePath,reqJson,callBackData); -}); - -TableEditAdapter.method('updateDataSuccessCallBack', function(callBackData,serverData) { - this.hideLoader(); - modJs.cellDataUpdates = {}; - modJs.get(); -}); - -TableEditAdapter.method('updateDataFailCallBack', function(callBackData,serverData) { - this.hideLoader(); -}); - -TableEditAdapter.method('sendAllCellDataUpdates' , function() { - - var req = this.cellDataUpdates; - req.rowTable = this.rowTable; - req.columnTable = this.columnTable; - req.valueTable = this.valueTable; - req = this.addAdditionalRequestData('updateAllData', req); - var reqJson = JSON.stringify(req); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'updateDataAllSuccessCallBack'; - callBackData['callBackFail'] = 'updateDataAllFailCallBack'; - this.showLoader(); - this.customAction('updateAllData',this.modulePath,reqJson,callBackData); -}); - -TableEditAdapter.method('updateDataAllSuccessCallBack', function(callBackData,serverData) { - this.hideLoader(); - modJs.cellDataUpdates = {}; - modJs.getAllData(true); -}); - -TableEditAdapter.method('updateDataAllFailCallBack', function(callBackData,serverData) { - this.hideLoader(); -}); - -TableEditAdapter.method('showActionButtons' , function() { - return false; -}); - - - - - - - -/** - * RequestCache - */ - -function RequestCache() { - -} - -RequestCache.method('getKey', function(url,params) { - var key = url+"|"; - for(index in params){ - key += index+"="+params[index]+"|"; - } - return key; -}); - -RequestCache.method('invalidateTable', function(table) { - - var key; - for (var i = 0; i < localStorage.length; i++){ - key = localStorage.key(i); - if(key.indexOf('t='+table) > 0){ - localStorage.removeItem(key); - } - - } -}); - - -RequestCache.method('getData', function(key) { - var data; - - if (typeof(Storage) == "undefined") { - return null; - } - - var strData = localStorage.getItem(key); - if(strData != undefined && strData != null && strData != ""){ - data = JSON.parse(strData); - if(data == undefined || data == null){ - return null; - } - - if(data.status != undefined && data.status != null && data.status != "SUCCESS"){ - return null; - } - - return data; - } - - return null; -}); - -RequestCache.method('setData', function(key, data) { - - if (typeof(Storage) == "undefined") { - return null; - } - - if(data.status != undefined && data.status != null && data.status != "SUCCESS"){ - return null; - } - - var strData = JSON.stringify(data); - localStorage.setItem(key,strData); - return strData; -}); - - -/** -* ObjectAdapter -*/ - -function ObjectAdapter(endPoint,tab,filter,orderBy){ - this.initAdapter(endPoint,tab,filter,orderBy); - this.container = null; - this.loadMoreButton = null; - this.start = 0; - this.pageSize = 6; - this.currentPage = 1; - this.hasMoreData = true; - this.searchTerm = ""; - this.searchInput = null; -} - -ObjectAdapter.inherits(AdapterBase); - -ObjectAdapter.method('getObjectHTML', function(object) { - var template = this.getCustomTemplate(this.getTemplateName()); - var t = template; - for(index in object){ - t = t.replace(new RegExp('#_'+index+'_#', 'g'), object[index]); - } - return t; - -}); - -ObjectAdapter.method('setPageSize', function(pageSize) { - this.pageSize = pageSize; -}); - -ObjectAdapter.method('addDomEvents', function(object) { - -}); - -ObjectAdapter.method('getTemplateName', function() { - return ''; -}); - -ObjectAdapter.method('renderObject', function(object) { - - var objDom = this.getObjectDom(object.id); - - var html = this.getObjectHTML(object); - var domObj = $(html); - - - if(objDom != undefined && objDom != null){ - objDom.replace(domObj); - }else{ - this.container.append(domObj); - } - - this.addDomEvents(domObj); -}); - -ObjectAdapter.method('setContainer', function(container) { - this.container = container; -}); - -ObjectAdapter.method('setLoadMoreButton', function(loadMoreButton) { - var that = this; - this.loadMoreButton = loadMoreButton; - this.loadMoreButton.off().on('click',function(){ - that.loadMoreButton.attr('disabled','disabled'); - that.loadMore([]); - } - ); -}); - -ObjectAdapter.method('showLoadError', function(msg) { - $("#"+this.getTableName()+"_error").html(msg); - $("#"+this.getTableName()+"_error").show(); -}); - -ObjectAdapter.method('hideLoadError', function() { - $("#"+this.getTableName()+"_error").hide(); -}); - -ObjectAdapter.method('setSearchBox', function(searchInput) { - var that = this; - this.searchInput = searchInput; - this.searchInput.off(); - this.searchInput.keydown(function(event){ - var val = $(this).val(); - if ( event.which == 13 ) { - event.preventDefault(); - that.search([]); - }else if(( event.which == 8 || event.which == 46) && val.length == 1 && that.searchTerm != ''){ - that.search([]); - } - }); -}); - -ObjectAdapter.method('getObjectDom', function(id) { - obj = this.container.find("#obj_"+id); - if(obj.length){ - return obj; - } - return null; -}); - -ObjectAdapter.method('loadMore', function(callBackData) { - if(!this.hasMoreData){ - return; - } - this.currentPage++; - this.get(callBackData, true); -}); - -ObjectAdapter.method('get', function(callBackData, loadMore) { - var that = this; - - this.hideLoadError(); - - if(!loadMore){ - this.currentPage = 1; - if(this.container != null){ - this.container.html(''); - } - this.hasMoreData = true; - this.tableData = []; - } - - this.start = (this.currentPage - 1) * this.pageSize; - - - this.container = $("#"+this.getTableName()).find('.objectList'); - - that.showLoader(); - - - var url = this.getDataUrl(that.getDataMapping()) + - "&iDisplayStart="+this.start+"&iDisplayLength="+this.pageSize+"&objects=1"; - - if(this.searchTerm != "" && this.searchTerm != undefined && this.searchTerm != null){ - url += "&sSearch="+this.searchTerm; - } - - $.post(url, function(data) { - that.getSuccessCallBack(callBackData,data); - },"json").always(function() {that.hideLoader()}); - - that.initFieldMasterData(); - - this.trackEvent("get",this.tab,this.table); -}); - -ObjectAdapter.method('search', function(callBackData) { - var that = this; - this.searchTerm = $("#"+this.getTableName()+"_search").val(); - - this.get(callBackData); - -}); - - -ObjectAdapter.method('getSuccessCallBack', function(callBackData,serverData) { - var data = []; - - if(serverData.length == 0 && this.container.html() == ""){ - this.showLoadError("No Results Found !!!"); - return; - } - - if(this.getFilters() == null){ - $("#"+this.getTableName()+"_filterBtn").hide(); - $("#"+this.getTableName()+"_resetFilters").hide(); - }else{ - $("#"+this.getTableName()+"_filterBtn").show(); - $("#"+this.getTableName()+"_resetFilters").show(); - if(this.currentFilterString != "" && this.currentFilterString != null){ - $("#"+this.getTableName()+"_resetFilters").html(this.currentFilterString+''); - }else{ - $("#"+this.getTableName()+"_resetFilters").html('Reset Filters'); - $("#"+this.getTableName()+"_resetFilters").hide(); - } - } - - $("#"+this.getTableName()).find('.search-controls').show(); - if(serverData.length > this.pageSize){ - this.hasMoreData = true; - serverData.pop(); - this.loadMoreButton.removeAttr('disabled'); - this.loadMoreButton.show(); - }else{ - this.hasMoreData = false; - this.loadMoreButton.hide(); - } - - this.scrollToElementBottom(this.container); - for(var i=0;i
    #_delete_##_edit_##_label_#:#_value_#
    ', - "validation":"none" - }], - [ "display_order", {"label":"Priority","type":"text","validation":"number"}], - [ "display_section", {"label":"Display Section","type":"text","validation":"none"}] - ]; -}); - -CustomFieldAdapter.method('setTableType', function(type) { - this.tableType = type; -}); - -CustomFieldAdapter.method('doCustomValidation', function(params) { - var validateName= function (str) { - var name = /^[a-z][a-z0-9\._]+$/; - return str != null && name.test(str); +import ModuleBase from './ModuleBase'; +import RequestCache from '../api-common/RequestCache'; + +class AdapterBase extends ModuleBase { + constructor(endPoint, tab, filter, orderBy) { + super(); + this.moduleRelativeURL = null; + this.tableData = []; + this.sourceData = []; + this.filter = null; + this.origFilter = null; + this.orderBy = null; + this.currentElement = null; + this.initAdapter(endPoint, tab, filter, orderBy); + } + + initAdapter(endPoint, tab, filter, orderBy) { + this.moduleRelativeURL = baseUrl; + this.table = endPoint; + if (tab === undefined || tab === null) { + this.tab = endPoint; + } else { + this.tab = tab; + } + + if (filter === undefined || filter === null) { + this.filter = null; + } else { + this.filter = filter; + } + + this.origFilter = this.filter; + + if (orderBy === undefined || orderBy === null) { + this.orderBy = null; + } else { + this.orderBy = orderBy; + } + + this.trackEvent('initAdapter', tab); + + this.requestCache = new RequestCache(); + } + + setFilter(filter) { + this.filter = filter; + } + + preSetFilterExternal(filter) { + this.initialFilter = filter; + } + + setFilterExternal(_filter) { + let filter = _filter; + if (filter === undefined || filter === null) { + filter = this.initialFilter; + } + + if (filter === undefined || filter === null) { + return; + } + + this.setFilter(filter); + this.filtersAlreadySet = true; + $(`#${this.getTableName()}_resetFilters`).show(); + this.currentFilterString = this.getFilterString(filter); + } + + getFilter() { + return this.filter; + } + + setOrderBy(orderBy) { + this.orderBy = orderBy; + } + + getOrderBy() { + return this.orderBy; + } + + /** + * @method add + * @param object {Array} object data to be added to database + * @param getFunctionCallBackData {Array} once a success is returned call get() function for this module with these parameters + * @param _callGetFunction {Boolean} if false the get function of the module will not be called (default: true) + * @param successCallback {Function} this will get called after success response + */ + + add(object, getFunctionCallBackData, callGetFunction, successCallback) { + const that = this; + if (callGetFunction === undefined || callGetFunction === null) { + // eslint-disable-next-line no-param-reassign + callGetFunction = true; + } + $(object).attr('a', 'add'); + $(object).attr('t', this.table); + that.showLoader(); + this.requestCache.invalidateTable(this.table); + $.post(this.moduleRelativeURL, object, (data) => { + if (data.status === 'SUCCESS') { + that.addSuccessCallBack(getFunctionCallBackData, data.object, callGetFunction, successCallback, that); + } else { + that.addFailCallBack(getFunctionCallBackData, data.object); + } + }, 'json').always(() => { that.hideLoader(); }); + this.trackEvent('add', this.tab, this.table); + } + + addSuccessCallBack(callBackData, serverData, callGetFunction, successCallback, thisObject) { + if (callGetFunction) { + this.get(callBackData); + } + this.initFieldMasterData(); + if (successCallback !== undefined && successCallback !== null) { + successCallback.apply(thisObject, [serverData]); + } + this.trackEvent('addSuccess', this.tab, this.table); + } + + addFailCallBack(callBackData, serverData) { + try { + this.closePlainMessage(); + } catch (e) { + // No need to report + } + this.showMessage('Error saving', serverData); + this.trackEvent('addFailed', this.tab, this.table); + } + + deleteObj(id, callBackData) { + const that = this; + that.showLoader(); + this.requestCache.invalidateTable(this.table); + $.post(this.moduleRelativeURL, { t: this.table, a: 'delete', id }, (data) => { + if (data.status === 'SUCCESS') { + that.deleteSuccessCallBack(callBackData, data.object); + } else { + that.deleteFailCallBack(callBackData, data.object); + } + }, 'json').always(() => { that.hideLoader(); }); + this.trackEvent('delete', this.tab, this.table); + } + + // eslint-disable-next-line no-unused-vars + deleteSuccessCallBack(callBackData, serverData) { + this.get(callBackData); + this.clearDeleteParams(); + } + + deleteFailCallBack(callBackData, serverData) { + this.clearDeleteParams(); + this.showMessage('Error Occurred while Deleting Item', serverData); + } + + get(callBackData) { + const that = this; + + if (this.getRemoteTable()) { + this.createTableServer(this.getTableName()); + $(`#${this.getTableName()}Form`).hide(); + $(`#${this.getTableName()}`).show(); + return; + } + + let sourceMappingJson = JSON.stringify(this.getSourceMapping()); + + let filterJson = ''; + if (this.getFilter() !== null) { + filterJson = JSON.stringify(this.getFilter()); + } + + let orderBy = ''; + if (this.getOrderBy() !== null) { + orderBy = this.getOrderBy(); + } + + sourceMappingJson = this.fixJSON(sourceMappingJson); + filterJson = this.fixJSON(filterJson); + + that.showLoader(); + $.post(this.moduleRelativeURL, { + t: this.table, a: 'get', sm: sourceMappingJson, ft: filterJson, ob: orderBy, + }, (data) => { + if (data.status === 'SUCCESS') { + that.getSuccessCallBack(callBackData, data.object); + } else { + that.getFailCallBack(callBackData, data.object); + } + }, 'json').always(() => { that.hideLoader(); }); + + that.initFieldMasterData(); + + this.trackEvent('get', this.tab, this.table); + // var url = this.getDataUrl(); + // console.log(url); + } + + + getDataUrl(_columns) { + const sourceMappingJson = JSON.stringify(this.getSourceMapping()); + + const columns = JSON.stringify(_columns); + + let filterJson = ''; + if (this.getFilter() !== null) { + filterJson = JSON.stringify(this.getFilter()); + } + + let orderBy = ''; + if (this.getOrderBy() !== null) { + orderBy = this.getOrderBy(); + } + + let url = this.moduleRelativeURL.replace('service.php', 'data.php'); + url = `${url}?t=${this.table}`; + url = `${url}&sm=${this.fixJSON(sourceMappingJson)}`; + url = `${url}&cl=${this.fixJSON(columns)}`; + url = `${url}&ft=${this.fixJSON(filterJson)}`; + url = `${url}&ob=${orderBy}`; + + if (this.isSubProfileTable()) { + url = `${url}&type=sub`; + } + + if (this.remoteTableSkipProfileRestriction()) { + url = `${url}&skip=1`; + } + + return url; + } + + isSubProfileTable() { + return false; + } + + remoteTableSkipProfileRestriction() { + return false; + } + + preProcessTableData(row) { + return row; + } + + getSuccessCallBack(callBackData, serverData) { + const data = []; + const mapping = this.getDataMapping(); + for (let i = 0; i < serverData.length; i++) { + const row = []; + for (let j = 0; j < mapping.length; j++) { + row[j] = serverData[i][mapping[j]]; + } + data.push(this.preProcessTableData(row)); + } + this.sourceData = serverData; + if (callBackData.callBack !== undefined && callBackData.callBack !== null) { + if (callBackData.callBackData === undefined || callBackData.callBackData === null) { + callBackData.callBackData = []; + } + callBackData.callBackData.push(serverData); + callBackData.callBackData.push(data); + this.callFunction(callBackData.callBack, callBackData.callBackData); + } + + this.tableData = data; + + if (!(callBackData.noRender !== undefined && callBackData.noRender !== null && callBackData.noRender === true)) { + this.createTable(this.getTableName()); + $(`#${this.getTableName()}Form`).hide(); + $(`#${this.getTableName()}`).show(); + } + } + + // eslint-disable-next-line no-unused-vars + getFailCallBack(callBackData, serverData) { + + } + + + getElement(id, callBackData, clone) { + const that = this; + let sourceMappingJson = JSON.stringify(this.getSourceMapping()); + sourceMappingJson = this.fixJSON(sourceMappingJson); + that.showLoader(); + $.post(this.moduleRelativeURL, { + t: this.table, a: 'getElement', id, sm: sourceMappingJson, + }, function (data) { + if (data.status === 'SUCCESS') { + if (clone) { + delete data.object.id; + } + this.currentElement = data.object; + that.getElementSuccessCallBack.apply(that, [callBackData, data.object]); + } else { + that.getElementFailCallBack.apply(that, [callBackData, data.object]); + } + }, 'json').always(() => { that.hideLoader(); }); + this.trackEvent('getElement', this.tab, this.table); + } + + getElementSuccessCallBack(callBackData, serverData) { + if (callBackData.callBack !== undefined && callBackData.callBack !== null) { + if (callBackData.callBackData === undefined || callBackData.callBackData === null) { + callBackData.callBackData = []; + } + callBackData.callBackData.push(serverData); + this.callFunction(callBackData.callBack, callBackData.callBackData, this); + } + this.currentElement = serverData; + if (!(callBackData.noRender !== undefined && callBackData.noRender !== null && callBackData.noRender === true)) { + this.renderForm(serverData); + } + } + + // eslint-disable-next-line no-unused-vars + getElementFailCallBack(callBackData, serverData) { + + } + + + getTableData() { + return this.tableData; + } + + getTableName() { + return this.tab; + } + + getFieldValues(fieldMaster, callBackData) { + const that = this; + let method = ''; + let methodParams = ''; + if (fieldMaster[3] !== undefined && fieldMaster[3] !== null) { + // eslint-disable-next-line prefer-destructuring + method = fieldMaster[3]; + } + + if (fieldMaster[4] !== undefined && fieldMaster[4] !== null) { + methodParams = JSON.stringify(fieldMaster[4]); + } + + const key = this.requestCache.getKey(this.moduleRelativeURL, { + t: fieldMaster[0], key: fieldMaster[1], value: fieldMaster[2], method, methodParams, a: 'getFieldValues', + }); + const cacheData = this.requestCache.getData(key); + + if (cacheData !== null && cacheData !== undefined) { + if (cacheData.status === 'SUCCESS') { + callBackData.callBackData.push(cacheData.data); + if (callBackData.callBackSuccess !== null && callBackData.callBackSuccess !== undefined) { + callBackData.callBackData.push(callBackData.callBackSuccess); + } + that.callFunction(callBackData.callBack, callBackData.callBackData); + } + } + + const callbackWraper = function (data) { + if (data.status === 'SUCCESS') { + that.requestCache.setData(this.success.key, data); + const localCallBackData = callBackData; + localCallBackData.callBackData = [callBackData.callBackData[0]]; + localCallBackData.callBackData.push(data.data); + if (localCallBackData.callBackSuccess !== null && localCallBackData.callBackSuccess !== undefined) { + localCallBackData.callBackData.push(callBackData.callBackSuccess); + } + that.callFunction(localCallBackData.callBack, localCallBackData.callBackData); + } else if (data.message === 'Access violation') { + alert(`Error : ${callbackWraper.table} ${data.message}`); + } }; - if(!validateName(params.name)){ - return "Invalid name for custom field"; + callbackWraper.key = key; + // eslint-disable-next-line prefer-destructuring + callbackWraper.table = fieldMaster[0]; + + $.post(this.moduleRelativeURL, { + t: fieldMaster[0], key: fieldMaster[1], value: fieldMaster[2], method, methodParams, a: 'getFieldValues', + }, callbackWraper, 'json'); + } + + setAdminProfile(empId) { + try { + localStorage.clear(); + } catch (e) { + // No need to report } + $.post(this.moduleRelativeURL, { a: 'setAdminEmp', empid: empId }, () => { + // eslint-disable-next-line no-restricted-globals + top.location.href = clientUrl; + }, 'json'); + } - - return null; -}); - -CustomFieldAdapter.method('forceInjectValuesBeforeSave', function(params) { - - - //Build data field - var data = [params.name], options = [], optionsData; - data.push({}); - data[1]['label'] = params.field_label; - data[1]['type'] = params.field_type; - data[1]['validation'] = params.field_validation; - if(["select","select2","select2multi"].indexOf(params.field_type) >= 0){ - optionsData = JSON.parse(params.field_options); - for(index in optionsData){ - options.push([optionsData[index].value, optionsData[index].label]); + customAction(subAction, module, request, callBackData, isPost) { + const that = this; + request = this.fixJSON(request); + if (!isPost) { + $.getJSON(this.moduleRelativeURL, { + t: this.table, a: 'ca', sa: subAction, mod: module, req: request, + }, (data) => { + if (data.status === 'SUCCESS') { + callBackData.callBackData.push(data.data); + that.callFunction(callBackData.callBackSuccess, callBackData.callBackData); + } else { + callBackData.callBackData.push(data.data); + that.callFunction(callBackData.callBackFail, callBackData.callBackData); } - data[1]['source'] = options; + }); + } else { + $.post(this.moduleRelativeURL, { + t: this.table, a: 'ca', sa: subAction, mod: module, req: request, + }, (data) => { + if (data.status === 'SUCCESS') { + callBackData.callBackData.push(data.data); + that.callFunction(callBackData.callBackSuccess, callBackData.callBackData); + } else { + callBackData.callBackData.push(data.data); + that.callFunction(callBackData.callBackFail, callBackData.callBackData); + } + }, 'json'); } - if(params.field_validation == null || params.field_validation == undefined){ - params.field_validation = ""; - } - params.data = JSON.stringify(data); - params.type = this.tableType; - return params; -}); + } + + sendCustomRequest(action, params, successCallback, failCallback) { + params.a = action; + $.post(this.moduleRelativeURL, params, (data) => { + if (data.status === 'SUCCESS') { + successCallback(data.data); + } else { + failCallback(data.data); + } + }, 'json'); + } + + + getCustomActionUrl(action, params) { + params.a = action; + let str = ''; + for (const key in params) { + if (params.hasOwnProperty(key)) { + if (str !== '') { + str += '&'; + } + str += `${key}=${params[key]}`; + } + } + return `${this.moduleRelativeURL}?${str}`; + } + + + getClientDataUrl() { + return `${this.moduleRelativeURL.replace('service.php', '')}data/`; + } + + getCustomUrl(str) { + return this.moduleRelativeURL.replace('service.php', str); + } +} + +export default AdapterBase; diff --git a/web/api/AesCrypt.js b/web/api/AesCrypt.js deleted file mode 100644 index d5204009..00000000 --- a/web/api/AesCrypt.js +++ /dev/null @@ -1,503 +0,0 @@ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* AES implementation in JavaScript (c) Chris Veness 2005-2014 / MIT Licence */ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -/* jshint node:true *//* global define */ -'use strict'; - - -/** - * AES (Rijndael cipher) encryption routines, - * - * Reference implementation of FIPS-197 http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf. - * - * @namespace - */ -var Aes = {}; - - -/** - * AES Cipher function: encrypt 'input' state with Rijndael algorithm [§5.1]; - * applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage. - * - * @param {number[]} input - 16-byte (128-bit) input state array. - * @param {number[][]} w - Key schedule as 2D byte-array (Nr+1 x Nb bytes). - * @returns {number[]} Encrypted output state array. - */ -Aes.cipher = function(input, w) { - var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) - var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys - - var state = [[],[],[],[]]; // initialise 4xNb byte-array 'state' with input [§3.4] - for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i]; - - state = Aes.addRoundKey(state, w, 0, Nb); - - for (var round=1; round 6 && i%Nk == 4) { - temp = Aes.subWord(temp); - } - // xor w[i] with w[i-1] and w[i-Nk] - for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t]; - } - - return w; -}; - - -/** - * Apply SBox to state S [§5.1.1] - * @private - */ -Aes.subBytes = function(s, Nb) { - for (var r=0; r<4; r++) { - for (var c=0; c>> i*8) & 0xff; - for (var i=0; i<2; i++) counterBlock[i+2] = (nonceRnd >>> i*8) & 0xff; - for (var i=0; i<4; i++) counterBlock[i+4] = (nonceSec >>> i*8) & 0xff; - - // and convert it to a string to go on the front of the ciphertext - var ctrTxt = ''; - for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]); - - // generate key schedule - an expansion of the key into distinct Key Rounds for each round - var keySchedule = Aes.keyExpansion(key); - - var blockCount = Math.ceil(plaintext.length/blockSize); - var ciphertxt = new Array(blockCount); // ciphertext as array of strings - - for (var b=0; b>> c*8) & 0xff; - for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8); - - var cipherCntr = Aes.cipher(counterBlock, keySchedule); // -- encrypt counter block -- - - // block size is reduced on final block - var blockLength = b>> c*8) & 0xff; - for (var c=0; c<4; c++) counterBlock[15-c-4] = (((b+1)/0x100000000-1) >>> c*8) & 0xff; - - var cipherCntr = Aes.cipher(counterBlock, keySchedule); // encrypt counter block - - var plaintxtByte = new Array(ciphertext[b].length); - for (var i=0; i. - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - - - -/** - * The base class for providing core functions to all module classes. - * @class Base.js - */ -function IceHRMBase() { - this.deleteParams = {}; - this.createRemoteTable = false; - this.instanceId = "None"; - this.ga = []; - this.showEdit = true; - this.showDelete = true; - this.showSave = true; - this.showCancel = true; - this.showFormOnPopup = false; - this.filtersAlreadySet = false; - this.currentFilterString = ""; - this.sorting = 0; - this.settings = {}; - this.translations = {}; - this.customFields = []; - this.csrfRequired = false; -} - -this.fieldTemplates = null; -this.templates = null; -this.customTemplates = null; -this.emailTemplates = null; -this.fieldMasterData = null; -this.fieldMasterDataKeys = null; -this.fieldMasterDataCallback = null; -this.sourceMapping = null; -this.currentId = null; -this.currentElement = null; -this.user = null; -this.currentProfile = null; -this.permissions = {}; - - - -this.baseUrl = null; - -IceHRMBase.method('init' , function(appName, currentView, dataUrl, permissions) { - -}); - -/** - * Some browsers do not support sending JSON in get parameters. Set this to true to avoid sending JSON - * @method setNoJSONRequests - * @param val {Boolean} - */ -IceHRMBase.method('setNoJSONRequests' , function(val) { - this.noJSONRequests = val; -}); - - -IceHRMBase.method('setPermissions' , function(permissions) { - this.permissions = permissions; -}); - -IceHRMBase.method('sortingStarted' , function(val) { - this.sorting = val; -}); - -/** - * Check if the current user has a permission - * @method checkPermission - * @param permission {String} - * @example - * this.checkPermission("Upload/Delete Profile Image") - */ -IceHRMBase.method('checkPermission' , function(permission) { - if(this.permissions[permission] == undefined || this.permissions[permission] == null || this.permissions[permission] == "Yes"){ - return "Yes"; - }else{ - return this.permissions[permission]; - } -}); - -IceHRMBase.method('setBaseUrl' , function(url) { - this.baseUrl = url; -}); - -IceHRMBase.method('setUser' , function(user) { - this.user = user; -}); - -IceHRMBase.method('getUser' , function() { - return this.user; -}); - -IceHRMBase.method('setInstanceId' , function(id) { - this.instanceId = id; -}); - -IceHRMBase.method('setCSRFRequired' , function(val) { - this.csrfRequired = val; -}); - -IceHRMBase.method('setGoogleAnalytics' , function(ga) { - this.ga = ga; -}); - -IceHRMBase.method('scrollToTop' , function() { - $("html, body").animate({ scrollTop: 0 }, "fast"); -}); - -IceHRMBase.method('scrollToBottom' , function() { - $("html, body").animate({ scrollTop: $(document).height() }, "slow"); -}); - -IceHRMBase.method('scrollToElement' , function(element) { - if($(window).height() <= element.offset().top){ - $("html, body").animate({ scrollTop: element.offset().top }, "slow"); - } - -}); - -IceHRMBase.method('scrollToElementBottom' , function(element) { - if($(window).height() <= element.offset().top + element.height()){ - $("html, body").animate({ scrollTop: element.offset().top + element.height() }, "slow"); - } - -}); - - -IceHRMBase.method('setTranslations' , function(txt) { - this.translations = txt['messages']['']; -}); - -IceHRMBase.method('setTranslationsSubModules' , function(translations) { - this.translations = translations; -}); - -IceHRMBase.method('gt' , function(key) { - if(this.translations[key] === undefined || this.translations[key] === null){ - return key; - } - return this.translations[key][0]; -}); - -IceHRMBase.method('addToLangTerms' , function(key) { - var termsArr; - var terms = localStorage.getItem("terms"); - if(terms == undefined){ - termsArr = {}; - }else{ - try{ - termsArr = JSON.parse(terms); - }catch(e){ - termsArr = {}; - } - - } - - if(this.translations[key] == undefined){ - termsArr[key] = key; - localStorage.setItem("terms", JSON.stringify(termsArr)); - } -}); - -/** - * If this method returned false the action buttons in data table for modules will not be displayed. - * Override this method in module lib.js to hide action buttons - * @method showActionButtons - * @param permission {String} - * @example - * EmployeeLeaveEntitlementAdapter.method('showActionButtons' , function() { - * return false; - * }); - */ -IceHRMBase.method('showActionButtons' , function() { - return true; -}); - -IceHRMBase.method('trackEvent' , function(action, label, value) { - try{ - if(label == undefined || label == null){ - this.ga.push(['_trackEvent', this.instanceId, action]); - }else if(value == undefined || value == null){ - this.ga.push(['_trackEvent', this.instanceId, action, label]); - }else{ - this.ga.push(['_trackEvent', this.instanceId, action, label, value]); - } - }catch(e){ - - } - - -}); - - -IceHRMBase.method('setCurrentProfile' , function(currentProfile) { - this.currentProfile = currentProfile; -}); - -/** - * Get the current profile - * @method getCurrentProfile - * @returns Profile of the current user if the profile is not switched if not switched profile - */ - -IceHRMBase.method('getCurrentProfile' , function() { - return this.currentProfile; -}); - -/** - * Retrive data required to create select boxes for add new /edit forms for a given module. This is called when loading the module - * @method initFieldMasterData - * @param callback {Function} call this once loading completed - * @param callback {Function} call this once all field loading completed. This indicate that the form can be displayed saftly - * @example - * ReportAdapter.method('renderForm', function(object) { - * var that = this; - * this.processFormFieldsWithObject(object); - * var cb = function(){ - * that.uber('renderForm',object); - * }; - * this.initFieldMasterData(cb); - * }); - */ -IceHRMBase.method('initFieldMasterData' , function(callback, loadAllCallback, loadAllCallbackData) { - var values; - if(this.showAddNew == undefined || this.showAddNew == null){ - this.showAddNew = true; - } - this.fieldMasterData = {}; - this.fieldMasterDataKeys = {}; - this.fieldMasterDataCallback = loadAllCallback; - this.fieldMasterDataCallbackData = loadAllCallbackData; - this.sourceMapping = {}; - var fields = this.getFormFields(); - var filterFields = this.getFilters(); - - if(filterFields != null){ - for(var j=0;j'; - } - - if(this.getFilters() != null){ - if(html != ""){ - html += "  "; - } - html+=''; - html += "  "; - if(this.filtersAlreadySet){ - html+=''; - }else{ - html+=''; - } - - } - - html = html.replace(/__id__/g, this.getTableName()); - - if(this.currentFilterString != "" && this.currentFilterString != null){ - html = html.replace(/__filterString__/g, this.currentFilterString); - }else{ - html = html.replace(/__filterString__/g, 'Reset Filters'); - } - - if(html != ""){ - html = '
    '+html+'
    '; - } - - return html; -}); - - -IceHRMBase.method('getActionButtonHeader', function() { - return { "sTitle": "", "sClass": "center" }; -}); - -IceHRMBase.method('getTableHTMLTemplate', function() { - return '
    '; -}); - -IceHRMBase.method('isSortable', function() { - return true; -}); - -/** - * Create the data table on provided element id - * @method createTable - * @param val {Boolean} - */ - -IceHRMBase.method('createTable', function(elementId) { - - - var that = this; - - if(this.getRemoteTable()){ - this.createTableServer(elementId); - return; - } - - - var headers = this.getHeaders(); - - //add translations - for(index in headers){ - headers[index].sTitle = this.gt(headers[index].sTitle); - } - - var data = this.getTableData(); - - if(this.showActionButtons()){ - headers.push(this.getActionButtonHeader()); - } - - - if(this.showActionButtons()){ - for(var i=0;i
    '; - }else{ - html = '
    '; - } - */ - //Find current page - var activePage = $('#'+elementId +" .dataTables_paginate .active a").html(); - var start = 0; - if(activePage != undefined && activePage != null){ - start = parseInt(activePage, 10)*15 - 15; - } - - $('#'+elementId).html(html); - - var dataTableParams = { - "oLanguage": { - "sLengthMenu": "_MENU_ records per page" - }, - "aaData": data, - "aoColumns": headers, - "bSort": that.isSortable(), - "iDisplayLength": 15, - "iDisplayStart": start - }; - - - var customTableParams = this.getCustomTableParams(); - - $.extend(dataTableParams, customTableParams); - - $('#'+elementId+' #grid').dataTable( dataTableParams ); - - $(".dataTables_paginate ul").addClass("pagination"); - $(".dataTables_length").hide(); - $(".dataTables_filter input").addClass("form-control"); - $(".dataTables_filter input").attr("placeholder","Search"); - $(".dataTables_filter label").contents().filter(function(){ - return (this.nodeType == 3); - }).remove(); - $('.tableActionButton').tooltip(); -}); - -/** - * Create a data table on provided element id which loads data page by page - * @method createTableServer - * @param val {Boolean} - */ - -IceHRMBase.method('createTableServer', function(elementId) { - var that = this; - var headers = this.getHeaders(); - - headers.push({ "sTitle": "", "sClass": "center" }); - - //add translations - for(index in headers){ - headers[index].sTitle = this.gt(headers[index].sTitle); - } - - var html = ""; - html = this.getTableTopButtonHtml() + this.getTableHTMLTemplate(); - /* - if(this.getShowAddNew()){ - html = this.getTableTopButtonHtml()+'
    '; - }else{ - html = '
    '; - } - */ - - //Find current page - var activePage = $('#'+elementId +" .dataTables_paginate .active a").html(); - var start = 0; - if(activePage != undefined && activePage != null){ - start = parseInt(activePage, 10)*15 - 15; - } - - - $('#'+elementId).html(html); - - var dataTableParams = { - "oLanguage": { - "sLengthMenu": "_MENU_ records per page" - }, - "bProcessing": true, - "bServerSide": true, - "sAjaxSource": that.getDataUrl(that.getDataMapping()), - "aoColumns": headers, - "bSort": that.isSortable(), - "parent":that, - "iDisplayLength": 15, - "iDisplayStart": start - }; - - if(this.showActionButtons()){ - dataTableParams["aoColumnDefs"] = [ - { - "fnRender": that.getActionButtons, - "aTargets": [that.getDataMapping().length] - } - ]; - } - - var customTableParams = this.getCustomTableParams(); - - $.extend(dataTableParams, customTableParams); - - $('#'+elementId+' #grid').dataTable( dataTableParams ); - - $(".dataTables_paginate ul").addClass("pagination"); - $(".dataTables_length").hide(); - $(".dataTables_filter input").addClass("form-control"); - $(".dataTables_filter input").attr("placeholder","Search"); - $(".dataTables_filter label").contents().filter(function(){ - return (this.nodeType == 3); - }).remove(); - - $('.tableActionButton').tooltip(); - -}); - -/** - * This should be overridden in module lib.js classes to return module headers which are used to create the data table. - * @method getHeaders - * @example - SettingAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Value"}, - { "sTitle": "Details"} - ]; - }); - */ -IceHRMBase.method('getHeaders', function() { - -}); - - -/** - * This should be overridden in module lib.js classes to return module field values which are used to create the data table. - * @method getDataMapping - * @example - SettingAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "value", - "description" - ]; - }); - */ - -IceHRMBase.method('getDataMapping', function() { - -}); - -/** - * This should be overridden in module lib.js classes to return module from fields which are used to create the add/edit form and also used for initializing select box values in form. - * @method getFormFields - * @example - SettingAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "value", {"label":"Value","type":"text","validation":"none"}] - ]; - }); - */ -IceHRMBase.method('getFormFields', function() { - -}); - -IceHRMBase.method('getTableData', function() { - -}); - -/** - * This can be overridden in module lib.js classes inorder to show a filter form - * @method getFilters - * @example - EmployeeAdapter.method('getFilters', function() { - return [ - [ "job_title", {"label":"Job Title","type":"select2","allow-null":true,"null-label":"All Job Titles","remote-source":["JobTitle","id","name"]}], - [ "department", {"label":"Department","type":"select2","allow-null":true,"null-label":"All Departments","remote-source":["CompanyStructure","id","title"]}], - [ "supervisor", {"label":"Supervisor","type":"select2","allow-null":true,"null-label":"Anyone","remote-source":["Employee","id","first_name+last_name"]}] - ]; - }); - */ -IceHRMBase.method('getFilters', function() { - return null; -}); - -/** - * Show the edit form for an item - * @method edit - * @param id {int} id of the item to edit - */ -IceHRMBase.method('edit', function(id) { - this.currentId = id; - this.getElement(id,[]); -}); - -IceHRMBase.method('copyRow', function(id) { - this.getElement(id,[],true); -}); - -IceHRMBase.method('renderModel', function(id,header,body) { - $('#'+id+'ModelBody').html(""); - - if(body == undefined || body == null){ - body = ""; - } - - $('#'+id+'ModelLabel').html(header); - $('#'+id+'ModelBody').html(body); -}); - - -IceHRMBase.method('renderYesNoModel', function(header,body,yesBtnName,noBtnName,callback, callbackParams) { - var that = this; - var modelId = "#yesnoModel"; - - if(body == undefined || body == null){ - body = ""; - } - - $(modelId+'Label').html(header); - $(modelId+'Body').html(body); - if(yesBtnName != null){ - $(modelId+'YesBtn').html(yesBtnName); - } - if(noBtnName != null){ - $(modelId+'NoBtn').html(noBtnName); - } - - $(modelId+'YesBtn').off().on('click',function(){ - if(callback != undefined && callback != null){ - callback.apply(that,callbackParams); - that.cancelYesno(); - } - }); - - $(modelId).modal({ - backdrop: 'static' - }); - - -}); - -IceHRMBase.method('renderModelFromDom', function(id,header,element) { - $('#'+id+'ModelBody').html(""); - - if(element == undefined || element == null){ - element = $("
    "); - } - - $('#'+id+'ModelLabel').html(header); - $('#'+id+'ModelBody').html(""); - $('#'+id+'ModelBody').append(element); -}); - -/** - * Delete an item - * @method deleteRow - * @param id {int} id of the item to edit - */ - -IceHRMBase.method('deleteRow', function(id) { - this.deleteParams['id'] = id; - this.renderModel('delete',"Confirm Deletion","Are you sure you want to delete this item ?"); - $('#deleteModel').modal('show'); - -}); - -/** - * Show a popup with message - * @method showMessage - * @param title {String} title of the message box - * @param message {String} message - * @param closeCallback {Function} this will be called once the dialog is closed (optional) - * @param closeCallback {Function} data to pass to close callback (optional) - * @param isPlain {Boolean} if true buttons are not shown (optional / default = true) - * @example - * this.showMessage("Error Occured while Applying Leave", callBackData); - */ -IceHRMBase.method('showMessage', function(title,message,closeCallback,closeCallbackData, isPlain) { - var that = this; - var modelId = ""; - if(isPlain){ - modelId = "#plainMessageModel"; - }else{ - modelId = "#messageModel"; - } - - $(modelId).off(); - - if(isPlain){ - this.renderModel('plainMessage',title,message); - }else{ - this.renderModel('message',title,message); - } - - if(closeCallback !== null && closeCallback !== undefined){ - $(modelId).modal({show:true}); - $(modelId).on('hidden.bs.modal',function(){ - closeCallback.apply(that,closeCallbackData); - $('.modal-backdrop').remove(); - }); - } else { - $(modelId).modal({ - backdrop: 'static' - }); - } -}); - -IceHRMBase.method('showDomElement', function(title,element,closeCallback,closeCallbackData, isPlain) { - var that = this; - var modelId = ""; - if (isPlain) { - modelId = "#dataMessageModel"; - } else{ - modelId = "#messageModel"; - } - - $(modelId).unbind('hide'); - - if(isPlain){ - this.renderModelFromDom('dataMessage',title,element); - }else{ - this.renderModelFromDom('message',title,element); - } - - - if(closeCallback !== null && closeCallback !== undefined){ - $(modelId).modal({show:true}); - $(modelId).on('hidden.bs.modal',function(){ - closeCallback.apply(that,closeCallbackData); - $('.modal-backdrop').remove(); - }); - } else { - $(modelId).modal({ - backdrop: 'static' - }); - } -}); - -IceHRMBase.method('confirmDelete', function() { - if(this.deleteParams['id'] != undefined || this.deleteParams['id'] != null){ - this.deleteObj(this.deleteParams['id'],[]); - } - $('#deleteModel').modal('hide'); -}); - -IceHRMBase.method('cancelDelete', function() { - $('#deleteModel').modal('hide'); - this.deleteParams['id'] = null; -}); - -IceHRMBase.method('closeMessage', function() { - $('#messageModel').modal('hide'); -}); - -IceHRMBase.method('cancelYesno', function() { - $('#yesnoModel').modal('hide'); -}); - -IceHRMBase.method('closePlainMessage', function() { - $('#plainMessageModel').modal('hide'); - $('#dataMessageModel').modal('hide'); -}); - -IceHRMBase.method('closeDataMessage', function() { - $('#dataMessageModel').modal('hide'); -}); - - -/** - * Create or edit an element - * @method save - * @param getFunctionCallBackData {Array} once a success is returned call get() function for this module with these parameters - * @param successCallback {Function} this will get called after success response - */ - -IceHRMBase.method('save', function(callGetFunction, successCallback) { - var validator = new FormValidation(this.getTableName()+"_submit",true,{'ShowPopup':false,"LabelErrorClass":"error"}); - if(validator.checkValues()){ - var params = validator.getFormParameters(); - params = this.forceInjectValuesBeforeSave(params); - var msg = this.doCustomValidation(params); - if(msg == null){ - if (this.csrfRequired) { - params['csrf'] = $('#'+this.getTableName()+'Form').data('csrf'); - } - var id = $('#'+this.getTableName()+"_submit #id").val(); - if(id != null && id != undefined && id != ""){ - params['id'] = id; - } - params = this.makeEmptyDateFieldsNull(params); - this.add(params,[],callGetFunction, successCallback); - }else{ - $("#"+this.getTableName()+'Form .label').html(msg); - $("#"+this.getTableName()+'Form .label').show(); - this.scrollToTop(); - } - - } -}); - - -IceHRMBase.method('makeEmptyDateFieldsNull', function(params) { - var fields = this.getFormFields(); - fields.forEach(function(field) { - if((field[1].type == 'date' || field[1].type == 'datetime') - && (params[field[0]] === '' || params[field[0]] === '0000-00-00' || params[field[0]] === '0000-00-00 00:00:00')){ - delete params[field[0]]; - } - }); - return params; -}); - -/** - * Override this method to inject attitional parameters or modify existing parameters retrived from add/edit form before sending to the server - * @method forceInjectValuesBeforeSave - * @param params {Array} keys and values in form - * @returns {Array} modified parameters - */ -IceHRMBase.method('forceInjectValuesBeforeSave', function(params) { - return params; -}); - -/** - * Override this method to do custom validations at client side - * @method doCustomValidation - * @param params {Array} keys and values in form - * @returns {Null or String} return null if validation success, returns error message if unsuccessful - * @example - EmployeeLeaveAdapter.method('doCustomValidation', function(params) { - try{ - if(params['date_start'] != params['date_end']){ - var ds = new Date(params['date_start']); - var de = new Date(params['date_end']); - if(de < ds){ - return "Start date should be earlier than end date of the leave period"; - } - } - }catch(e){ - - } - return null; -}); - */ -IceHRMBase.method('doCustomValidation', function(params) { - return null; -}); - -IceHRMBase.method('filterQuery', function() { - - var validator = new FormValidation(this.getTableName()+"_filter",true,{'ShowPopup':false,"LabelErrorClass":"error"}); - if(validator.checkValues()){ - var params = validator.getFormParameters(); - if(this.doCustomFilterValidation(params)){ - - //remove null params - for (var prop in params) { - if(params.hasOwnProperty(prop)){ - if(params[prop] == "NULL"){ - delete(params[prop]); - } - } - } - - this.setFilter(params); - this.filtersAlreadySet = true; - $("#"+this.getTableName()+"_resetFilters").show(); - this.currentFilterString = this.getFilterString(params); - - this.get([]); - this.closePlainMessage(); - } - - } -}); - - -IceHRMBase.method('getFilterString', function(filters) { - - var str = ''; - var rmf, source, values, select2MVal, value, valueOrig; - - var filterFields = this.getFilters(); - - - if(values == null){ - values = []; - } - - for (var prop in filters) { - if(filters.hasOwnProperty(prop)){ - values = this.getMetaFieldValues(prop,filterFields); - value = ""; - valueOrig = null; - - if((values['type'] == 'select' || values['type'] == 'select2')){ - - if(values['remote-source']!= undefined && values['remote-source']!= null){ - rmf = values['remote-source']; - if(filters[prop] == "NULL"){ - if(values['null-label'] != undefined && values['null-label'] != null){ - value = values['null-label']; - }else{ - value = "Not Selected"; - } - }else{ - value = this.fieldMasterData[rmf[0]+"_"+rmf[1]+"_"+rmf[2]][filters[prop]]; - valueOrig = value; - } - - - }else{ - source = values['source'][0]; - if(filters[prop] == "NULL"){ - if(values['null-label'] != undefined && values['null-label'] != null){ - value = values['null-label']; - }else{ - value = "Not Selected"; - } - }else{ - for(var i=0; i
    '); - $tempDomObj.attr('id',randomFormId); - - $tempDomObj.html(formHtml); - - - $tempDomObj.find('.datefield').datepicker({'viewMode':2}); - $tempDomObj.find('.timefield').datetimepicker({ - language: 'en', - pickDate: false - }); - $tempDomObj.find('.datetimefield').datetimepicker({ - language: 'en' - }); - - $tempDomObj.find('.colorpick').colorpicker(); - tinymce.init({ - selector: '#'+$tempDomObj.attr('id')+' .tinymce', - height: "400" - }); - - $tempDomObj.find('.simplemde').each(function() { - var simplemde = new SimpleMDE({ element: $(this)[0] }); - $(this).data('simplemde', simplemde); - //simplemde.value($(this).val()); - }); - - //$tempDomObj.find('.select2Field').select2(); - $tempDomObj.find('.select2Field').each(function() { - $(this).select2().select2('val', $(this).find("option:eq(0)").val()); - }); - - $tempDomObj.find('.select2Multi').each(function() { - $(this).select2().on("change",function(e){ - var parentRow = $(this).parents(".row"); - var height = parentRow.find(".select2-choices").height(); - parentRow.height(parseInt(height)); - }); - }); - - /* - $tempDomObj.find('.signatureField').each(function() { - $(this).data('signaturePad',new SignaturePad($(this))); - }); - */ - - //var tHtml = $tempDomObj.wrap('
    ').parent().html(); - this.showDomElement("Edit",$tempDomObj,null,null,true); - $(".filterBtn").off(); - $(".filterBtn").on('click',function(e) { - e.preventDefault(); - e.stopPropagation(); - try{ - modJs.filterQuery(); - - }catch(e){ - }; - return false; - }); - - if (this.filter != undefined && this.filter != null && this.filter != '') { - this.fillForm(this.filter,"#"+this.getTableName()+"_filter", this.getFilters()); - } - -}); - - -/** - * Override this method in your module class to make changes to data fo the form before showing the form - * @method preRenderForm - * @param object {Array} keys value list for populating form - */ - -IceHRMBase.method('preRenderForm', function(object) { - -}); - -/** - * Create the form - * @method renderForm - * @param object {Array} keys value list for populating form - */ - -IceHRMBase.method('renderForm', function(object) { - - var that = this; - var signatureIds = []; - if(object == null || object == undefined){ - this.currentId = null; - } - - this.preRenderForm(object); - - var formHtml = this.templates['formTemplate']; - var html = ""; - var fields = this.getFormFields(); - - for(var i=0;i
    '); - $tempDomObj.attr('id',randomFormId); - - } - - $tempDomObj.html(formHtml); - - - $tempDomObj.find('.datefield').datepicker({'viewMode':2}); - $tempDomObj.find('.timefield').datetimepicker({ - language: 'en', - pickDate: false - }); - $tempDomObj.find('.datetimefield').datetimepicker({ - language: 'en' - }); - - $tempDomObj.find('.colorpick').colorpicker(); - - tinymce.init({ - selector: '#'+$tempDomObj.attr('id')+' .tinymce', - height: "400" - }); - - $tempDomObj.find('.simplemde').each(function() { - var simplemde = new SimpleMDE({ element: $(this)[0] }); - $(this).data('simplemde', simplemde); - //simplemde.value($(this).val()); - }); - - //$tempDomObj.find('.select2Field').select2(); - $tempDomObj.find('.select2Field').each(function() { - $(this).select2().select2('val', $(this).find("option:eq(0)").val()); - - }); - - $tempDomObj.find('.select2Multi').each(function() { - $(this).select2().on("change",function(e){ - var parentRow = $(this).parents(".row"); - var height = parentRow.find(".select2-choices").height(); - parentRow.height(parseInt(height)); - }); - - }); - - - $tempDomObj.find('.signatureField').each(function() { - //$(this).data('signaturePad',new SignaturePad($(this))); - signatureIds.push($(this).attr('id')); - }); - - for(var i=0;i').parent().html(); - //this.showMessage("Edit",tHtml,null,null,true); - this.showMessage("Edit","",null,null,true); - - $("#plainMessageModel .modal-body").html(""); - $("#plainMessageModel .modal-body").append($tempDomObj); - - - for(var i=0;i
  • '; - editButton = '
  • '; - - template = field[1]['html']; - - if(data != null && data != undefined && field[1]['sort-function'] != undefined && field[1]['sort-function'] != null){ - data.sort(field[1]['sort-function']); - } - - - html = $('
    '); - - - - for(i=0;i'); - } - t = t.replace('#_'+key+'_#', itemVal); - } - - if(field[1]['render'] != undefined && field[1]['render'] != null){ - t = t.replace('#_renderFunction_#', field[1]['render'](item)); - } - - itemHtml = $(t); - itemHtml.attr('fieldId',field[0]+"_div"); - html.append(itemHtml); - } - - - - return html; -}); - -/** - * Reset the DataGroup for a given field - * @method resetDataGroup - * @param field {Array} field meta data - */ -IceHRMBase.method('resetDataGroup', function(field) { - $("#"+field[0]).val(""); - $("#"+field[0]+"_div").html(""); -}); - -IceHRMBase.method('showDataGroup', function(field, object) { - var formHtml = this.templates['datagroupTemplate']; - var html = ""; - var fields = field[1]['form']; - - if(object != undefined && object != null && object.id != undefined){ - this.currentDataGroupItemId = object.id; - }else{ - this.currentDataGroupItemId = null; - } - - for(var i=0;i
    '); - $tempDomObj.attr('id',randomFormId); - - $tempDomObj.html(formHtml); - - - $tempDomObj.find('.datefield').datepicker({'viewMode':2}); - $tempDomObj.find('.timefield').datetimepicker({ - language: 'en', - pickDate: false - }); - $tempDomObj.find('.datetimefield').datetimepicker({ - language: 'en' - }); - - $tempDomObj.find('.colorpick').colorpicker(); - - tinymce.init({ - selector: '#'+$tempDomObj.attr('id')+' .tinymce', - height: "400" - }); - - $tempDomObj.find('.simplemde').each(function() { - var simplemde = new SimpleMDE({ element: $(this)[0] }); - $(this).data('simplemde', simplemde); - //simplemde.value($(this).val()); - }); - - $tempDomObj.find('.select2Field').each(function() { - $(this).select2().select2('val', $(this).find("option:eq(0)").val()); - }); - - - $tempDomObj.find('.select2Multi').each(function() { - $(this).select2().on("change",function(e){ - var parentRow = $(this).parents(".row"); - var height = parentRow.find(".select2-choices").height(); - parentRow.height(parseInt(height)); - }); - }); - - /* - $tempDomObj.find('.signatureField').each(function() { - $(this).data('signaturePad',new SignaturePad($(this))); - }); - */ - - this.currentDataGroupField = field; - this.showDomElement("Add "+field[1]['label'],$tempDomObj,null,null,true); - - if (object != undefined && object != null) { - this.fillForm(object,"#"+this.getTableName()+"_field_"+field[0], field[1]['form']); - } else { - this.setDefaultValues("#"+this.getTableName()+"_field_"+field[0], field[1]['form']); - } - - - $(".groupAddBtn").off(); - if(object != undefined && object != null && object.id != undefined){ - $(".groupAddBtn").on('click',function(e) { - e.preventDefault(); - e.stopPropagation(); - try{ - modJs.editDataGroup(); - - }catch(e){ - }; - return false; - }); - }else{ - $(".groupAddBtn").on('click',function(e) { - e.preventDefault(); - e.stopPropagation(); - try{ - modJs.addDataGroup(); - - }catch(e){ - }; - return false; - }); - } - - -}); - -IceHRMBase.method('addDataGroup', function() { - var field = this.currentDataGroupField, tempParams; - $("#"+this.getTableName()+"_field_"+field[0]+"_error").html(""); - $("#"+this.getTableName()+"_field_"+field[0]+"_error").hide(); - var validator = new FormValidation(this.getTableName()+"_field_"+field[0],true,{'ShowPopup':false,"LabelErrorClass":"error"}); - if(validator.checkValues()){ - var params = validator.getFormParameters(); - if(field[1]['custom-validate-function'] != undefined && field[1]['custom-validate-function'] != null){ - tempParams = field[1]['custom-validate-function'].apply(this,[params]); - if(tempParams['valid']){ - params = tempParams['params']; - }else{ - $("#"+this.getTableName()+"_field_"+field[0]+"_error").html(tempParams['message']); - $("#"+this.getTableName()+"_field_"+field[0]+"_error").show(); - return false; - } - } - - var val = $("#"+field[0]).val(); - if(val == ""){ - val = "[]"; - } - var data = JSON.parse(val); - - params['id'] = field[0]+"_"+this.dataGroupGetNextAutoIncrementId(data); - data.push(params); - - - if(field[1]['sort-function'] != undefined && field[1]['sort-function'] != null){ - data.sort(field[1]['sort-function']); - } - - val = JSON.stringify(data); - - var html = this.dataGroupToHtml(val,field); - - $("#"+field[0]+"_div").html(""); - $("#"+field[0]+"_div").append(html); - - this.makeDataGroupSortable(field, $("#"+field[0]+"_div_inner")); - - - $("#"+field[0]).val(val); - this.orderDataGroup(field); - - this.closeDataMessage(); - - this.showMessage("Item Added","This change will be effective only when you save the form"); - - - } -}); - -IceHRMBase.method('nl2br' , function(str, len) { - var t = ""; - try{ - var arr = str.split(" "); - var count = 0; - for(var i=0;i len){ - t += arr[i] + "
    "; - count = 0; - }else{ - t += arr[i] + " "; - } - } - }catch(e){} - return t; -}); - -IceHRMBase.method('makeDataGroupSortable', function(field, obj) { - obj.data('field',field); - obj.data('firstSort',true); - obj.sortable({ - - create:function(){ - $(this).height($(this).height()); - }, - - 'ui-floating': false, - start: function(e, ui) { - $('#sortable-ul-selector-id').sortable({ - sort: function(event, ui) { - var $target = $(event.target); - if (!/html|body/i.test($target.offsetParent()[0].tagName)) { - var top = event.pageY - $target.offsetParent().offset().top - (ui.helper.outerHeight(true) / 2); - ui.helper.css({'top' : top + 'px'}); - } - } - }); - - }, - revert: true, - stop: function() { - modJs.orderDataGroup($(this).data('field')); - }, - axis: "y", - scroll: false, - placeholder: "sortable-placeholder", - cursor: "move" - }); - - -}); - -IceHRMBase.method('orderDataGroup', function(field) { - var newArr = [], id; - var list = $("#"+field[0]+"_div_inner [fieldid='"+field[0]+"_div']"); - var val = $("#"+field[0]).val(); - if(val == ""){ - val = "[]"; - } - var data = JSON.parse(val); - list.each(function(){ - id = $(this).attr('id'); - for(index in data){ - if(data[index].id == id){ - newArr.push(data[index]); - break; - } - } - }); - - $("#"+field[0]).val(JSON.stringify(newArr)); - - -}); - - -IceHRMBase.method('editDataGroup', function() { - var field = this.currentDataGroupField; - var id = this.currentDataGroupItemId; - var validator = new FormValidation(this.getTableName()+"_field_"+field[0],true,{'ShowPopup':false,"LabelErrorClass":"error"}); - if(validator.checkValues()){ - var params = validator.getFormParameters(); - - if(field[1]['custom-validate-function'] != undefined && field[1]['custom-validate-function'] != null){ - tempParams = field[1]['custom-validate-function'].apply(this,[params]); - if(tempParams['valid']){ - params = tempParams['params']; - }else{ - $("#"+this.getTableName()+"_field_"+field[0]+"_error").html(tempParams['message']); - $("#"+this.getTableName()+"_field_"+field[0]+"_error").show(); - return false; - } - } - - - if(this.doCustomFilterValidation(params)){ - - var val = $("#"+field[0]).val(); - if(val == ""){ - val = "[]"; - } - var data = JSON.parse(val); - - var editVal = {}; - var editValIndex = -1; - var newVals = []; - for(var i=0;i= autoId){ - autoId = parseInt(id) + 1; - } - } - - return autoId; - -}); - - -IceHRMBase.method('deleteDataGroupItem', function(id) { - var fieldId = id.substring(0,id.lastIndexOf("_")); - - var val = $("#"+fieldId).val(); - var data = JSON.parse(val); - - var newVal = []; - - for(var i=0;i'); - }catch(e){} - - } - - $(formId + ' #'+fields[i][0]).html(placeHolderVal); - }else if(fields[i][1].type == 'fileupload'){ - if(object[fields[i][0]] != null && object[fields[i][0]] != undefined && object[fields[i][0]] != ""){ - $(formId + ' #'+fields[i][0]).html(object[fields[i][0]]); - $(formId + ' #'+fields[i][0]).attr("val",object[fields[i][0]]); - $(formId + ' #'+fields[i][0]).show(); - $(formId + ' #'+fields[i][0]+"_download").show(); - $(formId + ' #'+fields[i][0]+"_remove").show(); - - } - if(fields[i][1].readonly == true){ - $(formId + ' #'+fields[i][0]+"_upload").remove(); - } - }else if(fields[i][1].type == 'select'){ - if(object[fields[i][0]] == undefined || object[fields[i][0]] == null || object[fields[i][0]] == ""){ - object[fields[i][0]] = "NULL"; - } - $(formId + ' #'+fields[i][0]).val(object[fields[i][0]]); - - }else if(fields[i][1].type == 'select2'){ - if(object[fields[i][0]] == undefined || object[fields[i][0]] == null || object[fields[i][0]] == ""){ - object[fields[i][0]] = "NULL"; - } - $(formId + ' #'+fields[i][0]).select2('val',object[fields[i][0]]); - - }else if(fields[i][1].type == 'select2multi'){ - //TODO - SM - if(object[fields[i][0]] == undefined || object[fields[i][0]] == null || object[fields[i][0]] == ""){ - object[fields[i][0]] = "NULL"; - } - - var msVal = []; - if(object[fields[i][0]] != undefined && object[fields[i][0]] != null && object[fields[i][0]] != ""){ - try{ - msVal = JSON.parse(object[fields[i][0]]); - }catch(e){} - } - - $(formId + ' #'+fields[i][0]).select2('val',msVal); - var select2Height = $(formId + ' #'+fields[i][0]).find(".select2-choices").height(); - $(formId + ' #'+fields[i][0]).find(".controls").css('min-height', select2Height+"px"); - $(formId + ' #'+fields[i][0]).css('min-height', select2Height+"px"); - - }else if(fields[i][1].type == 'datagroup'){ - try{ - var html = this.dataGroupToHtml(object[fields[i][0]],fields[i]); - $(formId + ' #'+fields[i][0]).val(object[fields[i][0]]); - $(formId + ' #'+fields[i][0]+"_div").html(""); - $(formId + ' #'+fields[i][0]+"_div").append(html); - - this.makeDataGroupSortable(fields[i], $(formId + ' #'+fields[i][0]+"_div_inner")); - - - }catch(e){} - - }else if(fields[i][1].type == 'signature'){ - - if(object[fields[i][0]] != '' || object[fields[i][0]] != undefined - || object[fields[i][0]] != null){ - $(formId + ' #'+fields[i][0]).data('signaturePad').fromDataURL(object[fields[i][0]]); - } - }else if(fields[i][1].type == 'simplemde'){ - $(formId + ' #'+fields[i][0]).data('simplemde').value(object[fields[i][0]]); - }else{ - $(formId + ' #'+fields[i][0]).val(object[fields[i][0]]); - } - - } -}); - -/** - * Cancel edit or add new on modules - * @method cancel - */ - -IceHRMBase.method('cancel', function() { - $("#"+this.getTableName()+'Form').hide(); - $("#"+this.getTableName()).show(); -}); - -IceHRMBase.method('renderFormField', function(field) { - var userId = 0; - if(this.fieldTemplates[field[1].type] == undefined || this.fieldTemplates[field[1].type] == null){ - return ""; - } - var t = this.fieldTemplates[field[1].type]; - field[1].label = this.gt(field[1].label); - if(field[1].validation != "none" && field[1].validation != "emailOrEmpty" && field[1].validation != "numberOrEmpty" && field[1].type != "placeholder" && field[1].label.indexOf('*') < 0){ - var tempSelectBoxes = ['select','select2']; - if(tempSelectBoxes.indexOf(field[1].type) >= 0 && field[1]['allow-null'] == true){ - - }else{ - field[1].label = field[1].label + '*'; - } - - } - if(field[1].type == 'text' || field[1].type == 'textarea' || field[1].type == 'hidden' || field[1].type == 'label' || field[1].type == 'placeholder'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - - }else if(field[1].type == 'select' || field[1].type == 'select2' || field[1].type == 'select2multi'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - if(field[1]['source'] != undefined && field[1]['source'] != null ){ - t = t.replace('_options_',this.renderFormSelectOptions(field[1].source, field)); - }else if(field[1]['remote-source'] != undefined && field[1]['remote-source'] != null ){ - var key = field[1]['remote-source'][0]+"_"+field[1]['remote-source'][1]+"_"+field[1]['remote-source'][2]; - t = t.replace('_options_',this.renderFormSelectOptionsRemote(this.fieldMasterData[key],field)); - } - - }else if(field[1].type == 'colorpick'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - - }else if(field[1].type == 'date'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - - }else if(field[1].type == 'datetime'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - - }else if(field[1].type == 'time'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - - }else if(field[1].type == 'fileupload'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - var ce = this.getCurrentProfile(); - if(ce != null && ce != undefined){ - userId = ce.id; - }else{ - userId = this.getUser().id * -1; - } - t = t.replace(/_userId_/g,userId); - t = t.replace(/_group_/g,this.tab); - - if(field[1].filetypes != undefined && field[1].filetypes != null){ - t = t.replace(/_filetypes_/g,field[1].filetypes); - }else{ - t = t.replace(/_filetypes_/g,'all'); - } - - t = t.replace(/_rand_/g,this.generateRandom(14)); - - }else if(field[1].type == 'datagroup'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - - }else if(field[1].type == 'signature'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - - }else if(field[1].type == 'tinymce' || field[1].type == 'simplemde'){ - t = t.replace(/_id_/g,field[0]); - t = t.replace(/_label_/g,field[1].label); - } - - - if(field[1].validation != undefined && field[1].validation != null && field[1].validation != "") { - t = t.replace(/_validation_/g,'validation="'+field[1].validation+'"'); - }else{ - t = t.replace(/_validation_/g,''); - } - - if(field[1].help !== undefined && field[1].help !== null){ - t = t.replace(/_helpline_/g,field[1].help); - t = t.replace(/_hidden_class_help_/g,''); - }else{ - t = t.replace(/_helpline_/g,''); - t = t.replace(/_hidden_class_help_/g,'hide'); - } - - if (field[1].placeholder !== undefined && field[1].placeholder !== null) { - t = t.replace(/_placeholder_/g,'placeholder="'+field[1].placeholder+'"'); - }else{ - t = t.replace(/_placeholder_/g,''); - } - - if (field[1].mask !== undefined && field[1].mask !== null) { - t = t.replace(/_mask_/g,'mask="'+field[1].mask+'"'); - }else{ - t = t.replace(/_mask_/g,''); - } - - return t; -}); - -IceHRMBase.method('renderFormSelectOptions', function(options, field) { - var html = ""; - - if(field != null && field != undefined){ - if(field[1]['allow-null'] == true){ - if(field[1]['null-label'] != undefined && field[1]['null-label'] != null){ - html += ''; - }else{ - html += ''; - } - - } - } - - - //Sort options - - var tuples = []; - - for (var key in options) { - tuples.push(options[key]); - } - if(field[1]['sort'] === true){ - tuples.sort(function(a, b) { - a = a[1]; - b = b[1]; - - return a < b ? -1 : (a > b ? 1 : 0); - }); - } - - - for (var i = 0; i < tuples.length; i++) { - var prop = tuples[i][0]; - var value = tuples[i][1]; - var t = ''; - t = t.replace('_id_', prop); - t = t.replace('_val_', this.gt(value)); - html += t; - - } - return html; - -}); - -IceHRMBase.method('renderFormSelectOptionsRemote', function(options,field) { - var html = ""; - if(field[1]['allow-null'] == true){ - if(field[1]['null-label'] != undefined && field[1]['null-label'] != null){ - html += ''; - }else{ - html += ''; - } - - } - - //Sort options - - var tuples = []; - - for (var key in options) { - tuples.push([key, options[key]]); - } - if(field[1]['sort'] === 'true') { - tuples.sort(function (a, b) { - a = a[1]; - b = b[1]; - - return a < b ? -1 : (a > b ? 1 : 0); - }); - } - - for (var i = 0; i < tuples.length; i++) { - var prop = tuples[i][0]; - var value = tuples[i][1]; - - var t = ''; - t = t.replace('_id_', prop); - t = t.replace('_val_', this.gt(value)); - html += t; - } - - - return html; - -}); - -IceHRMBase.method('setTemplates', function(templates) { - this.templates = templates; -}); - -IceHRMBase.method('setCustomTemplates', function(templates) { - this.customTemplates = templates; -}); - -IceHRMBase.method('setEmailTemplates', function(templates) { - this.emailTemplates = templates; -}); - -IceHRMBase.method('getCustomTemplate', function(file) { - return this.customTemplates[file]; -}); - -IceHRMBase.method('setFieldTemplates', function(templates) { - this.fieldTemplates = templates; -}); - - -IceHRMBase.method('getMetaFieldForRendering', function(fieldName) { - return ""; -}); - -IceHRMBase.method('clearDeleteParams', function() { - this.deleteParams = {}; -}); - -IceHRMBase.method('getShowAddNew', function() { - return this.showAddNew; -}); - -/** - * Override this method to change add new button label - * @method getAddNewLabel - */ - -IceHRMBase.method('getAddNewLabel', function() { - return "Add New"; -}); - -/** - * Used to set whether to show the add new button for a module - * @method setShowAddNew - * @param showAddNew {Boolean} value - */ - -IceHRMBase.method('setShowAddNew', function(showAddNew) { - this.showAddNew = showAddNew; -}); - -/** - * Used to set whether to show delete button for each entry in module - * @method setShowDelete - * @param val {Boolean} value - */ -IceHRMBase.method('setShowDelete', function(val) { - this.showDelete = val; -}); - - -/** - * Used to set whether to show edit button for each entry in module - * @method setShowEdit - * @param val {Boolean} value - */ - -IceHRMBase.method('setShowEdit', function(val) { - this.showEdit = val; -}); - -/** - * Used to set whether to show save button in form - * @method setShowSave - * @param val {Boolean} value - */ - - -IceHRMBase.method('setShowSave', function(val) { - this.showSave = val; -}); - - -/** - * Used to set whether to show cancel button in form - * @method setShowCancel - * @param val {Boolean} value - */ - -IceHRMBase.method('setShowCancel', function(val) { - this.showCancel = val; -}); - -/** - * Datatable option array will be extended with associative array provided here - * @method getCustomTableParams - * @param val {Boolean} value - */ - - -IceHRMBase.method('getCustomTableParams', function() { - return {}; -}); - -IceHRMBase.method('getActionButtons', function(obj) { - return modJs.getActionButtonsHtml(obj.aData[0],obj.aData); -}); - - -/** - * This return html for action buttons in each row. Override this method if you need to make changes to action buttons. - * @method getActionButtonsHtml - * @param id {int} id of the row - * @param data {Array} data for the row - * @returns {String} html for action buttons - */ - -IceHRMBase.method('getActionButtonsHtml', function(id,data) { - var editButton = ''; - var deleteButton = ''; - var cloneButton = ''; - var html = '
    _edit__delete__clone_
    '; - - if(this.showAddNew){ - html = html.replace('_clone_',cloneButton); - }else{ - html = html.replace('_clone_',''); - } - - if(this.showDelete){ - html = html.replace('_delete_',deleteButton); - }else{ - html = html.replace('_delete_',''); - } - - if(this.showEdit){ - html = html.replace('_edit_',editButton); - }else{ - html = html.replace('_edit_',''); - } - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - - -/** - * Generates a random string - * @method generateRandom - * @param length {int} required length of the string - * @returns {String} random string - */ - -IceHRMBase.method('generateRandom', function(length) { - var d = new Date(); - var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - var result = ''; - for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))]; - return result+d.getTime(); -}); - - - -IceHRMBase.method('checkFileType', function (elementName, fileTypes) { - var fileElement = document.getElementById(elementName); - var fileExtension = ""; - if (fileElement.value.lastIndexOf(".") > 0) { - fileExtension = fileElement.value.substring(fileElement.value.lastIndexOf(".") + 1, fileElement.value.length); - } - - fileExtension = fileExtension.toLowerCase(); - - var allowed = fileTypes.split(","); - - if (allowed.indexOf(fileExtension) < 0) { - fileElement.value = ""; - this.showMessage("File Type Error",'Selected file type is not supported'); - this.clearFileElement(elementName); - return false; - } - - return true; - -}); - -IceHRMBase.method('clearFileElement', function (elementName) { - - var control = $("#"+elementName); - control.replaceWith( control = control.val('').clone( true ) ); -}); - - -IceHRMBase.method('fixJSON', function (json) { - if(this.noJSONRequests == "1"){ - json = window.btoa(json); - } - return json; - -}); - - -IceHRMBase.method('getClientDate', function (date) { - - var offset = this.getClientGMTOffset(); - var tzDate = date.addMinutes(offset*60); - return tzDate; - -}); - -IceHRMBase.method('getClientGMTOffset', function () { - - var rightNow = new Date(); - var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0); - var temp = jan1.toGMTString(); - var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1)); - var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60); - - return std_time_offset; - -}); - -/** - * Override this method in a module to provide the help link for the module. Help link of the module on frontend will get updated with this. - * @method getHelpLink - * @returns {String} help link - */ - -IceHRMBase.method('getHelpLink', function () { - - return null; - -}); - -IceHRMBase.method('showLoader', function () { - $('#iceloader').show(); -}); - -IceHRMBase.method('hideLoader', function () { - $('#iceloader').hide(); -}); - -IceHRMBase.method('generateOptions', function (data) { - var template = ''; - var options = ""; - for(index in data){ - options += template.replace("__val__",index).replace("__text__",data[index]); - } - - return options; -}); - -IceHRMBase.method('isModuleInstalled', function (type, name) { - if(modulesInstalled == undefined || modulesInstalled == null){ - return false; - } - - return (modulesInstalled[type+"_"+name] == 1); -}); - - -IceHRMBase.method('setCustomFields', function(fields) { - var field, parsed; - for(var i=0;i this.pageSize){ - this.hasMoreData = true; - serverData.pop(); - this.loadMoreButton.removeAttr('disabled'); - this.loadMoreButton.show(); + const data = []; + if (!addToTop && serverData.length > this.pageSize) { + this.hasMoreData = true; + serverData.pop(); + this.loadMoreButton.removeAttr('disabled'); + this.loadMoreButton.show(); } else if (!addToTop) { - this.hasMoreData = false; - this.loadMoreButton.hide(); + this.hasMoreData = false; + this.loadMoreButton.hide(); } if (!addToTop) { - this.scrollToElementBottom(this.container); + this.scrollToElementBottom(this.container); } - for(var i=0;i this.topLimit || this.topLimit === 0) { - this.topLimit = data[i].timeint; - this.topLimitUpdated = true; - } + if (data[i].timeint > this.topLimit || this.topLimit === 0) { + this.topLimit = data[i].timeint; + this.topLimitUpdated = true; + } } this.hideConversationLoader(); -}); + } -ConversationsAdapter.method('getConversationsFailCallBack', function(callBackData) { + getConversationsFailCallBack() { this.hideLoader(); this.hideConversationLoader(); if (this.timer !== null) { - clearTimeout(this.timer); - this.timer = null; + clearTimeout(this.timer); + this.timer = null; } -}); + } -ConversationsAdapter.method('getObjectHTML', function(object) { - var t = this.getCustomTemplate(this.getTemplateName()); + getObjectHTML(object) { + let t = this.getCustomTemplate(this.getTemplateName()); t = t.replace(new RegExp('#_id_#', 'g'), object.id); t = t.replace(new RegExp('#_message_#', 'g'), object.message); t = t.replace(new RegExp('#_employeeName_#', 'g'), object.employeeName); t = t.replace(new RegExp('#_employeeImage_#', 'g'), object.employeeImage); t = t.replace(new RegExp('#_date_#', 'g'), object.date); - if (object.attachment !== '' && object.attachment !== null && object.attachment !== undefined) { - var at = this.getCustomTemplate('attachment.html'); - at = at.replace(new RegExp('#_attachment_#', 'g'), object.attachment); - at = at.replace(new RegExp('#_icon_#', 'g'), this.getIconByFileType(object.file.type)); - at = at.replace(new RegExp('#_color_#', 'g'), this.getColorByFileType(object.file.type)); - at = at.replace(new RegExp('#_name_#', 'g'), object.file.name); - at = at.replace(new RegExp('#_size_#', 'g'), object.file.size_text); - t = t.replace(new RegExp('#_attachment_#', 'g'), at); + if (object.attachment !== '' && object.attachment !== null && object.attachment !== undefined) { + let at = this.getCustomTemplate('attachment.html'); + at = at.replace(new RegExp('#_attachment_#', 'g'), object.attachment); + at = at.replace(new RegExp('#_icon_#', 'g'), this.getIconByFileType(object.file.type)); + at = at.replace(new RegExp('#_color_#', 'g'), this.getColorByFileType(object.file.type)); + at = at.replace(new RegExp('#_name_#', 'g'), object.file.name); + at = at.replace(new RegExp('#_size_#', 'g'), object.file.size_text); + t = t.replace(new RegExp('#_attachment_#', 'g'), at); } else { - t = t.replace(new RegExp('#_attachment_#', 'g'), ''); + t = t.replace(new RegExp('#_attachment_#', 'g'), ''); } return t; + } -}); - -ConversationsAdapter.method('setPageSize', function(pageSize) { + setPageSize(pageSize) { this.pageSize = pageSize; -}); + } -ConversationsAdapter.method('addDomEvents', function(object) { + // eslint-disable-next-line no-unused-vars + addDomEvents(object) { -}); + } -ConversationsAdapter.method('getTemplateName', function() { + getTemplateName() { return 'conversation.html'; -}); + } -ConversationsAdapter.method('renderObject', function(object, addToTop) { + renderObject(object, addToTop) { + const objDom = this.getObjectDom(object.id); - var objDom = this.getObjectDom(object.id); - - var html = this.getObjectHTML(object); - var domObj = $(html); + const html = this.getObjectHTML(object); + const domObj = $(html); - if (objDom !== undefined && objDom !== null) { - objDom.replace(domObj); + if (objDom !== undefined && objDom !== null) { + objDom.replace(domObj); } else if (addToTop) { - this.container.prepend(domObj); - $('#obj_'+object.id).css('background-color', '#FFF8DC'); - $('#obj_'+object.id).fadeIn('slow'); - $('#obj_'+object.id).animate({backgroundColor: '#FFF'}, 'slow'); + this.container.prepend(domObj); + $(`#obj_${object.id}`).css('background-color', '#FFF8DC'); + $(`#obj_${object.id}`).fadeIn('slow'); + $(`#obj_${object.id}`).animate({ backgroundColor: '#FFF' }, 'slow'); } else { - this.container.append(domObj); - $('#obj_'+object.id).fadeIn('slow'); + this.container.append(domObj); + $(`#obj_${object.id}`).fadeIn('slow'); } if (domObj.find('.conversation-body').prop('scrollHeight') > 290) { - domObj.find('.conversation-expand').show(); + domObj.find('.conversation-expand').show(); } if (object.actionDelete === 1) { - domObj.find('.delete-button').show(); + domObj.find('.delete-button').show(); } this.addDomEvents(domObj); -}); + } -ConversationsAdapter.method('setContainer', function(container) { + setContainer(container) { this.container = container; -}); + } -ConversationsAdapter.method('setLoadMoreButton', function(loadMoreButton) { - var that = this; + setLoadMoreButton(loadMoreButton) { + const that = this; this.loadMoreButton = loadMoreButton; - this.loadMoreButton.off().on('click',function(){ - that.loadMoreButton.attr('disabled','disabled'); - that.loadMore([]); - } - ); -}); + this.loadMoreButton.off().on('click', () => { + that.loadMoreButton.attr('disabled', 'disabled'); + that.loadMore([]); + }); + } -ConversationsAdapter.method('showLoadError', function(msg) { - $("#"+this.getTableName()+"_error").html(msg); - $("#"+this.getTableName()+"_error").show(); -}); + showLoadError(msg) { + $(`#${this.getTableName()}_error`).html(msg); + $(`#${this.getTableName()}_error`).show(); + } -ConversationsAdapter.method('hideLoadError', function() { - $("#"+this.getTableName()+"_error").hide(); -}); + hideLoadError() { + $(`#${this.getTableName()}_error`).hide(); + } -ConversationsAdapter.method('setSearchBox', function(searchInput) { - var that = this; + setSearchBox(searchInput) { + const that = this; this.searchInput = searchInput; this.searchInput.off(); - this.searchInput.keydown(function(event){ - var val = $(this).val(); - if ( event.which == 13 ) { - event.preventDefault(); - that.search([]); - }else if(( event.which == 8 || event.which == 46) && val.length == 1 && that.searchTerm != ''){ - that.search([]); - } + this.searchInput.keydown(function (event) { + const val = $(this).val(); + if (event.which === 13) { + event.preventDefault(); + that.search([]); + } else if ((event.which === 8 || event.which === 46) && val.length === 1 && that.searchTerm !== '') { + that.search([]); + } }); -}); + } -ConversationsAdapter.method('getObjectDom', function(id) { - obj = this.container.find("#obj_"+id); - if(obj.length){ - return obj; + getObjectDom(id) { + const obj = this.container.find(`#obj_${id}`); + if (obj.length) { + return obj; } return null; -}); + } -ConversationsAdapter.method('loadMore', function(callBackData) { - if(!this.hasMoreData){ - return; + loadMore(callBackData) { + if (!this.hasMoreData) { + return; } this.currentPage++; this.get(callBackData, true); -}); + } -ConversationsAdapter.method('get', function(callBackData, loadMore) { - var that = this; + get(callBackData, loadMore) { + const that = this; this.hideLoadError(); - if(!loadMore){ - this.currentPage = 1; - if(this.container != null){ - this.container.html(''); - } - this.hasMoreData = true; - this.tableData = []; + if (!loadMore) { + this.currentPage = 1; + if (this.container != null) { + this.container.html(''); + } + this.hasMoreData = true; + this.tableData = []; } this.start = (this.currentPage === 1) ? 0 : this.bottomLimit; - this.container = $("#"+this.getTableName()).find('.objectList'); + this.container = $(`#${this.getTableName()}`).find('.objectList'); that.showLoader(); this.getConversations(this.start, this.pageSize, false); if (this.timer === null && that.getTimeout() > 0) { - this.timeoutDelay = 0; - this.timer = setTimeout(function tick() { - that.getConversations(that.topLimit, that.pageSize, true); - that.timeoutDelay += that.getTimeout(); - if (that.topLimitUpdated) { - that.timeoutDelay = 0; - } - that.timer = setTimeout(tick, that.getTimeout() + that.timeoutDelay); - }, that.getTimeout() + that.timeoutDelay); + this.timeoutDelay = 0; + this.timer = setTimeout(function tick() { + that.getConversations(that.topLimit, that.pageSize, true); + that.timeoutDelay += that.getTimeout(); + if (that.topLimitUpdated) { + that.timeoutDelay = 0; + } + that.timer = setTimeout(tick, that.getTimeout() + that.timeoutDelay); + }, that.getTimeout() + that.timeoutDelay); } + } -}); - -ConversationsAdapter.method('getTimeout', function() { + getTimeout() { return 0; -}); + } -ConversationsAdapter.method('getTimeoutUpper', function() { + getTimeoutUpper() { return 0; -}); + } -ConversationsAdapter.method('showConversationLoader', function() { - //Do nothing -}); + showConversationLoader() { + // Do nothing + } -ConversationsAdapter.method('hideConversationLoader', function() { - //Do nothing -}); + hideConversationLoader() { + // Do nothing + } -ConversationsAdapter.method('search', function(callBackData) { - this.searchTerm = $("#"+this.getTableName()+"_search").val(); + search(callBackData) { + this.searchTerm = $(`#${this.getTableName()}_search`).val(); this.get(callBackData); + } +} -}); +export default ConversationsAdapter; diff --git a/web/api/FormValidation.js b/web/api/FormValidation.js index 152a5d9b..8c2c3a3e 100644 --- a/web/api/FormValidation.js +++ b/web/api/FormValidation.js @@ -1,280 +1,246 @@ /* -This file is part of Ice Framework. - -Ice Framework is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Ice Framework is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Ice Framework. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) */ +/* global tinyMCE */ +const ValidationRules = { -ValidationRules = { - - float: function (str) { - var floatstr = /^[-+]?[0-9]+(\.[0-9]+)?$/; - if (str != null && str.match(floatstr)) { - return true; - } else { - return false; - } - }, - - number: function (str) { - var numstr = /^[0-9]+$/; - if (str != null && str.match(numstr)) { - return true; - } else { - return false; - } - }, - - numberOrEmpty: function (str) { - if(str == ""){ - return true; - } - var numstr = /^[0-9]+$/; - if (str != null && str.match(numstr)) { - return true; - } else { - return false; - } - }, - - email: function (str) { - var emailPattern = /^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/; - return str != null && emailPattern.test(str); - }, - - emailOrEmpty: function (str) { - if(str == ""){ - return true; - } - var emailPattern = /^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/; - return str != null && emailPattern.test(str); - }, - - username: function (str) { - var username = /^[a-zA-Z0-9\.-]+$/; - return str != null && username.test(str); - }, - - input: function (str) { - if (str != null && str.length > 0) { - return true; - } else { - return false; - } + float(str) { + const floatstr = /^[-+]?[0-9]+(\.[0-9]+)?$/; + if (str != null && str.match(floatstr)) { + return true; } + return false; + }, + + number(str) { + const numstr = /^[0-9]+$/; + if (str != null && str.match(numstr)) { + return true; + } + return false; + }, + + numberOrEmpty(str) { + if (str === '') { + return true; + } + const numstr = /^[0-9]+$/; + if (str != null && str.match(numstr)) { + return true; + } + return false; + }, + + email(str) { + const emailPattern = /^\s*[\w\-+_]+(\.[\w\-+_]+)*@[\w\-+_]+\.[\w\-+_]+(\.[\w\-+_]+)*\s*$/; + return str != null && emailPattern.test(str); + }, + + emailOrEmpty(str) { + if (str === '') { + return true; + } + const emailPattern = /^\s*[\w\-+_]+(\.[\w\-+_]+)*@[\w\-+_]+\.[\w\-+_]+(\.[\w\-+_]+)*\s*$/; + return str != null && emailPattern.test(str); + }, + + username(str) { + const username = /^[a-zA-Z0-9.-]+$/; + return str != null && username.test(str); + }, + + input(str) { + if (str != null && str.length > 0) { + return true; + } + return false; + }, }; -function FormValidation(formId,validateAll,options) { +class FormValidation { + constructor(formId, validateAll, options) { this.tempOptions = {}; - this.formId = formId; - this.formError = false; + this.formId = formId; + this.formError = false; this.formObject = null; - this.errorMessages = ""; + this.errorMessages = ''; this.popupDialog = null; this.validateAll = validateAll; - this.errorMap = new Array(); + this.errorMap = []; - this.settings = {"thirdPartyPopup":null,"LabelErrorClass":false, "ShowPopup":true}; + this.settings = { thirdPartyPopup: null, LabelErrorClass: false, ShowPopup: true }; - this.settings = jQuery.extend(this.settings,options); + this.settings = jQuery.extend(this.settings, options); - this.inputTypes = new Array( "text", "radio", "checkbox", "file", "password", "select-one","select-multi", "textarea","fileupload" ,"signature"); + this.inputTypes = ['text', 'radio', 'checkbox', 'file', 'password', 'select-one', 'select-multi', 'textarea', 'fileupload', 'signature']; this.validator = ValidationRules; + } -} + // eslint-disable-next-line no-unused-vars + clearError(formInput, overrideMessage) { + const id = formInput.attr('id'); + $(`#${this.formId} #field_${id}`).removeClass('error'); + $(`#${this.formId} #help_${id}`).html(''); + } -FormValidation.method('clearError' , function(formInput, overrideMessage) { - var id = formInput.attr("id"); - $('#'+ this.formId +' #field_'+id).removeClass('error'); - $('#'+ this.formId +' #help_'+id).html(''); -}); - -FormValidation.method('addError' , function(formInput, overrideMessage) { + // eslint-disable-next-line no-unused-vars + addError(formInput, overrideMessage) { this.formError = true; - if(formInput.attr("message") != null) { - this.errorMessages += (formInput.attr("message") + "\n"); - this.errorMap[formInput.attr("name")] = formInput.attr("message"); - }else{ - this.errorMap[formInput.attr("name")] = ""; + if (formInput.attr('message') != null) { + this.errorMessages += (`${formInput.attr('message')}\n`); + this.errorMap[formInput.attr('name')] = formInput.attr('message'); + } else { + this.errorMap[formInput.attr('name')] = ''; } - var id = formInput.attr("id"); - var validation = formInput.attr("validation"); - var message = formInput.attr("validation"); - $('#'+ this.formId +' #field_'+id).addClass('error'); - if(message == undefined || message == null || message == ""){ - $('#'+ this.formId +' #help_err_'+id).html(message); - }else{ - if(validation == undefined || validation == null || validation == ""){ - $('#'+ this.formId +' #help_err_'+id).html("Required"); - }else{ - if(validation == "float" || validation == "number"){ - $('#'+ this.formId +' #help_err_'+id).html("Number required"); - }else if(validation == "email"){ - $('#'+ this.formId +' #help_err_'+id).html("Email required"); - }else{ - $('#'+ this.formId +' #help_err_'+id).html("Required"); - } + const id = formInput.attr('id'); + const validation = formInput.attr('validation'); + const message = formInput.attr('validation'); + $(`#${this.formId} #field_${id}`).addClass('error'); + if (message === undefined || message == null || message === '') { + $(`#${this.formId} #help_err_${id}`).html(message); + } else if (validation === undefined || validation == null || validation === '') { + $(`#${this.formId} #help_err_${id}`).html('Required'); + } else if (validation === 'float' || validation === 'number') { + $(`#${this.formId} #help_err_${id}`).html('Number required'); + } else if (validation === 'email') { + $(`#${this.formId} #help_err_${id}`).html('Email required'); + } else { + $(`#${this.formId} #help_err_${id}`).html('Required'); + } + } + + + showErrors() { + if (this.formError) { + if (this.settings.thirdPartyPopup !== undefined && this.settings.thirdPartyPopup != null) { + this.settings.thirdPartyPopup.alert(); + } else if (this.settings.ShowPopup === true) { + if (this.tempOptions.popupTop !== undefined && this.tempOptions.popupTop != null) { + this.alert('Errors Found', this.errorMessages, this.tempOptions.popupTop); + } else { + this.alert('Errors Found', this.errorMessages, -1); } + } } + } -}); - - -FormValidation.method('showErrors' , function() { - if(this.formError) { - if(this.settings['thirdPartyPopup'] != undefined && this.settings['thirdPartyPopup'] != null){ - this.settings['thirdPartyPopup'].alert(); - }else{ - if(this.settings['ShowPopup'] == true){ - if(this.tempOptions['popupTop'] != undefined && this.tempOptions['popupTop'] != null){ - this.alert("Errors Found",this.errorMessages,this.tempOptions['popupTop']); - }else{ - this.alert("Errors Found",this.errorMessages,-1); - } - - } - } - } -}); - - -FormValidation.method('checkValues' , function(options) { + checkValues(options) { this.tempOptions = options; - var that = this; + const that = this; this.formError = false; - this.errorMessages = ""; - this.formObject = new Object(); - var validate = function (inputObject) { - if(that.settings['LabelErrorClass'] != false){ - $("label[for='" + name + "']").removeClass(that.settings['LabelErrorClass']); - } - var id = inputObject.attr("id"); - var name = inputObject.attr("name"); - var type = inputObject.attr("type"); + this.errorMessages = ''; + this.formObject = {}; + // eslint-disable-next-line consistent-return + const validate = function (inputObject) { + let inputValue = null; + const name = inputObject.attr('name'); + if (that.settings.LabelErrorClass !== false) { + $(`label[for='${name}']`).removeClass(that.settings.LabelErrorClass); + } + const id = inputObject.attr('id'); + const type = inputObject.attr('type'); - if(inputObject.hasClass('select2-focusser') || inputObject.hasClass('select2-input')){ - return true; + if (inputObject.hasClass('select2-focusser') || inputObject.hasClass('select2-input')) { + return true; + } + + if (jQuery.inArray(type, that.inputTypes) >= 0) { + if (inputObject.hasClass('uploadInput')) { + inputValue = inputObject.attr('val'); + } else if (type === 'radio' || type === 'checkbox') { + inputValue = $(`input[name='${name}']:checked`).val(); + } else if (inputObject.hasClass('select2Field')) { + if ($(`#${that.formId} #${id}`).select2('data') != null && $(`#${that.formId} #${id}`).select2('data') !== undefined) { + inputValue = $(`#${that.formId} #${id}`).select2('data').id; + } else { + inputValue = ''; + } + } else if (inputObject.hasClass('select2Multi')) { + if ($(`#${that.formId} #${id}`).select2('data') != null && $(`#${that.formId} #${id}`).select2('data') !== undefined) { + const inputValueObjects = $(`#${that.formId} #${id}`).select2('data'); + inputValue = []; + for (let i = 0; i < inputValueObjects.length; i++) { + inputValue.push(inputValueObjects[i].id); + } + inputValue = JSON.stringify(inputValue); + } else { + inputValue = ''; + } + } else if (inputObject.hasClass('signatureField')) { + if ($(`#${that.formId} #${id}`).data('signaturePad').isEmpty()) { + inputValue = ''; + } else { + inputValue = $(`#${id}`).data('signaturePad').toDataURL(); + } + } else if (inputObject.hasClass('simplemde')) { + inputValue = $(`#${that.formId} #${id}`).data('simplemde').value(); + } else if (inputObject.hasClass('tinymce')) { + inputValue = tinyMCE.get(id).getContent({ format: 'raw' }); + } else { + inputValue = inputObject.val(); } - if(jQuery.inArray(type, that.inputTypes ) >= 0) { - if(inputObject.hasClass('uploadInput')){ - inputValue = inputObject.attr("val"); - //}else if(inputObject.hasClass('datetimeInput')){ - //inputValue = inputObject.getDate()+":00"; - }else{ - //inputValue = (type == "radio" || type == "checkbox")?$("input[name='" + name + "']:checked").val():inputObject.val(); + const validation = inputObject.attr('validation'); + let valid = false; - inputValue = null; - if(type == "radio" || type == "checkbox"){ - inputValue = $("input[name='" + name + "']:checked").val(); - }else if(inputObject.hasClass('select2Field')){ - if($('#'+id).select2('data') != null && $('#'+id).select2('data') != undefined){ - inputValue = $('#'+id).select2('data').id; - }else{ - inputValue = ""; - } - - }else if(inputObject.hasClass('select2Multi')){ - if($('#'+id).select2('data') != null && $('#'+id).select2('data') != undefined){ - inputValueObjects = $('#'+id).select2('data'); - inputValue = []; - for(var i=0;i. - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function NotificationManager() { - this.baseUrl = ""; - this.templates = {}; -} - -NotificationManager.method('setBaseUrl' , function(url) { - this.baseUrl = url; -}); - -NotificationManager.method('setTemplates' , function(data) { - this.templates = data; -}); - -NotificationManager.method('setTimeUtils' , function(timeUtils) { - this.timeUtils = timeUtils; -}); - -NotificationManager.method('getNotifications' , function(name, data) { - var that = this; - $.getJSON(this.baseUrl, {'a':'getNotifications'}, function(data) { - if(data.status == "SUCCESS"){ - that.renderNotifications(data.data[1],data.data[0]); - } - }); -}); - -NotificationManager.method('clearPendingNotifications' , function(name, data) { - var that = this; - $.getJSON(this.baseUrl, {'a':'clearNotifications'}, function(data) { - - }); -}); - -NotificationManager.method('renderNotifications' , function(notifications, unreadCount) { - - if(notifications.length == 0){ - return; - } - - var t = this.templates['notifications']; - if(unreadCount > 0){ - t = t.replace('#_count_#',unreadCount); - if(unreadCount > 1){ - t = t.replace('#_header_#',"You have "+unreadCount+" new notifications"); - }else{ - t = t.replace('#_header_#',"You have "+unreadCount+" new notification"); - } - - }else{ - t = t.replace('#_count_#',""); - t = t.replace('#_header_#',"You have no new notifications"); - } - - var notificationStr = ""; - - for (index in notifications){ - notificationStr += this.renderNotification(notifications[index]); - } - - t = t.replace('#_notifications_#',notificationStr); - - $obj = $(t); - - if(unreadCount == 0){ - $obj.find('.label-danger').remove(); - } - - $obj.attr("id","notifications"); - var k = $("#notifications"); - k.replaceWith($obj); - - $(".navbar .menu").slimscroll({ - height: "320px", - alwaysVisible: false, - size: "3px" - }).css("width", "100%"); - - this.timeUtils.convertToRelativeTime($(".notificationTime")); -}); - - -NotificationManager.method('renderNotification' , function(notification) { - var t = this.templates['notification']; - t = t.replace('#_image_#',notification.image); - - try{ - var json = JSON.parse(notification.action); - t = t.replace('#_url_#',this.baseUrl.replace('service.php','?')+json['url']); - }catch(e){ - t = t.replace('#_url_#',""); - } - - t = t.replace('#_time_#',notification.time); - t = t.replace('#_fromName_#',notification.type); - t = t.replace('#_message_#',this.getLineBreakString(notification.message,27)); - return t; -}); - - -NotificationManager.method('getLineBreakString' , function(str, len) { - var t = ""; - try{ - var arr = str.split(" "); - var count = 0; - for(var i=0;i len){ - t += arr[i] + "
    "; - count = 0; - }else{ - t += arr[i] + " "; - } - } - }catch(e){} - return t; -}); \ No newline at end of file diff --git a/web/api/SocialShare.js b/web/api/SocialShare.js index ea7a42b2..df14cd35 100644 --- a/web/api/SocialShare.js +++ b/web/api/SocialShare.js @@ -1,47 +1,49 @@ -function SocialShare(){ -}; +/* eslint-disable no-restricted-globals */ +/* + Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) + Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) + */ +const SocialShare = { + facebook: (url) => { + const w = 700; + const h = 500; + const left = (screen.width / 2) - (w / 2); + const top = (screen.height / 2) - (h / 2); -SocialShare.facebook = function(url) { - var w = 700; - var h = 500; - var left = (screen.width/2)-(w/2); - var top = (screen.height/2)-(h/2); - - var url = "https://www.facebook.com/sharer/sharer.php?u="+encodeURIComponent(url); + url = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`; - window.open(url, "Share on Facebook", "width="+w+",height="+h+",left="+left+",top="+top); + window.open(url, 'Share on Facebook', `width=${w},height=${h},left=${left},top=${top}`); return false; - -}; + }, -SocialShare.google = function(url) { - var w = 500; - var h = 500; - var left = (screen.width/2)-(w/2); - var top = (screen.height/2)-(h/2); - - var url = "https://plus.google.com/share?url="+encodeURIComponent(url); + google: (url) => { + const w = 500; + const h = 500; + const left = (screen.width / 2) - (w / 2); + const top = (screen.height / 2) - (h / 2); - window.open(url, "Share on Google", "width="+w+",height="+h+",left="+left+",top="+top); + url = `https://plus.google.com/share?url=${encodeURIComponent(url)}`; + + window.open(url, 'Share on Google', `width=${w},height=${h},left=${left},top=${top}`); return false; - -}; + }, -SocialShare.linkedin = function(url) { - var w = 500; - var h = 500; - var left = (screen.width/2)-(w/2); - var top = (screen.height/2)-(h/2); - - var url = "https://www.linkedin.com/cws/share?url="+encodeURIComponent(url); + linkedin: (url) => { + const w = 500; + const h = 500; + const left = (screen.width / 2) - (w / 2); + const top = (screen.height / 2) - (h / 2); - window.open(url, "Share on Linked in", "width="+w+",height="+h+",left="+left+",top="+top); + url = `https://www.linkedin.com/cws/share?url=${encodeURIComponent(url)}`; + + window.open(url, 'Share on Linked in', `width=${w},height=${h},left=${left},top=${top}`); return false; - + }, + + twitter(url, msg) { + window.open(`http://twitter.com/share?text=${escape(msg)}&url=${escape(url)}`, 'popup', 'width=550,height=260,scrollbars=yes,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no,left=200,top=200'); + return false; + }, }; -SocialShare.twitter = function(url, msg) { - window.open('http://twitter.com/share?text='+escape(msg) + '&url=' + escape(url),'popup','width=550,height=260,scrollbars=yes,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no,left=200,top=200'); - return false; - -}; \ No newline at end of file +export default SocialShare; diff --git a/web/api/TimeUtils.js b/web/api/TimeUtils.js deleted file mode 100644 index 6848378e..00000000 --- a/web/api/TimeUtils.js +++ /dev/null @@ -1,163 +0,0 @@ -/* - This file is part of Ice Framework. - - Ice Framework is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Ice Framework is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Ice Framework. If not, see . - - ------------------------------------------------------------------ - - Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] - Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function TimeUtils() { - -} - -TimeUtils.method('setServerGMToffset' , function(serverGMToffset) { - this.serverGMToffset = serverGMToffset; -}); - -TimeUtils.method('getMySQLFormatDate' , function(date) { - - var format = function(val){ - if(val < 10){return "0"+val;} - return val; - - } - - return date.getUTCFullYear()+"-"+format(date.getUTCMonth()+1)+"-"+format(date.getUTCDate()); -}); - -TimeUtils.method('convertToRelativeTime',function(selector) { - - var that = this; - - var getAmPmTime = function(curHour, curMin) { - var amPm = "am"; - var amPmHour = curHour; - if (amPmHour >= 12) { - amPm = "pm"; - if (amPmHour > 12) { - amPmHour = amPmHour - 12; - } - } - var prefixCurMin = ""; - if (curMin < 10) { - prefixCurMin = "0"; - } - - var prefixCurHour = ""; - if (curHour == 0) { - prefixCurHour = "0"; - } - return " at " + prefixCurHour + amPmHour + ":" + prefixCurMin + curMin + amPm; - }; - - var getBrowserTimeZone = function() { - var current_date = new Date(); - var gmt_offset = current_date.getTimezoneOffset() / 60; - return -gmt_offset; - }; - - var curDate = new Date(); - var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; - var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; - - - var timezoneDiff = this.serverGMToffset - getBrowserTimeZone(); - var timezoneTimeDiff = timezoneDiff*60*60*1000; - - - selector.each(function () { - try{ - var thisValue = $(this).html(); - // Split value into date and time - var thisValueArray = thisValue.split(" "); - var thisValueDate = thisValueArray[0]; - var thisValueTime = thisValueArray[1]; - - // Split date into components - var thisValueDateArray = thisValueDate.split("-"); - var curYear = thisValueDateArray[0]; - var curMonth = thisValueDateArray[1]-1; - var curDay = thisValueDateArray[2]; - - // Split time into components - var thisValueTimeArray = thisValueTime.split(":"); - var curHour = thisValueTimeArray[0]; - var curMin = thisValueTimeArray[1]; - var curSec = thisValueTimeArray[2]; - - // Create this date - var thisDate = new Date(curYear, curMonth, curDay, curHour, curMin, curSec); - var thisTime = thisDate.getTime(); - var tzDate = new Date(thisTime - timezoneTimeDiff); - //var tzDay = tzDate.getDay();//getDay will return the day of the week not the month - //var tzDay = tzDate.getUTCDate(); //getUTCDate will return the day of the month - var tzDay = tzDate.toString('d'); // - var tzYear = tzDate.getFullYear(); - var tzHour = tzDate.getHours(); - var tzMin = tzDate.getMinutes(); - - // Create the full date - //var fullDate = days[tzDate.getDay()] + ", " + months[tzDate.getMonth()] + " " + tzDay + ", " + tzYear + getAmPmTime(tzHour, tzMin); - var fullDate = days[tzDate.getDay()] + ", " + months[tzDate.getMonth()] + " " + tzDay + ", " + tzYear + getAmPmTime(tzHour, tzMin); - - // Get the time different - var timeDiff = (curDate.getTime() - tzDate.getTime())/1000; - var minDiff = Math.abs(timeDiff/60); - var hourDiff = Math.abs(timeDiff/(60*60)); - var dayDiff = Math.abs(timeDiff/(60*60*24)); - var yearDiff = Math.abs(timeDiff/(60*60*24*365)); - - // If more than a day old, display the month, day and time (and year, if applicable) - var fbDate = ''; - if (dayDiff > 1) { - //fbDate = curDay + " " + months[tzDate.getMonth()].substring(0,3); - fbDate = tzDay + " " + months[tzDate.getMonth()].substring(0,3); - // Add the year, if applicable - if (yearDiff > 1) { - fbDate = fbDate + " "+ curYear; - } - - // Add the time - fbDate = fbDate + getAmPmTime(tzHour, tzMin); - } - // Less than a day old, and more than an hour old - else if (hourDiff >= 1) { - var roundedHour = Math.round(hourDiff); - if (roundedHour == 1) - fbDate = "about an hour ago"; - else - fbDate = roundedHour + " hours ago"; - } - // Less than an hour, and more than a minute - else if (minDiff >= 1) { - var roundedMin = Math.round(minDiff); - if (roundedMin == 1) - fbDate = "about a minute ago"; - else - fbDate = roundedMin + " minutes ago"; - } - // Less than a minute - else if (minDiff < 1) { - fbDate = "less than a minute ago"; - } - - // Update this element - $(this).html(fbDate); - $(this).attr('title', fullDate); - }catch(e){} - }); -}); \ No newline at end of file diff --git a/web/bower_components/flag-icon-css/flags/4x3/ar.svg b/web/bower_components/flag-icon-css/flags/4x3/ar.svg index 2bd1a609..a5f82e83 100644 --- a/web/bower_components/flag-icon-css/flags/4x3/ar.svg +++ b/web/bower_components/flag-icon-css/flags/4x3/ar.svg @@ -1,31 +1,6 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/web/css/style.css b/web/css/style.css index e0128273..2a2354bc 100644 --- a/web/css/style.css +++ b/web/css/style.css @@ -840,4 +840,4 @@ table.dataTable{ .conversation-save-post { padding: 1px 10px; margin-bottom: 15px; -} +} \ No newline at end of file diff --git a/web/js/app-global.js b/web/js/app-global.js deleted file mode 100644 index a0761552..00000000 --- a/web/js/app-global.js +++ /dev/null @@ -1,184 +0,0 @@ -var uploadId=""; -var uploadAttr=""; -var popupUpload = null; - -function showUploadDialog(id,msg,group,user,postUploadId,postUploadAttr,postUploadResultAttr,fileType){ - var ts = Math.round((new Date()).getTime() / 1000); - uploadId = postUploadId; - uploadAttr = postUploadAttr; - uploadResultAttr = postUploadResultAttr; - var html='
    '; - var html = html.replace(/_id_/g,id); - var html = html.replace(/_msg_/g,msg); - var html = html.replace(/_file_group_/g,group); - var html = html.replace(/_user_/g,user); - var html = html.replace(/_file_type_/g,fileType); - - modJs.renderModel('upload',"Upload File",html); - $('#uploadModel').modal('show'); - -} - -function closeUploadDialog(success,error,data){ - var arr = data.split("|"); - var file = arr[0]; - var fileBaseName = arr[1]; - var fileId = arr[2]; - - if(success == 1){ - //popupUpload.close(); - $('#uploadModel').modal('hide'); - if(uploadResultAttr == "url"){ - if(uploadAttr == "val"){ - $('#'+uploadId).val(file); - }else if(uploadAttr == "html"){ - $('#'+uploadId).html(file); - }else{ - $('#'+uploadId).attr(uploadAttr,file); - } - - }else if(uploadResultAttr == "name"){ - if(uploadAttr == "val"){ - $('#'+uploadId).val(fileBaseName); - }else if(uploadAttr == "html"){ - $('#'+uploadId).html(fileBaseName); - $('#'+uploadId).attr("val",fileBaseName); - }else{ - $('#'+uploadId).attr(uploadAttr,fileBaseName); - } - $('#'+uploadId).show(); - $('#'+uploadId+"_download").show(); - $('#'+uploadId+"_remove").show(); - }else if(uploadResultAttr == "id"){ - if(uploadAttr == "val"){ - $('#'+uploadId).attr(uploadAttr,fileId); - }else if(uploadAttr == "html"){ - $('#'+uploadId).html(fileBaseName); - $('#'+uploadId).attr("val",fileId); - }else{ - $('#'+uploadId).attr(uploadAttr,fileId); - } - $('#'+uploadId).show(); - $('#'+uploadId+"_download").show(); - $('#'+uploadId+"_remove").show(); - } - - - }else{ - //popupUpload.close(); - $('#uploadModel').modal('hide'); - } - -} - -function download(name, closeCallback, closeCallbackData){ - - var successCallback = function(data){ - - var link; - var fileParts; - var viewableImages = ["png","jpg","gif","bmp","jpge"]; - var viewableFiles = ["pdf","xml"]; - - $('.modal').modal('hide'); - - if(data['filename'].indexOf("https:") == 0 || data['filename'].indexOf("http:") == 0){ - fileParts = data['filename'].split("?"); - fileParts = fileParts[0].split("."); - - if(jQuery.inArray(fileParts[fileParts.length - 1], viewableFiles ) >= 0) { - var win = window.open(data['filename'], '_blank'); - win.focus(); - }else{ - link = 'Download File '; - if(jQuery.inArray(fileParts[fileParts.length - 1], viewableImages ) >= 0) { - link += '

    '; - } - modJs.showMessage("Download File Attachment",link,closeCallback,closeCallbackData); - } - }else{ - fileParts = data['filename'].split("."); - link = 'Download File '; - if(jQuery.inArray(fileParts[fileParts.length - 1], viewableImages ) >= 0) { - link += '

    '; - } - - modJs.showMessage("Download File Attachment",link,closeCallback,closeCallbackData); - } - - - }; - - var failCallback = function(data){ - modJs.showMessage("Error Downloading File","File not found"); - }; - - modJs.sendCustomRequest("file",{'name':name},successCallback,failCallback); -} - -function randomString(length){ - var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split(''); - - if (! length) { - length = Math.floor(Math.random() * chars.length); - } - - var str = ''; - for (var i = 0; i < length; i++) { - str += chars[Math.floor(Math.random() * chars.length)]; - } - return str; -} - -function verifyInstance(key){ - var object = {}; - object['a'] = "verifyInstance"; - object['key'] = key; - $.post(this.baseUrl, object, function(data) { - if(data.status == "SUCCESS"){ - $("#verifyModel").hide(); - $('body').removeClass('modal-open'); - $('.modal-backdrop').remove(); - alert("Success: Instance Verified"); - }else{ - alert("Error: "+data.message); - } - },"json"); -} - -function nl2br(str, is_xhtml) { - // discuss at: http://phpjs.org/functions/nl2br/ - // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // improved by: Philip Peterson - // improved by: Onno Marsman - // improved by: Atli ��r - // improved by: Brett Zamir (http://brett-zamir.me) - // improved by: Maximusya - // bugfixed by: Onno Marsman - // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // input by: Brett Zamir (http://brett-zamir.me) - // example 1: nl2br('Kevin\nvan\nZonneveld'); - // returns 1: 'Kevin
    \nvan
    \nZonneveld' - // example 2: nl2br("\nOne\nTwo\n\nThree\n", false); - // returns 2: '
    \nOne
    \nTwo
    \n
    \nThree
    \n' - // example 3: nl2br("\nOne\nTwo\n\nThree\n", true); - // returns 3: '
    \nOne
    \nTwo
    \n
    \nThree
    \n' - - var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '
    ' : '
    '; // Adjust comment to avoid issue on phpjs.org display - - return (str + '') - .replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2'); -} - -function updateLanguage(language) { - var object = {}; - object['a'] = "updateLanguage"; - object['language'] = language; - $.post(this.baseUrl, object, function(data) { - if(data.status == "SUCCESS"){ - location.reload(); - } else { - alert("Error occurred while changing language"); - } - },"json"); -} diff --git a/web/js/bootstrap-colorpicker-2.1.1/css/bootstrap-colorpicker.css b/web/js/bootstrap-colorpicker-2.1.1/css/bootstrap-colorpicker.css index 80175eaf..e055992b 100644 --- a/web/js/bootstrap-colorpicker-2.1.1/css/bootstrap-colorpicker.css +++ b/web/js/bootstrap-colorpicker-2.1.1/css/bootstrap-colorpicker.css @@ -13,7 +13,7 @@ width: 100px; height: 100px; cursor: crosshair; - background-image: url("../img/bootstrap-colorpicker/saturation.png"); + background-image: url("img/bootstrap-colorpicker/saturation.png"); } .colorpicker-saturation i { @@ -64,12 +64,12 @@ } .colorpicker-hue { - background-image: url("../img/bootstrap-colorpicker/hue.png"); + background-image: url("img/bootstrap-colorpicker/hue.png"); } .colorpicker-alpha { display: none; - background-image: url("../img/bootstrap-colorpicker/alpha.png"); + background-image: url("img/bootstrap-colorpicker/alpha.png"); } .colorpicker { @@ -135,7 +135,7 @@ height: 10px; margin-top: 5px; clear: both; - background-image: url("../img/bootstrap-colorpicker/alpha.png"); + background-image: url("img/bootstrap-colorpicker/alpha.png"); background-position: 0 100%; } @@ -197,11 +197,11 @@ } .colorpicker.colorpicker-horizontal .colorpicker-hue { - background-image: url("../img/bootstrap-colorpicker/hue-horizontal.png"); + background-image: url("img/bootstrap-colorpicker/hue-horizontal.png"); } .colorpicker.colorpicker-horizontal .colorpicker-alpha { - background-image: url("../img/bootstrap-colorpicker/alpha-horizontal.png"); + background-image: url("img/bootstrap-colorpicker/alpha-horizontal.png"); } .colorpicker.colorpicker-hidden { diff --git a/web/js/downloadify/images/download.png b/web/js/downloadify/images/download.png deleted file mode 100755 index d2fabbf5a2bae5496b4d5db6fbd4c5338ff46cff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2500 zcmV;#2|MnEsHmv0u&|t*o~o*Io}QqtuCA)8tm5M0 z!otI+r>L~FwydnKsHm#3v9YhOu(!9khlhx{xw)I0od5s-$jHfecXwxJXI@@jkB^Uj zet&awbI#7sZ*Om+qNBdPzV*cn*8l(rnn^@KRCwClS!=Gwk|h{OAv>yII7nhNf?*KJNibeVBKp7+NjBU+7XVy(U<{iGuz?6)h?W}& zQNsWjkLL!Lcl(=_;ydW>Yi3W`mis@e9vk^~W8XMrovCH@b zKo5%yGP5?0Tc*NZO(C-$vuk)x_HZx`abmfwFqn%&w6VPk1s+`T7lsO|Q9x=KDO@L@ z2lfSqSg^L)KwFR(lmm^1+?Mrft&7c5e+m+0)CSCd+93D9*-B;z~U zXDsTvJx*wGS~6I4g(M%<9r*!sG07{~SJfV>%A12dt2~7gwcrsJSXHH9%0>ze_vDF9 z%6wI!6jo?1PD}2Kejv%>bAZ3j=ks5mpW4so=Z}VC@4O*1TF)L2*lbG~Hc&m|QJr;~LlJurv^hok+CK$hvWakOS z4oQ}_U@VbjA^MmsUPUq%y+ec zgY5A$8D^Is&74`}d!CE%ypExbr4~Elx9A+7O$W8GW3s*D?8)b)fF72bXf|2nI1Tey z=UHsIdCaciIq6`#+VUmmF3E2$4Q4D&c3Lh^0pk0&hyy#I>6qt7py7!}$hiShzH5BH zZF5xh$9xC{N%X;8wlQ>Fhi=RYT`$#!BTC^>2|i7m4Hrd{Z~%QWndo6S(ZW!h;8>Zg$&A*C!UNXaFq%w8e5g(M1nSl| zE6r6V{e8{2{=e=Oek>_1FND>JLl9<9lDJ&dF;t2(hcAtEyVzb6#PQ zQ00t%(&e%~1@y2KrSWkaHC5F_SO&}rwlg2j$;097*fLn!EAzxY=h5jV+D{UA_+3r@ z71yaNCI^AcW&MevhfP-*cqW?$L2hGrV%h5P#6NshE{<3`7>oQ`JKRKj%WH>Qgbj9{ z1Ic=Jm-Q`|^)sp+b~)7!zlMuGUy#A9>$zD;aWCSSMJy_NCEyAO%yKWZ^8@^p_kijJ| z-s`%7fT=MnhKnLeImGl@JCtCRr3IxvVlaA_T9JMD|87>{qFJ@!R!VGQ*Kzgr;Pk>$OnS zXC%=?*C!g1)TLn5NTM$VLq`(jLogI15&y3ZBzY4}^7bl{muy$R8lY<1wxWmQ5u3!v z#!pr&w6-1@=%GzkP1`m+o*OFO**7c2&)V62O(I!u?{F-oR4iw^Js`H*FBxsBb5ZA* z?g2jc<-DDjy_}V0rt%3LdK#lA^U*6y@3@t}wwFd3-xpm!ofAn8`>+g`P80Nnv;30L zrrIBEfCrcSLI2Tw^nq;my-mKQEu%;N3O>4EDS!3-TZx^cqH2FUC;IM=ey*yjS?*$A zRsDEp%V<-bd8?|{En?9wb~}Hw+il2qjgXz4*?sJkL{*c1Cl~Qb8LYV@lHsqZZy^>& zSsu!XZ6|){$Y@igymf5*7O`qpVc2ZKaMRJyrU>~G=G{14dstLCVHd}nM^*ZCLB8jj zrpZ#@V4pX=S(x;C?-cD%)O-8h_YG}VL&FQTjnpr?pf`0*^G)&V`edD%+}3`Tph{7{n)xxc_RUxwmOojGjqE;AJFd z(IotXUke5o5{h8ZInmw(gR2$c|39G%GTaG8NEhT%bapMxmk92E1sDM8vG0LscT3>_ O0000 - is released under the MIT License -*/ -var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab+JCW$?cC$cOh zc4RBIWG9muk3~tB7AG{R5h*{qX*RRzX3$MnT?7RhOfeYrCv;a7Xi?A(nkmpt(M8ce z&|O>iT#|kyGiZf`Jdf|5d+vA6A?ZED{|%w=YlH?dnvb4C2>rPC_ZXp>c0-w7oi8Nz zwl&?H2JQYx)3RFA>GbaI?)dJlaihJJo|u}NN@ph1laphB7&G^EOWqsP&8s7`PJnr8 z*4t{!QVl)9bh&19totJ)UereYBxtMC)|`-ydYWosGvNe`!X>>N*FlsbW(CA*`b|QPa-a)$%25y`t zI(z1rGFv@fH@4HQw$bR+AtwbwIg8IOVIf+bnx>jf+Mey`FLYzq-Qv{BF!eT-E#qCp zv5omPS>Ni&TXZ(R?D$S}Cr8<$vx~Bxn4Cx@CNmQmHw|W;Nx#RoXMqCFqWQ=_d^0G= z9UUD#5BQ+MBK+skKd&R_7yo(p$}m*?4}p0|Ni*bzs_diR^oe1Fz>Ji(yiF%i1dSsO z)O|$e3`3)`&hHp%qs!rbobIrK33+xC%T`;}w}P&xW2u@c&Fxz>+iuJI!84nLTtq`P zTbjHtmRoJrqQr0xV2Y*M=d^C|imFk`1?toa6+m633T;!pP6J}Nm0itr!%JzrrEiI@Uo3)7 z+X0hWc{fB4h@I9vRpgFl%{ibhLtipFCe7;>Z67N|3LP2r6n0q2lh;~NPs%|PzHq1t z8+sYwIb*w}QHyqYstjk-g07Npw~cl`wBUGS9}cS4PiYnBWRu>xec=b4)2_2?E?dsu zxxJZtlwB=nvvaxmeBt4vg~i9krRCC-mDO@(ZT;!9kDtr6dV?xkP4)8^+O}@AzG$0P zXJ>bB|3{gL$y>KSxO4a3)XnsL0z8^f9sx#kJR?F8j0Wv?ZznYt8-ym7dIG?xbrSRkKvR z@135Uc6&1Uu5sSIyA7H%;F+iDw0-$q&;n};xo)XD)CHdZA3-jhouX-{HJD$v>hR?7 zTZTJPg4^P5Yln`z)@fzG+-T&Qs@4d&{mXa=xXsCe3Ay4z?r{V_j#^Zq0Fbh@S}GPd zOY8Ynzbma(0!yW}a(;8Z^mN(pifd28UUqwMB3;&^c~5YTsK|91WV=HRYjXXCKUZ3M zQp{KKVlKO!%NOx}U~RRyN?}w@i)RVrz4)1j!1xxmDiFG0v{}3JP(|(1dww?b%TPiO z^S*mtw&cow>)0)t4qLp*=N0z8jeGB@f-jv%}tII)qk%+1{=w3;YocPQnIB8#V9~y}|6x>XxW&(!MQtOHO zaY6}0*Y@Kv9OGjo78sNS6zh%+4_=4+gn$OH|D(7Re-O{c=i<5ed^{9e1?zD9Iv*A> z-xUfA-H~WdZ(qL@zytoluyn2;`!@*Y2=)<9AXp?mKfw~=gGB5iI7GxSArT@*iP%GM zFA@8Q*iXb55eJAkNW?hd&lB+i5ib(q5)m#FAwh&8B3vQDRU#ybaEqB=|PL9}xZy!FLJ1NBAj%rwRU$;2DDN6Fe(Lv6RPB0ZR|D^avBYK=2~r z9ur(7c!}U;f=dKHA$Wzv$^=&kUL$y&;HQK^bs&0f1SfHv;gN?++7 zwuhTjc6D0$&{i&#W;iC^x0OLpoVAs6p7@ci#69tWt(*t3noV7>l~`$xvz0*Ar{rwq zB11UJyscaU1&+h{I4O{U(;PG-wh|eR1J$s163KacSe}Y_>c4HJ`xjsuk*5Il2q7N_ z>uxd@`WO3Avu~qdE4_;a{Ic*Tz#o(zVmHboFBojav#qYc61L3%i`z3254!P>y!gY- zC?EwE{E~<4^^oK=u@MI)@;)h$^iby{ z7Pmg{St__{dg->Y_pqN^BaSwIup=^e;z8H9m>nB#~0N_AmT(l6wtcK8YPm()V?e|K*z` z29baLE62mRYBxZ^!+|Jz9-pgz^tD`hqpU-+5qKs@HNGY$@vGzmz=)892&%9D??*?@ zQ6e#b99D+_MU+b6DSq|k+Zq8FsgWA5toQ%*=*UTR;PTPYA@CAmtn~tG!v|1kM%$sX zUU(NwO}~Q#oCT4%Lzq|{I;aUX@f9Rf_!ytbng{CO zF?z%C9w_VIM*nz*J%X=B*rC0=~PpN>}<>ac92m#i> z|DX>VndNrqa#VVb-y!G??vgq?f&e&i-}y0QCO?e5sLSA3+C} diff --git a/web/js/select2/select2.css b/web/js/select2/select2.css index c88e73e5..f72e0f71 100644 --- a/web/js/select2/select2.css +++ b/web/js/select2/select2.css @@ -105,7 +105,7 @@ html[dir="rtl"] .select2-container .select2-choice > .select2-chosen { text-decoration: none; border: 0; - background: url('select2.png') right top no-repeat; + background: url(' img/select2/select2.png') right top no-repeat; cursor: pointer; outline: 0; } @@ -218,7 +218,7 @@ html[dir="rtl"] .select2-container .select2-choice .select2-arrow { display: block; width: 100%; height: 100%; - background: url('select2.png') no-repeat 0 1px; + background: url(' img/select2/select2.png') no-repeat 0 1px; } html[dir="rtl"] .select2-container .select2-choice .select2-arrow b { @@ -256,21 +256,21 @@ html[dir="rtl"] .select2-container .select2-choice .select2-arrow b { -webkit-box-shadow: none; box-shadow: none; - background: #fff url('select2.png') no-repeat 100% -22px; - background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee)); - background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2.png') no-repeat 100% -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0; + background: #fff url(' img/select2/select2.png') no-repeat 100% -22px; + background: url(' img/select2/select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee)); + background: url(' img/select2/select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%); + background: url(' img/select2/select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%); + background: url(' img/select2/select2.png') no-repeat 100% -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0; } html[dir="rtl"] .select2-search input { padding: 4px 5px 4px 20px; - background: #fff url('select2.png') no-repeat -37px -22px; - background: url('select2.png') no-repeat -37px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee)); - background: url('select2.png') no-repeat -37px -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2.png') no-repeat -37px -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2.png') no-repeat -37px -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0; + background: #fff url(' img/select2/select2.png') no-repeat -37px -22px; + background: url(' img/select2/select2.png') no-repeat -37px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee)); + background: url(' img/select2/select2.png') no-repeat -37px -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%); + background: url(' img/select2/select2.png') no-repeat -37px -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%); + background: url(' img/select2/select2.png') no-repeat -37px -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0; } .select2-drop.select2-drop-above .select2-search input { @@ -278,11 +278,11 @@ html[dir="rtl"] .select2-search input { } .select2-search input.select2-active { - background: #fff url('select2-spinner.gif') no-repeat 100%; - background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee)); - background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%); - background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0; + background: #fff url(' img/select2/select2-spinner.gif') no-repeat 100%; + background: url(' img/select2/select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee)); + background: url(' img/select2/select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%); + background: url(' img/select2/select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%); + background: url(' img/select2/select2-spinner.gif') no-repeat 100%, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0; } .select2-container-active .select2-choice, @@ -451,7 +451,7 @@ disabled look for disabled choices in the results dropdown } .select2-more-results.select2-active { - background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%; + background: #f4f4f4 url(' img/select2/select2-spinner.gif') no-repeat 100%; } .select2-results .select2-ajax-error { @@ -551,7 +551,7 @@ html[dir="rtl"] .select2-container-multi .select2-choices li } .select2-container-multi .select2-choices .select2-search-field input.select2-active { - background: #fff url('select2-spinner.gif') no-repeat 100% !important; + background: #fff url(' img/select2/select2-spinner.gif') no-repeat 100% !important; } .select2-default { @@ -610,7 +610,7 @@ html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice font-size: 1px; outline: none; - background: url('select2.png') right top no-repeat; + background: url(' img/select2/select2.png') right top no-repeat; } html[dir="rtl"] .select2-search-choice-close { right: auto; @@ -693,7 +693,7 @@ html[dir="rtl"] .select2-container-multi .select2-search-choice-close { .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b { - background-image: url('select2x2.png') !important; + background-image: url('img/select2/select2x2.png') !important; background-repeat: no-repeat !important; background-size: 60px 40px !important; } diff --git a/web/modules/attendance/lib.js b/web/modules/attendance/lib.js deleted file mode 100644 index c579a27f..00000000 --- a/web/modules/attendance/lib.js +++ /dev/null @@ -1,513 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function AttendanceAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); - this.punch = null; - this.useServerTime = 0; - this.photoTaken = 0; - this.photoAttendance = 0; -} - -AttendanceAdapter.inherits(AdapterBase); - -AttendanceAdapter.method('updatePunchButton', function() { - this.getPunch('changePunchButtonSuccessCallBack'); -}); - -AttendanceAdapter.method('setUseServerTime', function(val) { - this.useServerTime = val; -}); - -AttendanceAdapter.method('setPhotoAttendance', function(val) { - this.photoAttendance = val; -}); - - -AttendanceAdapter.method('getDataMapping', function() { - return [ - "id", - "in_time", - "out_time", - "note" - ]; -}); - -AttendanceAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Time-In" }, - { "sTitle": "Time-Out"}, - { "sTitle": "Note"} - ]; -}); - -AttendanceAdapter.method('getFormFields', function() { - if(this.useServerTime == 0){ - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "time", {"label":"Time","type":"datetime"}], - [ "note", {"label":"Note","type":"textarea","validation":"none"}] - ]; - }else{ - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "note", {"label":"Note","type":"textarea","validation":"none"}] - ]; - } - -}); - - -AttendanceAdapter.method('getCustomTableParams', function() { - var that = this; - var dataTableParams = { - "aoColumnDefs": [ - { - "fnRender": function(data, cell){ - return that.preProcessRemoteTableData(data, cell, 1) - } , - "aTargets": [1] - }, - { - "fnRender": function(data, cell){ - return that.preProcessRemoteTableData(data, cell, 2) - } , - "aTargets": [2] - }, - { - "fnRender": function(data, cell){ - return that.preProcessRemoteTableData(data, cell, 3) - } , - "aTargets": [3] - }, - { - "fnRender": that.getActionButtons, - "aTargets": [that.getDataMapping().length] - } - ] - }; - return dataTableParams; -}); - -AttendanceAdapter.method('preProcessRemoteTableData', function(data, cell, id) { - if(id == 1){ - if(cell == '0000-00-00 00:00:00' || cell == "" || cell == undefined || cell == null){ - return ""; - } - return Date.parse(cell).toString('yyyy MMM d HH:mm'); - }else if(id == 2){ - if(cell == '0000-00-00 00:00:00' || cell == "" || cell == undefined || cell == null){ - return ""; - } - return Date.parse(cell).toString('MMM d HH:mm'); - }else if(id == 3){ - if(cell != undefined && cell != null){ - if(cell.length > 20){ - return cell.substring(0,20)+".."; - } - } - return cell; - } - -}); - - -AttendanceAdapter.method('getActionButtonsHtml', function(id,data) { - /* - var html = '
    '; - html = html.replace(/_id_/g,id); - html = html.replace(/_attachment_/g,data[5]); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; - */ - return ""; -}); - -AttendanceAdapter.method('getTableTopButtonHtml', function() { - if(this.punch == null || this.punch == undefined){ - return ''; - }else{ - return ''; - } - -}); - - -AttendanceAdapter.method('save', function() { - var that = this; - var validator = new FormValidation(this.getTableName()+"_submit",true,{'ShowPopup':false,"LabelErrorClass":"error"}); - if(validator.checkValues()){ - - var msg = this.doCustomValidation(params); - if(msg == null){ - var params = validator.getFormParameters(); - params = this.forceInjectValuesBeforeSave(params); - params['cdate'] = this.getClientDate(new Date()).toISOString().slice(0, 19).replace('T', ' '); - var reqJson = JSON.stringify(params); - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'saveSuccessCallback'; - callBackData['callBackFail'] = 'getPunchFailCallBack'; - - this.customAction('savePunch','modules=attendance',reqJson,callBackData, true); - }else{ - $("#"+this.getTableName()+'Form .label').html(msg); - $("#"+this.getTableName()+'Form .label').show(); - } - } -}); - -AttendanceAdapter.method('saveSuccessCallback', function(callBackData) { - this.punch = callBackData; - this.getPunch('changePunchButtonSuccessCallBack'); - $('#PunchModel').modal('hide'); - this.get([]); -}); - - -AttendanceAdapter.method('cancel', function() { - $('#PunchModel').modal('hide'); -}); - -AttendanceAdapter.method('showPunchDialog', function() { - this.getPunch('showPunchDialogShowPunchSuccessCallBack'); -}); - -AttendanceAdapter.method('getPunch', function(successCallBack) { - var that = this; - var object = {}; - - object['date'] = this.getClientDate(new Date()).toISOString().slice(0, 19).replace('T', ' '); - object['offset'] = this.getClientGMTOffset(); - var reqJson = JSON.stringify(object); - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = successCallBack; - callBackData['callBackFail'] = 'getPunchFailCallBack'; - - this.customAction('getPunch','modules=attendance',reqJson,callBackData); -}); - -AttendanceAdapter.method('postRenderForm', function(object, $tempDomObj) { - $("#Attendance").show(); -}); - - -AttendanceAdapter.method('showPunchDialogShowPunchSuccessCallBack', function(callBackData) { - this.punch = callBackData; - $('#PunchModel').modal('show'); - if(this.punch == null){ - $('#PunchModel').find("h3").html("Punch Time-in"); - modJs.renderForm(); - }else{ - $('#PunchModel').find("h3").html("Punch Time-out"); - modJs.renderForm(this.punch); - } - $('#Attendance').show(); - var picker = $('#time_datetime').data('datetimepicker'); - picker.setLocalDate(new Date()); -}); - -AttendanceAdapter.method('changePunchButtonSuccessCallBack', function(callBackData) { - this.punch = callBackData; - if(this.punch == null){ - $("#punchButton").html('Punch-in '); - }else{ - $("#punchButton").html('Punch-out '); - } -}); - -AttendanceAdapter.method('getPunchFailCallBack', function(callBackData) { - this.showMessage("Error Occured while Time Punch", callBackData); -}); - -AttendanceAdapter.method('getClientDate', function (date) { - - var offset = this.getClientGMTOffset(); - var tzDate = date.addMinutes(offset*60); - return tzDate; - -}); - -AttendanceAdapter.method('getClientGMTOffset', function () { - - var rightNow = new Date(); - var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0); - var temp = jan1.toGMTString(); - var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1)); - var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60); - - return std_time_offset; - -}); - -AttendanceAdapter.method('doCustomValidation', function(params) { - if (this.photoAttendance && !this.photoTaken) { - return "Please attach a photo before submitting"; - } - return null; -}); - -AttendanceAdapter.method('forceInjectValuesBeforeSave', function(params) { - if (this.photoAttendance) { - var canvas = document.getElementById('attendnaceCanvas'); - params.image = canvas.toDataURL(); - } - return params; -}); - -AttendanceAdapter.method('postRenderForm', function() { - if (this.photoAttendance == '1') { - $('.photoAttendance').show(); - var video = document.getElementById('attendnaceVideo'); - - // Get access to the camera! - if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { - navigator.mediaDevices.getUserMedia({ video: true }).then(function(stream) { - video.src = window.URL.createObjectURL(stream); - video.play(); - }); - } - this.photoTaken = false; - this.configureEvents(); - } else { - $('.photoAttendance').remove(); - } - -}); - -AttendanceAdapter.method('configureEvents', function() { - var that = this; - var canvas = document.getElementById('attendnaceCanvas'); - var context = canvas.getContext('2d'); - var video = document.getElementById('attendnaceVideo'); - $('.attendnaceSnap').click(function() { - context.drawImage(video, 0, 0, 208, 156); - that.photoTaken = true; - return false; - }); -}); - - - - - -function EmployeeAttendanceSheetAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeAttendanceSheetAdapter.inherits(AdapterBase); - -this.currentTimesheetId = null; -this.currentTimesheet = null; - -EmployeeAttendanceSheetAdapter.method('getDataMapping', function() { - return [ - "id", - "date_start", - "date_end", - "total_time", - "status" - ]; -}); - -EmployeeAttendanceSheetAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Start Date"}, - { "sTitle": "End Date"}, - { "sTitle": "Total Time"}, - { "sTitle": "Status"} - ]; -}); - -EmployeeAttendanceSheetAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "date_start", {"label":"TimeSheet Start Date","type":"date","validation":""}], - [ "date_end", {"label":"TimeSheet End Date","type":"date","validation":""}], - [ "details", {"label":"Reason","type":"textarea","validation":"none"}] - ]; -}); - -EmployeeAttendanceSheetAdapter.method('preProcessTableData', function(row) { - row[1] = Date.parse(row[1]).toString('MMM d, yyyy (dddd)'); - row[2] = Date.parse(row[2]).toString('MMM d, yyyy (dddd)'); - return row; -}); - -EmployeeAttendanceSheetAdapter.method('renderForm', function(object) { - var formHtml = this.templates['formTemplate']; - var html = ""; - - $("#"+this.getTableName()+'Form').html(formHtml); - $("#"+this.getTableName()+'Form').show(); - $("#"+this.getTableName()).hide(); - - $('#attendnacesheet_start').html(Date.parse(object.date_start).toString('MMM d, yyyy (dddd)')); - $('#attendnacesheet_end').html(Date.parse(object.date_end).toString('MMM d, yyyy (dddd)')); - - this.currentTimesheet = object; - - this.getTimeEntries(); - -}); - - - -EmployeeAttendanceSheetAdapter.method('getTimeEntries', function() { - timesheetId = this.currentId; - var sourceMappingJson = JSON.stringify(modJsList['tabEmployeeTimeEntry'].getSourceMapping()); - object = {"id":timesheetId,"sm":sourceMappingJson}; - - var reqJson = JSON.stringify(object); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'getTimeEntriesSuccessCallBack'; - callBackData['callBackFail'] = 'getTimeEntriesFailCallBack'; - - this.customAction('getTimeEntries','modules=time_sheets',reqJson,callBackData); -}); - -EmployeeAttendanceSheetAdapter.method('getTimeEntriesSuccessCallBack', function(callBackData) { - var entries = callBackData; - var html = ""; - var temp = '_start__end__duration__project__details_'; - - for(var i=0;i. - - ------------------------------------------------------------------ - - Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] - Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function DashboardAdapter(endPoint) { - this.initAdapter(endPoint); -} - -DashboardAdapter.inherits(AdapterBase); - - - -DashboardAdapter.method('getDataMapping', function() { - return []; -}); - -DashboardAdapter.method('getHeaders', function() { - return []; -}); - -DashboardAdapter.method('getFormFields', function() { - return []; -}); - - -DashboardAdapter.method('get', function(callBackData) { -}); - - -DashboardAdapter.method('getPunch', function() { - var that = this; - var object = {}; - - object['date'] = this.getClientDate(new Date()).toISOString().slice(0, 19).replace('T', ' '); - object['offset'] = this.getClientGMTOffset(); - var reqJson = JSON.stringify(object); - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'getPunchSuccessCallBack'; - callBackData['callBackFail'] = 'getPunchFailCallBack'; - - this.customAction('getPunch','modules=attendance',reqJson,callBackData); -}); - - - -DashboardAdapter.method('getPunchSuccessCallBack', function(callBackData) { - var punch = callBackData; - if(punch == null){ - $("#lastPunchTime").html("Not"); - $("#punchTimeText").html("Punched In"); - }else{ - $("#lastPunchTime").html(Date.parse(punch.in_time).toString('h:mm tt')); - $("#punchTimeText").html("Punched In"); - } -}); - -DashboardAdapter.method('getPunchFailCallBack', function(callBackData) { - -}); - -DashboardAdapter.method('getInitData', function() { - var that = this; - var object = {}; - var reqJson = JSON.stringify(object); - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'getInitDataSuccessCallBack'; - callBackData['callBackFail'] = 'getInitDataFailCallBack'; - - this.customAction('getInitData','modules=dashboard',reqJson,callBackData); -}); - - - -DashboardAdapter.method('getInitDataSuccessCallBack', function(data) { - - $("#timeSheetHoursWorked").html(data['lastTimeSheetHours']); - $("#numberOfProjects").html(data['activeProjects']); - $("#pendingLeaveCount").html(data['pendingLeaves']); - - $("#numberOfEmployees").html(data['numberOfEmployees']+" Subordinates"); - $("#numberOfCandidates").html(data['numberOfCandidates']+" Candidates"); - $("#numberOfJobs").html(data['numberOfJobs']+" Active"); - $("#numberOfCourses").html(data['numberOfCourses']+" Active"); - -}); - -DashboardAdapter.method('getInitDataFailCallBack', function(callBackData) { - -}); - - -DashboardAdapter.method('getClientDate', function (date) { - - var offset = this.getClientGMTOffset(); - var tzDate = date.addMinutes(offset*60); - return tzDate; - -}); - -DashboardAdapter.method('getClientGMTOffset', function () { - - var rightNow = new Date(); - var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0); - var temp = jan1.toGMTString(); - var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1)); - var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60); - - return std_time_offset; - -}); diff --git a/web/modules/dependents/lib.js b/web/modules/dependents/lib.js deleted file mode 100644 index 937b600a..00000000 --- a/web/modules/dependents/lib.js +++ /dev/null @@ -1,64 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - - -/** - * EmployeeDependentAdapter - */ - -function EmployeeDependentAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeDependentAdapter.inherits(AdapterBase); - - - -EmployeeDependentAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "relationship", - "dob", - "id_number" - ]; -}); - -EmployeeDependentAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Relationship"}, - { "sTitle": "Date of Birth"}, - { "sTitle": "Id Number"} - ]; -}); - -EmployeeDependentAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "relationship", {"label":"Relationship","type":"select","source":[["Child","Child"],["Spouse","Spouse"],["Parent","Parent"],["Other","Other"]]}], - [ "dob", {"label":"Date of Birth","type":"date","validation":""}], - [ "id_number", {"label":"Id Number","type":"text","validation":"none"}] - ]; -}); diff --git a/web/modules/emergency_contact/lib.js b/web/modules/emergency_contact/lib.js deleted file mode 100644 index 3d485d93..00000000 --- a/web/modules/emergency_contact/lib.js +++ /dev/null @@ -1,63 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - - -function EmergencyContactAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmergencyContactAdapter.inherits(AdapterBase); - - - -EmergencyContactAdapter.method('getDataMapping', function() { - return [ - "id", - "name", - "relationship", - "home_phone", - "work_phone", - "mobile_phone" - ]; -}); - -EmergencyContactAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Name" }, - { "sTitle": "Relationship"}, - { "sTitle": "Home Phone"}, - { "sTitle": "Work Phone"}, - { "sTitle": "Mobile Phone"} - ]; -}); - -EmergencyContactAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "name", {"label":"Name","type":"text","validation":""}], - [ "relationship", {"label":"Relationship","type":"text","validation":"none"}], - [ "home_phone", {"label":"Home Phone","type":"text","validation":"none"}], - [ "work_phone", {"label":"Work Phone","type":"text","validation":"none"}], - [ "mobile_phone", {"label":"Mobile Phone","type":"text","validation":"none"}] - ]; -}); diff --git a/web/modules/employees/lib.js b/web/modules/employees/lib.js deleted file mode 100644 index 290a633f..00000000 --- a/web/modules/employees/lib.js +++ /dev/null @@ -1,730 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function EmployeeAdapter(endPoint) { - this.initAdapter(endPoint); - this.fieldNameMap = {}; - this.hiddenFields = {}; - this.tableFields = {}; - this.formOnlyFields = {}; -} - -EmployeeAdapter.inherits(AdapterBase); - -this.currentUserId = null; - -EmployeeAdapter.method('setFieldNameMap', function(fields) { - var field; - for(var i=0;i 0) { - - - var ct = '
    '; - - var sectionTemplate = '

    #_section.name_#

    '; - var customFieldHtml; - for (index in data.customFields) { - - if(!data.customFields[index][1]){ - data.customFields[index][1] = this.gt('Other Details'); - } - - sectionId = data.customFields[index][1].toLocaleLowerCase(); - sectionId = sectionId.replace(' ','_'); - - if($("#cont_"+sectionId).length <= 0){ - //Add section - sectionHtml = sectionTemplate; - sectionHtml = sectionHtml.replace('#_section_#', sectionId); - sectionHtml = sectionHtml.replace('#_section.name_#', data.customFields[index][1]); - $("#customFieldsCont").append($(sectionHtml)); - } - - customFieldHtml = ct; - customFieldHtml = customFieldHtml.replace('#_label_#', index); - if (data.customFields[index][2] === 'fileupload') { - customFieldHtml = customFieldHtml.replace( - '#_value_#', - '' - ); - } else { - customFieldHtml = customFieldHtml.replace('#_value_#', data.customFields[index][0]); - } - $("#cont_"+sectionId).append($(customFieldHtml)); - } - }else{ - $("#customFieldsCont").remove(); - } - - $("#"+this.getTableName()+" #subordinates").html(subordinates); - - - $("#"+this.getTableName()+" #name").html(data.first_name + " " + data.last_name); - this.currentUserId = data.id; - - $("#"+this.getTableName()+" #profile_image_"+data.id).attr('src',data.image); - - if(this.checkPermission("Upload/Delete Profile Image") == "No"){ - $("#employeeUploadProfileImage").remove(); - $("#employeeDeleteProfileImage").remove(); - } - - if(this.checkPermission("Edit Employee Details") == "No"){ - $("#employeeProfileEditInfo").remove(); - } - - if(currentEmpId != userEmpId){ - $("#employeeUpdatePassword").remove(); - } - - this.cancel(); -}); - -EmployeeAdapter.method('modEmployeeGetFailCallBack' , function(data) { - -}); - -EmployeeAdapter.method('editEmployee' , function() { - this.edit(this.currentUserId); -}); - -EmployeeAdapter.method('changePassword', function() { - $('#adminUsersModel').modal('show'); - $('#adminUsersChangePwd #newpwd').val(''); - $('#adminUsersChangePwd #conpwd').val(''); -}); - -EmployeeAdapter.method('changePasswordConfirm', function() { - $('#adminUsersChangePwd_error').hide(); - - var passwordValidation = function (str) { - return str.length > 7; - }; - - var password = $('#adminUsersChangePwd #newpwd').val(); - - if(!passwordValidation(password)){ - $('#adminUsersChangePwd_error').html("Password should be longer than 7 characters"); - $('#adminUsersChangePwd_error').show(); - return; - } - - var conPassword = $('#adminUsersChangePwd #conpwd').val(); - - if(conPassword != password){ - $('#adminUsersChangePwd_error').html("Passwords don't match"); - $('#adminUsersChangePwd_error').show(); - return; - } - - var req = {"pwd":conPassword}; - var reqJson = JSON.stringify(req); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'changePasswordSuccessCallBack'; - callBackData['callBackFail'] = 'changePasswordFailCallBack'; - - this.customAction('changePassword','modules=employees',reqJson,callBackData); - -}); - -EmployeeAdapter.method('closeChangePassword', function() { - $('#adminUsersModel').modal('hide'); -}); - -EmployeeAdapter.method('changePasswordSuccessCallBack', function(callBackData,serverData) { - this.closeChangePassword(); - this.showMessage("Password Change","Password changed successfully"); -}); - -EmployeeAdapter.method('changePasswordFailCallBack', function(callBackData,serverData) { - this.closeChangePassword(); - this.showMessage("Error",callBackData); -}); - - - - -/* - * Company Graph - */ - -function CompanyStructureAdapter(endPoint) { - this.initAdapter(endPoint); -} - -CompanyStructureAdapter.inherits(AdapterBase); - - - -CompanyStructureAdapter.method('getDataMapping', function() { - return [ - "id", - "title", - "address", - "type", - "country", - "parent" - ]; -}); - -CompanyStructureAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID","bVisible":false }, - { "sTitle": "Name" }, - { "sTitle": "Address"}, - { "sTitle": "Type"}, - { "sTitle": "Country", "sClass": "center" }, - { "sTitle": "Parent Structure"} - ]; -}); - -CompanyStructureAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden","validation":""}], - [ "title", {"label":"Name","type":"text","validation":""}], - [ "description", {"label":"Details","type":"textarea","validation":""}], - [ "address", {"label":"Address","type":"textarea","validation":"none"}], - [ "type", {"label":"Type","type":"select","source":[["Company","Company"],["Head Office","Head Office"],["Regional Office","Regional Office"],["Department","Department"],["Unit","Unit"],["Sub Unit","Sub Unit"],["Other","Other"]]}], - [ "country", {"label":"Country","type":"select","remote-source":["Country","code","name"]}], - [ "parent", {"label":"Parent Structure","type":"select","allow-null":true,"remote-source":["CompanyStructure","id","title"]}] - ]; -}); - - - -function CompanyGraphAdapter(endPoint) { - this.initAdapter(endPoint); - this.nodeIdCounter = 0; -} - -CompanyGraphAdapter.inherits(CompanyStructureAdapter); - - -CompanyGraphAdapter.method('convertToTree', function(data) { - var ice = {}; - ice['id'] = -1; - ice['title'] = ''; - ice['name'] = ''; - ice['children'] = []; - - var parent = null; - - var added = {}; - - - for(var i=0;i"; - obj.parent = null; - break; - } - parentIdArr[parent.id] = 1; - curObj = parent; - } - } - - if(errorMsg != ""){ - this.showMessage("Company Structure is having a cyclic dependency","We found a cyclic dependency due to following reasons:
    "+errorMsg); - return false; - } - - return true; - -}); - - - -/* - * Api Access - */ - -function ApiAccessAdapter(endPoint) { - this.initAdapter(endPoint); -} - -ApiAccessAdapter.inherits(AdapterBase); - - - -ApiAccessAdapter.method('getDataMapping', function() { - return [ - ]; -}); - -ApiAccessAdapter.method('getHeaders', function() { - return [ - - ]; -}); - -ApiAccessAdapter.method('getFormFields', function() { - return [ - ]; -}); - -ApiAccessAdapter.method('get', function() { - -}); diff --git a/web/modules/loans/lib.js b/web/modules/loans/lib.js deleted file mode 100644 index 148449f3..00000000 --- a/web/modules/loans/lib.js +++ /dev/null @@ -1,91 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function EmployeeCompanyLoanAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeCompanyLoanAdapter.inherits(AdapterBase); - - - -EmployeeCompanyLoanAdapter.method('getDataMapping', function() { - return [ - "id", - "loan", - "start_date", - "period_months", - "currency", - "amount", - "status" - ]; -}); - -EmployeeCompanyLoanAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Loan Type" }, - { "sTitle": "Loan Start Date"}, - { "sTitle": "Loan Period (Months)"}, - { "sTitle": "Currency"}, - { "sTitle": "Amount"}, - { "sTitle": "Status"} - ]; -}); - -EmployeeCompanyLoanAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "loan", {"label":"Loan Type","type":"placeholder","remote-source":["CompanyLoan","id","name"]}], - [ "start_date", {"label":"Loan Start Date","type":"placeholder","validation":""}], - [ "last_installment_date", {"label":"Last Installment Date","type":"placeholder","validation":"none"}], - [ "period_months", {"label":"Loan Period (Months)","type":"placeholder","validation":"number"}], - [ "currency", {"label":"Currency","type":"placeholder","remote-source":["CurrencyType","id","name"]}], - [ "amount", {"label":"Loan Amount","type":"placeholder","validation":"float"}], - [ "monthly_installment", {"label":"Monthly Installment","type":"placeholder","validation":"float"}], - [ "status", {"label":"Status","type":"placeholder","source":[["Approved","Approved"],["Paid","Paid"],["Suspended","Suspended"]]}], - [ "details", {"label":"Details","type":"placeholder","validation":"none"}] - ]; -}); - - -EmployeeCompanyLoanAdapter.method('getActionButtonsHtml', function(id,data) { - var editButton = ''; - var deleteButton = ''; - var html = '
    _edit__delete_
    '; - - if(this.showDelete){ - html = html.replace('_delete_',deleteButton); - }else{ - html = html.replace('_delete_',''); - } - - if(this.showEdit){ - html = html.replace('_edit_',editButton); - }else{ - html = html.replace('_edit_',''); - } - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); diff --git a/web/modules/overtime/lib.js b/web/modules/overtime/lib.js deleted file mode 100644 index 07af1c42..00000000 --- a/web/modules/overtime/lib.js +++ /dev/null @@ -1,120 +0,0 @@ -/* -This file is part of iCE Hrm. - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - - -function EmployeeOvertimeAdapter(endPoint) { - this.initAdapter(endPoint); - this.itemName = 'Overtime'; - this.itemNameLower = 'employeeovertime'; - this.modulePathName = 'overtime'; -} - -EmployeeOvertimeAdapter.inherits(ApproveModuleAdapter); - - - -EmployeeOvertimeAdapter.method('getDataMapping', function() { - return [ - "id", - "category", - "start_time", - "end_time", - "project", - "status" - ]; -}); - -EmployeeOvertimeAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Category" }, - { "sTitle": "Start Time" }, - { "sTitle": "End Time"}, - { "sTitle": "Project"}, - { "sTitle": "Status"} - ]; -}); - -EmployeeOvertimeAdapter.method('getFormFields', function() { - return [ - ["id", {"label": "ID", "type": "hidden"}], - ["category", {"label": "Category", "type": "select2", "allow-null":false, "remote-source": ["OvertimeCategory", "id", "name"]}], - ["start_time", {"label": "Start Time", "type": "datetime", "validation": ""}], - ["end_time", {"label": "End Time", "type": "datetime", "validation": ""}], - ["project", {"label": "Project", "type": "select2", "allow-null":true,"null=label":"none","remote-source": ["Project", "id", "name"]}], - ["notes", {"label": "Notes", "type": "textarea", "validation": "none"}] - ]; -}); - - -/* - EmployeeOvertimeApproverAdapter - */ - -function EmployeeOvertimeApproverAdapter(endPoint) { - this.initAdapter(endPoint); - this.itemName = 'Overtime'; - this.itemNameLower = 'employeeovertime'; - this.modulePathName = 'overtime'; -} - -EmployeeOvertimeApproverAdapter.inherits(EmployeeOvertimeAdminAdapter); - -EmployeeOvertimeApproverAdapter.method('getActionButtonsHtml', function(id,data) { - var statusChangeButton = ''; - var viewLogsButton = ''; - - var html = '
    _status__logs_
    '; - - - html = html.replace('_logs_',viewLogsButton); - - - if(data[this.getStatusFieldPosition()] == 'Processing'){ - html = html.replace('_status_',statusChangeButton); - - }else{ - html = html.replace('_status_',''); - } - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - html = html.replace(/_cstatus_/g,data[this.getStatusFieldPosition()]); - return html; -}); - -EmployeeOvertimeApproverAdapter.method('getStatusOptionsData', function(currentStatus) { - var data = {}; - if(currentStatus != 'Processing'){ - - }else{ - data["Approved"] = "Approved"; - data["Rejected"] = "Rejected"; - - } - - return data; -}); - -EmployeeOvertimeApproverAdapter.method('getStatusOptions', function(currentStatus) { - return this.generateOptions(this.getStatusOptionsData(currentStatus)); -}); - - -/* - EmployeeOvertimeAdapter - */ - -function SubordinateEmployeeOvertimeAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); - this.itemName = 'Overtime'; - this.itemNameLower = 'employeeovertime'; - this.modulePathName = 'overtime'; -} - -SubordinateEmployeeOvertimeAdapter.inherits(EmployeeOvertimeAdminAdapter); - diff --git a/web/modules/projects/lib.js b/web/modules/projects/lib.js deleted file mode 100644 index 1de245b1..00000000 --- a/web/modules/projects/lib.js +++ /dev/null @@ -1,51 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function EmployeeProjectAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeProjectAdapter.inherits(AdapterBase); - - - -EmployeeProjectAdapter.method('getDataMapping', function() { - return [ - "id", - "project" - ]; -}); - -EmployeeProjectAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Project" } - ]; -}); - -EmployeeProjectAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "project", {"label":"Project","type":"select2","remote-source":["Project","id","name"]}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}] - ]; -}); diff --git a/web/modules/qualifications/lib.js b/web/modules/qualifications/lib.js deleted file mode 100644 index bff3966a..00000000 --- a/web/modules/qualifications/lib.js +++ /dev/null @@ -1,200 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function EmployeeSkillAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeSkillAdapter.inherits(AdapterBase); - - - -EmployeeSkillAdapter.method('getDataMapping', function() { - return [ - "id", - "skill_id", - "details" - ]; -}); - -EmployeeSkillAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Skill" }, - { "sTitle": "Details"} - ]; -}); - -EmployeeSkillAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "skill_id", {"label":"Skill","type":"select2","allow-null":true,"remote-source":["Skill","id","name"]}], - [ "details", {"label":"Details","type":"textarea","validation":""}] - ]; -}); - - - - - -/** - * EmployeeEducationAdapter - */ - -function EmployeeEducationAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeEducationAdapter.inherits(AdapterBase); - - - -EmployeeEducationAdapter.method('getDataMapping', function() { - return [ - "id", - "education_id", - "institute", - "date_start", - "date_end" - ]; -}); - -EmployeeEducationAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID", "bVisible":false}, - { "sTitle": "Qualification" }, - { "sTitle": "Institute"}, - { "sTitle": "Start Date"}, - { "sTitle": "Completed On"}, - ]; -}); - -EmployeeEducationAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "education_id", {"label":"Qualification","type":"select2","allow-null":false,"remote-source":["Education","id","name"]}], - [ "institute", {"label":"Institute","type":"text","validation":""}], - [ "date_start", {"label":"Start Date","type":"date","validation":"none"}], - [ "date_end", {"label":"Completed On","type":"date","validation":"none"}] - ]; -}); - - - - - -/** - * EmployeeCertificationAdapter - */ - -function EmployeeCertificationAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeCertificationAdapter.inherits(AdapterBase); - - - -EmployeeCertificationAdapter.method('getDataMapping', function() { - return [ - "id", - "certification_id", - "institute", - "date_start", - "date_start" - ]; -}); - -EmployeeCertificationAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID","bVisible":false}, - { "sTitle": "Certification" }, - { "sTitle": "Institute"}, - { "sTitle": "Granted On"}, - { "sTitle": "Valid Thru"}, - ]; -}); - -EmployeeCertificationAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "certification_id", {"label":"Certification","type":"select2","allow-null":false,"remote-source":["Certification","id","name"]}], - [ "institute", {"label":"Institute","type":"text","validation":""}], - [ "date_start", {"label":"Granted On","type":"date","validation":"none"}], - [ "date_end", {"label":"Valid Thru","type":"date","validation":"none"}] - ]; -}); - - - -/** - * EmployeeLanguageAdapter - */ - -function EmployeeLanguageAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeLanguageAdapter.inherits(AdapterBase); - - - -EmployeeLanguageAdapter.method('getDataMapping', function() { - return [ - "id", - "language_id", - "reading", - "speaking", - "writing", - "understanding" - ]; -}); - -EmployeeLanguageAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID", "bVisible":false }, - { "sTitle": "Language" }, - { "sTitle": "Reading"}, - { "sTitle": "Speaking"}, - { "sTitle": "Writing"}, - { "sTitle": "Understanding"} - ]; -}); - -EmployeeLanguageAdapter.method('getFormFields', function() { - - var compArray = [["Elementary Proficiency","Elementary Proficiency"], - ["Limited Working Proficiency","Limited Working Proficiency"], - ["Professional Working Proficiency","Professional Working Proficiency"], - ["Full Professional Proficiency","Full Professional Proficiency"], - ["Native or Bilingual Proficiency","Native or Bilingual Proficiency"]]; - - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "language_id", {"label":"Language","type":"select2","allow-null":false,"remote-source":["Language","id","description"]}], - [ "reading", {"label":"Reading","type":"select","source":compArray}], - [ "speaking", {"label":"Speaking","type":"select","source":compArray}], - [ "writing", {"label":"Writing","type":"select","source":compArray}], - [ "understanding", {"label":"Understanding","type":"select","source":compArray}] - ]; -}); - diff --git a/web/modules/reports/lib.js b/web/modules/reports/lib.js deleted file mode 100644 index 31cc5d42..00000000 --- a/web/modules/reports/lib.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Author: Thilina Hasantha - */ - - -/** - * UserReportAdapter - */ - - -function UserReportAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); - this._construct(); -} - -UserReportAdapter.inherits(ReportAdapter); - -UserReportAdapter.method('renderForm', function(object) { - var that = this; - this.processFormFieldsWithObject(object); - if(this.remoteFieldsExists){ - var cb = function(){ - that.renderFormNew(object); - }; - this.initFieldMasterData(cb); - }else{ - this.initFieldMasterData(); - that.renderFormNew(object); - } - - this.currentReport = object; - -}); - diff --git a/web/modules/salary/lib.js b/web/modules/salary/lib.js deleted file mode 100644 index ab7b93f2..00000000 --- a/web/modules/salary/lib.js +++ /dev/null @@ -1,56 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function EmployeeSalaryAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeSalaryAdapter.inherits(AdapterBase); - - - -EmployeeSalaryAdapter.method('getDataMapping', function() { - return [ - "id", - "component", - "amount", - "details" - ]; -}); - -EmployeeSalaryAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Salary Component" }, - { "sTitle": "Amount"}, - { "sTitle": "Details"} - ]; -}); - -EmployeeSalaryAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "component", {"label":"Salary Component","type":"select2","remote-source":["SalaryComponent","id","name"]}], - [ "amount", {"label":"Amount","type":"text","validation":"float"}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}] - ]; -}); diff --git a/web/modules/src/staffdirectory/index.js b/web/modules/src/staffdirectory/index.js new file mode 100644 index 00000000..63adbbd1 --- /dev/null +++ b/web/modules/src/staffdirectory/index.js @@ -0,0 +1,7 @@ +import { + StaffDirectoryAdapter, + StaffDirectoryObjectAdapter, +} from './lib'; + +window.StaffDirectoryAdapter = StaffDirectoryAdapter; +window.StaffDirectoryObjectAdapter = StaffDirectoryObjectAdapter; diff --git a/web/modules/src/staffdirectory/lib.js b/web/modules/src/staffdirectory/lib.js new file mode 100644 index 00000000..bcdda526 --- /dev/null +++ b/web/modules/src/staffdirectory/lib.js @@ -0,0 +1,173 @@ +/* +Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de) +Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah) + */ +import AdapterBase from '../../../api/AdapterBase'; +import ObjectAdapter from '../../../api/ObjectAdapter'; + +class StaffDirectoryAdapter extends AdapterBase { + getDataMapping() { + return [ + 'id', + 'image', + 'first_name', + 'last_name', + 'job_title', + 'department', + 'work_phone', + 'work_email', + 'joined_date', + ]; + } + + getHeaders() { + return [ + { sTitle: 'ID', bVisible: false }, + { sTitle: '' }, + { sTitle: 'First Name' }, + { sTitle: 'Last Name' }, + { sTitle: 'Job Title' }, + { sTitle: 'Department' }, + { sTitle: 'Work Phone' }, + { sTitle: 'Work Email' }, + { sTitle: 'Joined Date' }, + ]; + } + + getFormFields() { + return [ + ['id', { label: 'ID', type: 'hidden', validation: '' }], + ['first_name', { label: 'First Name', type: 'text', validation: '' }], + ['last_name', { label: 'Last Name', type: 'text', validation: '' }], + ['job_title', { label: 'Job Title', type: 'select2', 'remote-source': ['JobTitle', 'id', 'name'] }], + ['department', { label: 'Department', type: 'select2', 'remote-source': ['CompanyStructure', 'id', 'title'] }], + ['work_phone', { label: 'Work Phone', type: 'text', validation: 'none' }], + ['work_email', { label: 'Work Email', type: 'placeholder', validation: 'emailOrEmpty' }], + ['joined_date', { label: 'Joined Date', type: 'date', validation: '' }], + ]; + } + + showActionButtons() { + return false; + } + + + getCustomTableParams() { + const that = this; + const dataTableParams = { + aoColumnDefs: [ + { + fnRender(data, cell) { + try { + return that.preProcessRemoteTableData(data, cell, 1); + } catch (e) { return cell; } + }, + aTargets: [1], + }, + { + fnRender(data, cell) { + try { + return that.preProcessRemoteTableData(data, cell, 8); + } catch (e) { return cell; } + }, + aTargets: [8], + }, + ], + }; + return dataTableParams; + } + + // eslint-disable-next-line consistent-return + preProcessRemoteTableData(data, cell, id) { + if (id === 8) { + if (cell === '0000-00-00 00:00:00' || cell === '' || cell === undefined || cell === null) { + return ''; + } + return Date.parse(cell).toString('yyyy MMM d'); + } if (id === 1) { + const tmp = 'User Image'; + return tmp.replace('_img_', cell); + } + } +} + + +/* + StaffDirectoryObjectAdapter + */ + + +class StaffDirectoryObjectAdapter extends ObjectAdapter { + getDataMapping() { + return [ + 'id', + 'image', + 'first_name', + 'last_name', + 'job_title', + 'department', + 'work_phone', + 'work_email', + 'joined_date', + ]; + } + + getHeaders() { + return [ + { sTitle: 'ID', bVisible: false }, + { sTitle: '' }, + { sTitle: 'First Name' }, + { sTitle: 'Last Name' }, + { sTitle: 'Job Title' }, + { sTitle: 'Department' }, + { sTitle: 'Work Phone' }, + { sTitle: 'Work Email' }, + { sTitle: 'Joined Date' }, + ]; + } + + getFormFields() { + return [ + ['id', { label: 'ID', type: 'hidden', validation: '' }], + ['first_name', { label: 'First Name', type: 'text', validation: '' }], + ['last_name', { label: 'Last Name', type: 'text', validation: '' }], + ['job_title', { label: 'Job Title', type: 'select2', 'remote-source': ['JobTitle', 'id', 'name'] }], + ['department', { label: 'Department', type: 'select2', 'remote-source': ['CompanyStructure', 'id', 'title'] }], + ['work_phone', { label: 'Work Phone', type: 'text', validation: 'none' }], + ['work_email', { label: 'Work Email', type: 'placeholder', validation: 'emailOrEmpty' }], + ['joined_date', { label: 'Joined Date', type: 'date', validation: '' }], + ]; + } + + // eslint-disable-next-line no-unused-vars + addDomEvents(object) { + + } + + getTemplateName() { + return 'element.html'; + } + + preProcessTableData(_row) { + const row = _row; + row.color = this.getColorByRandomString(row.first_name); + return row; + } + + getFilters() { + return [ + ['job_title', { + label: 'Job Title', type: 'select2', 'allow-null': true, 'null-label': 'All Job Titles', 'remote-source': ['JobTitle', 'id', 'name'], + }], + ['department', { + label: 'Department', type: 'select2', 'allow-null': true, 'null-label': 'All Departments', 'remote-source': ['CompanyStructure', 'id', 'title'], + }], + ]; + } +} + + +module.exports = { + StaffDirectoryAdapter, + StaffDirectoryObjectAdapter, +}; diff --git a/web/modules/time_sheets/lib.js b/web/modules/time_sheets/lib.js deleted file mode 100644 index 6d62f9ca..00000000 --- a/web/modules/time_sheets/lib.js +++ /dev/null @@ -1,966 +0,0 @@ -/* -This file is part of iCE Hrm. - -iCE Hrm is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -iCE Hrm is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with iCE Hrm. If not, see . - ------------------------------------------------------------------- - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function EmployeeTimeSheetAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeTimeSheetAdapter.inherits(AdapterBase); - -this.currentTimesheetId = null; -this.currentTimesheet = null; -this.needStartEndTime = false; - -EmployeeTimeSheetAdapter.method('getDataMapping', function() { - return [ - "id", - "date_start", - "date_end", - "total_time", - "status" - ]; -}); - -EmployeeTimeSheetAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Start Date"}, - { "sTitle": "End Date"}, - { "sTitle": "Total Time"}, - { "sTitle": "Status"} - ]; -}); - -EmployeeTimeSheetAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "date_start", {"label":"TimeSheet Start Date","type":"date","validation":""}], - [ "date_end", {"label":"TimeSheet End Date","type":"date","validation":""}], - [ "details", {"label":"Reason","type":"textarea","validation":"none"}] - ]; -}); - -EmployeeTimeSheetAdapter.method('preProcessTableData', function(row) { - row[1] = Date.parse(row[1]).toString('MMM d, yyyy (dddd)'); - row[2] = Date.parse(row[2]).toString('MMM d, yyyy (dddd)'); - return row; -}); - -EmployeeTimeSheetAdapter.method('setNeedStartEndTime', function(status) { - this.needStartEndTime = status; -}); - -EmployeeTimeSheetAdapter.method('renderForm', function(object) { - var formHtml = this.templates['formTemplate']; - - $('#EmployeeTimesheetBlock').remove(); - $("#"+this.getTableName()+'Form').html(formHtml); - $("#"+this.getTableName()+'Form').show(); - $("#"+this.getTableName()).hide(); - - $('.timesheet_start').html(Date.parse(object.date_start).toString('MMM d, yyyy (dddd)')); - $('.timesheet_end').html(Date.parse(object.date_end).toString('MMM d, yyyy (dddd)')); - - this.currentTimesheet = object; - - this.getTimeEntries(); - - var st = Date.parse(object.date_start); - - $('#EmployeeTimesheetBlock').fullCalendar({ - header: { - //left: 'prev,next today', - left: false, - //center: 'title', - center: false, - //right: 'month,agendaWeek,agendaDay' - right: false - }, - year: st.toString('yyyy'), - month: st.toString('M'), - date: st.toString('d'), - - defaultView: 'basicWeek', - height:200, - editable: false, - - events: modJs.getScheduleJsonUrl(this.currentTimesheet.employee), - - loading: function(bool) { - if (bool) $('#loadingBlock').show(); - else $('#loadingBlock').hide(); - }, - - dayClick: function(date, jsEvent, view, resourceObj) { - - modJs.renderFormByDate(date.format()); - - }, - - eventClick: function(calEvent, jsEvent, view) { - - modJs.renderFormTimeEntryCalender(calEvent.id); - - }, - eventRender: function(event, element) { - element.find(".fc-time").remove(); - } - }); - - $('#EmployeeTimesheetBlock').fullCalendar('gotoDate', st); - - $('.fc-toolbar').hide(); - -}); - - -EmployeeTimeSheetAdapter.method('quickEdit', function(id, status, sdate, edate) { - $('#Qtsheet').data('lastActiveTab', modJs.tab); - modJs = modJsList['tabQtsheet']; - modJs.setCurrentTimeSheetId(id); - - $('.timesheet_start').html(sdate); - $('.timesheet_end').html(edate); - - $("#timesheetTabs").find('.active').find('.reviewBlock.reviewBlockTable').hide(); - $("#QtsheetHeader").show(); - $("#Qtsheet").show(); - $("#QtsheetDataButtons").show(); - - if(status == 'Submitted' || status == 'Approved'){ - $(".completeBtnTable").hide(); - $(".saveBtnTable").hide(); - }else{ - $(".completeBtnTable").show(); - $(".saveBtnTable").show(); - } - - modJs.get([]); -}); - - -EmployeeTimeSheetAdapter.method('getScheduleJsonUrl', function(employeeId) { - var url = this.moduleRelativeURL+"?a=ca&sa=getEmployeeTimeEntries&t="+this.table+"&mod=modules%3Dtime_sheets&e="+employeeId; - return url; -}); - - -EmployeeTimeSheetAdapter.method('renderFormByDate', function (date) { - var start, end; - var origDate = date; - if(date.indexOf('T') < 0){ - var s1 = moment(); - date = date + " " + s1.format("HH:mm:ss"); - } - - start = date.replace('T',' '); - var m1 = moment(start); - m1.add(1,'h'); - end = m1.format('YYYY-MM-DD HH:mm:ss'); - - var obj = {}; - obj.date = origDate; - obj.date_start = start; - obj.date_end = end; - - this.renderFormTimeEntryCalender(obj); - -}); - - - -EmployeeTimeSheetAdapter.method('renderFormTimeEntryCalender', function(object) { - - if (this.needStartEndTime+'' == '0') { - return; - } - this.openTimeEntryDialog(object); - if(object.id != undefined && object.id != null){ - var cid = object.id; - $('.deleteBtnWorkSchedule').show(); - $('.deleteBtnWorkSchedule').off().on('click',function(){ - modJs.deleteRow(cid); - return false; - }); - }else{ - $('.deleteBtnWorkSchedule').remove(); - } - - -}); - - -EmployeeTimeSheetAdapter.method('openTimeEntryDialog', function(object) { - this.currentTimesheetId = this.currentId; - var obj = modJsList['tabEmployeeTimeEntry']; - $('#TimeEntryModel').modal({ - backdrop: 'static', - keyboard: false - }); - obj.currentTimesheet = this.currentTimesheet; - obj.renderForm(object); - obj.timesheetId = this.currentId; - -}); - -EmployeeTimeSheetAdapter.method('closeTimeEntryDialog', function() { - $('#TimeEntryModel').modal('hide'); -}); - - -EmployeeTimeSheetAdapter.method('getTimeEntries', function() { - timesheetId = this.currentId; - var sourceMappingJson = JSON.stringify(modJsList['tabEmployeeTimeEntry'].getSourceMapping()); - object = {"id":timesheetId,"sm":sourceMappingJson}; - - var reqJson = JSON.stringify(object); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'getTimeEntriesSuccessCallBack'; - callBackData['callBackFail'] = 'getTimeEntriesFailCallBack'; - - this.customAction('getTimeEntries','modules=time_sheets',reqJson,callBackData); -}); - -EmployeeTimeSheetAdapter.method('getTimeEntriesSuccessCallBack', function(callBackData) { - var entries = callBackData; - var html = ""; - var temp = '_start__end__duration__project__details_'; - - for(var i=0;i' + - '' + - '_redoBtn_'+ - '
    '; - }else{ - html = '
    ' + - '' + - '_redoBtn_'+ - '
    '; - } - - if(this.getTableName() == "EmployeeTimeSheetAll"){ - var redoBtn = ''; - html = html.replace(/_redoBtn_/g,redoBtn); - } else { - html = html.replace(/_redoBtn_/g,''); - } - html = html.replace(/_id_/g,id); - html = html.replace(/_sdate_/g,data[1]); - html = html.replace(/_edate_/g,data[2]); - html = html.replace(/_status_/g,data[4]); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - -EmployeeTimeSheetAdapter.method('getCustomTableParams', function() { - var that = this; - var dataTableParams = { - "aoColumnDefs": [ - { - "fnRender": function(data, cell){ - return that.preProcessRemoteTableData(data, cell, 1) - } , - "aTargets": [1] - }, - { - "fnRender": function(data, cell){ - return that.preProcessRemoteTableData(data, cell, 2) - } , - "aTargets": [2] - }, - { - "fnRender": that.getActionButtons, - "aTargets": [that.getDataMapping().length] - } - ] - }; - return dataTableParams; -}); - -EmployeeTimeSheetAdapter.method('preProcessRemoteTableData', function(data, cell, id) { - return Date.parse(cell).toString('MMM d, yyyy (dddd)'); -}); - - -/* - * Subordinate TimeSheets - */ - -function SubEmployeeTimeSheetAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -this.timeSheetStatusChangeId = null; - -SubEmployeeTimeSheetAdapter.inherits(EmployeeTimeSheetAdapter); - -SubEmployeeTimeSheetAdapter.method('getDataMapping', function() { - return [ - "id", - "employee", - "date_start", - "date_end", - "status" - ]; -}); - -SubEmployeeTimeSheetAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Employee","bSearchable":true}, - { "sTitle": "Start Date","bSearchable":true}, - { "sTitle": "End Date","bSearchable":true}, - { "sTitle": "Status"} - ]; -}); - -SubEmployeeTimeSheetAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "employee", {"label":"Employee","type":"select","allow-null":false,"remote-source":["Employee","id","first_name+last_name"]}], - [ "date_start", {"label":"TimeSheet Start Date","type":"date","validation":""}], - [ "date_end", {"label":"TimeSheet Start Date","type":"date","validation":""}], - [ "details", {"label":"Reason","type":"textarea","validation":"none"}] - ]; -}); - - -SubEmployeeTimeSheetAdapter.method('isSubProfileTable', function() { - return true; -}); - -SubEmployeeTimeSheetAdapter.method('getCustomSuccessCallBack', function(serverData) { - var data = []; - var mapping = this.getDataMapping(); - for(var i=0;i' + - '' + - '' + - '
    '; - }else{ - - html = '
    ' + - '' + - '' + - '
    '; - } - - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - html = html.replace(/_sdate_/g,data[1]); - html = html.replace(/_edate_/g,data[2]); - html = html.replace(/_status_/g,data[4]); - return html; -}); - - -SubEmployeeTimeSheetAdapter.method('getCustomTableParams', function() { - var that = this; - var dataTableParams = { - "aoColumnDefs": [ - { - "fnRender": function(data, cell){ - return that.preProcessRemoteTableData(data, cell, 2) - } , - "aTargets": [2] - }, - { - "fnRender": function(data, cell){ - return that.preProcessRemoteTableData(data, cell, 3) - } , - "aTargets": [3] - }, - { - "fnRender": that.getActionButtons, - "aTargets": [that.getDataMapping().length] - } - ] - }; - return dataTableParams; -}); - -SubEmployeeTimeSheetAdapter.method('getFilters', function() { - return [ - [ "employee", {"label":"Employee","type":"select2","allow-null":true,"null-label":"All Employees","remote-source":["Employee","id","first_name+last_name"]}], - [ "status", {"label":"Status","type":"select","allow-null":true,"null-label":"All","source":[["Submitted","Submitted"],["Pending","Pending"],["Approved","Approved"], ["Rejected","Rejected"]]}], - ]; -}); - - -/** - * EmployeeTimeEntryAdapter - */ - -function EmployeeTimeEntryAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); -} - -EmployeeTimeEntryAdapter.inherits(AdapterBase); - -this.timesheetId = null; -this.currentTimesheet = null; -this.allProjectsAllowed = 1; -this.employeeProjects = []; - -EmployeeTimeEntryAdapter.method('getDataMapping', function() { - return [ - "id", - "project", - "date_start", - "time_start", - "date_end", - "time_end", - "details" - ]; -}); - -EmployeeTimeEntryAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Project"}, - { "sTitle": "Start Date"}, - { "sTitle": "Start Time"}, - { "sTitle": "End Date"}, - { "sTitle": "End Time"}, - { "sTitle": "Details"} - ]; -}); - -EmployeeTimeEntryAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "project", {"label":"Project","type":"select2","allow-null":false,"remote-source":["Project","id","name","getEmployeeProjects"]}], - [ "date_select", {"label":"Date","type":"select","source":[]}], - [ "date_start", {"label":"Start Time","type":"time","validation":""}], - [ "date_end", {"label":"End Time","type":"time","validation":""}], - [ "details", {"label":"Details","type":"textarea","validation":""}] - ]; -}); - - -EmployeeTimeEntryAdapter.method('getDates', function(startDate, stopDate) { - - var dateArray = new Array(); - var currentDate = startDate; - while (currentDate <= stopDate) { - dateArray.push( new Date (currentDate) ); - currentDate = currentDate.add({ days: 1 }); - } - return dateArray; -}); - - -EmployeeTimeEntryAdapter.method('renderForm', function(object) { - var formHtml = this.getCustomTemplate('time_entry_form.html'); - formHtml = formHtml.replace(/modJs/g,"modJsList['tabEmployeeTimeEntry']"); - var html = ""; - var fields = this.getFormFields(); - - for(var i=0;i'+k.toUTCString().slice(0, -13)+''; - optionList += ''; - } - - - - formHtml = formHtml.replace(/_id_/g,this.getTableName()+"_submit"); - formHtml = formHtml.replace(/_fields_/g,html); - $("#"+this.getTableName()+'Form').html(formHtml); - $("#"+this.getTableName()+'Form').show(); - $("#"+this.getTableName()).hide(); - - $("#"+this.getTableName()+'Form .datefield').datepicker({'viewMode':2}); - $("#"+this.getTableName()+'Form .datetimefield').datetimepicker({ - language: 'en' - }); - $("#"+this.getTableName()+'Form .timefield').datetimepicker({ - language: 'en', - pickDate: false - }); - - $("#"+this.getTableName()+'Form .select2Field').select2(); - - $("#date_select").html(optionList); - - - if(object != undefined && object != null){ - this.fillForm(object); - } -}); - - -EmployeeTimeEntryAdapter.method('fillForm', function(object, formId, fields) { - - if(formId == null || formId == undefined || formId == ""){ - formId = "#"+this.getTableName()+'Form'; - } - - if(object.id != null && object.id != undefined){ - $(formId + ' #id').val(object.id); - } - - if(object.project != null && object.project != undefined){ - $(formId + ' #project').select2('val',object.project); - } - - if(object.date != null && object.date != undefined){ - $(formId + ' #date_select').val(object.date); - } -}); - - - -EmployeeTimeEntryAdapter.method('cancel', function() { - $('#TimeEntryModel').modal('hide'); -}); - -EmployeeTimeEntryAdapter.method('setAllProjectsAllowed', function(allProjectsAllowed) { - this.allProjectsAllowed = allProjectsAllowed; -}); - -EmployeeTimeEntryAdapter.method('setEmployeeProjects', function(employeeProjects) { - this.employeeProjects = employeeProjects; -}); - - -EmployeeTimeEntryAdapter.method('save', function() { - var validator = new FormValidation(this.getTableName()+"_submit",true,{'ShowPopup':false,"LabelErrorClass":"error"}); - - if(validator.checkValues()){ - var params = validator.getFormParameters(); - $(params).attr('timesheet',this.timesheetId); - - params.time_start = params.date_start; - params.time_end = params.date_end; - - params.date_start = params.date_select+" "+params.date_start; - params.date_end = params.date_select+" "+params.date_end; - - - var msg = this.doCustomValidation(params); - - if(msg == null){ - var id = $('#'+this.getTableName()+"_submit #id").val(); - if(id != null && id != undefined && id != ""){ - $(params).attr('id',id); - } - this.add(params,[]); - this.cancel(); - }else{ - $("#"+this.getTableName()+'Form .label').html(msg); - $("#"+this.getTableName()+'Form .label').show(); - } - - } -}); - -EmployeeTimeEntryAdapter.method('doCustomValidation', function(params) { - var st = Date.parse(params.date_start); - var et = Date.parse(params.date_end); - if(st.compareTo(et) != -1){ - return "Start time should be less than End time"; - } - /* - var sd = Date.parse(this.currentTimesheet.date_start); - var ed = Date.parse(this.currentTimesheet.date_end).addDays(1); - - if(sd.compareTo(et) != -1 || sd.compareTo(st) > 0 || st.compareTo(ed) != -1 || et.compareTo(ed) != -1){ - return "Start time and end time shoud be with in " + sd.toString('MMM d, yyyy (dddd)') + " and " + ed.toString('MMM d, yyyy (dddd)'); - } - */ - return null; -}); - -EmployeeTimeEntryAdapter.method('addSuccessCallBack', function(callBackData,serverData) { - this.get(callBackData); - modJs.getTimeEntries(); -}); - -EmployeeTimeEntryAdapter.method('deleteRow', function(id) { - this.deleteObj(id,[]); - -}); - -EmployeeTimeEntryAdapter.method('deleteSuccessCallBack', function(callBackData,serverData) { - modJs.getTimeEntries(); -}); - - - - -/** - * QtsheetAdapter - */ - -function QtsheetAdapter(endPoint) { - this.initAdapter(endPoint); - this.cellDataUpdates = {}; - this.currentId = null; -} - -QtsheetAdapter.inherits(TableEditAdapter); - -QtsheetAdapter.method('validateCellValue', function(element, evt, newValue) { - - if ( !ValidationRules.float(newValue)) { - return false; - } - var val = parseFloat(newValue); - if(val < 0 || val > 24){ - return false; - } - - //Update total - //Find current column number - //Adding 2 because nth child is based on 1 and we are adding a virtual column for row names - var coldNum = this.columnIDMap[element.data('colId')] + 2; - var columnTotal = 0; - var columnTotalWithoutCurrent = 0; - $("#"+this.getTableName()+' tr td:nth-child('+coldNum+')').each(function(){ - var rowId = $(this).data('rowId'); - var tval = ''; - if(element.data('rowId') == rowId){ - tval = newValue; - }else{ - tval = $(this).html(); - } - - if(rowId != -1){ - if(ValidationRules.float(tval)){ - columnTotal += parseFloat(tval); - if(element.data('rowId') != rowId){ - columnTotalWithoutCurrent += parseFloat(tval); - } - } - }else{ - if(columnTotal > 24){ - $(this).html(columnTotalWithoutCurrent); - }else{ - $(this).html(columnTotal); - } - } - }); - - if(columnTotal > 24){ - return false; - } - - modJs.addCellDataUpdate(element.data('colId'),element.data('rowId'),newValue); - return true; -}); - -QtsheetAdapter.method('setCurrentTimeSheetId', function(val) { - this.currentId = val; - this.cellDataUpdates = {}; -}); - - -QtsheetAdapter.method('addAdditionalRequestData' , function(type, req) { - if(type == 'updateData'){ - req.currentId = this.currentId; - }else if(type == 'updateAllData'){ - req.currentId = this.currentId; - }else if(type == 'getAllData'){ - req.currentId = this.currentId; - } - - return req; -}); - -QtsheetAdapter.method('modifyCSVHeader', function(header) { - header.unshift(""); - return header; -}); - -QtsheetAdapter.method('getCSVData' , function() { - var csv = ""; - - for(var i=0;i
    '; - - //Find current page - var activePage = $('#'+elementId +" .dataTables_paginate .active a").html(); - var start = 0; - if(activePage != undefined && activePage != null){ - start = parseInt(activePage, 10)*100 - 100; - } - - $('#'+elementId).html(html); - - var dataTableParams = { - "oLanguage": { - "sLengthMenu": "_MENU_ records per page" - }, - "aaData": data, - "aoColumns": headers, - "bSort": false, - "iDisplayLength": 100, - "iDisplayStart": start - }; - - - var customTableParams = this.getCustomTableParams(); - - $.extend(dataTableParams, customTableParams); - - $('#'+elementId+' #grid').dataTable( dataTableParams ); - - $('#'+elementId+' #grid tr:last').find('td').removeClass('editcell'); - - $(".dataTables_paginate ul").addClass("pagination"); - $(".dataTables_length").hide(); - $(".dataTables_filter input").addClass("form-control"); - $(".dataTables_filter input").attr("placeholder","Search"); - $(".dataTables_filter label").contents().filter(function(){ - return (this.nodeType == 3); - }).remove(); - //$('.tableActionButton').tooltip(); - $('#'+elementId+' #grid').editableTableWidget(); - - $('#'+elementId+' #grid .editcell').on('validate', function(evt, newValue) { - - return modJs.validateCellValue($(this), evt, newValue); - - }); -}); - diff --git a/web/modules/travel/lib.js b/web/modules/travel/lib.js deleted file mode 100644 index 50bb0987..00000000 --- a/web/modules/travel/lib.js +++ /dev/null @@ -1,241 +0,0 @@ -/* -This file is part of iCE Hrm. - -Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd] -Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah) - */ - -function EmployeeImmigrationAdapter(endPoint) { - this.initAdapter(endPoint); -} - -EmployeeImmigrationAdapter.inherits(AdapterBase); - - - -EmployeeImmigrationAdapter.method('getDataMapping', function() { - return [ - "id", - "document", - "documentname", - "valid_until", - "status" - ]; -}); - -EmployeeImmigrationAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Document" }, - { "sTitle": "Document Id" }, - { "sTitle": "Valid Until"}, - { "sTitle": "Status"} - ]; -}); - -EmployeeImmigrationAdapter.method('getFormFields', function() { - return [ - [ "id", {"label":"ID","type":"hidden"}], - [ "document", {"label":"Document","type":"select2","remote-source":["ImmigrationDocument","id","name"]}], - [ "documentname", {"label":"Document Id","type":"text","validation":""}], - [ "valid_until", {"label":"Valid Until","type":"date","validation":"none"}], - [ "status", {"label":"Status","type":"select","source":[["Active","Active"],["Inactive","Inactive"],["Draft","Draft"]]}], - [ "details", {"label":"Details","type":"textarea","validation":"none"}], - [ "attachment1", {"label":"Attachment 1","type":"fileupload","validation":"none"}], - [ "attachment2", {"label":"Attachment 2","type":"fileupload","validation":"none"}], - [ "attachment3", {"label":"Attachment 3","type":"fileupload","validation":"none"}] - ]; -}); - - - - - -function EmployeeTravelRecordAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); - this.itemName = 'Travel'; - this.itemNameLower = 'employeetravelrecord'; - this.modulePathName = 'travel'; -} - -EmployeeTravelRecordAdapter.inherits(ApproveModuleAdapter); - - - -EmployeeTravelRecordAdapter.method('getDataMapping', function() { - return [ - "id", - "type", - "purpose", - "travel_from", - "travel_to", - "travel_date", - "return_date", - "status" - ]; -}); - -EmployeeTravelRecordAdapter.method('getHeaders', function() { - return [ - { "sTitle": "ID" ,"bVisible":false}, - { "sTitle": "Travel Type" }, - { "sTitle": "Purpose" }, - { "sTitle": "From"}, - { "sTitle": "To"}, - { "sTitle": "Travel Date"}, - { "sTitle": "Return Date"}, - { "sTitle": "Status"} - ]; -}); - -EmployeeTravelRecordAdapter.method('getFormFields', function() { - return this.addCustomFields([ - ["id", {"label": "ID", "type": "hidden"}], - ["type", { - "label": "Means of Transportation", - "type": "select", - "source": [ - ["Plane", "Plane"], - ["Rail", "Rail"], - ["Taxi", "Taxi"], - ["Own Vehicle", "Own Vehicle"], - ["Rented Vehicle", "Rented Vehicle"], - ["Other", "Other"] - ] - }], - ["purpose", {"label": "Purpose of Travel", "type": "textarea", "validation": ""}], - ["travel_from", {"label": "Travel From", "type": "text", "validation": ""}], - ["travel_to", {"label": "Travel To", "type": "text", "validation": ""}], - ["travel_date", {"label": "Travel Date", "type": "datetime", "validation": ""}], - ["return_date", {"label": "Return Date", "type": "datetime", "validation": ""}], - ["details", {"label": "Notes", "type": "textarea", "validation": "none"}], - ["currency", {"label": "Currency", "type": "select2", "allow-null":false, "remote-source": ["CurrencyType", "id", "code"]}], - ["funding", {"label": "Total Funding Proposed", "type": "text", "validation": "float", "default":"0.00", "mask":"9{0,10}.99"}], - ["attachment1", {"label": "Attachment", "type": "fileupload", "validation": "none"}], - ["attachment2", {"label": "Attachment", "type": "fileupload", "validation": "none"}], - ["attachment3", {"label": "Attachment", "type": "fileupload", "validation": "none"}] - ]); -}); - -/* -EmployeeTravelRecordAdapter.method('getActionButtonsHtml', function(id,data) { - var editButton = ''; - var deleteButton = ''; - var requestCancellationButton = ''; - - var html = '
    _edit__delete_
    '; - - if(this.showDelete){ - if(data[7] == "Approved"){ - html = html.replace('_delete_',requestCancellationButton); - }else{ - html = html.replace('_delete_',deleteButton); - } - - }else{ - html = html.replace('_delete_',''); - } - - if(this.showEdit){ - html = html.replace('_edit_',editButton); - }else{ - html = html.replace('_edit_',''); - } - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - return html; -}); - -EmployeeTravelRecordAdapter.method('cancelTravel', function(id) { - var that = this; - var object = {}; - object['id'] = id; - - var reqJson = JSON.stringify(object); - - var callBackData = []; - callBackData['callBackData'] = []; - callBackData['callBackSuccess'] = 'cancelSuccessCallBack'; - callBackData['callBackFail'] = 'cancelFailCallBack'; - - this.customAction('cancelTravel','modules=travel',reqJson,callBackData); -}); - -EmployeeTravelRecordAdapter.method('cancelSuccessCallBack', function(callBackData) { - this.showMessage("Successful", "Travel request cancellation request sent"); - this.get([]); -}); - -EmployeeTravelRecordAdapter.method('cancelFailCallBack', function(callBackData) { - this.showMessage("Error Occurred while cancelling Travel request", callBackData); -}); -*/ - -/* - EmployeeTravelRecordApproverAdapter - */ - -function EmployeeTravelRecordApproverAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); - this.itemName = 'Travel'; - this.itemNameLower = 'employeetravelrecord'; - this.modulePathName = 'travel'; -} - -EmployeeTravelRecordApproverAdapter.inherits(EmployeeTravelRecordAdminAdapter); - -EmployeeTravelRecordApproverAdapter.method('getActionButtonsHtml', function(id,data) { - var statusChangeButton = ''; - var viewLogsButton = ''; - - var html = '
    _status__logs_
    '; - - - html = html.replace('_logs_',viewLogsButton); - - - if(data[this.getStatusFieldPosition()] == 'Processing'){ - html = html.replace('_status_',statusChangeButton); - - }else{ - html = html.replace('_status_',''); - } - - html = html.replace(/_id_/g,id); - html = html.replace(/_BASE_/g,this.baseUrl); - html = html.replace(/_cstatus_/g,data[this.getStatusFieldPosition()]); - return html; -}); - -EmployeeTravelRecordApproverAdapter.method('getStatusOptionsData', function(currentStatus) { - var data = {}; - if(currentStatus != 'Processing'){ - - }else{ - data["Approved"] = "Approved"; - data["Rejected"] = "Rejected"; - - } - - return data; -}); - -EmployeeTravelRecordApproverAdapter.method('getStatusOptions', function(currentStatus) { - return this.generateOptions(this.getStatusOptionsData(currentStatus)); -}); - - -/* - SubordinateExpenseModuleAdapter - */ - -function SubordinateEmployeeTravelRecordAdapter(endPoint,tab,filter,orderBy) { - this.initAdapter(endPoint,tab,filter,orderBy); - this.itemName = 'Travel'; - this.itemNameLower = 'employeetravelrecord'; - this.modulePathName = 'travel'; -} - -SubordinateEmployeeTravelRecordAdapter.inherits(EmployeeTravelRecordAdminAdapter); - diff --git a/web/themecss/AdminLTE.css b/web/themecss/AdminLTE.css index 15b33eba..a7b778e8 100644 --- a/web/themecss/AdminLTE.css +++ b/web/themecss/AdminLTE.css @@ -5112,4 +5112,4 @@ fieldset[disabled] .btn-vk.active { } .control-sidebar-light .control-sidebar-menu > li > a .menu-info > p { color: #5e5e5e; -} +} \ No newline at end of file diff --git a/web/themejs/plugins/datatables/dataTables.bootstrap.js b/web/themejs/plugins/datatables/dataTables.bootstrap.js deleted file mode 100644 index 87b317c7..00000000 --- a/web/themejs/plugins/datatables/dataTables.bootstrap.js +++ /dev/null @@ -1,250 +0,0 @@ -/* Set the defaults for DataTables initialisation */ -$.extend( true, $.fn.dataTable.defaults, { - "sDom": - "<'row'<'col-xs-6'l><'col-xs-6'f>r>"+ - "t"+ - "<'row'<'col-xs-6'i><'col-xs-6'p>>", - "oLanguage": { - "sLengthMenu": "_MENU_ records per page" - } -} ); - - -/* Default class modification */ -$.extend( $.fn.dataTableExt.oStdClasses, { - "sWrapper": "dataTables_wrapper form-inline", - "sFilterInput": "form-control input-sm", - "sLengthSelect": "form-control input-sm" -} ); - -// In 1.10 we use the pagination renderers to draw the Bootstrap paging, -// rather than custom plug-in -if ( $.fn.dataTable.Api ) { - $.fn.dataTable.defaults.renderer = 'bootstrap'; - $.fn.dataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) { - var api = new $.fn.dataTable.Api( settings ); - var classes = settings.oClasses; - var lang = settings.oLanguage.oPaginate; - var btnDisplay, btnClass; - - var attach = function( container, buttons ) { - var i, ien, node, button; - var clickHandler = function ( e ) { - e.preventDefault(); - if ( e.data.action !== 'ellipsis' ) { - api.page( e.data.action ).draw( false ); - } - }; - - for ( i=0, ien=buttons.length ; i 0 ? - '' : ' disabled'); - break; - - case 'previous': - btnDisplay = lang.sPrevious; - btnClass = button + (page > 0 ? - '' : ' disabled'); - break; - - case 'next': - btnDisplay = lang.sNext; - btnClass = button + (page < pages-1 ? - '' : ' disabled'); - break; - - case 'last': - btnDisplay = lang.sLast; - btnClass = button + (page < pages-1 ? - '' : ' disabled'); - break; - - default: - btnDisplay = button + 1; - btnClass = page === button ? - 'active' : ''; - break; - } - - if ( btnDisplay ) { - node = $('
  • ', { - 'class': classes.sPageButton+' '+btnClass, - 'aria-controls': settings.sTableId, - 'tabindex': settings.iTabIndex, - 'id': idx === 0 && typeof button === 'string' ? - settings.sTableId +'_'+ button : - null - } ) - .append( $('', { - 'href': '#' - } ) - .html( btnDisplay ) - ) - .appendTo( container ); - - settings.oApi._fnBindAction( - node, {action: button}, clickHandler - ); - } - } - } - }; - - attach( - $(host).empty().html('
      ').children('ul'), - buttons - ); - } -} -else { - // Integration for 1.9- - $.fn.dataTable.defaults.sPaginationType = 'bootstrap'; - - /* API method to get paging information */ - $.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings ) - { - return { - "iStart": oSettings._iDisplayStart, - "iEnd": oSettings.fnDisplayEnd(), - "iLength": oSettings._iDisplayLength, - "iTotal": oSettings.fnRecordsTotal(), - "iFilteredTotal": oSettings.fnRecordsDisplay(), - "iPage": oSettings._iDisplayLength === -1 ? - 0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ), - "iTotalPages": oSettings._iDisplayLength === -1 ? - 0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength ) - }; - }; - - /* Bootstrap style pagination control */ - $.extend( $.fn.dataTableExt.oPagination, { - "bootstrap": { - "fnInit": function( oSettings, nPaging, fnDraw ) { - var oLang = oSettings.oLanguage.oPaginate; - var fnClickHandler = function ( e ) { - e.preventDefault(); - if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) { - fnDraw( oSettings ); - } - }; - - $(nPaging).append( - '' - ); - var els = $('a', nPaging); - $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler ); - $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler ); - }, - - "fnUpdate": function ( oSettings, fnDraw ) { - var iListLength = 5; - var oPaging = oSettings.oInstance.fnPagingInfo(); - var an = oSettings.aanFeatures.p; - var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2); - - if ( oPaging.iTotalPages < iListLength) { - iStart = 1; - iEnd = oPaging.iTotalPages; - } - else if ( oPaging.iPage <= iHalf ) { - iStart = 1; - iEnd = iListLength; - } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) { - iStart = oPaging.iTotalPages - iListLength + 1; - iEnd = oPaging.iTotalPages; - } else { - iStart = oPaging.iPage - iHalf + 1; - iEnd = iStart + iListLength - 1; - } - - for ( i=0, ien=an.length ; i'+j+'') - .insertBefore( $('li:last', an[i])[0] ) - .bind('click', function (e) { - e.preventDefault(); - oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength; - fnDraw( oSettings ); - } ); - } - - // Add / remove disabled classes from the static elements - if ( oPaging.iPage === 0 ) { - $('li:first', an[i]).addClass('disabled'); - } else { - $('li:first', an[i]).removeClass('disabled'); - } - - if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) { - $('li:last', an[i]).addClass('disabled'); - } else { - $('li:last', an[i]).removeClass('disabled'); - } - } - } - } - } ); -} - - -/* - * TableTools Bootstrap compatibility - * Required TableTools 2.1+ - */ -if ( $.fn.DataTable.TableTools ) { - // Set the classes that TableTools uses to something suitable for Bootstrap - $.extend( true, $.fn.DataTable.TableTools.classes, { - "container": "DTTT btn-group", - "buttons": { - "normal": "btn btn-default", - "disabled": "disabled" - }, - "collection": { - "container": "DTTT_dropdown dropdown-menu", - "buttons": { - "normal": "", - "disabled": "disabled" - } - }, - "print": { - "info": "DTTT_print_info modal" - }, - "select": { - "row": "active" - } - } ); - - // Have the collection use a bootstrap compatible dropdown - $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, { - "collection": { - "container": "ul", - "button": "li", - "liner": "a" - } - } ); -} \ No newline at end of file diff --git a/web/themejs/plugins/datatables/jquery.dataTables.js b/web/themejs/plugins/datatables/jquery.dataTables.js deleted file mode 100644 index 0762a0c7..00000000 --- a/web/themejs/plugins/datatables/jquery.dataTables.js +++ /dev/null @@ -1,12129 +0,0 @@ -/** - * @summary DataTables - * @description Paginate, search and sort HTML tables - * @version 1.9.4 - * @file jquery.dataTables.js - * @author Allan Jardine (www.sprymedia.co.uk) - * @contact www.sprymedia.co.uk/contact - * - * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved. - * - * This source file is free software, under either the GPL v2 license or a - * BSD style license, available at: - * http://datatables.net/license_gpl2 - * http://datatables.net/license_bsd - * - * This source file 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 license files for details. - * - * For details please refer to: http://www.datatables.net - */ - -/*jslint evil: true, undef: true, browser: true */ -/*globals $, jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns*/ - -(/** @lends */function( window, document, undefined ) { - -(function( factory ) { - "use strict"; - - // Define as an AMD module if possible - if ( typeof define === 'function' && define.amd ) - { - define( ['jquery'], factory ); - } - /* Define using browser globals otherwise - * Prevent multiple instantiations if the script is loaded twice - */ - else if ( jQuery && !jQuery.fn.dataTable ) - { - factory( jQuery ); - } -} -(/** @lends */function( $ ) { - "use strict"; - /** - * DataTables is a plug-in for the jQuery Javascript library. It is a - * highly flexible tool, based upon the foundations of progressive - * enhancement, which will add advanced interaction controls to any - * HTML table. For a full list of features please refer to - * DataTables.net. - * - * Note that the DataTable object is not a global variable but is - * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which - * it may be accessed. - * - * @class - * @param {object} [oInit={}] Configuration object for DataTables. Options - * are defined by {@link DataTable.defaults} - * @requires jQuery 1.3+ - * - * @example - * // Basic initialisation - * $(document).ready( function { - * $('#example').dataTable(); - * } ); - * - * @example - * // Initialisation with configuration options - in this case, disable - * // pagination and sorting. - * $(document).ready( function { - * $('#example').dataTable( { - * "bPaginate": false, - * "bSort": false - * } ); - * } ); - */ - var DataTable = function( oInit ) - { - - - /** - * Add a column to the list used for the table with default values - * @param {object} oSettings dataTables settings object - * @param {node} nTh The th element for this column - * @memberof DataTable#oApi - */ - function _fnAddColumn( oSettings, nTh ) - { - var oDefaults = DataTable.defaults.columns; - var iCol = oSettings.aoColumns.length; - var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { - "sSortingClass": oSettings.oClasses.sSortable, - "sSortingClassJUI": oSettings.oClasses.sSortJUI, - "nTh": nTh ? nTh : document.createElement('th'), - "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', - "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], - "mData": oDefaults.mData ? oDefaults.oDefaults : iCol - } ); - oSettings.aoColumns.push( oCol ); - - /* Add a column specific filter */ - if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null ) - { - oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch ); - } - else - { - var oPre = oSettings.aoPreSearchCols[ iCol ]; - - /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */ - if ( oPre.bRegex === undefined ) - { - oPre.bRegex = true; - } - - if ( oPre.bSmart === undefined ) - { - oPre.bSmart = true; - } - - if ( oPre.bCaseInsensitive === undefined ) - { - oPre.bCaseInsensitive = true; - } - } - - /* Use the column options function to initialise classes etc */ - _fnColumnOptions( oSettings, iCol, null ); - } - - - /** - * Apply options for a column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column index to consider - * @param {object} oOptions object with sType, bVisible and bSearchable etc - * @memberof DataTable#oApi - */ - function _fnColumnOptions( oSettings, iCol, oOptions ) - { - var oCol = oSettings.aoColumns[ iCol ]; - - /* User specified column options */ - if ( oOptions !== undefined && oOptions !== null ) - { - /* Backwards compatibility for mDataProp */ - if ( oOptions.mDataProp && !oOptions.mData ) - { - oOptions.mData = oOptions.mDataProp; - } - - if ( oOptions.sType !== undefined ) - { - oCol.sType = oOptions.sType; - oCol._bAutoType = false; - } - - $.extend( oCol, oOptions ); - _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); - - /* iDataSort to be applied (backwards compatibility), but aDataSort will take - * priority if defined - */ - if ( oOptions.iDataSort !== undefined ) - { - oCol.aDataSort = [ oOptions.iDataSort ]; - } - _fnMap( oCol, oOptions, "aDataSort" ); - } - - /* Cache the data get and set functions for speed */ - var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; - var mData = _fnGetObjectDataFn( oCol.mData ); - - oCol.fnGetData = function (oData, sSpecific) { - var modData = []; - for (var index in oData) { - if (oData.hasOwnProperty(index)) { - modData[index] = modJs.gt(oData[index]); - } - } - var innerData = mData( modData, sSpecific ); - - if ( oCol.mRender && (sSpecific && sSpecific !== '') ) - { - return mRender( innerData, sSpecific, modData ); - } - return innerData; - }; - oCol.fnSetData = _fnSetObjectDataFn( oCol.mData ); - - /* Feature sorting overrides column specific when off */ - if ( !oSettings.oFeatures.bSort ) - { - oCol.bSortable = false; - } - - /* Check that the class assignment is correct for sorting */ - if ( !oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableNone; - oCol.sSortingClassJUI = ""; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortable; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; - } - else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableAsc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableDesc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; - } - } - - - /** - * Adjust the table column widths for new data. Note: you would probably want to - * do a redraw after calling this function! - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnAdjustColumnSizing ( oSettings ) - { - /* Not interested in doing column width calculation if auto-width is disabled */ - if ( oSettings.oFeatures.bAutoWidth === false ) - { - return false; - } - - _fnCalculateColumnWidths( oSettings ); - for ( var i=0 , iLen=oSettings.aoColumns.length ; i
  • ')[0]; - oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable ); - - /* - * All DataTables are wrapped in a div - */ - oSettings.nTableWrapper = $('
    ')[0]; - oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; - - /* Track where we want to insert the option */ - var nInsertNode = oSettings.nTableWrapper; - - /* Loop over the user set positioning and place the elements as needed */ - var aDom = oSettings.sDom.split(''); - var nTmp, iPushFeature, cOption, nNewNode, cNext, sAttr, j; - for ( var i=0 ; i
    ')[0]; - - /* Check to see if we should append an id and/or a class name to the container */ - cNext = aDom[i+1]; - if ( cNext == "'" || cNext == '"' ) - { - sAttr = ""; - j = 2; - while ( aDom[i+j] != cNext ) - { - sAttr += aDom[i+j]; - j++; - } - - /* Replace jQuery UI constants */ - if ( sAttr == "H" ) - { - sAttr = oSettings.oClasses.sJUIHeader; - } - else if ( sAttr == "F" ) - { - sAttr = oSettings.oClasses.sJUIFooter; - } - - /* The attribute can be in the format of "#id.class", "#id" or "class" This logic - * breaks the string into parts and applies them as needed - */ - if ( sAttr.indexOf('.') != -1 ) - { - var aSplit = sAttr.split('.'); - nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1); - nNewNode.className = aSplit[1]; - } - else if ( sAttr.charAt(0) == "#" ) - { - nNewNode.id = sAttr.substr(1, sAttr.length-1); - } - else - { - nNewNode.className = sAttr; - } - - i += j; /* Move along the position array */ - } - - nInsertNode.appendChild( nNewNode ); - nInsertNode = nNewNode; - } - else if ( cOption == '>' ) - { - /* End container div */ - nInsertNode = nInsertNode.parentNode; - } - else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange ) - { - /* Length */ - nTmp = _fnFeatureHtmlLength( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'f' && oSettings.oFeatures.bFilter ) - { - /* Filter */ - nTmp = _fnFeatureHtmlFilter( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'r' && oSettings.oFeatures.bProcessing ) - { - /* pRocessing */ - nTmp = _fnFeatureHtmlProcessing( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 't' ) - { - /* Table */ - nTmp = _fnFeatureHtmlTable( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'i' && oSettings.oFeatures.bInfo ) - { - /* Info */ - nTmp = _fnFeatureHtmlInfo( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'p' && oSettings.oFeatures.bPaginate ) - { - /* Pagination */ - nTmp = _fnFeatureHtmlPaginate( oSettings ); - iPushFeature = 1; - } - else if ( DataTable.ext.aoFeatures.length !== 0 ) - { - /* Plug-in features */ - var aoFeatures = DataTable.ext.aoFeatures; - for ( var k=0, kLen=aoFeatures.length ; k') : - sSearchStr==="" ? '' : sSearchStr+' '; - - var nFilter = document.createElement( 'div' ); - nFilter.className = oSettings.oClasses.sFilter; - nFilter.innerHTML = ''; - if ( !oSettings.aanFeatures.f ) - { - nFilter.id = oSettings.sTableId+'_filter'; - } - - var jqFilter = $('input[type="text"]', nFilter); - - // Store a reference to the input element, so other input elements could be - // added to the filter wrapper if needed (submit button for example) - nFilter._DT_Input = jqFilter[0]; - - jqFilter.val( oPreviousSearch.sSearch.replace('"','"') ); - jqFilter.bind( 'keyup.DT', function(e) { - /* Update all other filter input elements for the new display */ - var n = oSettings.aanFeatures.f; - var val = this.value==="" ? "" : this.value; // mental IE8 fix :-( - - for ( var i=0, iLen=n.length ; i=0 ; i-- ) - { - var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ), - oSettings.aoColumns[iColumn].sType ); - if ( ! rpSearch.test( sData ) ) - { - oSettings.aiDisplay.splice( i, 1 ); - iIndexCorrector++; - } - } - } - - - /** - * Filter the data table based on user input and draw the table - * @param {object} oSettings dataTables settings object - * @param {string} sInput string to filter on - * @param {int} iForce optional - force a research of the master array (1) or not (undefined or 0) - * @param {bool} bRegex treat as a regular expression or not - * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insenstive matching or not - * @memberof DataTable#oApi - */ - function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart, bCaseInsensitive ) - { - var i; - var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive ); - var oPrevSearch = oSettings.oPreviousSearch; - - /* Check if we are forcing or not - optional parameter */ - if ( !iForce ) - { - iForce = 0; - } - - /* Need to take account of custom filtering functions - always filter */ - if ( DataTable.ext.afnFiltering.length !== 0 ) - { - iForce = 1; - } - - /* - * If the input is blank - we want the full data set - */ - if ( sInput.length <= 0 ) - { - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - } - else - { - /* - * We are starting a new search or the new search string is smaller - * then the old one (i.e. delete). Search from the master array - */ - if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length || - oPrevSearch.sSearch.length > sInput.length || iForce == 1 || - sInput.indexOf(oPrevSearch.sSearch) !== 0 ) - { - /* Nuke the old display array - we are going to rebuild it */ - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - - /* Force a rebuild of the search array */ - _fnBuildSearchArray( oSettings, 1 ); - - /* Search through all records to populate the search array - * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1 - * mapping - */ - for ( i=0 ; i').html(sSearch).text(); - } - - // Strip newline characters - return sSearch.replace( /[\n\r]/g, " " ); - } - - /** - * Build a regular expression object suitable for searching a table - * @param {string} sSearch string to search for - * @param {bool} bRegex treat as a regular expression or not - * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insensitive matching or not - * @returns {RegExp} constructed object - * @memberof DataTable#oApi - */ - function _fnFilterCreateSearch( sSearch, bRegex, bSmart, bCaseInsensitive ) - { - var asSearch, sRegExpString; - - if ( bSmart ) - { - /* Generate the regular expression to use. Something along the lines of: - * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$ - */ - asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' ); - sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$'; - return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" ); - } - else - { - sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch ); - return new RegExp( sSearch, bCaseInsensitive ? "i" : "" ); - } - } - - - /** - * Convert raw data into something that the user can search on - * @param {string} sData data to be modified - * @param {string} sType data type - * @returns {string} search string - * @memberof DataTable#oApi - */ - function _fnDataToSearch ( sData, sType ) - { - if ( typeof DataTable.ext.ofnSearch[sType] === "function" ) - { - return DataTable.ext.ofnSearch[sType]( sData ); - } - else if ( sData === null ) - { - return ''; - } - else if ( sType == "html" ) - { - return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" ); - } - else if ( typeof sData === "string" ) - { - return sData.replace(/[\r\n]/g," "); - } - return sData; - } - - - /** - * scape a string such that it can be used in a regular expression - * @param {string} sVal string to escape - * @returns {string} escaped string - * @memberof DataTable#oApi - */ - function _fnEscapeRegex ( sVal ) - { - var acEscape = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ]; - var reReplace = new RegExp( '(\\' + acEscape.join('|\\') + ')', 'g' ); - return sVal.replace(reReplace, '\\$1'); - } - - - /** - * Generate the node required for the info display - * @param {object} oSettings dataTables settings object - * @returns {node} Information element - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlInfo ( oSettings ) - { - var nInfo = document.createElement( 'div' ); - nInfo.className = oSettings.oClasses.sInfo; - - /* Actions that are to be taken once only for this feature */ - if ( !oSettings.aanFeatures.i ) - { - /* Add draw callback */ - oSettings.aoDrawCallback.push( { - "fn": _fnUpdateInfo, - "sName": "information" - } ); - - /* Add id */ - nInfo.id = oSettings.sTableId+'_info'; - } - oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' ); - - return nInfo; - } - - - /** - * Update the information elements in the display - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnUpdateInfo ( oSettings ) - { - /* Show information about the table */ - if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 ) - { - return; - } - - var - oLang = oSettings.oLanguage, - iStart = oSettings._iDisplayStart+1, - iEnd = oSettings.fnDisplayEnd(), - iMax = oSettings.fnRecordsTotal(), - iTotal = oSettings.fnRecordsDisplay(), - sOut; - - if ( iTotal === 0 ) - { - /* Empty record set */ - sOut = oLang.sInfoEmpty; - } - else { - /* Normal record set */ - sOut = oLang.sInfo; - } - - if ( iTotal != iMax ) - { - /* Record set after filtering */ - sOut += ' ' + oLang.sInfoFiltered; - } - - // Convert the macros - sOut += oLang.sInfoPostFix; - sOut = _fnInfoMacros( oSettings, sOut ); - - if ( oLang.fnInfoCallback !== null ) - { - sOut = oLang.fnInfoCallback.call( oSettings.oInstance, - oSettings, iStart, iEnd, iMax, iTotal, sOut ); - } - - var n = oSettings.aanFeatures.i; - for ( var i=0, iLen=n.length ; i'; - var i, iLen; - var aLengthMenu = oSettings.aLengthMenu; - - if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' && - typeof aLengthMenu[1] === 'object' ) - { - for ( i=0, iLen=aLengthMenu[0].length ; i'+aLengthMenu[1][i]+''; - } - } - else - { - for ( i=0, iLen=aLengthMenu.length ; i'+aLengthMenu[i]+''; - } - } - sStdMenu += ''; - - var nLength = document.createElement( 'div' ); - if ( !oSettings.aanFeatures.l ) - { - nLength.id = oSettings.sTableId+'_length'; - } - nLength.className = oSettings.oClasses.sLength; - nLength.innerHTML = ''; - - /* - * Set the length to the current display length - thanks to Andrea Pavlovic for this fix, - * and Stefan Skopnik for fixing the fix! - */ - $('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true); - - $('select', nLength).bind( 'change.DT', function(e) { - var iVal = $(this).val(); - - /* Update all other length options for the new display */ - var n = oSettings.aanFeatures.l; - for ( i=0, iLen=n.length ; i oSettings.aiDisplay.length || - oSettings._iDisplayLength == -1 ) - { - oSettings._iDisplayEnd = oSettings.aiDisplay.length; - } - else - { - oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength; - } - } - } - - - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Note that most of the paging logic is done in - * DataTable.ext.oPagination - */ - - /** - * Generate the node required for default pagination - * @param {object} oSettings dataTables settings object - * @returns {node} Pagination feature node - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlPaginate ( oSettings ) - { - if ( oSettings.oScroll.bInfinite ) - { - return null; - } - - var nPaginate = document.createElement( 'div' ); - nPaginate.className = oSettings.oClasses.sPaging+oSettings.sPaginationType; - - DataTable.ext.oPagination[ oSettings.sPaginationType ].fnInit( oSettings, nPaginate, - function( oSettings ) { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - ); - - /* Add a draw callback for the pagination on first instance, to update the paging display */ - if ( !oSettings.aanFeatures.p ) - { - oSettings.aoDrawCallback.push( { - "fn": function( oSettings ) { - DataTable.ext.oPagination[ oSettings.sPaginationType ].fnUpdate( oSettings, function( oSettings ) { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } ); - }, - "sName": "pagination" - } ); - } - return nPaginate; - } - - - /** - * Alter the display settings to change the page - * @param {object} oSettings dataTables settings object - * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" - * or page number to jump to (integer) - * @returns {bool} true page has changed, false - no change (no effect) eg 'first' on page 1 - * @memberof DataTable#oApi - */ - function _fnPageChange ( oSettings, mAction ) - { - var iOldStart = oSettings._iDisplayStart; - - if ( typeof mAction === "number" ) - { - oSettings._iDisplayStart = mAction * oSettings._iDisplayLength; - if ( oSettings._iDisplayStart > oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "first" ) - { - oSettings._iDisplayStart = 0; - } - else if ( mAction == "previous" ) - { - oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ? - oSettings._iDisplayStart - oSettings._iDisplayLength : - 0; - - /* Correct for under-run */ - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "next" ) - { - if ( oSettings._iDisplayLength >= 0 ) - { - /* Make sure we are not over running the display array */ - if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart += oSettings._iDisplayLength; - } - } - else - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "last" ) - { - if ( oSettings._iDisplayLength >= 0 ) - { - var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1; - oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength; - } - else - { - oSettings._iDisplayStart = 0; - } - } - else - { - _fnLog( oSettings, 0, "Unknown paging action: "+mAction ); - } - $(oSettings.oInstance).trigger('page', oSettings); - - return iOldStart != oSettings._iDisplayStart; - } - - - - /** - * Generate the node required for the processing node - * @param {object} oSettings dataTables settings object - * @returns {node} Processing element - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlProcessing ( oSettings ) - { - var nProcessing = document.createElement( 'div' ); - - if ( !oSettings.aanFeatures.r ) - { - nProcessing.id = oSettings.sTableId+'_processing'; - } - nProcessing.innerHTML = oSettings.oLanguage.sProcessing; - nProcessing.className = oSettings.oClasses.sProcessing; - oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable ); - - return nProcessing; - } - - - /** - * Display or hide the processing indicator - * @param {object} oSettings dataTables settings object - * @param {bool} bShow Show the processing indicator (true) or not (false) - * @memberof DataTable#oApi - */ - function _fnProcessingDisplay ( oSettings, bShow ) - { - if ( oSettings.oFeatures.bProcessing ) - { - var an = oSettings.aanFeatures.r; - for ( var i=0, iLen=an.length ; i 0 ) - { - nCaption = nCaption[0]; - if ( nCaption._captionSide === "top" ) - { - nScrollHeadTable.appendChild( nCaption ); - } - else if ( nCaption._captionSide === "bottom" && nTfoot ) - { - nScrollFootTable.appendChild( nCaption ); - } - } - - /* - * Sizing - */ - /* When x-scrolling add the width and a scroller to move the header with the body */ - if ( oSettings.oScroll.sX !== "" ) - { - nScrollHead.style.width = _fnStringToCss( oSettings.oScroll.sX ); - nScrollBody.style.width = _fnStringToCss( oSettings.oScroll.sX ); - - if ( nTfoot !== null ) - { - nScrollFoot.style.width = _fnStringToCss( oSettings.oScroll.sX ); - } - - /* When the body is scrolled, then we also want to scroll the headers */ - $(nScrollBody).scroll( function (e) { - nScrollHead.scrollLeft = this.scrollLeft; - - if ( nTfoot !== null ) - { - nScrollFoot.scrollLeft = this.scrollLeft; - } - } ); - } - - /* When yscrolling, add the height */ - if ( oSettings.oScroll.sY !== "" ) - { - nScrollBody.style.height = _fnStringToCss( oSettings.oScroll.sY ); - } - - /* Redraw - align columns across the tables */ - oSettings.aoDrawCallback.push( { - "fn": _fnScrollDraw, - "sName": "scrolling" - } ); - - /* Infinite scrolling event handlers */ - if ( oSettings.oScroll.bInfinite ) - { - $(nScrollBody).scroll( function() { - /* Use a blocker to stop scrolling from loading more data while other data is still loading */ - if ( !oSettings.bDrawing && $(this).scrollTop() !== 0 ) - { - /* Check if we should load the next data set */ - if ( $(this).scrollTop() + $(this).height() > - $(oSettings.nTable).height() - oSettings.oScroll.iLoadGap ) - { - /* Only do the redraw if we have to - we might be at the end of the data */ - if ( oSettings.fnDisplayEnd() < oSettings.fnRecordsDisplay() ) - { - _fnPageChange( oSettings, 'next' ); - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - } - } - } ); - } - - oSettings.nScrollHead = nScrollHead; - oSettings.nScrollFoot = nScrollFoot; - - return nScroller; - } - - - /** - * Update the various tables for resizing. It's a bit of a pig this function, but - * basically the idea to: - * 1. Re-create the table inside the scrolling div - * 2. Take live measurements from the DOM - * 3. Apply the measurements - * 4. Clean up - * @param {object} o dataTables settings object - * @returns {node} Node to add to the DOM - * @memberof DataTable#oApi - */ - function _fnScrollDraw ( o ) - { - var - nScrollHeadInner = o.nScrollHead.getElementsByTagName('div')[0], - nScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0], - nScrollBody = o.nTable.parentNode, - i, iLen, j, jLen, anHeadToSize, anHeadSizers, anFootSizers, anFootToSize, oStyle, iVis, - nTheadSize, nTfootSize, - iWidth, aApplied=[], aAppliedFooter=[], iSanityWidth, - nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null, - nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null, - ie67 = o.oBrowser.bScrollOversize, - zeroOut = function(nSizer) { - oStyle = nSizer.style; - oStyle.paddingTop = "0"; - oStyle.paddingBottom = "0"; - oStyle.borderTopWidth = "0"; - oStyle.borderBottomWidth = "0"; - oStyle.height = 0; - }; - - /* - * 1. Re-create the table inside the scrolling div - */ - - /* Remove the old minimised thead and tfoot elements in the inner table */ - $(o.nTable).children('thead, tfoot').remove(); - - /* Clone the current header and footer elements and then place it into the inner table */ - nTheadSize = $(o.nTHead).clone()[0]; - o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] ); - anHeadToSize = o.nTHead.getElementsByTagName('tr'); - anHeadSizers = nTheadSize.getElementsByTagName('tr'); - - if ( o.nTFoot !== null ) - { - nTfootSize = $(o.nTFoot).clone()[0]; - o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] ); - anFootToSize = o.nTFoot.getElementsByTagName('tr'); - anFootSizers = nTfootSize.getElementsByTagName('tr'); - } - - /* - * 2. Take live measurements from the DOM - do not alter the DOM itself! - */ - - /* Remove old sizing and apply the calculated column widths - * Get the unique column headers in the newly created (cloned) header. We want to apply the - * calculated sizes to this header - */ - if ( o.oScroll.sX === "" ) - { - nScrollBody.style.width = '100%'; - nScrollHeadInner.parentNode.style.width = '100%'; - } - - var nThs = _fnGetUniqueThs( o, nTheadSize ); - for ( i=0, iLen=nThs.length ; i nScrollBody.offsetHeight || - $(nScrollBody).css('overflow-y') == "scroll") ) - { - o.nTable.style.width = _fnStringToCss( $(o.nTable).outerWidth() - o.oScroll.iBarWidth); - } - } - else - { - if ( o.oScroll.sXInner !== "" ) - { - /* x scroll inner has been given - use it */ - o.nTable.style.width = _fnStringToCss(o.oScroll.sXInner); - } - else if ( iSanityWidth == $(nScrollBody).width() && - $(nScrollBody).height() < $(o.nTable).height() ) - { - /* There is y-scrolling - try to take account of the y scroll bar */ - o.nTable.style.width = _fnStringToCss( iSanityWidth-o.oScroll.iBarWidth ); - if ( $(o.nTable).outerWidth() > iSanityWidth-o.oScroll.iBarWidth ) - { - /* Not possible to take account of it */ - o.nTable.style.width = _fnStringToCss( iSanityWidth ); - } - } - else - { - /* All else fails */ - o.nTable.style.width = _fnStringToCss( iSanityWidth ); - } - } - - /* Recalculate the sanity width - now that we've applied the required width, before it was - * a temporary variable. This is required because the column width calculation is done - * before this table DOM is created. - */ - iSanityWidth = $(o.nTable).outerWidth(); - - /* We want the hidden header to have zero height, so remove padding and borders. Then - * set the width based on the real headers - */ - - // Apply all styles in one pass. Invalidates layout only once because we don't read any - // DOM properties. - _fnApplyToChildren( zeroOut, anHeadSizers ); - - // Read all widths in next pass. Forces layout only once because we do not change - // any DOM properties. - _fnApplyToChildren( function(nSizer) { - aApplied.push( _fnStringToCss( $(nSizer).width() ) ); - }, anHeadSizers ); - - // Apply all widths in final pass. Invalidates layout only once because we do not - // read any DOM properties. - _fnApplyToChildren( function(nToSize, i) { - nToSize.style.width = aApplied[i]; - }, anHeadToSize ); - - $(anHeadSizers).height(0); - - /* Same again with the footer if we have one */ - if ( o.nTFoot !== null ) - { - _fnApplyToChildren( zeroOut, anFootSizers ); - - _fnApplyToChildren( function(nSizer) { - aAppliedFooter.push( _fnStringToCss( $(nSizer).width() ) ); - }, anFootSizers ); - - _fnApplyToChildren( function(nToSize, i) { - nToSize.style.width = aAppliedFooter[i]; - }, anFootToSize ); - - $(anFootSizers).height(0); - } - - /* - * 3. Apply the measurements - */ - - /* "Hide" the header and footer that we used for the sizing. We want to also fix their width - * to what they currently are - */ - _fnApplyToChildren( function(nSizer, i) { - nSizer.innerHTML = ""; - nSizer.style.width = aApplied[i]; - }, anHeadSizers ); - - if ( o.nTFoot !== null ) - { - _fnApplyToChildren( function(nSizer, i) { - nSizer.innerHTML = ""; - nSizer.style.width = aAppliedFooter[i]; - }, anFootSizers ); - } - - /* Sanity check that the table is of a sensible width. If not then we are going to get - * misalignment - try to prevent this by not allowing the table to shrink below its min width - */ - if ( $(o.nTable).outerWidth() < iSanityWidth ) - { - /* The min width depends upon if we have a vertical scrollbar visible or not */ - var iCorrection = ((nScrollBody.scrollHeight > nScrollBody.offsetHeight || - $(nScrollBody).css('overflow-y') == "scroll")) ? - iSanityWidth+o.oScroll.iBarWidth : iSanityWidth; - - /* IE6/7 are a law unto themselves... */ - if ( ie67 && (nScrollBody.scrollHeight > - nScrollBody.offsetHeight || $(nScrollBody).css('overflow-y') == "scroll") ) - { - o.nTable.style.width = _fnStringToCss( iCorrection-o.oScroll.iBarWidth ); - } - - /* Apply the calculated minimum width to the table wrappers */ - nScrollBody.style.width = _fnStringToCss( iCorrection ); - o.nScrollHead.style.width = _fnStringToCss( iCorrection ); - - if ( o.nTFoot !== null ) - { - o.nScrollFoot.style.width = _fnStringToCss( iCorrection ); - } - - /* And give the user a warning that we've stopped the table getting too small */ - if ( o.oScroll.sX === "" ) - { - _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ - " misalignment. The table has been drawn at its minimum possible width." ); - } - else if ( o.oScroll.sXInner !== "" ) - { - _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ - " misalignment. Increase the sScrollXInner value or remove it to allow automatic"+ - " calculation" ); - } - } - else - { - nScrollBody.style.width = _fnStringToCss( '100%' ); - o.nScrollHead.style.width = _fnStringToCss( '100%' ); - - if ( o.nTFoot !== null ) - { - o.nScrollFoot.style.width = _fnStringToCss( '100%' ); - } - } - - - /* - * 4. Clean up - */ - if ( o.oScroll.sY === "" ) - { - /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting - * the scrollbar height from the visible display, rather than adding it on. We need to - * set the height in order to sort this. Don't want to do it in any other browsers. - */ - if ( ie67 ) - { - nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+o.oScroll.iBarWidth ); - } - } - - if ( o.oScroll.sY !== "" && o.oScroll.bCollapse ) - { - nScrollBody.style.height = _fnStringToCss( o.oScroll.sY ); - - var iExtra = (o.oScroll.sX !== "" && o.nTable.offsetWidth > nScrollBody.offsetWidth) ? - o.oScroll.iBarWidth : 0; - if ( o.nTable.offsetHeight < nScrollBody.offsetHeight ) - { - nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+iExtra ); - } - } - - /* Finally set the width's of the header and footer tables */ - var iOuterWidth = $(o.nTable).outerWidth(); - nScrollHeadTable.style.width = _fnStringToCss( iOuterWidth ); - nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth ); - - // Figure out if there are scrollbar present - if so then we need a the header and footer to - // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar) - var bScrolling = $(o.nTable).height() > nScrollBody.clientHeight || $(nScrollBody).css('overflow-y') == "scroll"; - nScrollHeadInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; - - if ( o.nTFoot !== null ) - { - nScrollFootTable.style.width = _fnStringToCss( iOuterWidth ); - nScrollFootInner.style.width = _fnStringToCss( iOuterWidth ); - nScrollFootInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; - } - - /* Adjust the position of the header in case we loose the y-scrollbar */ - $(nScrollBody).scroll(); - - /* If sorting or filtering has occurred, jump the scrolling back to the top */ - if ( o.bSorted || o.bFiltered ) - { - nScrollBody.scrollTop = 0; - } - } - - - /** - * Apply a given function to the display child nodes of an element array (typically - * TD children of TR rows - * @param {function} fn Method to apply to the objects - * @param array {nodes} an1 List of elements to look through for display children - * @param array {nodes} an2 Another list (identical structure to the first) - optional - * @memberof DataTable#oApi - */ - function _fnApplyToChildren( fn, an1, an2 ) - { - var index=0, i=0, iLen=an1.length; - var nNode1, nNode2; - - while ( i < iLen ) - { - nNode1 = an1[i].firstChild; - nNode2 = an2 ? an2[i].firstChild : null; - while ( nNode1 ) - { - if ( nNode1.nodeType === 1 ) - { - if ( an2 ) - { - fn( nNode1, nNode2, index ); - } - else - { - fn( nNode1, index ); - } - index++; - } - nNode1 = nNode1.nextSibling; - nNode2 = an2 ? nNode2.nextSibling : null; - } - i++; - } - } - - /** - * Convert a CSS unit width to pixels (e.g. 2em) - * @param {string} sWidth width to be converted - * @param {node} nParent parent to get the with for (required for relative widths) - optional - * @returns {int} iWidth width in pixels - * @memberof DataTable#oApi - */ - function _fnConvertToWidth ( sWidth, nParent ) - { - if ( !sWidth || sWidth === null || sWidth === '' ) - { - return 0; - } - - if ( !nParent ) - { - nParent = document.body; - } - - var iWidth; - var nTmp = document.createElement( "div" ); - nTmp.style.width = _fnStringToCss( sWidth ); - - nParent.appendChild( nTmp ); - iWidth = nTmp.offsetWidth; - nParent.removeChild( nTmp ); - - return ( iWidth ); - } - - - /** - * Calculate the width of columns for the table - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnCalculateColumnWidths ( oSettings ) - { - var iTableWidth = oSettings.nTable.offsetWidth; - var iUserInputs = 0; - var iTmpWidth; - var iVisibleColumns = 0; - var iColums = oSettings.aoColumns.length; - var i, iIndex, iCorrector, iWidth; - var oHeaders = $('th', oSettings.nTHead); - var widthAttr = oSettings.nTable.getAttribute('width'); - var nWrapper = oSettings.nTable.parentNode; - - /* Convert any user input sizes into pixel sizes */ - for ( i=0 ; itd', nCalcTmp); - } - - /* Apply custom sizing to the cloned header */ - var nThs = _fnGetUniqueThs( oSettings, nTheadClone ); - iCorrector = 0; - for ( i=0 ; i 0 ) - { - oSettings.aoColumns[i].sWidth = _fnStringToCss( iWidth ); - } - iCorrector++; - } - } - - var cssWidth = $(nCalcTmp).css('width'); - oSettings.nTable.style.width = (cssWidth.indexOf('%') !== -1) ? - cssWidth : _fnStringToCss( $(nCalcTmp).outerWidth() ); - nCalcTmp.parentNode.removeChild( nCalcTmp ); - } - - if ( widthAttr ) - { - oSettings.nTable.style.width = _fnStringToCss( widthAttr ); - } - } - - - /** - * Adjust a table's width to take account of scrolling - * @param {object} oSettings dataTables settings object - * @param {node} n table node - * @memberof DataTable#oApi - */ - function _fnScrollingWidthAdjust ( oSettings, n ) - { - if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY !== "" ) - { - /* When y-scrolling only, we want to remove the width of the scroll bar so the table - * + scroll bar will fit into the area avaialble. - */ - var iOrigWidth = $(n).width(); - n.style.width = _fnStringToCss( $(n).outerWidth()-oSettings.oScroll.iBarWidth ); - } - else if ( oSettings.oScroll.sX !== "" ) - { - /* When x-scrolling both ways, fix the table at it's current size, without adjusting */ - n.style.width = _fnStringToCss( $(n).outerWidth() ); - } - } - - - /** - * Get the widest node - * @param {object} oSettings dataTables settings object - * @param {int} iCol column of interest - * @returns {node} widest table node - * @memberof DataTable#oApi - */ - function _fnGetWidestNode( oSettings, iCol ) - { - var iMaxIndex = _fnGetMaxLenString( oSettings, iCol ); - if ( iMaxIndex < 0 ) - { - return null; - } - - if ( oSettings.aoData[iMaxIndex].nTr === null ) - { - var n = document.createElement('td'); - n.innerHTML = _fnGetCellData( oSettings, iMaxIndex, iCol, '' ); - return n; - } - return _fnGetTdNodes(oSettings, iMaxIndex)[iCol]; - } - - - /** - * Get the maximum strlen for each data column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column of interest - * @returns {string} max string length for each column - * @memberof DataTable#oApi - */ - function _fnGetMaxLenString( oSettings, iCol ) - { - var iMax = -1; - var iMaxIndex = -1; - - for ( var i=0 ; i/g, "" ); - if ( s.length > iMax ) - { - iMax = s.length; - iMaxIndex = i; - } - } - - return iMaxIndex; - } - - - /** - * Append a CSS unit (only if required) to a string - * @param {array} aArray1 first array - * @param {array} aArray2 second array - * @returns {int} 0 if match, 1 if length is different, 2 if no match - * @memberof DataTable#oApi - */ - function _fnStringToCss( s ) - { - if ( s === null ) - { - return "0px"; - } - - if ( typeof s == 'number' ) - { - if ( s < 0 ) - { - return "0px"; - } - return s+"px"; - } - - /* Check if the last character is not 0-9 */ - var c = s.charCodeAt( s.length-1 ); - if (c < 0x30 || c > 0x39) - { - return s; - } - return s+"px"; - } - - - /** - * Get the width of a scroll bar in this browser being used - * @returns {int} width in pixels - * @memberof DataTable#oApi - */ - function _fnScrollBarWidth () - { - var inner = document.createElement('p'); - var style = inner.style; - style.width = "100%"; - style.height = "200px"; - style.padding = "0px"; - - var outer = document.createElement('div'); - style = outer.style; - style.position = "absolute"; - style.top = "0px"; - style.left = "0px"; - style.visibility = "hidden"; - style.width = "200px"; - style.height = "150px"; - style.padding = "0px"; - style.overflow = "hidden"; - outer.appendChild(inner); - - document.body.appendChild(outer); - var w1 = inner.offsetWidth; - outer.style.overflow = 'scroll'; - var w2 = inner.offsetWidth; - if ( w1 == w2 ) - { - w2 = outer.clientWidth; - } - - document.body.removeChild(outer); - return (w1 - w2); - } - - /** - * Change the order of the table - * @param {object} oSettings dataTables settings object - * @param {bool} bApplyClasses optional - should we apply classes or not - * @memberof DataTable#oApi - */ - function _fnSort ( oSettings, bApplyClasses ) - { - var - i, iLen, j, jLen, k, kLen, - sDataType, nTh, - aaSort = [], - aiOrig = [], - oSort = DataTable.ext.oSort, - aoData = oSettings.aoData, - aoColumns = oSettings.aoColumns, - oAria = oSettings.oLanguage.oAria; - - /* No sorting required if server-side or no sorting array */ - if ( !oSettings.oFeatures.bServerSide && - (oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) ) - { - aaSort = ( oSettings.aaSortingFixed !== null ) ? - oSettings.aaSortingFixed.concat( oSettings.aaSorting ) : - oSettings.aaSorting.slice(); - - /* If there is a sorting data type, and a function belonging to it, then we need to - * get the data from the developer's function and apply it for this column - */ - for ( i=0 ; i/g, "" ); - nTh = aoColumns[i].nTh; - nTh.removeAttribute('aria-sort'); - nTh.removeAttribute('aria-label'); - - /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ - if ( aoColumns[i].bSortable ) - { - if ( aaSort.length > 0 && aaSort[0][0] == i ) - { - nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" ); - - var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ? - aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0]; - nTh.setAttribute('aria-label', sTitle+ - (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - else - { - nTh.setAttribute('aria-label', sTitle+ - (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - } - else - { - nTh.setAttribute('aria-label', sTitle); - } - } - - /* Tell the draw function that we have sorted the data */ - oSettings.bSorted = true; - $(oSettings.oInstance).trigger('sort', oSettings); - - /* Copy the master data into the draw array and re-draw */ - if ( oSettings.oFeatures.bFilter ) - { - /* _fnFilter() will redraw the table for us */ - _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 ); - } - else - { - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - oSettings._iDisplayStart = 0; /* reset display back to page 0 */ - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - } - - - /** - * Attach a sort handler (click) to a node - * @param {object} oSettings dataTables settings object - * @param {node} nNode node to attach the handler to - * @param {int} iDataIndex column sorting index - * @param {function} [fnCallback] callback function - * @memberof DataTable#oApi - */ - function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback ) - { - _fnBindAction( nNode, {}, function (e) { - /* If the column is not sortable - don't to anything */ - if ( oSettings.aoColumns[iDataIndex].bSortable === false ) - { - return; - } - - /* - * This is a little bit odd I admit... I declare a temporary function inside the scope of - * _fnBuildHead and the click handler in order that the code presented here can be used - * twice - once for when bProcessing is enabled, and another time for when it is - * disabled, as we need to perform slightly different actions. - * Basically the issue here is that the Javascript engine in modern browsers don't - * appear to allow the rendering engine to update the display while it is still executing - * it's thread (well - it does but only after long intervals). This means that the - * 'processing' display doesn't appear for a table sort. To break the js thread up a bit - * I force an execution break by using setTimeout - but this breaks the expected - * thread continuation for the end-developer's point of view (their code would execute - * too early), so we only do it when we absolutely have to. - */ - var fnInnerSorting = function () { - modJs.sortingStarted(1); - var iColumn, iNextSort; - - /* If the shift key is pressed then we are multiple column sorting */ - if ( e.shiftKey ) - { - /* Are we already doing some kind of sort on this column? */ - var bFound = false; - for ( var i=0 ; i 0 && sCurrentClass.indexOf(sNewClass) == -1 ) - { - /* We need to add a class */ - nTds[i].className = sCurrentClass + " " + sNewClass; - } - } - } - } - - - - /** - * Save the state of a table in a cookie such that the page can be reloaded - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnSaveState ( oSettings ) - { - if ( !oSettings.oFeatures.bStateSave || oSettings.bDestroying ) - { - return; - } - - /* Store the interesting variables */ - var i, iLen, bInfinite=oSettings.oScroll.bInfinite; - var oState = { - "iCreate": new Date().getTime(), - "iStart": (bInfinite ? 0 : oSettings._iDisplayStart), - "iEnd": (bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd), - "iLength": oSettings._iDisplayLength, - "aaSorting": $.extend( true, [], oSettings.aaSorting ), - "oSearch": $.extend( true, {}, oSettings.oPreviousSearch ), - "aoSearchCols": $.extend( true, [], oSettings.aoPreSearchCols ), - "abVisCols": [] - }; - - for ( i=0, iLen=oSettings.aoColumns.length ; i 4096 ) /* Magic 10 for padding */ - { - for ( var i=0, iLen=aCookies.length ; i 4096 ) { - if ( aOldCookies.length === 0 ) { - // Deleted all DT cookies and still not enough space. Can't state save - return; - } - - var old = aOldCookies.pop(); - document.cookie = old.name+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+ - aParts.join('/') + "/"; - } - } - - document.cookie = sFullCookie; - } - - - /** - * Read an old cookie to get a cookie with an old table state - * @param {string} sName name of the cookie to read - * @returns {string} contents of the cookie - or null if no cookie with that name found - * @memberof DataTable#oApi - */ - function _fnReadCookie ( sName ) - { - var - aParts = window.location.pathname.split('/'), - sNameEQ = sName + '_' + aParts[aParts.length-1].replace(/[\/:]/g,"").toLowerCase() + '=', - sCookieContents = document.cookie.split(';'); - - for( var i=0 ; i=0 ; i-- ) - { - aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) ); - } - - if ( sTrigger !== null ) - { - $(oSettings.oInstance).trigger(sTrigger, aArgs); - } - - return aRet; - } - - - /** - * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other - * library, then we use that as it is fast, safe and accurate. If the function isn't - * available then we need to built it ourselves - the inspiration for this function comes - * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is - * not perfect and absolutely should not be used as a replacement to json2.js - but it does - * do what we need, without requiring a dependency for DataTables. - * @param {object} o JSON object to be converted - * @returns {string} JSON string - * @memberof DataTable#oApi - */ - var _fnJsonString = (window.JSON) ? JSON.stringify : function( o ) - { - /* Not an object or array */ - var sType = typeof o; - if (sType !== "object" || o === null) - { - // simple data type - if (sType === "string") - { - o = '"'+o+'"'; - } - return o+""; - } - - /* If object or array, need to recurse over it */ - var - sProp, mValue, - json = [], - bArr = $.isArray(o); - - for (sProp in o) - { - mValue = o[sProp]; - sType = typeof mValue; - - if (sType === "string") - { - mValue = '"'+mValue+'"'; - } - else if (sType === "object" && mValue !== null) - { - mValue = _fnJsonString(mValue); - } - - json.push((bArr ? "" : '"'+sProp+'":') + mValue); - } - - return (bArr ? "[" : "{") + json + (bArr ? "]" : "}"); - }; - - - /** - * From some browsers (specifically IE6/7) we need special handling to work around browser - * bugs - this function is used to detect when these workarounds are needed. - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnBrowserDetect( oSettings ) - { - /* IE6/7 will oversize a width 100% element inside a scrolling element, to include the - * width of the scrollbar, while other browsers ensure the inner element is contained - * without forcing scrolling - */ - var n = $( - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    ')[0]; - - document.body.appendChild( n ); - oSettings.oBrowser.bScrollOversize = $('#DT_BrowserTest', n)[0].offsetWidth === 100 ? true : false; - document.body.removeChild( n ); - } - - - /** - * Perform a jQuery selector action on the table's TR elements (from the tbody) and - * return the resulting jQuery object. - * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on - * @param {object} [oOpts] Optional parameters for modifying the rows to be included - * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter - * criterion ("applied") or all TR elements (i.e. no filter). - * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. - * Can be either 'current', whereby the current sorting of the table is used, or - * 'original' whereby the original order the data was read into the table is used. - * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page - * ("current") or not ("all"). If 'current' is given, then order is assumed to be - * 'current' and filter is 'applied', regardless of what they might be given as. - * @returns {object} jQuery object, filtered by the given selector. - * @dtopt API - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Highlight every second row - * oTable.$('tr:odd').css('backgroundColor', 'blue'); - * } ); - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Filter to rows with 'Webkit' in them, add a background colour and then - * // remove the filter, thus highlighting the 'Webkit' rows only. - * oTable.fnFilter('Webkit'); - * oTable.$('tr', {"filter": "applied"}).css('backgroundColor', 'blue'); - * oTable.fnFilter(''); - * } ); - */ - this.$ = function ( sSelector, oOpts ) - { - var i, iLen, a = [], tr; - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var aoData = oSettings.aoData; - var aiDisplay = oSettings.aiDisplay; - var aiDisplayMaster = oSettings.aiDisplayMaster; - - if ( !oOpts ) - { - oOpts = {}; - } - - oOpts = $.extend( {}, { - "filter": "none", // applied - "order": "current", // "original" - "page": "all" // current - }, oOpts ); - - // Current page implies that order=current and fitler=applied, since it is fairly - // senseless otherwise - if ( oOpts.page == 'current' ) - { - for ( i=oSettings._iDisplayStart, iLen=oSettings.fnDisplayEnd() ; i - *
  • 1D array of data - add a single row with the data provided
  • - *
  • 2D array of arrays - add multiple rows in a single call
  • - *
  • object - data object when using mData
  • - *
  • array of objects - multiple data objects when using mData
  • - * - * @param {bool} [bRedraw=true] redraw the table or not - * @returns {array} An array of integers, representing the list of indexes in - * aoData ({@link DataTable.models.oSettings}) that have been added to - * the table. - * @dtopt API - * - * @example - * // Global var for counter - * var giCount = 2; - * - * $(document).ready(function() { - * $('#example').dataTable(); - * } ); - * - * function fnClickAddRow() { - * $('#example').dataTable().fnAddData( [ - * giCount+".1", - * giCount+".2", - * giCount+".3", - * giCount+".4" ] - * ); - * - * giCount++; - * } - */ - this.fnAddData = function( mData, bRedraw ) - { - if ( mData.length === 0 ) - { - return []; - } - - var aiReturn = []; - var iTest; - - /* Find settings from table node */ - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - - /* Check if we want to add multiple rows or not */ - if ( typeof mData[0] === "object" && mData[0] !== null ) - { - for ( var i=0 ; i= oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart -= oSettings._iDisplayLength; - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - - if ( bRedraw === undefined || bRedraw ) - { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - - return oData; - }; - - - /** - * Restore the table to it's original state in the DOM by removing all of DataTables - * enhancements, alterations to the DOM structure of the table and event listeners. - * @param {boolean} [bRemove=false] Completely remove the table from the DOM - * @dtopt API - * - * @example - * $(document).ready(function() { - * // This example is fairly pointless in reality, but shows how fnDestroy can be used - * var oTable = $('#example').dataTable(); - * oTable.fnDestroy(); - * } ); - */ - this.fnDestroy = function ( bRemove ) - { - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var nOrig = oSettings.nTableWrapper.parentNode; - var nBody = oSettings.nTBody; - var i, iLen; - - bRemove = (bRemove===undefined) ? false : bRemove; - - /* Flag to note that the table is currently being destroyed - no action should be taken */ - oSettings.bDestroying = true; - - /* Fire off the destroy callbacks for plug-ins etc */ - _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] ); - - /* If the table is not being removed, restore the hidden columns */ - if ( !bRemove ) - { - for ( i=0, iLen=oSettings.aoColumns.length ; itr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove(); - - /* When scrolling we had to break the table up - restore it */ - if ( oSettings.nTable != oSettings.nTHead.parentNode ) - { - $(oSettings.nTable).children('thead').remove(); - oSettings.nTable.appendChild( oSettings.nTHead ); - } - - if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode ) - { - $(oSettings.nTable).children('tfoot').remove(); - oSettings.nTable.appendChild( oSettings.nTFoot ); - } - - /* Remove the DataTables generated nodes, events and classes */ - oSettings.nTable.parentNode.removeChild( oSettings.nTable ); - $(oSettings.nTableWrapper).remove(); - - oSettings.aaSorting = []; - oSettings.aaSortingFixed = []; - _fnSortingClasses( oSettings ); - - $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') ); - - $('th, td', oSettings.nTHead).removeClass( [ - oSettings.oClasses.sSortable, - oSettings.oClasses.sSortableAsc, - oSettings.oClasses.sSortableDesc, - oSettings.oClasses.sSortableNone ].join(' ') - ); - if ( oSettings.bJUI ) - { - $('th span.'+oSettings.oClasses.sSortIcon - + ', td span.'+oSettings.oClasses.sSortIcon, oSettings.nTHead).remove(); - - $('th, td', oSettings.nTHead).each( function () { - var jqWrapper = $('div.'+oSettings.oClasses.sSortJUIWrapper, this); - var kids = jqWrapper.contents(); - $(this).append( kids ); - jqWrapper.remove(); - } ); - } - - /* Add the TR elements back into the table in their original order */ - if ( !bRemove && oSettings.nTableReinsertBefore ) - { - nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore ); - } - else if ( !bRemove ) - { - nOrig.appendChild( oSettings.nTable ); - } - - for ( i=0, iLen=oSettings.aoData.length ; i