├── .nvmrc ├── VERSION ├── .doclintrc ├── codecov.yml ├── phpstan.neon.dist ├── .eslintrc.js ├── client ├── lang │ ├── src │ │ ├── fi_FI.js │ │ ├── pt_BR.js │ │ ├── de.js │ │ ├── zh.js │ │ ├── ar.js │ │ ├── mi.js │ │ ├── ru.js │ │ ├── eo.js │ │ ├── hr.js │ │ ├── it.js │ │ ├── es.js │ │ └── en.js │ ├── fi_FI.js │ ├── pt_BR.js │ ├── de.js │ ├── zh.js │ ├── ar.js │ ├── mi.js │ ├── ru.js │ ├── eo.js │ ├── hr.js │ ├── it.js │ ├── es.js │ └── en.js └── src │ ├── images │ ├── spinner.gif │ └── workflow-menu-icon.png │ ├── bundles │ ├── bundle.js │ ├── advanced-workflow-cms.js │ ├── advancedworkflow-management.js │ └── WorkflowGridField.js │ └── styles │ ├── bundle.scss │ ├── WorkflowGridField.scss │ ├── workflow-variables.scss │ ├── AdvancedWorkflowAdmin.scss │ └── WorkflowField.scss ├── .stylelintrc.js ├── images ├── action.png ├── assign.png ├── cancel.png ├── notify.png ├── approval.png ├── publish.png ├── unpublish.png ├── definition.png └── transition.png ├── babel.config.json ├── _config.php ├── templates ├── Includes │ ├── embargoIntro.ss │ ├── CommentHistory.ss │ ├── AssignedWorkflowList.ss │ └── WorkflowDefinitionExport.ss ├── Symbiote │ └── AdvancedWorkflow │ │ ├── Forms │ │ └── GridField │ │ │ └── GridFieldExportAction.ss │ │ ├── DataObjects │ │ └── WorkflowActionInstance │ │ │ └── ReadonlyField.ss │ │ └── FormFields │ │ └── WorkflowField.ss └── email │ └── WorkflowReminderEmail.ss ├── src ├── Services │ └── ExistingWorkflowException.php ├── Actions │ ├── CancelWorkflowAction.php │ ├── SimpleApprovalWorkflowAction.php │ ├── SetPropertyWorkflowAction.php │ ├── UnpublishItemWorkflowAction.php │ ├── AssignUsersToWorkflowAction.php │ └── PublishItemWorkflowAction.php ├── Admin │ ├── WorkflowDefinitionItemRequestClass.php │ └── WorkflowDefinitionImporter.php ├── DataObjects │ └── ImportedWorkflowTemplate.php ├── Jobs │ ├── WorkflowPublishTargetJob.php │ └── WorkflowReminderJob.php ├── FormFields │ ├── WorkflowFieldTransitionController.php │ ├── WorkflowFieldActionController.php │ ├── WorkflowFieldItemController.php │ └── WorkflowField.php ├── Controllers │ └── AdvancedWorkflowActionController.php ├── Tasks │ └── WorkflowReminderTask.php ├── Forms │ ├── gridfield │ │ ├── GridFieldWorkflowRestrictedEditButton.php │ │ └── GridFieldExportAction.php │ └── AWRequiredFieldsValidator.php ├── Extensions │ └── FileWorkflowApplicable.php └── Dev │ └── WorkflowBulkLoader.php ├── code-of-conduct.md ├── .github ├── ISSUE_TEMPLATE │ ├── 3_blank_issue.md │ ├── config.yml │ ├── 2_feature_request.yml │ └── 1_bug_report.yml ├── workflows │ ├── ci.yml │ ├── deploy-userhelp-docs.yml │ ├── keepalive.yml │ ├── merge-up.yml │ ├── add-prs-to-project.yml │ ├── tag-patch-release.yml │ ├── update-js.yml │ └── dispatch-ci.yml └── PULL_REQUEST_TEMPLATE.md ├── _config ├── workflowjobs.yml ├── workflowconfig.yml └── workflows.yml ├── .tx └── config ├── phpcs.xml.dist ├── .editorconfig ├── phpunit.xml.dist ├── webpack.config.js ├── behat.yml ├── package.json ├── README.md ├── lang ├── tr.yml ├── da.yml ├── ja_JP.yml ├── hu.yml ├── ro.yml ├── gl_ES.yml ├── pl_PL.yml ├── sr.yml ├── pt.yml ├── sr_RS@latin.yml ├── de_DE.yml ├── th.yml ├── sl_SI.yml ├── af.yml ├── sr@latin.yml ├── sr_RS.yml ├── es_MX.yml ├── ja.yml ├── id_ID.yml ├── nb.yml ├── et_EE.yml ├── pl.yml ├── cs.yml ├── bg.yml ├── lt.yml ├── fr.yml ├── fa_IR.yml ├── fi.yml ├── hr.yml ├── ru.yml ├── sv.yml ├── sl.yml ├── sk.yml ├── nl.yml ├── id.yml ├── fi_FI.yml └── pt_BR.yml ├── LICENSE └── composer.json /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 2.1.0 2 | -------------------------------------------------------------------------------- /.doclintrc: -------------------------------------------------------------------------------- 1 | docs/en/ 2 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | -------------------------------------------------------------------------------- /phpstan.neon.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | paths: 3 | - src 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@silverstripe/eslint-config/.eslintrc'); 2 | -------------------------------------------------------------------------------- /client/lang/src/fi_FI.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.CreateWorkflow": "Luo työnkulku" 3 | } -------------------------------------------------------------------------------- /client/lang/src/pt_BR.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.CreateWorkflow": "Criar workflow" 3 | } -------------------------------------------------------------------------------- /.stylelintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@silverstripe/eslint-config/.stylelintrc'); 2 | -------------------------------------------------------------------------------- /images/action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/action.png -------------------------------------------------------------------------------- /images/assign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/assign.png -------------------------------------------------------------------------------- /images/cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/cancel.png -------------------------------------------------------------------------------- /images/notify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/notify.png -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /images/approval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/approval.png -------------------------------------------------------------------------------- /images/publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/publish.png -------------------------------------------------------------------------------- /images/unpublish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/unpublish.png -------------------------------------------------------------------------------- /images/definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/definition.png -------------------------------------------------------------------------------- /images/transition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silverstripe/silverstripe-advancedworkflow/HEAD/images/transition.png -------------------------------------------------------------------------------- /_config.php: -------------------------------------------------------------------------------- 1 | $INTRO

3 | 9 |
-------------------------------------------------------------------------------- /client/src/bundles/bundle.js: -------------------------------------------------------------------------------- 1 | import 'bundles/advanced-workflow-cms'; 2 | import 'bundles/advancedworkflow-management'; 3 | import 'bundles/WorkflowField'; 4 | import 'bundles/WorkflowGridField'; 5 | -------------------------------------------------------------------------------- /src/Services/ExistingWorkflowException.php: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /client/src/styles/WorkflowGridField.scss: -------------------------------------------------------------------------------- 1 | .ss-gridfield { 2 | .ss-gridfield-item { 3 | .disabled { 4 | a.action { 5 | opacity: 0.35; 6 | filter: alpha(Opacity=35); 7 | cursor: default; 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /templates/Includes/CommentHistory.ss: -------------------------------------------------------------------------------- 1 | <% if PastActions %> 2 | ---
3 | <%t WorkflowList.CommentHistory "Comment history on this request:" %> 4 |
5 | <% loop PastActions %><% if Comment %>[$Created.Nice] $Member.FirstName $Member.Surname: $Comment
<% end_if %><% end_loop %> 6 | <% end_if %> 7 | -------------------------------------------------------------------------------- /_config/workflowjobs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Name: workflow_jobs 3 | Only: 4 | moduleexists: symbiote/silverstripe-queuedjobs 5 | --- 6 | SilverStripe\Core\Injector\Injector: 7 | Symbiote\AdvancedWorkflow\Jobs\WorkflowReminderJob: 8 | properties: 9 | queuedJobService: '%$Symbiote\QueuedJobs\Services\QueuedJobService' 10 | -------------------------------------------------------------------------------- /client/lang/src/zh.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.DeleteQuestion": "您确定要永久删除这项吗?", 3 | "Workflow.EMBARGOMESSAGEDATE": "这个页面已保存的草稿会在%s自动发布", 4 | "Workflow.EMBARGOMESSAGEDATETIME": "这个页面已保存的草稿会在%s %s自动发布", 5 | "Workflow.EMBARGOMESSAGETIME": "这个页面已保存的草稿会在今天%s自动发布", 6 | "Workflow.ProcessError": "无法处理工作流程" 7 | } -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | ci: 10 | name: CI 11 | # Do not run if this is a pull-request from same repo i.e. not a fork repo 12 | if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository 13 | uses: silverstripe/gha-ci/.github/workflows/ci.yml@v2 14 | -------------------------------------------------------------------------------- /templates/Symbiote/AdvancedWorkflow/Forms/GridField/GridFieldExportAction.ss: -------------------------------------------------------------------------------- 1 | 5 | <%t Symbiote\\AdvancedWorkflow\\Forms\\GridField\\GridFieldExportAction.Export 'Export' %> 6 | 7 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [o:silverstripe:p:silverstripe-advancedworkflow:r:master] 5 | file_filter = lang/.yml 6 | source_file = lang/en.yml 7 | source_lang = en 8 | type = YML 9 | 10 | [o:silverstripe:p:silverstripe-advancedworkflow:r:master-js] 11 | file_filter = client/lang/src/.js 12 | source_file = client/lang/src/en.js 13 | source_lang = en 14 | type = KEYVALUEJSON 15 | 16 | -------------------------------------------------------------------------------- /.github/workflows/deploy-userhelp-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Userhelp Docs 2 | on: 3 | push: 4 | branches: 5 | - '6' 6 | - '5' 7 | - '4' 8 | paths: 9 | - 'docs/en/userguide/**' 10 | jobs: 11 | deploy: 12 | name: deploy-userhelp-docs 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Run build hook 16 | run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_BUILD_HOOK }} 17 | -------------------------------------------------------------------------------- /client/src/styles/workflow-variables.scss: -------------------------------------------------------------------------------- 1 | // Advanced Workflow colours, that are not part of silverstripe/admin/client/src/styles/_variables.scss 2 | $grey-light: #ebfbff; 3 | $grey-lightish: #d9d9d9; 4 | 5 | $pale-green: #DFD; 6 | $pale-red: #FDD; 7 | 8 | $dark-blue: #7F9198; 9 | $med-blue: #95A5AB; 10 | $light-blue: #D7DDE0; 11 | $light-grey: #F8F8F8; 12 | 13 | $wf-grid: 8px; 14 | $wf-radius: 3px; 15 | 16 | $wf-height: 28px; 17 | $wf-min-width: 360px; 18 | 19 | -------------------------------------------------------------------------------- /client/lang/src/ar.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.DeleteQuestion": "هل أنت متأكد من كونك تريد حذف هذا بشكل دائم؟", 3 | "Workflow.EMBARGOMESSAGEDATE": "سوف تنشر المسودات المحفوظة لهذه الصفحة تلقائيا على %s", 4 | "Workflow.EMBARGOMESSAGEDATETIME": "سوف تنشر المسودات المحفوظة لهذه الصفحة تلقائيا على %s في %s", 5 | "Workflow.EMBARGOMESSAGETIME": "سوف تنشر المسودات المحفوظة لهذه الصفحة تلقائيا اليوم في %s", 6 | "Workflow.ProcessError": "لا يمكن تسيير العملية حتى النهاية" 7 | } -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeSniffer ruleset for SilverStripe coding conventions. 4 | 5 | src 6 | tests 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /client/lang/src/mi.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.DeleteQuestion": "Me muku pūmau tēnei?", 3 | "Workflow.EMBARGOMESSAGEDATE": "Ka whakaputa aunoatia ngā hukihuki kua tiakina o tēnei whārangi %s i %s", 4 | "Workflow.EMBARGOMESSAGEDATETIME": "Ka whakaputa aunoatia ngā hukihuki kua tiakina o tēnei whārangi %s i %s", 5 | "Workflow.EMBARGOMESSAGETIME": "Ka whakaputa aunoatia anō i tēnei rā ngā hukihuki kua tiakina o tēnei whārangi %s i %s", 6 | "Workflow.ProcessError": "Kāore i taea te tukatuka te reremahi" 7 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # For more information about the properties used in this file, 2 | # please see the EditorConfig documentation: 3 | # http://editorconfig.org 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 4 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [{*.yml,*.scss,*.js,package.json}] 14 | indent_size = 2 15 | 16 | # The indent size used in the package.json file cannot be changed: 17 | # https://github.com/npm/npm/pull/3180#issuecomment-16336516 18 | -------------------------------------------------------------------------------- /client/lang/src/ru.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.DeleteQuestion": "Действительно удалить? Эта операция необратима.", 3 | "Workflow.EMBARGOMESSAGEDATE": "Сохраненные черновики будут автоматически опубликованы %s", 4 | "Workflow.EMBARGOMESSAGEDATETIME": "Сохраненные черновики этой страницы будут автоматически опубликованы %s в %s", 5 | "Workflow.EMBARGOMESSAGETIME": "Сохраненные черновики на этой странице будут автоматически опубликованы сегодня в %s", 6 | "Workflow.ProcessError": "Не удалось обработать поток задач" 7 | } -------------------------------------------------------------------------------- /client/lang/fi_FI.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/fi_FI.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('fi_FI', { 9 | "Workflow.CreateWorkflow": "Luo työnkulku" 10 | }); 11 | } -------------------------------------------------------------------------------- /client/lang/pt_BR.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/pt_BR.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('pt_BR', { 9 | "Workflow.CreateWorkflow": "Criar workflow" 10 | }); 11 | } -------------------------------------------------------------------------------- /client/lang/src/eo.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.CreateWorkflow": "Krei laborfluon", 3 | "Workflow.DeleteQuestion": "Ĉi vi vere volas porĉiame forigi ĉi tiun dosieron?", 4 | "Workflow.EMBARGOMESSAGEDATE": "Konservitaj malnetoj de la paĝo aŭtomate publikiĝos je %s", 5 | "Workflow.EMBARGOMESSAGEDATETIME": "Konservitaj malnetoj de la paĝo aŭtomate publikiĝos ĉe %s je %s", 6 | "Workflow.EMBARGOMESSAGETIME": "Konservitaj malnetoj de la paĝo aŭtomate publikiĝos hodiaŭ je %s", 7 | "Workflow.ProcessError": "Ne povis trakti la laborfluon" 8 | } -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tests/ 5 | 6 | 7 | 8 | 9 | src/ 10 | 11 | tests/ 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /client/lang/src/hr.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.CreateWorkflow": "Kreiraj proces", 3 | "Workflow.DeleteQuestion": "Da li ste sigurni da želite trajno obrisati ovo?", 4 | "Workflow.EMBARGOMESSAGEDATE": "Spremljeni draft ove stranice će biti automatski objavljen %s", 5 | "Workflow.EMBARGOMESSAGEDATETIME": "Spremljeni draft ove stranice će biti automatski objavljen %s u %s", 6 | "Workflow.EMBARGOMESSAGETIME": "Spremljeni draft ove stranice će biti automatski objavljen danas u %s", 7 | "Workflow.ProcessError": "Ne mogu obraditi proces \"workflow\"" 8 | } -------------------------------------------------------------------------------- /client/lang/src/it.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.CreateWorkflow": "Crea flusso di lavoro", 3 | "Workflow.DeleteQuestion": "Si e' sicuri di voler eliminare definitivamente questo? ", 4 | "Workflow.EMBARGOMESSAGEDATE": "Le bozze salvate di questa pagina saranno auto pubblicate il %s", 5 | "Workflow.EMBARGOMESSAGEDATETIME": "Le bozze salvate di questa pagina saranno auto pubblicate il %s alle %s", 6 | "Workflow.EMBARGOMESSAGETIME": "Le bozze salvate di questa pagina saranno auto pubblicate oggi alle %s", 7 | "Workflow.ProcessError": "Impossibile processare il flusso di lavoro" 8 | } -------------------------------------------------------------------------------- /templates/Symbiote/AdvancedWorkflow/DataObjects/WorkflowActionInstance/ReadonlyField.ss: -------------------------------------------------------------------------------- 1 | <%-- Modified from silverstripe/admin/themes/cms-forms/templates/SilverStripe/Forms/ReadonlyField.ss to change p to div --%> 2 |
8 | >$FormattedValue
9 | <% if $IncludeHiddenField %> 10 | 11 | <% end_if %> 12 | -------------------------------------------------------------------------------- /.github/workflows/keepalive.yml: -------------------------------------------------------------------------------- 1 | name: Keepalive 2 | 3 | on: 4 | # At 12:00 AM UTC, on day 1 of the month 5 | schedule: 6 | - cron: '0 0 1 * *' 7 | workflow_dispatch: 8 | 9 | permissions: {} 10 | 11 | jobs: 12 | keepalive: 13 | name: Keepalive 14 | # Only run cron on the silverstripe account 15 | if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule') 16 | runs-on: ubuntu-latest 17 | permissions: 18 | actions: write 19 | steps: 20 | - name: Keepalive 21 | uses: silverstripe/gha-keepalive@v1 22 | -------------------------------------------------------------------------------- /src/Actions/CancelWorkflowAction.php: -------------------------------------------------------------------------------- 1 | getRecord(); 13 | if ($record) { 14 | $record->updateFromTemplate(); 15 | } 16 | return $form->loadDataFrom($form->getRecord())->forAjaxTemplate(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/merge-up.yml: -------------------------------------------------------------------------------- 1 | name: Merge-up 2 | 3 | on: 4 | # At 3:15 AM UTC, only on Friday 5 | schedule: 6 | - cron: '15 3 * * 5' 7 | workflow_dispatch: 8 | 9 | permissions: {} 10 | 11 | jobs: 12 | merge-up: 13 | name: Merge-up 14 | # Only run cron on the silverstripe account 15 | if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule') 16 | runs-on: ubuntu-latest 17 | permissions: 18 | contents: write 19 | actions: write 20 | steps: 21 | - name: Merge-up 22 | uses: silverstripe/gha-merge-up@v2 23 | -------------------------------------------------------------------------------- /client/lang/src/es.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.CreateWorkflow": "Crear flujo de trabajo", 3 | "Workflow.DeleteQuestion": "¿Está seguro de querer borrar esto permanentemente?", 4 | "Workflow.EMBARGOMESSAGEDATE": "Los borradores guardados de esta página se publicarán automáticamente el %s", 5 | "Workflow.EMBARGOMESSAGEDATETIME": "Los borradores guardados de esta página se publicarán automáticamente el %s a las %s", 6 | "Workflow.EMBARGOMESSAGETIME": "Los borradores guardados de esta página se publicarán automáticamente hoy a las %s", 7 | "Workflow.ProcessError": "No se pudo procesar el flujo de trabajo" 8 | } -------------------------------------------------------------------------------- /.github/workflows/add-prs-to-project.yml: -------------------------------------------------------------------------------- 1 | name: Add new PRs to github project 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - ready_for_review 8 | 9 | permissions: {} 10 | 11 | jobs: 12 | addprtoproject: 13 | name: Add PR to GitHub Project 14 | # Only run on the silverstripe account 15 | if: github.repository_owner == 'silverstripe' 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Add PR to github project 19 | uses: silverstripe/gha-add-pr-to-project@v1 20 | with: 21 | app_id: ${{ vars.PROJECT_PERMISSIONS_APP_ID }} 22 | private_key: ${{ secrets.PROJECT_PERMISSIONS_APP_PRIVATE_KEY }} 23 | -------------------------------------------------------------------------------- /client/lang/de.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/de.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('de', { 9 | "Workflow.CreateWorkflow": "Arbeitsablauf erstellen", 10 | "Workflow.DeleteQuestion": "Sind Sie sicher, dass sie dies endgültig löschen wollen?", 11 | "Workflow.ProcessError": "Arbeitsablauf konnte nicht verarbeitet werden" 12 | }); 13 | } -------------------------------------------------------------------------------- /client/lang/src/en.js: -------------------------------------------------------------------------------- 1 | { 2 | "Workflow.CreateWorkflow": "Create workflow", 3 | "Workflow.DeleteQuestion": "Are you sure you want to permanently delete this?", 4 | "Workflow.EMBARGOMESSAGEDATE": "Saved drafts of this page will auto publish on %s", 5 | "Workflow.EMBARGOMESSAGEDATETIME": "Saved drafts of this page will auto publish on %s at %s", 6 | "Workflow.EMBARGOMESSAGETIME": "Saved drafts of this page will auto publish today at %s", 7 | "Workflow.ProcessError": "Could not process workflow", 8 | "Workflow.CreateWorkflow": "Create workflow", 9 | "WorkflowField.AddTransition": "Add transition to {action}", 10 | "WorkflowField.EditSpecificAction": "Edit {action}", 11 | "WorkflowField.EditTransition": "Edit transition {action}" 12 | } 13 | -------------------------------------------------------------------------------- /client/lang/zh.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/zh.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('zh', { 9 | "Workflow.DeleteQuestion": "您确定要永久删除这项吗?", 10 | "Workflow.EMBARGOMESSAGEDATE": "这个页面已保存的草稿会在%s自动发布", 11 | "Workflow.EMBARGOMESSAGEDATETIME": "这个页面已保存的草稿会在%s %s自动发布", 12 | "Workflow.EMBARGOMESSAGETIME": "这个页面已保存的草稿会在今天%s自动发布", 13 | "Workflow.ProcessError": "无法处理工作流程" 14 | }); 15 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const Path = require('path'); 2 | const { JavascriptWebpackConfig, CssWebpackConfig } = require('@silverstripe/webpack-config'); 3 | 4 | const ENV = process.env.NODE_ENV; 5 | const PATHS = { 6 | ROOT: Path.resolve(), 7 | SRC: Path.resolve('client/src'), 8 | DIST: Path.resolve('client/dist'), 9 | }; 10 | 11 | const config = [ 12 | // Main JS bundle 13 | new JavascriptWebpackConfig('js', PATHS, 'symbiote/silverstripe-advancedworkflow') 14 | .setEntry({ 15 | advancedworkflow: `${PATHS.SRC}/bundles/bundle.js`, 16 | }) 17 | .getConfig(), 18 | // sass to css 19 | new CssWebpackConfig('css', PATHS) 20 | .setEntry({ 21 | advancedworkflow: `${PATHS.SRC}/styles/bundle.scss`, 22 | }) 23 | .getConfig(), 24 | ]; 25 | 26 | module.exports = config; 27 | -------------------------------------------------------------------------------- /_config/workflowconfig.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Name: workflowconfig 3 | --- 4 | SilverStripe\Core\Injector\Injector: 5 | Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable: 6 | class: Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable 7 | type: prototype 8 | 9 | SilverStripe\CMS\Model\SiteTree: 10 | extensions: 11 | - Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable 12 | SilverStripe\CMS\Controllers\CMSPageEditController: 13 | extensions: 14 | - Symbiote\AdvancedWorkflow\Extensions\AdvancedWorkflowExtension 15 | SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest: 16 | extensions: 17 | - Symbiote\AdvancedWorkflow\Extensions\AdvancedWorkflowExtension 18 | SilverStripe\Admin\LeftAndMain: 19 | extra_requirements_css: 20 | - symbiote/silverstripe-advancedworkflow:client/dist/styles/advancedworkflow.css 21 | -------------------------------------------------------------------------------- /.github/workflows/tag-patch-release.yml: -------------------------------------------------------------------------------- 1 | name: Tag patch release 2 | 3 | on: 4 | # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch 5 | workflow_dispatch: 6 | inputs: 7 | latest_local_sha: 8 | description: The latest local sha 9 | required: true 10 | type: string 11 | 12 | permissions: {} 13 | 14 | jobs: 15 | tagpatchrelease: 16 | name: Tag patch release 17 | # Only run cron on the silverstripe account 18 | if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule') 19 | runs-on: ubuntu-latest 20 | permissions: 21 | contents: write 22 | steps: 23 | - name: Tag release 24 | uses: silverstripe/gha-tag-release@v2 25 | with: 26 | latest_local_sha: ${{ inputs.latest_local_sha }} 27 | -------------------------------------------------------------------------------- /client/lang/ar.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/ar.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('ar', { 9 | "Workflow.DeleteQuestion": "هل أنت متأكد من كونك تريد حذف هذا بشكل دائم؟", 10 | "Workflow.EMBARGOMESSAGEDATE": "سوف تنشر المسودات المحفوظة لهذه الصفحة تلقائيا على %s", 11 | "Workflow.EMBARGOMESSAGEDATETIME": "سوف تنشر المسودات المحفوظة لهذه الصفحة تلقائيا على %s في %s", 12 | "Workflow.EMBARGOMESSAGETIME": "سوف تنشر المسودات المحفوظة لهذه الصفحة تلقائيا اليوم في %s", 13 | "Workflow.ProcessError": "لا يمكن تسيير العملية حتى النهاية" 14 | }); 15 | } -------------------------------------------------------------------------------- /client/lang/mi.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/mi.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('mi', { 9 | "Workflow.DeleteQuestion": "Me muku pūmau tēnei?", 10 | "Workflow.EMBARGOMESSAGEDATE": "Ka whakaputa aunoatia ngā hukihuki kua tiakina o tēnei whārangi %s i %s", 11 | "Workflow.EMBARGOMESSAGEDATETIME": "Ka whakaputa aunoatia ngā hukihuki kua tiakina o tēnei whārangi %s i %s", 12 | "Workflow.EMBARGOMESSAGETIME": "Ka whakaputa aunoatia anō i tēnei rā ngā hukihuki kua tiakina o tēnei whārangi %s i %s", 13 | "Workflow.ProcessError": "Kāore i taea te tukatuka te reremahi" 14 | }); 15 | } -------------------------------------------------------------------------------- /client/lang/ru.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/ru.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('ru', { 9 | "Workflow.DeleteQuestion": "Действительно удалить? Эта операция необратима.", 10 | "Workflow.EMBARGOMESSAGEDATE": "Сохраненные черновики будут автоматически опубликованы %s", 11 | "Workflow.EMBARGOMESSAGEDATETIME": "Сохраненные черновики этой страницы будут автоматически опубликованы %s в %s", 12 | "Workflow.EMBARGOMESSAGETIME": "Сохраненные черновики на этой странице будут автоматически опубликованы сегодня в %s", 13 | "Workflow.ProcessError": "Не удалось обработать поток задач" 14 | }); 15 | } -------------------------------------------------------------------------------- /src/DataObjects/ImportedWorkflowTemplate.php: -------------------------------------------------------------------------------- 1 | "Varchar(255)", 25 | "Filename" => "Varchar(255)", 26 | "Content" => "Text" 27 | ); 28 | 29 | /** 30 | * 31 | * @var array 32 | */ 33 | private static $has_one = array( 34 | 'Definition' => WorkflowDefinition::class 35 | ); 36 | 37 | private static $table_name = 'ImportedWorkflowTemplate'; 38 | } 39 | -------------------------------------------------------------------------------- /client/lang/eo.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/eo.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('eo', { 9 | "Workflow.CreateWorkflow": "Krei laborfluon", 10 | "Workflow.DeleteQuestion": "Ĉi vi vere volas porĉiame forigi ĉi tiun dosieron?", 11 | "Workflow.EMBARGOMESSAGEDATE": "Konservitaj malnetoj de la paĝo aŭtomate publikiĝos je %s", 12 | "Workflow.EMBARGOMESSAGEDATETIME": "Konservitaj malnetoj de la paĝo aŭtomate publikiĝos ĉe %s je %s", 13 | "Workflow.EMBARGOMESSAGETIME": "Konservitaj malnetoj de la paĝo aŭtomate publikiĝos hodiaŭ je %s", 14 | "Workflow.ProcessError": "Ne povis trakti la laborfluon" 15 | }); 16 | } -------------------------------------------------------------------------------- /client/lang/hr.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/hr.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('hr', { 9 | "Workflow.CreateWorkflow": "Kreiraj proces", 10 | "Workflow.DeleteQuestion": "Da li ste sigurni da želite trajno obrisati ovo?", 11 | "Workflow.EMBARGOMESSAGEDATE": "Spremljeni draft ove stranice će biti automatski objavljen %s", 12 | "Workflow.EMBARGOMESSAGEDATETIME": "Spremljeni draft ove stranice će biti automatski objavljen %s u %s", 13 | "Workflow.EMBARGOMESSAGETIME": "Spremljeni draft ove stranice će biti automatski objavljen danas u %s", 14 | "Workflow.ProcessError": "Ne mogu obraditi proces \"workflow\"" 15 | }); 16 | } -------------------------------------------------------------------------------- /client/lang/it.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/it.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('it', { 9 | "Workflow.CreateWorkflow": "Crea flusso di lavoro", 10 | "Workflow.DeleteQuestion": "Si e' sicuri di voler eliminare definitivamente questo? ", 11 | "Workflow.EMBARGOMESSAGEDATE": "Le bozze salvate di questa pagina saranno auto pubblicate il %s", 12 | "Workflow.EMBARGOMESSAGEDATETIME": "Le bozze salvate di questa pagina saranno auto pubblicate il %s alle %s", 13 | "Workflow.EMBARGOMESSAGETIME": "Le bozze salvate di questa pagina saranno auto pubblicate oggi alle %s", 14 | "Workflow.ProcessError": "Impossibile processare il flusso di lavoro" 15 | }); 16 | } -------------------------------------------------------------------------------- /client/lang/es.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/es.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('es', { 9 | "Workflow.CreateWorkflow": "Crear flujo de trabajo", 10 | "Workflow.DeleteQuestion": "¿Está seguro de querer borrar esto permanentemente?", 11 | "Workflow.EMBARGOMESSAGEDATE": "Los borradores guardados de esta página se publicarán automáticamente el %s", 12 | "Workflow.EMBARGOMESSAGEDATETIME": "Los borradores guardados de esta página se publicarán automáticamente el %s a las %s", 13 | "Workflow.EMBARGOMESSAGETIME": "Los borradores guardados de esta página se publicarán automáticamente hoy a las %s", 14 | "Workflow.ProcessError": "No se pudo procesar el flujo de trabajo" 15 | }); 16 | } -------------------------------------------------------------------------------- /templates/Includes/AssignedWorkflowList.ss: -------------------------------------------------------------------------------- 1 | 2 | <% if UserWorkflows %> 3 | 4 | <% require javascript(symbiote/silverstripe-advancedworkflow:client/dist/js/advancedworkflow.js) %> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <% loop UserWorkflows %> 17 | 18 | 19 | 20 | 21 | 30 | 31 | <% end_loop %> 32 | 33 | 34 |
<%t WorkflowList.TableHeaderItem "Item" %><%t WorkflowList.TableHeaderEditedBy "Edited by" %><%t WorkflowList.TableHeaderSubmitted "Submitted" %><%t WorkflowList.TableHeaderActions "Actions" %>
$Target.Title.XML$Initiator.getTitle$Created.Nice 22 | <% if validTransitions %> 23 |
    24 | <% loop validTransitions %> 25 |
  • $Title.XML
  • 26 | <% end_loop %> 27 |
28 | <% end_if %> 29 |
35 | <% end_if %> 36 | -------------------------------------------------------------------------------- /.github/workflows/update-js.yml: -------------------------------------------------------------------------------- 1 | name: Update JS 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | branch_type: 7 | description: 'The branch type to run action on' 8 | required: true 9 | default: 'schedule' 10 | type: choice 11 | options: 12 | - 'schedule' 13 | - 'prev-major-curr-minor' 14 | - 'curr-major-curr-minor' 15 | - 'curr-major-next-minor' 16 | # At 7:35 AM UTC, on day 1 of the month, only in February and August 17 | schedule: 18 | - cron: '35 7 1 2,8 *' 19 | 20 | permissions: {} 21 | 22 | jobs: 23 | update-js: 24 | name: Update JS 25 | # Only run cron on the silverstripe account 26 | if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule') 27 | runs-on: ubuntu-latest 28 | permissions: 29 | contents: write 30 | pull-requests: write 31 | actions: write 32 | steps: 33 | - name: Update JS 34 | uses: silverstripe/gha-update-js@v1 35 | with: 36 | branch_type: ${{ github.event_name == 'schedule' && 'schedule' || github.event.inputs.branch_type }} 37 | -------------------------------------------------------------------------------- /client/lang/en.js: -------------------------------------------------------------------------------- 1 | // This file was generated by silverstripe/tx-translator from client/lang/src/en.js. 2 | // See https://github.com/silverstripe/silverstripe-tx-translator for details 3 | if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') { 4 | if (typeof(console) !== 'undefined') { // eslint-disable-line no-console 5 | console.error('Class ss.i18n not defined'); // eslint-disable-line no-console 6 | } 7 | } else { 8 | ss.i18n.addDictionary('en', { 9 | "Workflow.CreateWorkflow": "Create workflow", 10 | "Workflow.DeleteQuestion": "Are you sure you want to permanently delete this?", 11 | "Workflow.EMBARGOMESSAGEDATE": "Saved drafts of this page will auto publish on %s", 12 | "Workflow.EMBARGOMESSAGEDATETIME": "Saved drafts of this page will auto publish on %s at %s", 13 | "Workflow.EMBARGOMESSAGETIME": "Saved drafts of this page will auto publish today at %s", 14 | "Workflow.ProcessError": "Could not process workflow", 15 | "WorkflowField.AddTransition": "Add transition to {action}", 16 | "WorkflowField.EditSpecificAction": "Edit {action}", 17 | "WorkflowField.EditTransition": "Edit transition {action}" 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /client/src/bundles/advanced-workflow-cms.js: -------------------------------------------------------------------------------- 1 | import jQuery from 'jquery'; 2 | 3 | jQuery.entwine('ss', ($) => { 4 | $('.cms-edit-form') 5 | .find('.Actions, .btn-toolbar') 6 | .find('#ActionMenus_WorkflowOptions .action') 7 | .entwine({ 8 | onclick(e) { 9 | const transitionId = this.attr('data-transitionid'); 10 | let buttonName = this.attr('name'); 11 | 12 | buttonName = buttonName.replace(/-\d+/, ''); 13 | this.attr('name', buttonName); 14 | 15 | $('input[name=TransitionID]').val(transitionId); 16 | 17 | this._super(e); 18 | }, 19 | }); 20 | 21 | $('.cms-edit-form') 22 | .find('.Actions, .btn-toolbar') 23 | .find('.action.start-workflow') 24 | .entwine({ 25 | onmouseup(e) { 26 | // Populate the hidden form field with the selected workflow definition. 27 | $('input[name=TriggeredWorkflowID]').val(this.data('workflow')); 28 | 29 | // Update the element name to exclude the ID, therefore submitting correctly. 30 | const name = this.attr('name'); 31 | this.attr('name', name.replace(/-\d+/, '')); 32 | this._super(e); 33 | }, 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /src/Actions/SimpleApprovalWorkflowAction.php: -------------------------------------------------------------------------------- 1 | 2 | <%t WorkflowReminderEmail.Content "This is an automated reminder that the workflow '{title}' you are currently 3 | assigned to has not been actioned for {days} days. The 4 | workflow was last updated on {date} at {time}." title=$Instance.Title days=$Instance.Definition.RemindDays date=$Instance.LastEdited.Date time=$Instance.LastEdited.Time %> 5 |

6 | 7 | <% if $Diff %> 8 |
9 | <%t WorkflowReminderEmail.Differences "These are the changes made" %> 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | <% loop $Diff %> 19 | 20 | 21 | 22 | 23 | <% end_loop %> 24 | 25 |
<%t WorkflowReminderEmail.HeadingTitle "Title" %><%t WorkflowReminderEmail.HeadingDiff "Differences" %>
$Title$Diff
26 |
27 | <% end_if %> 28 | 29 | <% if Link %> 30 |

31 | <%t WorkflowReminderEmail.Action "Click here to action this workflow" %>. 32 |

33 | <% end_if %> 34 | -------------------------------------------------------------------------------- /.github/workflows/dispatch-ci.yml: -------------------------------------------------------------------------------- 1 | name: Dispatch CI 2 | 3 | on: 4 | # At 3:15 AM UTC, only on Sunday, Monday, and Tuesday 5 | schedule: 6 | - cron: '15 3 * * 0,1,2' 7 | workflow_dispatch: 8 | inputs: 9 | major_type: 10 | description: 'Major branch type' 11 | required: true 12 | type: choice 13 | options: 14 | - 'dynamic' 15 | - 'current' 16 | - 'next' 17 | - 'previous' 18 | default: 'dynamic' 19 | minor_type: 20 | description: 'Minor branch type' 21 | required: true 22 | type: choice 23 | options: 24 | - 'dynamic' 25 | - 'next-minor' 26 | - 'next-patch' 27 | default: 'dynamic' 28 | 29 | permissions: {} 30 | 31 | jobs: 32 | dispatch-ci: 33 | name: Dispatch CI 34 | # Only run cron on the silverstripe account 35 | if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule') 36 | runs-on: ubuntu-latest 37 | permissions: 38 | contents: read 39 | actions: write 40 | steps: 41 | - name: Dispatch CI 42 | uses: silverstripe/gha-dispatch-ci@v1 43 | with: 44 | major_type: ${{ inputs.major_type }} 45 | minor_type: ${{ inputs.minor_type }} 46 | -------------------------------------------------------------------------------- /client/src/styles/AdvancedWorkflowAdmin.scss: -------------------------------------------------------------------------------- 1 | .field.date, 2 | .field.datetime { 3 | .message { 4 | &.required { 5 | position: relative; 6 | top: 10px; 7 | } 8 | } 9 | } 10 | 11 | // Embargo & expiry badge styling 12 | // 3 different statuses - embargo, expiry, embargo & expiry (both assigned) 13 | // Note: CSS nesting convention based on SilverStripe admin styling 14 | .badge.status-embargo, 15 | .badge.status-expiry, 16 | .badge.status-embargo_expiry {// sass-lint:disable-line class-name-format 17 | background-color: $grey-light; 18 | border-color: $brand-success; 19 | color: $brand-success; 20 | 21 | #cms-content-tools-CMSMain & {// sass-lint:disable-line no-ids 22 | -webkit-box-shadow: 0 0 6px 2px $grey-light; 23 | box-shadow: 0 0 6px 2px $grey-light; 24 | } 25 | } 26 | 27 | .badge.status-workflow-approval { 28 | background-color: #E8FAFF; 29 | border-color: #0070B4; 30 | color: #0070B4; 31 | } 32 | 33 | .workflow-field-diff { 34 | del { 35 | background-color: $pale-red; 36 | color: $brand-danger; 37 | padding: 2px; 38 | 39 | p { 40 | background-color: inherit; 41 | } 42 | } 43 | 44 | ins { 45 | background-color: $pale-green; 46 | padding: 2px; 47 | text-decoration: none; 48 | 49 | p { 50 | background-color: inherit; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symbiote-advancedworkflow", 3 | "description": "Adds configurable workflow support to the CMS, with a GUI for creating custom workflow definitions.", 4 | "scripts": { 5 | "build": "yarn && yarn lint && rm -rf client/dist/* && NODE_ENV=production webpack --mode production --bail --progress", 6 | "dev": "NODE_ENV=development webpack --progress", 7 | "watch": "yarn && NODE_ENV=development webpack --watch --progress", 8 | "css": "WEBPACK_CHILD=css npm run build", 9 | "lint": "eslint client/src; stylelint client/src" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/symbiote/silverstripe-advancedworkflow.git" 14 | }, 15 | "keywords": [ 16 | "silverstripe", 17 | "cms", 18 | "workflow" 19 | ], 20 | "author": "SilverStripe Ltd", 21 | "license": "BSD-3-Clause", 22 | "bugs": { 23 | "url": "https://github.com/symbiote/silverstripe-advancedworkflow/issues" 24 | }, 25 | "homepage": "https://github.com/symbiote/silverstripe-advancedworkflow#readme", 26 | "dependencies": {}, 27 | "devDependencies": { 28 | "@silverstripe/eslint-config": "^1.3.0", 29 | "@silverstripe/webpack-config": "^3", 30 | "webpack": "^5.74.0", 31 | "webpack-cli": "^5.0.0" 32 | }, 33 | "resolutions": { 34 | "colors": "1.4.0" 35 | }, 36 | "browserslist": [ 37 | "defaults" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advanced Workflow Module 2 | 3 | [![CI](https://github.com/symbiote/silverstripe-advancedworkflow/actions/workflows/ci.yml/badge.svg)](https://github.com/symbiote/silverstripe-advancedworkflow/actions/workflows/ci.yml) 4 | [![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/) 5 | 6 | ## Overview 7 | 8 | A module that provides an action / transition approach to workflow, where a 9 | single workflow process is split into multiple configurable states (Actions) 10 | with multiple possible transitions between the actions. 11 | 12 | ## Installation 13 | 14 | ```sh 15 | composer require symbiote/silverstripe-advancedworkflow 16 | ``` 17 | 18 | ## Documentation 19 | - [User guide](docs/en/userguide/index.md) 20 | - [Developer documentation](docs/en/index.md) 21 | 22 | ## Contributing 23 | 24 | ### Translations 25 | 26 | Translations of the natural language strings are managed through a third party translation interface, transifex.com. Newly added strings will be periodically uploaded there for translation, and any new translations will be merged back to the project source code. 27 | 28 | Please use [https://www.transifex.com/projects/p/silverstripe-advancedworkflow](https://www.transifex.com/projects/p/silverstripe-advancedworkflow) to contribute translations, rather than sending pull requests with YAML files. 29 | -------------------------------------------------------------------------------- /client/src/bundles/advancedworkflow-management.js: -------------------------------------------------------------------------------- 1 | import jQuery from 'jquery'; 2 | import i18n from 'i18n'; 3 | 4 | jQuery.entwine('ss', ($) => { 5 | $('.advancedWorkflowTransition').entwine({ 6 | onclick(e) { 7 | e.preventDefault(); 8 | 9 | // get the stuff for it and show a dialog 10 | // eslint-disable-next-line no-alert 11 | const comments = prompt('Comments'); 12 | const instanceId = this.parents('ul').attr('data-instance-id'); 13 | const transitionId = this.attr('data-transition-id'); 14 | const securityId = $('[name=SecurityID]').val(); 15 | if (!securityId) { 16 | // eslint-disable-next-line no-alert 17 | alert('Invalid SecurityID field!'); 18 | return false; 19 | } 20 | 21 | $.post( 22 | 'AdvancedWorkflowActionController/transition', 23 | { 24 | SecurityID: securityId, 25 | comments, 26 | transition: transitionId, 27 | id: instanceId, 28 | }, 29 | (data) => { 30 | if (data) { 31 | const parsedData = $.parseJSON(data); 32 | 33 | if (parsedData.success) { 34 | location.href = parsedData.link; 35 | } else { 36 | // eslint-disable-next-line no-alert 37 | alert(i18n._t('Workflow.ProcessError')); 38 | } 39 | } 40 | } 41 | ); 42 | 43 | return false; 44 | }, 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /lang/tr.yml: -------------------------------------------------------------------------------- 1 | tr: 2 | AdvancedWorkflowAdmin: 3 | Title: Başlık 4 | AllowEditing: 5 | NoString: Hayır 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Gruplar 8 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 9 | many_many_Groups: Gruplar 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: İçerik 12 | db_Filename: 'Dosya adı' 13 | db_Name: Ad 14 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 15 | db_Title: Başlık 16 | has_one_Member: Üye 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 18 | has_one_Member: Üye 19 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 20 | db_Description: Açıklama 21 | db_Title: Başlık 22 | many_many_Groups: Gruplar 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 24 | db_Title: Başlık 25 | many_many_Groups: Gruplar 26 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 27 | db_Title: Başlık 28 | many_many_Groups: Gruplar 29 | WorkflowAction: 30 | Author: Yazar 31 | TITLE: Başlık 32 | WorkflowActionInstance: 33 | Title: Başlık 34 | WorkflowDefinition: 35 | DESCRIPTION: Açıklama 36 | TITLE: Başlık 37 | WorkflowField: 38 | CreateLabel: Oluştur 39 | DeleteAction: Sil 40 | WorkflowInstance: 41 | TitleLabel: Başlık 42 | WorkflowReminderEmail: 43 | HeadingTitle: Başlık 44 | WorkflowReminderTask: 45 | SAVE: Kaydet 46 | -------------------------------------------------------------------------------- /lang/da.yml: -------------------------------------------------------------------------------- 1 | da: 2 | AdvancedWorkflowAdmin: 3 | Title: Titel 4 | AllowEditing: 5 | NoString: Nej 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Grupper 8 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 9 | many_many_Groups: Grupper 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: Indhold 12 | db_Filename: Filnavn 13 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 14 | db_Title: Titel 15 | has_one_Member: Bruger 16 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 17 | has_one_Member: Bruger 18 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 19 | db_Description: Beskrivelse 20 | db_Title: Titel 21 | many_many_Groups: Grupper 22 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 23 | db_Title: Titel 24 | many_many_Groups: Grupper 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 26 | db_Title: Titel 27 | many_many_Groups: Grupper 28 | WorkflowAction: 29 | Author: Forfatter 30 | TITLE: Titel 31 | WorkflowActionInstance: 32 | Title: Titel 33 | WorkflowDefinition: 34 | DESCRIPTION: Beskrivelse 35 | TITLE: Titel 36 | WorkflowField: 37 | CreateLabel: Opret 38 | DeleteAction: Slet 39 | EditAction: Rediger 40 | WorkflowInstance: 41 | TitleLabel: Titel 42 | WorkflowReminderEmail: 43 | HeadingTitle: Titel 44 | WorkflowReminderTask: 45 | SAVE: Gem 46 | -------------------------------------------------------------------------------- /lang/ja_JP.yml: -------------------------------------------------------------------------------- 1 | ja_JP: 2 | AdvancedWorkflowAdmin: 3 | Title: タイトル 4 | AssignUsersToWorkflowAction: 5 | GROUPS: グループ 6 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 7 | many_many_Groups: グループ 8 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 9 | db_Content: 内容 10 | db_Filename: ファイル名 11 | db_Name: 名前 12 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 13 | db_Title: タイトル 14 | has_one_Member: メンバー 15 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 16 | has_one_Member: メンバー 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 18 | db_Description: 説明文 19 | db_Title: タイトル 20 | has_many_Actions: アクション 21 | many_many_Groups: グループ 22 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 23 | db_Title: タイトル 24 | has_many_Actions: アクション 25 | many_many_Groups: グループ 26 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 27 | db_Title: タイトル 28 | many_many_Groups: グループ 29 | WorkflowAction: 30 | Author: 作成者 31 | TITLE: タイトル 32 | WorkflowActionInstance: 33 | Title: タイトル 34 | WorkflowDefinition: 35 | DESCRIPTION: 説明文 36 | TITLE: タイトル 37 | WorkflowField: 38 | CreateLabel: 作成 39 | DeleteAction: 削除 40 | WorkflowInstance: 41 | TitleLabel: タイトル 42 | WorkflowList: 43 | TableHeaderActions: アクション 44 | WorkflowReminderEmail: 45 | HeadingTitle: タイトル 46 | WorkflowReminderTask: 47 | SAVE: 保存 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, Symbiote 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | -------------------------------------------------------------------------------- /lang/hu.yml: -------------------------------------------------------------------------------- 1 | hu: 2 | AdvancedWorkflowAdmin: 3 | Title: Cím 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Csoportok 6 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 7 | many_many_Groups: Csoportok 8 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 9 | db_Content: Tartalom 10 | db_Filename: Fájlnév 11 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 12 | db_Comment: Hozzászólás 13 | db_Title: Cím 14 | has_one_Member: Tag 15 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 16 | db_Comment: Hozzászólás 17 | has_one_Member: Tag 18 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 19 | db_Title: Cím 20 | many_many_Groups: Csoportok 21 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 22 | db_Title: Cím 23 | many_many_Groups: Csoportok 24 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 25 | db_Title: Cím 26 | many_many_Groups: Csoportok 27 | WorkflowAction: 28 | Author: Szerző 29 | COMMENT: Hozzászólás 30 | CommentLabel: Hozzászólás 31 | FRONTENDCOMMENT: Hozzászólás 32 | TITLE: Cím 33 | WorkflowActionInstance: 34 | Title: Cím 35 | WorkflowDefinition: 36 | TITLE: Cím 37 | WorkflowField: 38 | CreateLabel: Létrehozni 39 | DeleteAction: Törlés 40 | EditAction: Szerkeszt 41 | WorkflowInstance: 42 | TitleLabel: Cím 43 | WorkflowReminderEmail: 44 | HeadingTitle: Cím 45 | WorkflowReminderTask: 46 | SAVE: Mentés 47 | -------------------------------------------------------------------------------- /lang/ro.yml: -------------------------------------------------------------------------------- 1 | ro: 2 | AdvancedWorkflowAdmin: 3 | Title: Titlu 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Grupuri 6 | NotifyUsersWorkflowAction: 7 | FORMATTINGHELP: 'Ajutor formatare' 8 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 9 | many_many_Groups: Grupuri 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: Continut 12 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 13 | db_Comment: Comentariu 14 | db_Title: Titlu 15 | has_one_Member: Membru 16 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 17 | db_Comment: Comentariu 18 | has_one_Member: Membru 19 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 20 | db_Title: Titlu 21 | many_many_Groups: Grupuri 22 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 23 | db_Title: Titlu 24 | many_many_Groups: Grupuri 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 26 | db_Title: Titlu 27 | many_many_Groups: Grupuri 28 | WorkflowAction: 29 | Author: Autor 30 | COMMENT: Comentariu 31 | CommentLabel: Comentariu 32 | FRONTENDCOMMENT: Comentariu 33 | TITLE: Titlu 34 | WorkflowActionInstance: 35 | Title: Titlu 36 | WorkflowDefinition: 37 | TITLE: Titlu 38 | WorkflowField: 39 | CreateLabel: Creaţi 40 | DeleteAction: Ştergere 41 | EditAction: Editare 42 | WorkflowInstance: 43 | TitleLabel: Titlu 44 | WorkflowReminderEmail: 45 | HeadingTitle: Titlu 46 | WorkflowReminderTask: 47 | SAVE: Salvează 48 | -------------------------------------------------------------------------------- /src/Actions/SetPropertyWorkflowAction.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class SetPropertyWorkflowAction extends WorkflowAction 13 | { 14 | private static $db = array( 15 | 'Property' => 'Varchar', 16 | 'Value' => 'Text', 17 | ); 18 | 19 | private static $table_name = 'SetPropertyWorkflowAction'; 20 | 21 | public function execute(WorkflowInstance $workflow) 22 | { 23 | if (!$target = $workflow->getTarget()) { 24 | return true; 25 | } 26 | 27 | if ($target->hasField($this->Property)) { 28 | $target->setField($this->Property, $this->Value); 29 | } 30 | 31 | $target->write(); 32 | 33 | return true; 34 | } 35 | 36 | public function getCMSFields() 37 | { 38 | $fields = parent::getCMSFields(); 39 | 40 | $fields->addFieldsToTab('Root.Main', array( 41 | TextField::create('Property', _t('SetPropertyWorkflowAction.PROPERTY', 'Property')) 42 | ->setRightTitle(_t( 43 | 'SetPropertyWorkflowAction.PROPERTYTITLE', 44 | 'Property to set; if this exists as a setter method, will be called passing the value' 45 | )), 46 | TextField::create('Value', 'Value') 47 | )); 48 | 49 | return $fields; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lang/gl_ES.yml: -------------------------------------------------------------------------------- 1 | gl_ES: 2 | AdvancedWorkflowAdmin: 3 | Title: Título 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Grupos 6 | USERS: Usuarios 7 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 8 | many_many_Groups: Grupos 9 | many_many_Users: Usuarios 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: Contido 12 | db_Filename: 'Nome ficheiro' 13 | db_Name: Nome 14 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 15 | db_Title: Título 16 | has_one_Member: Membro 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 18 | has_one_Member: Membro 19 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 20 | db_Title: Título 21 | has_many_Actions: Accións 22 | many_many_Groups: Grupos 23 | many_many_Users: Usuarios 24 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 25 | db_Title: Título 26 | has_many_Actions: Accións 27 | many_many_Groups: Grupos 28 | many_many_Users: Usuarios 29 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 30 | db_Title: Título 31 | many_many_Groups: Grupos 32 | many_many_Users: Usuarios 33 | WorkflowAction: 34 | TITLE: Título 35 | WorkflowActionInstance: 36 | Title: Título 37 | WorkflowDefinition: 38 | TITLE: Título 39 | WorkflowField: 40 | CreateLabel: Crear 41 | DeleteAction: Eliminar 42 | WorkflowInstance: 43 | TitleLabel: Título 44 | WorkflowList: 45 | TableHeaderActions: Accións 46 | WorkflowReminderEmail: 47 | HeadingTitle: Título 48 | WorkflowReminderTask: 49 | SAVE: Gardar 50 | -------------------------------------------------------------------------------- /lang/pl_PL.yml: -------------------------------------------------------------------------------- 1 | pl_PL: 2 | AdvancedWorkflowAdmin: 3 | Title: Tytuł 4 | AllowEditing: 5 | NoString: Nie 6 | NotifyUsersWorkflowAction: 7 | EMAILSUBJECT: 'Email Subject' 8 | EMAILTEMPLATE: 'Szablon e-mail' 9 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 10 | db_EmailSubject: 'Email Subject' 11 | db_EmailTemplate: 'Szablon e-mail' 12 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 13 | db_Value: Wartość 14 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 15 | db_Content: Zawartość 16 | db_Name: Nazwa 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 18 | db_Comment: Komentarz 19 | db_Title: Tytuł 20 | db_Type: Typ 21 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 22 | db_Comment: Komentarz 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 24 | db_Template: Szablon 25 | db_Title: Tytuł 26 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 27 | db_Title: Tytuł 28 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 29 | db_Title: Tytuł 30 | db_Type: Typ 31 | WorkflowAction: 32 | Author: Autor 33 | COMMENT: Komentarz 34 | CommentLabel: Komentarz 35 | FRONTENDCOMMENT: Komentarz 36 | TITLE: Tytuł 37 | TypeLabel: Typ 38 | WorkflowActionInstance: 39 | Title: Tytuł 40 | WorkflowDefinition: 41 | TITLE: Tytuł 42 | WorkflowField: 43 | CreateLabel: Utwórz 44 | DeleteAction: Usuń 45 | EditAction: Edytuj 46 | WorkflowInstance: 47 | TitleLabel: Tytuł 48 | WorkflowReminderEmail: 49 | HeadingTitle: Tytuł 50 | WorkflowReminderTask: 51 | SAVE: Zapisz 52 | WorkflowTransition: 53 | TYPE: Typ 54 | -------------------------------------------------------------------------------- /lang/sr.yml: -------------------------------------------------------------------------------- 1 | sr: 2 | AdvancedWorkflowAdmin: 3 | Title: Наслов 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Групе 6 | USERS: Корисници 7 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 8 | many_many_Groups: Групе 9 | many_many_Users: Корисници 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: Садржај 12 | db_Filename: 'Име датотеке' 13 | db_Name: Име 14 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 15 | db_Title: Наслов 16 | has_one_Member: Члан 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 18 | has_one_Member: Члан 19 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 20 | db_Description: Опис 21 | db_Title: Наслов 22 | has_many_Actions: Акције 23 | many_many_Groups: Групе 24 | many_many_Users: Корисници 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 26 | db_Title: Наслов 27 | has_many_Actions: Акције 28 | many_many_Groups: Групе 29 | many_many_Users: Корисници 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 31 | db_Title: Наслов 32 | many_many_Groups: Групе 33 | many_many_Users: Корисници 34 | WorkflowAction: 35 | Author: Аутор 36 | TITLE: Наслов 37 | WorkflowActionInstance: 38 | Title: Наслов 39 | WorkflowDefinition: 40 | DESCRIPTION: Опис 41 | TITLE: Наслов 42 | WorkflowField: 43 | CreateLabel: Креирај 44 | DeleteAction: Избриши 45 | EditAction: Измени 46 | WorkflowInstance: 47 | TitleLabel: Наслов 48 | WorkflowList: 49 | TableHeaderActions: Акције 50 | WorkflowReminderEmail: 51 | HeadingTitle: Наслов 52 | WorkflowReminderTask: 53 | SAVE: Сачувај 54 | -------------------------------------------------------------------------------- /lang/pt.yml: -------------------------------------------------------------------------------- 1 | pt: 2 | AdvancedWorkflowAdmin: 3 | Title: Título 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Grupos 6 | USERS: Utilizadores 7 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 8 | many_many_Groups: Grupos 9 | many_many_Users: Utilizadores 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: Conteúdo 12 | db_Filename: 'Nome do ficheiro' 13 | db_Name: Nome 14 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 15 | db_Title: Título 16 | has_one_Member: Membro 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 18 | has_one_Member: Membro 19 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 20 | db_Description: Descrição 21 | db_Title: Título 22 | has_many_Actions: Ações 23 | many_many_Groups: Grupos 24 | many_many_Users: Utilizadores 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 26 | db_Title: Título 27 | has_many_Actions: Ações 28 | many_many_Groups: Grupos 29 | many_many_Users: Utilizadores 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 31 | db_Title: Título 32 | many_many_Groups: Grupos 33 | many_many_Users: Utilizadores 34 | WorkflowAction: 35 | Author: Autor 36 | TITLE: Título 37 | WorkflowActionInstance: 38 | Title: Título 39 | WorkflowDefinition: 40 | DESCRIPTION: Descrição 41 | TITLE: Título 42 | WorkflowField: 43 | CreateLabel: Criar 44 | DeleteAction: Apagar 45 | WorkflowInstance: 46 | TitleLabel: Título 47 | WorkflowList: 48 | TableHeaderActions: Ações 49 | WorkflowReminderEmail: 50 | HeadingTitle: Título 51 | WorkflowReminderTask: 52 | SAVE: Guardar 53 | -------------------------------------------------------------------------------- /lang/sr_RS@latin.yml: -------------------------------------------------------------------------------- 1 | sr_RS@latin: 2 | AdvancedWorkflowAdmin: 3 | Title: Naslov 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Grupe 6 | USERS: Korisnici 7 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 8 | many_many_Groups: Grupe 9 | many_many_Users: Korisnici 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: Sadržaj 12 | db_Filename: 'Ime datoteke' 13 | db_Name: Ime 14 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 15 | db_Title: Naslov 16 | has_one_Member: Član 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 18 | has_one_Member: Član 19 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 20 | db_Description: Opis 21 | db_Title: Naslov 22 | has_many_Actions: Akcije 23 | many_many_Groups: Grupe 24 | many_many_Users: Korisnici 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 26 | db_Title: Naslov 27 | has_many_Actions: Akcije 28 | many_many_Groups: Grupe 29 | many_many_Users: Korisnici 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 31 | db_Title: Naslov 32 | many_many_Groups: Grupe 33 | many_many_Users: Korisnici 34 | WorkflowAction: 35 | Author: Autor 36 | TITLE: Naslov 37 | WorkflowActionInstance: 38 | Title: Naslov 39 | WorkflowDefinition: 40 | DESCRIPTION: Opis 41 | TITLE: Naslov 42 | WorkflowField: 43 | CreateLabel: Kreiraj 44 | DeleteAction: Izbriši 45 | EditAction: Izmeni 46 | WorkflowInstance: 47 | TitleLabel: Naslov 48 | WorkflowList: 49 | TableHeaderActions: Akcije 50 | WorkflowReminderEmail: 51 | HeadingTitle: Naslov 52 | WorkflowReminderTask: 53 | SAVE: Sačuvaj 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2_feature_request.yml: -------------------------------------------------------------------------------- 1 | name: 🚀 Feature Request 2 | description: Submit a feature request (but only if you're planning on implementing it) 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | Please only submit feature requests if you plan on implementing the feature yourself. 8 | See the [contributing code documentation](https://docs.silverstripe.org/en/contributing/code/#make-or-find-a-github-issue) for more guidelines about submitting feature requests. 9 | - type: textarea 10 | id: description 11 | attributes: 12 | label: Description 13 | description: A clear and concise description of the new feature, and why it belongs in core 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: more-info 18 | attributes: 19 | label: Additional context or points of discussion 20 | description: | 21 | *Optional: Any additional context, points of discussion, etc that might help validate and refine your idea* 22 | - type: checkboxes 23 | id: validations 24 | attributes: 25 | label: Validations 26 | description: "Before submitting the issue, please confirm the following:" 27 | options: 28 | - label: You intend to implement the feature yourself 29 | required: true 30 | - label: You have read the [contributing guide](https://docs.silverstripe.org/en/contributing/code/) 31 | required: true 32 | - label: You strongly believe this feature should be in core, rather than being its own community module 33 | required: true 34 | - label: You have checked for existing issues or pull requests related to this feature (and didn't find any) 35 | required: true 36 | -------------------------------------------------------------------------------- /lang/de_DE.yml: -------------------------------------------------------------------------------- 1 | de_DE: 2 | AdvancedWorkflowAdmin: 3 | Title: Titel 4 | AllowEditing: 5 | NoString: Nein 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Grouppen 8 | NotifyUsersWorkflowAction: 9 | EMAILSUBJECT: Betreff 10 | EMAILTEMPLATE: E-Mail-Template 11 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 12 | many_many_Groups: Grouppen 13 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 14 | db_EmailSubject: Betreff 15 | db_EmailTemplate: E-Mail-Template 16 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 17 | db_Value: Wert 18 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 19 | db_Title: Titel 20 | db_Type: Typ 21 | has_one_Member: Mitglied 22 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 23 | has_one_Member: Mitglied 24 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 25 | db_Description: Beschreibung 26 | db_Title: Titel 27 | many_many_Groups: Grouppen 28 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 29 | db_Title: Titel 30 | many_many_Groups: Grouppen 31 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 32 | db_Title: Titel 33 | db_Type: Typ 34 | many_many_Groups: Grouppen 35 | WorkflowAction: 36 | TITLE: Titel 37 | TypeLabel: Typ 38 | WorkflowActionInstance: 39 | Title: Titel 40 | WorkflowDefinition: 41 | DESCRIPTION: Beschreibung 42 | TITLE: Titel 43 | WorkflowField: 44 | DeleteAction: Löschen 45 | EditAction: Bearbeiten 46 | WorkflowInstance: 47 | TitleLabel: Titel 48 | WorkflowReminderEmail: 49 | HeadingTitle: Titel 50 | WorkflowReminderTask: 51 | SAVE: Speichern 52 | WorkflowTransition: 53 | TYPE: Typ 54 | -------------------------------------------------------------------------------- /lang/th.yml: -------------------------------------------------------------------------------- 1 | th: 2 | AdvancedWorkflowAdmin: 3 | Title: หัวเรื่อง 4 | AssignUsersToWorkflowAction: 5 | GROUPS: กลุ่ม 6 | USERS: ผู้ใช้งาน 7 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 8 | many_many_Groups: กลุ่ม 9 | many_many_Users: ผู้ใช้งาน 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: เนื้อหา 12 | db_Filename: ชื่อไฟล์ 13 | db_Name: ชื่อ 14 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 15 | db_Title: หัวเรื่อง 16 | has_one_Member: สมาชิก 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 18 | has_one_Member: สมาชิก 19 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 20 | db_Description: คำอธิบาย 21 | db_Title: หัวเรื่อง 22 | has_many_Actions: การกระทำ 23 | many_many_Groups: กลุ่ม 24 | many_many_Users: ผู้ใช้งาน 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 26 | db_Title: หัวเรื่อง 27 | has_many_Actions: การกระทำ 28 | many_many_Groups: กลุ่ม 29 | many_many_Users: ผู้ใช้งาน 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 31 | db_Title: หัวเรื่อง 32 | many_many_Groups: กลุ่ม 33 | many_many_Users: ผู้ใช้งาน 34 | WorkflowAction: 35 | Author: ผู้แต่ง 36 | TITLE: หัวเรื่อง 37 | WorkflowActionInstance: 38 | Title: หัวเรื่อง 39 | WorkflowDefinition: 40 | DESCRIPTION: คำอธิบาย 41 | TITLE: หัวเรื่อง 42 | WorkflowField: 43 | CreateLabel: สร้าง 44 | DeleteAction: ลบ 45 | EditAction: แก้ไข 46 | WorkflowInstance: 47 | TitleLabel: หัวเรื่อง 48 | WorkflowList: 49 | TableHeaderActions: การกระทำ 50 | WorkflowReminderEmail: 51 | HeadingTitle: หัวเรื่อง 52 | WorkflowReminderTask: 53 | SAVE: บันทึก 54 | -------------------------------------------------------------------------------- /lang/sl_SI.yml: -------------------------------------------------------------------------------- 1 | sl_SI: 2 | AdvancedWorkflowAdmin: 3 | Title: Naslov 4 | AllowEditing: 5 | NoString: Ne 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Grupe 8 | USERS: Uporabniki 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'Predmet e-pošte' 11 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 12 | many_many_Groups: Grupe 13 | many_many_Users: Uporabniki 14 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 15 | db_EmailSubject: 'Predmet e-pošte' 16 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 17 | db_Content: Vsebina 18 | db_Filename: 'Ime datoteke' 19 | db_Name: Ime 20 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 21 | db_Title: Naslov 22 | has_one_Member: Uporabnik 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 24 | has_one_Member: Uporabnik 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 26 | db_Description: Opis 27 | db_Title: Naslov 28 | many_many_Groups: Grupe 29 | many_many_Users: Uporabniki 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 31 | db_Title: Naslov 32 | many_many_Groups: Grupe 33 | many_many_Users: Uporabniki 34 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 35 | db_Title: Naslov 36 | many_many_Groups: Grupe 37 | many_many_Users: Uporabniki 38 | WorkflowAction: 39 | TITLE: Naslov 40 | WorkflowActionInstance: 41 | Title: Naslov 42 | WorkflowDefinition: 43 | DESCRIPTION: Opis 44 | TITLE: Naslov 45 | WorkflowField: 46 | CreateLabel: Ustvari 47 | DeleteAction: Izbriši 48 | EditAction: Uredi 49 | WorkflowInstance: 50 | TitleLabel: Naslov 51 | WorkflowReminderEmail: 52 | HeadingTitle: Naslov 53 | WorkflowReminderTask: 54 | SAVE: Shrani 55 | -------------------------------------------------------------------------------- /lang/af.yml: -------------------------------------------------------------------------------- 1 | af: 2 | AdvancedWorkflow: 3 | ADVANCED_WORKFLOW: 'Gevorderde werksvloei' 4 | APPLY_WORKFLOW: 'Aktiveer werksvloei' 5 | AdvancedWorkflowAdmin: 6 | Title: Tietel 7 | AssignUsersToWorkflowAction: 8 | GROUPS: Groepe 9 | USERS: Gebruikers 10 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 11 | many_many_Groups: Groepe 12 | many_many_Users: Gebruikers 13 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 14 | db_Content: Inhoud 15 | db_Filename: 'Lêer naam' 16 | db_Name: Naam 17 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 18 | db_Title: Tietel 19 | has_one_Member: Lid 20 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 21 | has_one_Member: Lid 22 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 23 | db_Description: Beskrywing 24 | db_Title: Tietel 25 | has_many_Actions: Aksies 26 | many_many_Groups: Groepe 27 | many_many_Users: Gebruikers 28 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 29 | db_Title: Tietel 30 | has_many_Actions: Aksies 31 | many_many_Groups: Groepe 32 | many_many_Users: Gebruikers 33 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 34 | db_Title: Tietel 35 | many_many_Groups: Groepe 36 | many_many_Users: Gebruikers 37 | WorkflowAction: 38 | TITLE: Tietel 39 | WorkflowActionInstance: 40 | Title: Tietel 41 | WorkflowDefinition: 42 | DESCRIPTION: Beskrywing 43 | TITLE: Tietel 44 | WorkflowField: 45 | CreateLabel: Skep 46 | DeleteAction: Verwyder 47 | EditAction: Verander 48 | WorkflowInstance: 49 | TitleLabel: Tietel 50 | WorkflowList: 51 | TableHeaderActions: Aksies 52 | WorkflowReminderEmail: 53 | HeadingTitle: Tietel 54 | WorkflowReminderTask: 55 | SAVE: Stoor 56 | -------------------------------------------------------------------------------- /lang/sr@latin.yml: -------------------------------------------------------------------------------- 1 | sr@latin: 2 | AdvancedWorkflowAdmin: 3 | Title: Naslov 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Grupe 6 | USERS: Korisnici 7 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 8 | many_many_Groups: Grupe 9 | many_many_Users: Korisnici 10 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 11 | db_Content: Sadržaj 12 | db_Filename: 'Ime datoteke' 13 | db_Name: Ime 14 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 15 | db_Comment: Komentar 16 | db_Title: Naslov 17 | has_one_Member: Član 18 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 19 | db_Comment: Komentar 20 | has_one_Member: Član 21 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 22 | db_Description: Opis 23 | db_Title: Naslov 24 | has_many_Actions: Akcije 25 | many_many_Groups: Grupe 26 | many_many_Users: Korisnici 27 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 28 | db_Title: Naslov 29 | has_many_Actions: Akcije 30 | many_many_Groups: Grupe 31 | many_many_Users: Korisnici 32 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 33 | db_Title: Naslov 34 | many_many_Groups: Grupe 35 | many_many_Users: Korisnici 36 | WorkflowAction: 37 | COMMENT: Komentar 38 | CommentLabel: Komentar 39 | FRONTENDCOMMENT: Komentar 40 | TITLE: Naslov 41 | WorkflowActionInstance: 42 | Title: Naslov 43 | WorkflowDefinition: 44 | DESCRIPTION: Opis 45 | TITLE: Naslov 46 | WorkflowField: 47 | CreateLabel: Kreiraj 48 | DeleteAction: Izbriši 49 | EditAction: Izmeni 50 | WorkflowInstance: 51 | TitleLabel: Naslov 52 | WorkflowList: 53 | TableHeaderActions: Akcije 54 | WorkflowReminderEmail: 55 | HeadingTitle: Naslov 56 | WorkflowReminderTask: 57 | SAVE: Sačuvaj 58 | -------------------------------------------------------------------------------- /lang/sr_RS.yml: -------------------------------------------------------------------------------- 1 | sr_RS: 2 | AdvancedWorkflowAdmin: 3 | Title: Наслов 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Групе 6 | USERS: Корисници 7 | NotifyUsersWorkflowAction: 8 | EMAILSUBJECT: 'Email Subject' 9 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 10 | many_many_Groups: Групе 11 | many_many_Users: Корисници 12 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 13 | db_EmailSubject: 'Email Subject' 14 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 15 | db_Content: Садржај 16 | db_Filename: 'Име датотеке' 17 | db_Name: Име 18 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 19 | db_Title: Наслов 20 | has_one_Member: Члан 21 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 22 | has_one_Member: Члан 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 24 | db_Description: Опис 25 | db_Title: Наслов 26 | has_many_Actions: Акције 27 | many_many_Groups: Групе 28 | many_many_Users: Корисници 29 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 30 | db_Title: Наслов 31 | has_many_Actions: Акције 32 | many_many_Groups: Групе 33 | many_many_Users: Корисници 34 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 35 | db_Title: Наслов 36 | many_many_Groups: Групе 37 | many_many_Users: Корисници 38 | WorkflowAction: 39 | TITLE: Наслов 40 | WorkflowActionInstance: 41 | Title: Наслов 42 | WorkflowDefinition: 43 | DESCRIPTION: Опис 44 | TITLE: Наслов 45 | WorkflowField: 46 | CreateLabel: Креирај 47 | DeleteAction: Избриши 48 | EditAction: Измени 49 | WorkflowInstance: 50 | TitleLabel: Наслов 51 | WorkflowList: 52 | TableHeaderActions: Акције 53 | WorkflowReminderEmail: 54 | HeadingTitle: Наслов 55 | WorkflowReminderTask: 56 | SAVE: Сачувај 57 | -------------------------------------------------------------------------------- /lang/es_MX.yml: -------------------------------------------------------------------------------- 1 | es_MX: 2 | AdvancedWorkflowAdmin: 3 | Title: Título 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Grupos 6 | NotifyUsersWorkflowAction: 7 | EMAILSUBJECT: 'Email Subject' 8 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 9 | many_many_Groups: Grupos 10 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 11 | db_EmailSubject: 'Email Subject' 12 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 13 | db_Content: Contenido 14 | db_Filename: 'Nombre del archivo' 15 | db_Name: Nombre 16 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 17 | db_Title: Título 18 | db_Type: Tipo 19 | has_one_Member: Miembro 20 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 21 | has_one_Member: Miembro 22 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 23 | db_Description: Descripción 24 | db_Title: Título 25 | has_many_Actions: Acciones 26 | many_many_Groups: Grupos 27 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 28 | db_Title: Título 29 | has_many_Actions: Acciones 30 | many_many_Groups: Grupos 31 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 32 | db_Title: Título 33 | db_Type: Tipo 34 | many_many_Groups: Grupos 35 | WorkflowAction: 36 | Author: Autor 37 | TITLE: Título 38 | TypeLabel: Tipo 39 | WorkflowActionInstance: 40 | Title: Título 41 | WorkflowDefinition: 42 | DESCRIPTION: Descripción 43 | TITLE: Título 44 | WorkflowField: 45 | CreateLabel: Crear 46 | DeleteAction: Eliminar 47 | EditAction: Editar 48 | WorkflowInstance: 49 | TitleLabel: Título 50 | WorkflowList: 51 | TableHeaderActions: Acciones 52 | WorkflowReminderEmail: 53 | HeadingTitle: Título 54 | WorkflowReminderTask: 55 | SAVE: Guardar 56 | WorkflowTransition: 57 | TYPE: Tipo 58 | -------------------------------------------------------------------------------- /lang/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | AdvancedWorkflowAdmin: 3 | Title: タイトル 4 | AssignUsersToWorkflowAction: 5 | GROUPS: グループ 6 | USERS: ユーザー 7 | NotifyUsersWorkflowAction: 8 | EMAILSUBJECT: メールの件名 9 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 10 | many_many_Groups: グループ 11 | many_many_Users: ユーザー 12 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 13 | db_EmailSubject: メールの件名 14 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 15 | db_Value: 数値 16 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 17 | db_Content: 内容 18 | db_Filename: ファイル名 19 | db_Name: 名前 20 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 21 | db_Title: タイトル 22 | has_one_Member: メンバー 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 24 | has_one_Member: メンバー 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 26 | db_Description: 説明文 27 | db_Template: テンプレート 28 | db_Title: タイトル 29 | has_many_Actions: アクション 30 | many_many_Groups: グループ 31 | many_many_Users: ユーザー 32 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 33 | db_Title: タイトル 34 | has_many_Actions: アクション 35 | many_many_Groups: グループ 36 | many_many_Users: ユーザー 37 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 38 | db_Title: タイトル 39 | many_many_Groups: グループ 40 | many_many_Users: ユーザー 41 | WorkflowAction: 42 | Author: 作成者 43 | TITLE: タイトル 44 | WorkflowActionInstance: 45 | Title: タイトル 46 | WorkflowDefinition: 47 | DESCRIPTION: 説明文 48 | TITLE: タイトル 49 | WorkflowField: 50 | CreateLabel: 作成 51 | DeleteAction: 削除 52 | EditAction: 編集 53 | WorkflowInstance: 54 | TitleLabel: タイトル 55 | WorkflowList: 56 | TableHeaderActions: アクション 57 | WorkflowReminderEmail: 58 | HeadingTitle: タイトル 59 | WorkflowReminderTask: 60 | SAVE: 保存 61 | -------------------------------------------------------------------------------- /lang/id_ID.yml: -------------------------------------------------------------------------------- 1 | id_ID: 2 | AdvancedWorkflowAdmin: 3 | Title: Judul 4 | AllowEditing: 5 | NoString: Tidak 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Kelompok 8 | USERS: Pengguna 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'Subyek email' 11 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 12 | many_many_Groups: Kelompok 13 | many_many_Users: Pengguna 14 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 15 | db_EmailSubject: 'Subyek email' 16 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 17 | db_Content: Konten 18 | db_Filename: 'Nama berkas' 19 | db_Name: Nama 20 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 21 | db_Title: Judul 22 | has_one_Member: Pengguna 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 24 | has_one_Member: Pengguna 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 26 | db_Description: Deskripsi 27 | db_Title: Judul 28 | has_many_Actions: Tindakan 29 | many_many_Groups: Kelompok 30 | many_many_Users: Pengguna 31 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 32 | db_Title: Judul 33 | has_many_Actions: Tindakan 34 | many_many_Groups: Kelompok 35 | many_many_Users: Pengguna 36 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 37 | db_Title: Judul 38 | many_many_Groups: Kelompok 39 | many_many_Users: Pengguna 40 | WorkflowAction: 41 | TITLE: Judul 42 | WorkflowActionInstance: 43 | Title: Judul 44 | WorkflowDefinition: 45 | DESCRIPTION: Deskripsi 46 | TITLE: Judul 47 | WorkflowField: 48 | CreateLabel: Buat 49 | DeleteAction: Hapus 50 | WorkflowInstance: 51 | TitleLabel: Judul 52 | WorkflowList: 53 | TableHeaderActions: Tindakan 54 | WorkflowReminderEmail: 55 | HeadingTitle: Judul 56 | WorkflowReminderTask: 57 | SAVE: Simpan 58 | -------------------------------------------------------------------------------- /client/src/bundles/WorkflowGridField.js: -------------------------------------------------------------------------------- 1 | import jQuery from 'jquery'; 2 | 3 | jQuery.entwine('ss', ($) => { 4 | // Disable clicking on each disabled table-row. 5 | $('.ss-gridfield .ss-gridfield-item').entwine({ 6 | onmatch() { 7 | const row = this.closest('tr'); 8 | 9 | if (this.find('.col-buttons.disabled').length) { 10 | row 11 | .addClass('disabled') 12 | // Disable any actions on the and edit icons, but do allow 13 | // for target-object's hyperlink. 14 | .on('click', (e) => { 15 | if (e.target.nodeName === 'A' && e.target.className.match(/edit-link/) === null) { 16 | return true; 17 | } 18 | return false; 19 | }); 20 | 21 | this.find('a.edit-link').attr('title', ''); 22 | } 23 | }, 24 | }); 25 | 26 | // Override GridField's method of providing cursor styles on hover. 27 | $('.AdvancedWorkflowAdmin .ss-gridfield-item.disabled').entwine({ 28 | onmouseover() { 29 | this.css('cursor', 'default'); 30 | }, 31 | }); 32 | 33 | /* 34 | * Prevent a precursor POST to gridfield record URLs (all Pending/Submitted GridFields) 35 | * when clicking on target-object's hyperlinks, which results in a 404. 36 | */ 37 | $('.ss-gridfield .ss-gridfield-item td.col-Title a').entwine({ 38 | onclick(e) { 39 | e.stopPropagation(); 40 | }, 41 | }); 42 | 43 | /* 44 | * Reload the current (central) CMS pane, to ensure that previously related content 45 | * objects, are visually cleared from the UI immediately. 46 | */ 47 | /* eslint-disable max-len */ 48 | $('.ss-gridfield .col-buttons .action.gridfield-button-delete, .cms-edit-form .Actions button.action.action-delete').entwine({ 49 | /* eslint-enable max-len */ 50 | onclick(e) { 51 | this._super(e); 52 | $('.cms-container').reloadCurrentPanel(); 53 | e.preventDefault(); 54 | }, 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /templates/Includes/WorkflowDefinitionExport.ss: -------------------------------------------------------------------------------- 1 | --- 2 | Name: exportedworkflow 3 | --- 4 | SilverStripe\\Core\\Injector\\Injector: 5 | ExportedWorkflow: 6 | class: Symbiote\\AdvancedWorkflow\\Templates\\WorkflowTemplate 7 | constructor: 8 | <% with ExportMetaData %> 9 | - '$ExportWorkflowDefName $ExportDate' 10 | - 'Exported from $ExportHost on $ExportDate by $ExportUser using SilverStripe versions $ExportVersionFramework' 11 | - 0.2 12 | - $ExportRemindDays 13 | - $ExportSort 14 | <% end_with %> 15 | properties: 16 | structure: 17 | <% if ExportUsers %> 18 | users: 19 | <% loop ExportUsers %> 20 | - email: $Email 21 | <% end_loop %> 22 | <% end_if %> 23 | <% if ExportGroups %> 24 | groups: 25 | <% loop ExportGroups %> 26 | - title: '$Title' 27 | <% end_loop %> 28 | <% end_if %> 29 | <% if ExportActions %> 30 | <% loop ExportActions %> 31 | '$Title': 32 | type: $ClassName 33 | <% if Users %> 34 | users: 35 | <% loop Users %> 36 | - email: $Email 37 | <% end_loop %> 38 | <% end_if %> 39 | <% if Groups %> 40 | groups: 41 | <% loop Groups %> 42 | - title: '$Title' 43 | <% end_loop %> 44 | <% end_if %> 45 | <% if Transitions %> 46 | transitions: 47 | <% loop Transitions %> 48 | - $Title: '$NextAction.Title' 49 | <% if Users %> 50 | users: 51 | <% loop Users %> 52 | - email: $Email 53 | <% end_loop %> 54 | <% end_if %> 55 | <% if Groups %> 56 | groups: 57 | <% loop Groups %> 58 | - title: '$Title' 59 | <% end_loop %> 60 | <% end_if %> 61 | <% end_loop %> 62 | <% end_if %> 63 | <% end_loop %> 64 | <% end_if %> 65 | Symbiote\\AdvancedWorkflow\\Services\\WorkflowService: 66 | properties: 67 | templates: 68 | - %\$ExportedWorkflow 69 | -------------------------------------------------------------------------------- /lang/nb.yml: -------------------------------------------------------------------------------- 1 | nb: 2 | AdvancedWorkflowAdmin: 3 | Title: Tittel 4 | AssignUsersToWorkflowAction: 5 | GROUPS: Grupper 6 | USERS: Brukere 7 | NotifyUsersWorkflowAction: 8 | FORMATTINGHELP: Formatteringshjelp 9 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 10 | many_many_Groups: Grupper 11 | many_many_Users: Brukere 12 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 13 | db_Content: Innhold 14 | db_Filename: Filnavn 15 | db_Name: Navn 16 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 17 | db_Comment: Kommentar 18 | db_Title: Tittel 19 | has_one_Member: Medlem 20 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 21 | db_Comment: Kommentar 22 | has_one_Member: Medlem 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 24 | db_Description: Beskrivelse 25 | db_Title: Tittel 26 | has_many_Actions: Handlinger 27 | many_many_Groups: Grupper 28 | many_many_Users: Brukere 29 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 30 | db_Title: Tittel 31 | has_many_Actions: Handlinger 32 | many_many_Groups: Grupper 33 | many_many_Users: Brukere 34 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 35 | db_Title: Tittel 36 | many_many_Groups: Grupper 37 | many_many_Users: Brukere 38 | WorkflowAction: 39 | Author: Forfatter 40 | COMMENT: Kommentar 41 | CommentLabel: Kommentar 42 | FRONTENDCOMMENT: Kommentar 43 | TITLE: Tittel 44 | WorkflowActionInstance: 45 | Title: Tittel 46 | WorkflowDefinition: 47 | DESCRIPTION: Beskrivelse 48 | TITLE: Tittel 49 | WorkflowField: 50 | CreateLabel: Opprett 51 | DeleteAction: Slett 52 | EditAction: Rediger 53 | WorkflowInstance: 54 | TitleLabel: Tittel 55 | WorkflowList: 56 | TableHeaderActions: Handlinger 57 | WorkflowReminderEmail: 58 | HeadingTitle: Tittel 59 | WorkflowReminderTask: 60 | SAVE: Lagre 61 | -------------------------------------------------------------------------------- /lang/et_EE.yml: -------------------------------------------------------------------------------- 1 | et_EE: 2 | AdvancedWorkflowAdmin: 3 | Title: Pealkiri 4 | AllowEditing: 5 | NoString: Ei 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Grupid 8 | USERS: Kasutajad 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'Email Subject' 11 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 12 | many_many_Groups: Grupid 13 | many_many_Users: Kasutajad 14 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 15 | db_EmailSubject: 'Email Subject' 16 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 17 | db_Content: Sisu 18 | db_Filename: Failinimi 19 | db_Name: Nimi 20 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 21 | db_Title: Pealkiri 22 | has_one_Member: Kasutaja 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 24 | has_one_Member: Kasutaja 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 26 | db_Description: Kirjeldus 27 | db_Title: Pealkiri 28 | has_many_Actions: Tegevused 29 | many_many_Groups: Grupid 30 | many_many_Users: Kasutajad 31 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 32 | db_Title: Pealkiri 33 | has_many_Actions: Tegevused 34 | many_many_Groups: Grupid 35 | many_many_Users: Kasutajad 36 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 37 | db_Title: Pealkiri 38 | many_many_Groups: Grupid 39 | many_many_Users: Kasutajad 40 | WorkflowAction: 41 | Author: Autor 42 | TITLE: Pealkiri 43 | WorkflowActionInstance: 44 | Title: Pealkiri 45 | WorkflowDefinition: 46 | DESCRIPTION: Kirjeldus 47 | TITLE: Pealkiri 48 | WorkflowField: 49 | CreateLabel: Loo 50 | DeleteAction: Kustuta 51 | EditAction: Redigeeri 52 | WorkflowInstance: 53 | TitleLabel: Pealkiri 54 | WorkflowList: 55 | TableHeaderActions: Tegevused 56 | WorkflowReminderEmail: 57 | HeadingTitle: Pealkiri 58 | WorkflowReminderTask: 59 | SAVE: Salvesta 60 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symbiote/silverstripe-advancedworkflow", 3 | "description": "Adds configurable workflow support to the CMS, with a GUI for creating custom workflow definitions.", 4 | "type": "silverstripe-vendormodule", 5 | "keywords": [ 6 | "silverstripe", 7 | "advancedworkflow", 8 | "workflow" 9 | ], 10 | "license": "BSD-3-Clause", 11 | "authors": [ 12 | { 13 | "name": "Marcus Nyeholt", 14 | "email": "marcus@symbiote.com.au" 15 | }, 16 | { 17 | "name": "Andrew Short", 18 | "email": "andrewjshort@gmail.com" 19 | } 20 | ], 21 | "require": { 22 | "php": "^8.3", 23 | "silverstripe/cms": "^6", 24 | "silverstripe/framework": "^6.1", 25 | "silverstripe/admin": "^3", 26 | "silverstripe/versioned": "^3", 27 | "symfony/yaml": "^7.0" 28 | }, 29 | "require-dev": { 30 | "phpunit/phpunit": "^11.3", 31 | "squizlabs/php_codesniffer": "^3", 32 | "silverstripe/documentation-lint": "^1", 33 | "silverstripe/standards": "^1", 34 | "phpstan/extension-installer": "^1.3" 35 | }, 36 | "extra": { 37 | "expose": [ 38 | "client/dist", 39 | "client/lang", 40 | "images" 41 | ] 42 | }, 43 | "config": { 44 | "allow-plugins": { 45 | "dealerdirect/phpcodesniffer-composer-installer": true 46 | } 47 | }, 48 | "suggest": { 49 | "symbiote/silverstripe-queuedjobs": "Allow automated workflow transitions with queued system jobs" 50 | }, 51 | "autoload": { 52 | "psr-4": { 53 | "Symbiote\\AdvancedWorkflow\\": "src/", 54 | "Symbiote\\AdvancedWorkflow\\Tests\\": "tests/php/", 55 | "Symbiote\\AdvancedWorkflow\\Tests\\Behat\\": "tests/behat/" 56 | } 57 | }, 58 | "replace": { 59 | "silverstripe/advancedworkflow": "self.version" 60 | }, 61 | "minimum-stability": "dev", 62 | "prefer-stable": true 63 | } 64 | -------------------------------------------------------------------------------- /lang/pl.yml: -------------------------------------------------------------------------------- 1 | pl: 2 | AdvancedWorkflowAdmin: 3 | Title: Tytuł 4 | AllowEditing: 5 | NoString: Nie 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Grupy 8 | USERS: Użytkownicy 9 | NotifyUsersWorkflowAction: 10 | FORMATTINGHELP: 'Pomoc formatowania' 11 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 12 | many_many_Groups: Grupy 13 | many_many_Users: Użytkownicy 14 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 15 | db_Content: Zawartość 16 | db_Filename: 'Nazwa pliku' 17 | db_Name: Nazwa 18 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 19 | db_Sort: Sortuj 20 | db_Title: Tytuł 21 | db_Type: 'Rodzaj strony' 22 | has_one_Member: Użytkownik 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 24 | has_one_Member: Użytkownik 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 26 | db_Description: Opis 27 | db_Sort: Sortuj 28 | db_Title: Tytuł 29 | has_many_Actions: Akcje 30 | many_many_Groups: Grupy 31 | many_many_Users: Użytkownicy 32 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 33 | db_Title: Tytuł 34 | has_many_Actions: Akcje 35 | many_many_Groups: Grupy 36 | many_many_Users: Użytkownicy 37 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 38 | db_Sort: Sortuj 39 | db_Title: Tytuł 40 | db_Type: 'Rodzaj strony' 41 | many_many_Groups: Grupy 42 | many_many_Users: Użytkownicy 43 | WorkflowAction: 44 | Author: Autor 45 | TITLE: Tytuł 46 | TypeLabel: 'Rodzaj strony' 47 | WorkflowActionInstance: 48 | Title: Tytuł 49 | WorkflowDefinition: 50 | DESCRIPTION: Opis 51 | TITLE: Tytuł 52 | WorkflowField: 53 | CreateLabel: Stwórz 54 | DeleteAction: Usuń 55 | EditAction: Edytuj 56 | WorkflowInstance: 57 | TitleLabel: Tytuł 58 | WorkflowList: 59 | TableHeaderActions: Akcje 60 | WorkflowReminderEmail: 61 | HeadingTitle: Tytuł 62 | WorkflowReminderTask: 63 | SAVE: Zapisz 64 | WorkflowTransition: 65 | TYPE: 'Rodzaj strony' 66 | -------------------------------------------------------------------------------- /_config/workflows.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Name: defaultworkflows 3 | --- 4 | SilverStripe\Core\Injector\Injector: 5 | SimpleReviewApprove: 6 | class: Symbiote\AdvancedWorkflow\Templates\WorkflowTemplate 7 | constructor: 8 | - 'Review and Approve' 9 | - 'Single step review and approve. Make sure to update the Apply for approval and Notify users steps!' 10 | - 0.2 11 | properties: 12 | structure: 13 | 'Apply for approval': 14 | type: Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction 15 | transitions: 16 | notify: 'Notify users' 17 | 'Notify users': 18 | type: Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction 19 | transitions: 20 | approval: Approval 21 | Approval: 22 | type: Symbiote\AdvancedWorkflow\Actions\SimpleApprovalWorkflowAction 23 | transitions: 24 | Approve: Publish 25 | Reject: 'Reject changes' 26 | Publish: 27 | type: Symbiote\AdvancedWorkflow\Actions\PublishItemWorkflowAction 28 | transitions: 29 | assign: 'Assign Initiator Publish' 30 | 'Assign Initiator Publish': 31 | type: Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction 32 | transitions: 33 | notify: 'Notify Initiator Publish' 34 | 'Notify Initiator Publish': 35 | type: Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction 36 | 'Reject changes': 37 | type: Symbiote\AdvancedWorkflow\Actions\CancelWorkflowAction 38 | transitions: 39 | assign: 'Assign Initiator Cancel' 40 | 'Assign Initiator Cancel': 41 | type: Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction 42 | transitions: 43 | notify: 'Notify Initiator Cancel' 44 | 'Notify Initiator Cancel': 45 | type: Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction 46 | Symbiote\AdvancedWorkflow\Services\WorkflowService: 47 | properties: 48 | templates: 49 | - '%$SimpleReviewApprove' 50 | -------------------------------------------------------------------------------- /src/Jobs/WorkflowPublishTargetJob.php: -------------------------------------------------------------------------------- 1 | setObject($obj); 26 | $this->publishType = $type ? strtolower($type) : 'publish'; 27 | $this->totalSteps = 1; 28 | } 29 | } 30 | 31 | public function getTitle() 32 | { 33 | return _t( 34 | 'AdvancedWorkflowPublishJob.SCHEDULEJOBTITLE', 35 | "Scheduled {type} of {object}", 36 | "", 37 | array( 38 | 'type' => $this->publishType, 39 | 'object' => $this->getObject()->Title 40 | ) 41 | ); 42 | } 43 | 44 | public function process() 45 | { 46 | if ($target = $this->getObject()) { 47 | if ($this->publishType == 'publish') { 48 | $target->setIsPublishJobRunning(true); 49 | $target->PublishOnDate = ''; 50 | $target->writeWithoutVersion(); 51 | $target->publishRecursive(); 52 | $this->extend('onAfterWorkflowPublish', $target); 53 | } elseif ($this->publishType == 'unpublish') { 54 | $target->setIsPublishJobRunning(true); 55 | $target->UnPublishOnDate = ''; 56 | $target->writeWithoutVersion(); 57 | $target->doUnpublish(); 58 | $this->extend('onAfterWorkflowUnublish', $target); 59 | } 60 | } 61 | $this->currentStep = 1; 62 | $this->isComplete = true; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lang/cs.yml: -------------------------------------------------------------------------------- 1 | cs: 2 | AdvancedWorkflowAdmin: 3 | Title: Název 4 | AllowEditing: 5 | NoString: Ne 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Skupiny 8 | USERS: Uživatelé 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'Předmět emailu' 11 | FORMATTINGHELP: 'Nápověda k formátování' 12 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 13 | many_many_Groups: Skupiny 14 | many_many_Users: Uživatelé 15 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 16 | db_EmailSubject: 'Předmět emailu' 17 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 18 | db_Content: Obsah 19 | db_Filename: 'Jméno souboru' 20 | db_Name: Jméno 21 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 22 | db_Title: Název 23 | db_Type: Typ 24 | has_one_Member: Člen 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 26 | has_one_Member: Člen 27 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 28 | db_Description: Popis 29 | db_Title: Název 30 | has_many_Actions: Akce 31 | many_many_Groups: Skupiny 32 | many_many_Users: Uživatelé 33 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 34 | db_Title: Název 35 | has_many_Actions: Akce 36 | many_many_Groups: Skupiny 37 | many_many_Users: Uživatelé 38 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 39 | db_Title: Název 40 | db_Type: Typ 41 | many_many_Groups: Skupiny 42 | many_many_Users: Uživatelé 43 | WorkflowAction: 44 | Author: Autor 45 | TITLE: Název 46 | TypeLabel: Typ 47 | WorkflowActionInstance: 48 | Title: Název 49 | WorkflowDefinition: 50 | DESCRIPTION: Popis 51 | TITLE: Název 52 | WorkflowField: 53 | CreateLabel: Vytvořit 54 | DeleteAction: Smazat 55 | EditAction: Editovat 56 | WorkflowInstance: 57 | TitleLabel: Název 58 | WorkflowList: 59 | TableHeaderActions: Akce 60 | WorkflowReminderEmail: 61 | HeadingTitle: Název 62 | WorkflowReminderTask: 63 | SAVE: Uložit 64 | WorkflowTransition: 65 | TYPE: Typ 66 | -------------------------------------------------------------------------------- /lang/bg.yml: -------------------------------------------------------------------------------- 1 | bg: 2 | AdvancedWorkflowAdmin: 3 | Title: Заглавие 4 | AllowEditing: 5 | NoString: Не 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Групи 8 | USERS: Потребители 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'Тема на Email' 11 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 12 | many_many_Groups: Групи 13 | many_many_Users: Потребители 14 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 15 | db_EmailSubject: 'Тема на Email' 16 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 17 | db_Content: Съдържание 18 | db_Filename: 'Име на файл' 19 | db_Name: Име 20 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 21 | db_Title: Заглавие 22 | db_Type: Тип 23 | has_one_Member: Потребител 24 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 25 | has_one_Member: Потребител 26 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 27 | db_Description: Описание 28 | db_Title: Заглавие 29 | has_many_Actions: Действия 30 | many_many_Groups: Групи 31 | many_many_Users: Потребители 32 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 33 | db_Title: Заглавие 34 | has_many_Actions: Действия 35 | many_many_Groups: Групи 36 | many_many_Users: Потребители 37 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 38 | db_Title: Заглавие 39 | db_Type: Тип 40 | many_many_Groups: Групи 41 | many_many_Users: Потребители 42 | WorkflowAction: 43 | Author: Автор 44 | TITLE: Заглавие 45 | TypeLabel: Тип 46 | WorkflowActionInstance: 47 | Title: Заглавие 48 | WorkflowDefinition: 49 | DESCRIPTION: Описание 50 | TITLE: Заглавие 51 | WorkflowField: 52 | CreateLabel: Създай 53 | DeleteAction: Изтрий 54 | EditAction: Редактиране 55 | WorkflowInstance: 56 | TitleLabel: Заглавие 57 | WorkflowList: 58 | TableHeaderActions: Действия 59 | WorkflowReminderEmail: 60 | HeadingTitle: Заглавие 61 | WorkflowReminderTask: 62 | SAVE: Запис 63 | WorkflowTransition: 64 | TYPE: Тип 65 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | ## Description 7 | 11 | 12 | ## Manual testing steps 13 | 17 | 18 | ## Issues 19 | 23 | - # 24 | 25 | ## Pull request checklist 26 | 30 | - [ ] The target branch is correct 31 | - See [picking the right version](https://docs.silverstripe.org/en/contributing/code/#picking-the-right-version) 32 | - [ ] All commits are relevant to the purpose of the PR (e.g. no debug statements, unrelated refactoring, or arbitrary linting) 33 | - Small amounts of additional linting are usually okay, but if it makes it hard to concentrate on the relevant changes, ask for the unrelated changes to be reverted, and submitted as a separate PR. 34 | - [ ] The commit messages follow our [commit message guidelines](https://docs.silverstripe.org/en/contributing/code/#commit-messages) 35 | - [ ] The PR follows our [contribution guidelines](https://docs.silverstripe.org/en/contributing/code/) 36 | - [ ] Code changes follow our [coding conventions](https://docs.silverstripe.org/en/contributing/coding_conventions/) 37 | - [ ] This change is covered with tests (or tests aren't necessary for this change) 38 | - [ ] Any relevant User Help/Developer documentation is updated; for impactful changes, information is added to the changelog for the intended release 39 | - [ ] CI is green 40 | -------------------------------------------------------------------------------- /lang/lt.yml: -------------------------------------------------------------------------------- 1 | lt: 2 | AdvancedWorkflowAdmin: 3 | Title: Pavadinimas 4 | AllowEditing: 5 | NoString: Ne 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Grupės 8 | USERS: Vartotojai 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'El. laiško tema' 11 | FORMATTINGHELP: 'Galimos reikšmės turinyje' 12 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 13 | many_many_Groups: Grupės 14 | many_many_Users: Vartotojai 15 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 16 | db_EmailSubject: 'El. laiško tema' 17 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 18 | db_Content: Turinys 19 | db_Filename: 'Bylos pavadinimas' 20 | db_Name: Pavadinimas 21 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 22 | db_Comment: Komentaras 23 | db_Title: Pavadinimas 24 | has_one_Member: Vartotojas 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 26 | db_Comment: Komentaras 27 | has_one_Member: Vartotojas 28 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 29 | db_Description: Aprašymas 30 | db_Title: Pavadinimas 31 | has_many_Actions: Veiksmai 32 | many_many_Groups: Grupės 33 | many_many_Users: Vartotojai 34 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 35 | db_Title: Pavadinimas 36 | has_many_Actions: Veiksmai 37 | many_many_Groups: Grupės 38 | many_many_Users: Vartotojai 39 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 40 | db_Title: Pavadinimas 41 | many_many_Groups: Grupės 42 | many_many_Users: Vartotojai 43 | WorkflowAction: 44 | Author: Autorius 45 | COMMENT: Komentaras 46 | CommentLabel: Komentaras 47 | FRONTENDCOMMENT: Komentaras 48 | TITLE: Pavadinimas 49 | WorkflowActionInstance: 50 | Title: Pavadinimas 51 | WorkflowDefinition: 52 | DESCRIPTION: Aprašymas 53 | TITLE: Pavadinimas 54 | WorkflowField: 55 | CreateLabel: Sukurti 56 | DeleteAction: Ištrinti 57 | EditAction: Redaguoti 58 | WorkflowInstance: 59 | TitleLabel: Pavadinimas 60 | WorkflowList: 61 | TableHeaderActions: Veiksmai 62 | WorkflowReminderEmail: 63 | HeadingTitle: Pavadinimas 64 | WorkflowReminderTask: 65 | SAVE: Saugoti 66 | -------------------------------------------------------------------------------- /lang/fr.yml: -------------------------------------------------------------------------------- 1 | fr: 2 | AdvancedWorkflowAdmin: 3 | Title: Titre 4 | AllowEditing: 5 | NoString: Non 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Groupes 8 | USERS: Utilisateurs 9 | NotifyUsersWorkflowAction: 10 | EMAILFROM: 'Email de' 11 | EMAILSUBJECT: "Sujet de l'email" 12 | EMAILTEMPLATE: "Modèle d'e-mail" 13 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 14 | many_many_Groups: Groupes 15 | many_many_Users: Utilisateurs 16 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 17 | db_EmailFrom: 'Email de' 18 | db_EmailSubject: "Sujet de l'email" 19 | db_EmailTemplate: "Modèle d'e-mail" 20 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 21 | db_Value: Valeur 22 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 23 | db_Content: Contenu 24 | db_Filename: 'Nom du fichier' 25 | db_Name: Nom 26 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 27 | db_Comment: Commentaire 28 | db_Sort: Tri 29 | db_Title: Titre 30 | has_one_Member: Membre 31 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 32 | db_Comment: Commentaire 33 | has_one_Member: Membre 34 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 35 | db_Sort: Tri 36 | db_Title: Titre 37 | many_many_Groups: Groupes 38 | many_many_Users: Utilisateurs 39 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 40 | db_Title: Titre 41 | many_many_Groups: Groupes 42 | many_many_Users: Utilisateurs 43 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 44 | db_Sort: Tri 45 | db_Title: Titre 46 | many_many_Groups: Groupes 47 | many_many_Users: Utilisateurs 48 | WorkflowAction: 49 | Author: Auteur 50 | COMMENT: Commentaire 51 | CommentLabel: Commentaire 52 | FRONTENDCOMMENT: Commentaire 53 | TITLE: Titre 54 | WorkflowActionInstance: 55 | Title: Titre 56 | WorkflowDefinition: 57 | TITLE: Titre 58 | WorkflowField: 59 | CreateLabel: Créer 60 | DeleteAction: Supprimer 61 | EditAction: Éditer 62 | WorkflowInstance: 63 | TitleLabel: Titre 64 | WorkflowReminderEmail: 65 | HeadingTitle: Titre 66 | WorkflowReminderTask: 67 | SAVE: Sauvegarder 68 | -------------------------------------------------------------------------------- /lang/fa_IR.yml: -------------------------------------------------------------------------------- 1 | fa_IR: 2 | AdvancedWorkflowAdmin: 3 | Title: عنوان 4 | AllowEditing: 5 | NoString: خیر 6 | AssignUsersToWorkflowAction: 7 | GROUPS: 'گروه ها' 8 | USERS: کاربران 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'موضوع پست الکترونیک' 11 | EMAILTEMPLATE: 'قالب پست الکترونیک' 12 | FORMATTINGHELP: 'راهنمای قالب‌بندی' 13 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 14 | many_many_Groups: گروه‌ها 15 | many_many_Users: کاربران 16 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 17 | db_EmailSubject: 'موضوع پست الکترونیک' 18 | db_EmailTemplate: 'قالب پست الکترونیک' 19 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 20 | db_Content: محتوا 21 | db_Filename: 'نام فايل' 22 | db_Name: نام 23 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 24 | db_Comment: دیدگاه 25 | db_Sort: مرتب‌سازی 26 | db_Title: عنوان 27 | db_Type: نوع 28 | has_one_Member: عضو 29 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 30 | db_Comment: دیدگاه 31 | has_one_Member: عضو 32 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 33 | db_Description: توضحیات 34 | db_Sort: مرتب‌سازی 35 | db_Title: عنوان 36 | many_many_Groups: گروه‌ها 37 | many_many_Users: کاربران 38 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 39 | db_Title: عنوان 40 | many_many_Groups: گروه‌ها 41 | many_many_Users: کاربران 42 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 43 | db_Sort: مرتب‌سازی 44 | db_Title: عنوان 45 | db_Type: نوع 46 | many_many_Groups: گروه‌ها 47 | many_many_Users: کاربران 48 | WorkflowAction: 49 | Author: نگارنده 50 | COMMENT: دیدگاه 51 | CommentLabel: دیدگاه 52 | FRONTENDCOMMENT: دیدگاه 53 | TITLE: عنوان 54 | TypeLabel: نوع 55 | WorkflowActionInstance: 56 | Title: عنوان 57 | WorkflowDefinition: 58 | DESCRIPTION: توضحیات 59 | TITLE: عنوان 60 | WorkflowField: 61 | CreateLabel: ایجاد 62 | DeleteAction: حذف 63 | EditAction: ویرایش 64 | WorkflowInstance: 65 | TitleLabel: عنوان 66 | WorkflowReminderEmail: 67 | HeadingTitle: عنوان 68 | WorkflowReminderTask: 69 | SAVE: ذخیره 70 | WorkflowTransition: 71 | TYPE: نوع 72 | -------------------------------------------------------------------------------- /lang/fi.yml: -------------------------------------------------------------------------------- 1 | fi: 2 | AdvancedWorkflowAdmin: 3 | Title: Nimi 4 | AllowEditing: 5 | NoString: Ei 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Ryhmät 8 | USERS: Käyttäjät 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'Sähköpostin aihe' 11 | FORMATTINGHELP: Muotoiluapu 12 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 13 | many_many_Groups: Ryhmät 14 | many_many_Users: Käyttäjät 15 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 16 | db_EmailSubject: 'Sähköpostin aihe' 17 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 18 | db_Content: Sisältö 19 | db_Filename: Tiedostonimi 20 | db_Name: Nimi 21 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 22 | db_Comment: Kommentti 23 | db_Sort: Järjestä 24 | db_Title: Otsikko 25 | db_Type: Tyyppi 26 | has_one_Member: Käyttäjä 27 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 28 | db_Comment: Kommentti 29 | has_one_Member: Käyttäjä 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 31 | db_Description: Kuvaus 32 | db_Sort: Järjestä 33 | db_Template: Sivupohja 34 | db_Title: Otsikko 35 | has_many_Actions: Toiminnot 36 | many_many_Groups: Ryhmät 37 | many_many_Users: Käyttäjät 38 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 39 | db_Title: Otsikko 40 | has_many_Actions: Toiminnot 41 | many_many_Groups: Ryhmät 42 | many_many_Users: Käyttäjät 43 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 44 | db_Sort: Järjestä 45 | db_Title: Otsikko 46 | db_Type: Tyyppi 47 | many_many_Groups: Ryhmät 48 | many_many_Users: Käyttäjät 49 | WorkflowAction: 50 | Author: Kirjoittaja 51 | COMMENT: Kommentti 52 | CommentLabel: Kommentti 53 | FRONTENDCOMMENT: Kommentti 54 | TITLE: Nimi 55 | TypeLabel: Tyyppi 56 | WorkflowActionInstance: 57 | Title: Nimi 58 | WorkflowDefinition: 59 | DESCRIPTION: Kuvaus 60 | TITLE: Nimi 61 | WorkflowField: 62 | CreateLabel: Luo 63 | DeleteAction: Poista 64 | EditAction: Muokkaa 65 | WorkflowInstance: 66 | TitleLabel: Nimi 67 | WorkflowList: 68 | TableHeaderActions: Toiminnot 69 | WorkflowReminderEmail: 70 | HeadingTitle: Otsikko 71 | WorkflowReminderTask: 72 | SAVE: Tallenna 73 | WorkflowTransition: 74 | TYPE: Tyyppi 75 | -------------------------------------------------------------------------------- /lang/hr.yml: -------------------------------------------------------------------------------- 1 | hr: 2 | AdvancedWorkflow: 3 | ADVANCED_WORKFLOW: 'Napredni proces "Workflow"' 4 | APPLY_WORKFLOW: 'Primjeni proces "workflow"' 5 | APPLY_WORKFLOW_HELP: 'Korisnici mogu primjeniti proces na stavke' 6 | CREATE_WORKFLOW: 'Kreiraj proces' 7 | CREATE_WORKFLOW_HELP: 'Korisnici mogu kreirati definicije procesa' 8 | DELETE_WORKFLOW: 'Obriši proces' 9 | DELETE_WORKFLOW_HELP: 'Korisnici mogu obrisati definicije procesa i aktivne procese' 10 | JOB_REMINDER_COMMENT: '%s: Email podsjetnik poslan\n\n' 11 | AdvancedWorkflowAdmin: 12 | Title: Naslov 13 | AllowEditing: 14 | NoString: Ne 15 | AssignUsersToWorkflowAction: 16 | GROUPS: Grupe 17 | USERS: Korisnici 18 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 19 | many_many_Groups: Grupe 20 | many_many_Users: Korisnici 21 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 22 | db_Content: Sadržaj 23 | db_Filename: 'Naziv datoteke' 24 | db_Name: Naziv 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 26 | db_Comment: Komentar 27 | db_Title: Naslov 28 | db_Type: Tip 29 | has_one_Member: Član 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 31 | db_Comment: Komentar 32 | has_one_Member: Član 33 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 34 | db_Description: Opis 35 | db_Title: Naslov 36 | many_many_Groups: Grupe 37 | many_many_Users: Korisnici 38 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 39 | db_Title: Naslov 40 | many_many_Groups: Grupe 41 | many_many_Users: Korisnici 42 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 43 | db_Title: Naslov 44 | db_Type: Tip 45 | many_many_Groups: Grupe 46 | many_many_Users: Korisnici 47 | WorkflowAction: 48 | Author: Autor 49 | COMMENT: Komentar 50 | CommentLabel: Komentar 51 | FRONTENDCOMMENT: Komentar 52 | TITLE: Naslov 53 | TypeLabel: Tip 54 | WorkflowActionInstance: 55 | Title: Naslov 56 | WorkflowDefinition: 57 | DESCRIPTION: Opis 58 | TITLE: Naslov 59 | WorkflowField: 60 | CreateLabel: Kreiraj 61 | DeleteAction: Obriši 62 | EditAction: Uredi 63 | WorkflowInstance: 64 | TitleLabel: Naslov 65 | WorkflowReminderEmail: 66 | HeadingTitle: Naslov 67 | WorkflowReminderTask: 68 | SAVE: Spremi 69 | WorkflowTransition: 70 | TYPE: Tip 71 | -------------------------------------------------------------------------------- /lang/ru.yml: -------------------------------------------------------------------------------- 1 | ru: 2 | AdvancedWorkflowAdmin: 3 | Title: Заголовок 4 | AllowEditing: 5 | NoString: Нет 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Группы 8 | USERS: Пользователи 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: 'Тема письма' 11 | FORMATTINGHELP: 'Справка по форматированию' 12 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 13 | many_many_Groups: Группы 14 | many_many_Users: Пользователи 15 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 16 | db_EmailSubject: 'Тема письма' 17 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 18 | db_Content: Содержимое 19 | db_Filename: 'Имя файла' 20 | db_Name: Название 21 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 22 | db_Comment: Комментарий 23 | db_Sort: Сортировать 24 | db_Title: Заголовок 25 | db_Type: Тип 26 | has_one_Member: Пользователь 27 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 28 | db_Comment: Комментарий 29 | has_one_Member: Пользователь 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 31 | db_Description: Описание 32 | db_Sort: Сортировать 33 | db_Title: Заголовок 34 | has_many_Actions: Действия 35 | many_many_Groups: Группы 36 | many_many_Users: Пользователи 37 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 38 | db_Title: Заголовок 39 | has_many_Actions: Действия 40 | many_many_Groups: Группы 41 | many_many_Users: Пользователи 42 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 43 | db_Sort: Сортировать 44 | db_Title: Заголовок 45 | db_Type: Тип 46 | many_many_Groups: Группы 47 | many_many_Users: Пользователи 48 | WorkflowAction: 49 | Author: Автор 50 | COMMENT: Комментарий 51 | CommentLabel: Комментарий 52 | FRONTENDCOMMENT: Комментарий 53 | TITLE: Заголовок 54 | TypeLabel: Тип 55 | WorkflowActionInstance: 56 | Title: Заголовок 57 | WorkflowDefinition: 58 | DESCRIPTION: Описание 59 | TITLE: Заголовок 60 | WorkflowField: 61 | CreateLabel: Создать 62 | DeleteAction: Удалить 63 | EditAction: Редактировать 64 | WorkflowInstance: 65 | TitleLabel: Заголовок 66 | WorkflowList: 67 | TableHeaderActions: Действия 68 | WorkflowReminderEmail: 69 | HeadingTitle: Заголовок 70 | WorkflowReminderTask: 71 | SAVE: Сохранить 72 | WorkflowTransition: 73 | TYPE: Тип 74 | -------------------------------------------------------------------------------- /src/FormFields/WorkflowFieldTransitionController.php: -------------------------------------------------------------------------------- 1 | 'handleAdd', 19 | 'item/$ID!' => 'handleItem' 20 | ); 21 | 22 | private static $allowed_actions = array( 23 | 'handleAdd', 24 | 'handleItem' 25 | ); 26 | 27 | protected $parent; 28 | protected $name; 29 | 30 | public function __construct($parent, $name) 31 | { 32 | $this->parent = $parent; 33 | $this->name = $name; 34 | 35 | parent::__construct(); 36 | } 37 | 38 | public function handleAdd() 39 | { 40 | $parent = $this->request->param('ParentID'); 41 | $action = WorkflowAction::get()->byID($this->request->param('ParentID')); 42 | 43 | if (!$action || $action->WorkflowDefID != $this->RootField()->Definition()->ID) { 44 | $this->httpError(404); 45 | } 46 | 47 | if (!singleton(WorkflowTransition::class)->canCreate()) { 48 | $this->httpError(403); 49 | } 50 | 51 | $transition = new WorkflowTransition(); 52 | $transition->ActionID = $action->ID; 53 | 54 | return new WorkflowFieldItemController($this, "new/$parent", $transition); 55 | } 56 | 57 | public function handleItem() 58 | { 59 | $id = $this->request->param('ID'); 60 | $trans = WorkflowTransition::get()->byID($id); 61 | 62 | if (!$trans || $trans->Action()->WorkflowDefID != $this->RootField()->Definition()->ID) { 63 | $this->httpError(404); 64 | } 65 | 66 | if (!$trans->canEdit()) { 67 | $this->httpError(403); 68 | } 69 | 70 | return new WorkflowFieldItemController($this, "item/$id", $trans); 71 | } 72 | 73 | public function RootField() 74 | { 75 | return $this->parent; 76 | } 77 | 78 | public function Link($action = null) 79 | { 80 | return Controller::join_links($this->parent->Link(), $this->name, $action); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lang/sv.yml: -------------------------------------------------------------------------------- 1 | sv: 2 | AdvancedWorkflowAdmin: 3 | Title: Titel 4 | AllowEditing: 5 | NoString: Nej 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Grupper 8 | USERS: Användare 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: E-postämne 11 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 12 | many_many_Groups: Grupper 13 | many_many_Users: Användare 14 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 15 | db_EmailSubject: E-postämne 16 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 17 | db_Value: Värde 18 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 19 | db_Content: Innehåll 20 | db_Filename: Filnamn 21 | db_Name: Namn 22 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 23 | db_Comment: Kommentar 24 | db_Sort: Sortera 25 | db_Title: Titel 26 | db_Type: Typ 27 | has_one_Member: Medlem 28 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 29 | db_Comment: Kommentar 30 | db_Finished: Slutförd 31 | has_one_Member: Medlem 32 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 33 | db_Description: Beskrivning 34 | db_Sort: Sortera 35 | db_Title: Titel 36 | has_many_Actions: Åtgärder 37 | many_many_Groups: Grupper 38 | many_many_Users: Användare 39 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 40 | db_Title: Titel 41 | has_many_Actions: Åtgärder 42 | many_many_Groups: Grupper 43 | many_many_Users: Användare 44 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 45 | db_Sort: Sortera 46 | db_Title: Titel 47 | db_Type: Typ 48 | many_many_Groups: Grupper 49 | many_many_Users: Användare 50 | WorkflowAction: 51 | Author: Författare 52 | COMMENT: Kommentar 53 | CommentLabel: Kommentar 54 | FRONTENDCOMMENT: Kommentar 55 | FinishedLabel: Slutförd 56 | TITLE: Titel 57 | TypeLabel: Typ 58 | WorkflowActionInstance: 59 | Title: Titel 60 | WorkflowDefinition: 61 | DESCRIPTION: Beskrivning 62 | TITLE: Titel 63 | WorkflowEmbargoExpiryExtension: 64 | BADGE_UNPUBLISH: 'Går ut' 65 | WorkflowField: 66 | CreateLabel: Skapa 67 | DeleteAction: Radera 68 | EditAction: Ändra 69 | WorkflowInstance: 70 | TitleLabel: Titel 71 | WorkflowList: 72 | TableHeaderActions: Åtgärder 73 | WorkflowReminderEmail: 74 | HeadingTitle: Titel 75 | WorkflowReminderTask: 76 | SAVE: Spara 77 | WorkflowTransition: 78 | TYPE: Typ 79 | -------------------------------------------------------------------------------- /lang/sl.yml: -------------------------------------------------------------------------------- 1 | sl: 2 | AdvancedWorkflowAdmin: 3 | Title: Naziv 4 | AllowEditing: 5 | NoString: Ne 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Skupine 8 | USERS: Uporabniki 9 | NotifyUsersWorkflowAction: 10 | EMAILFROM: 'Pošiljatelj e-sporočila' 11 | EMAILSUBJECT: 'Predmet e-sporočila' 12 | EMAILTEMPLATE: 'Predloga e-sporočila' 13 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 14 | many_many_Groups: Skupine 15 | many_many_Users: Uporabniki 16 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 17 | db_EmailFrom: 'Pošiljatelj e-sporočila' 18 | db_EmailSubject: 'Predmet e-sporočila' 19 | db_EmailTemplate: 'Predloga e-sporočila' 20 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 21 | db_Value: Vrednost 22 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 23 | db_Content: Vsebina 24 | db_Filename: 'Ime datoteke' 25 | db_Name: Ime 26 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 27 | db_Sort: Razvrščanje 28 | db_Title: Naziv 29 | db_Type: Tip 30 | has_one_Member: Uporabnik 31 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 32 | has_one_Member: Uporabnik 33 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 34 | db_Description: Opis 35 | db_Sort: Razvrščanje 36 | db_Title: Naziv 37 | has_many_Actions: Dejanja 38 | many_many_Groups: Skupine 39 | many_many_Users: Uporabniki 40 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 41 | db_Title: Naziv 42 | has_many_Actions: Dejanja 43 | many_many_Groups: Skupine 44 | many_many_Users: Uporabniki 45 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 46 | db_Sort: Razvrščanje 47 | db_Title: Naziv 48 | db_Type: Tip 49 | many_many_Groups: Skupine 50 | many_many_Users: Uporabniki 51 | Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable: 52 | has_one_WorkflowDefinition: 'Definicija uredniškega procesa' 53 | many_many_AdditionalWorkflowDefinitions: 'Dodatne definicije uredniških procesov' 54 | WorkflowAction: 55 | Author: Avtor 56 | TITLE: Naziv 57 | TypeLabel: Tip 58 | WorkflowActionInstance: 59 | Title: Naziv 60 | WorkflowDefinition: 61 | DESCRIPTION: Opis 62 | TITLE: Naziv 63 | WorkflowField: 64 | CreateLabel: Ustvari 65 | DeleteAction: Odstrani 66 | EditAction: Uredi 67 | WorkflowInstance: 68 | TitleLabel: Naziv 69 | WorkflowList: 70 | TableHeaderActions: Dejanja 71 | WorkflowReminderEmail: 72 | HeadingTitle: Naziv 73 | WorkflowReminderTask: 74 | SAVE: Shrani 75 | WorkflowTransition: 76 | TYPE: Tip 77 | -------------------------------------------------------------------------------- /src/Controllers/AdvancedWorkflowActionController.php: -------------------------------------------------------------------------------- 1 | request->requestVar('id'); 35 | $transitionID = (int) $this->request->requestVar('transition'); 36 | 37 | $instance = WorkflowInstance::get()->setUseCache(true)->byID((int) $id); 38 | if ($instance && $instance->canEdit()) { 39 | $transitionExists = WorkflowTransition::get()->setUseCache(true)->filter('ID', $transitionID)->exists(); 40 | if ($transitionExists) { 41 | if ($this->request->requestVar('comments')) { 42 | $action = $instance->CurrentAction(); 43 | $action->Comment = $this->request->requestVar('comments'); 44 | $action->write(); 45 | } 46 | 47 | singleton(WorkflowService::class)->executeTransition($instance->getTarget(), $transitionID); 48 | $result = array( 49 | 'success' => true, 50 | 'link' => $instance->getTarget()->AbsoluteLink() 51 | ); 52 | if (Director::is_ajax()) { 53 | return json_encode($result); 54 | } 55 | return $this->redirect($instance->getTarget()->Link()); 56 | } 57 | } 58 | 59 | if (Director::is_ajax()) { 60 | $result = array( 61 | 'success' => false, 62 | ); 63 | return json_encode($result); 64 | } 65 | 66 | return $this->redirect($instance->getTarget()->Link()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lang/sk.yml: -------------------------------------------------------------------------------- 1 | sk: 2 | AdvancedWorkflowAdmin: 3 | Title: Názov 4 | AllowEditing: 5 | NoString: ' Nie' 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Skupiny 8 | USERS: Používatelia 9 | NotifyUsersWorkflowAction: 10 | EMAILSUBJECT: Predmet 11 | EMAILTEMPLATE: 'E-mailová šablóna' 12 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 13 | many_many_Groups: Skupiny 14 | many_many_Users: Používatelia 15 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 16 | db_EmailSubject: Predmet 17 | db_EmailTemplate: 'E-mailová šablóna' 18 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 19 | db_Value: Hodnota 20 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 21 | db_Content: Obsah 22 | db_Filename: 'Meno súboru' 23 | db_Name: Meno 24 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 25 | db_Comment: Komentár 26 | db_Sort: Usporiadanie 27 | db_Title: Názov 28 | db_Type: Typ 29 | has_one_Member: Člen 30 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 31 | db_Comment: Komentár 32 | has_one_Member: Člen 33 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 34 | db_Description: Popis 35 | db_Sort: Usporiadanie 36 | db_Title: Názov 37 | has_many_Actions: Akcie 38 | many_many_Groups: Skupiny 39 | many_many_Users: Používatelia 40 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 41 | db_Title: Názov 42 | has_many_Actions: Akcie 43 | many_many_Groups: Skupiny 44 | many_many_Users: Používatelia 45 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 46 | db_Sort: Usporiadanie 47 | db_Title: Názov 48 | db_Type: Typ 49 | many_many_Groups: Skupiny 50 | many_many_Users: Používatelia 51 | Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable: 52 | has_one_WorkflowDefinition: 'Definícia pracovného toku' 53 | many_many_AdditionalWorkflowDefinitions: 'Ďalšie definície pracovného toku' 54 | WorkflowAction: 55 | Author: Autor 56 | COMMENT: Komentár 57 | CommentLabel: Komentár 58 | FRONTENDCOMMENT: Komentár 59 | TITLE: Názov 60 | TypeLabel: Typ 61 | WorkflowActionInstance: 62 | Title: Názov 63 | WorkflowDefinition: 64 | DESCRIPTION: Popis 65 | TITLE: Názov 66 | WorkflowField: 67 | CreateLabel: Vytvoriť 68 | DeleteAction: Vymazať 69 | EditAction: Editovať 70 | WorkflowInstance: 71 | TitleLabel: Názov 72 | WorkflowList: 73 | TableHeaderActions: Akcie 74 | WorkflowReminderEmail: 75 | HeadingTitle: Názov 76 | WorkflowReminderTask: 77 | SAVE: Uložiť 78 | WorkflowTransition: 79 | TYPE: Typ 80 | -------------------------------------------------------------------------------- /lang/nl.yml: -------------------------------------------------------------------------------- 1 | nl: 2 | AdvancedWorkflowAdmin: 3 | Title: Titel 4 | AllowEditing: 5 | NoString: Nee 6 | AssignUsersToWorkflowAction: 7 | GROUPS: Groepen 8 | USERS: Gebruikers 9 | NotifyUsersWorkflowAction: 10 | EMAILFROM: 'E-mail van' 11 | EMAILSUBJECT: E-mailonderwerp 12 | EMAILTEMPLATE: E-mailtemplate 13 | FORMATTINGHELP: 'Hulp met opmaak' 14 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 15 | many_many_Groups: Groepen 16 | many_many_Users: Gebruikers 17 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 18 | db_EmailFrom: 'E-mail van' 19 | db_EmailSubject: E-mailonderwerp 20 | db_EmailTemplate: E-mailtemplate 21 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 22 | db_Value: Waarde 23 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 24 | db_Content: Inhoud 25 | db_Filename: 'Bestandsnaam ' 26 | db_Name: Naam 27 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 28 | db_Comment: Reactie 29 | db_Sort: Volgorde 30 | db_Title: Titel 31 | db_Type: 'Soort veld' 32 | has_one_Member: Lid 33 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 34 | db_Comment: Reactie 35 | has_one_Member: Lid 36 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 37 | db_Description: Omschrijving 38 | db_Sort: Volgorde 39 | db_Title: Titel 40 | has_many_Actions: Acties 41 | many_many_Groups: Groepen 42 | many_many_Users: Gebruikers 43 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 44 | db_Title: Titel 45 | has_many_Actions: Acties 46 | many_many_Groups: Groepen 47 | many_many_Users: Gebruikers 48 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 49 | db_Sort: Volgorde 50 | db_Title: Titel 51 | db_Type: 'Soort veld' 52 | many_many_Groups: Groepen 53 | many_many_Users: Gebruikers 54 | Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable: 55 | has_one_WorkflowDefinition: 'Workflow definitie' 56 | many_many_AdditionalWorkflowDefinitions: 'Aanvullende workflow definities' 57 | WorkflowAction: 58 | Author: Auteur 59 | COMMENT: Reactie 60 | CommentLabel: Reactie 61 | FRONTENDCOMMENT: Reactie 62 | TITLE: Titel 63 | TypeLabel: 'Soort veld' 64 | WorkflowActionInstance: 65 | Title: Titel 66 | WorkflowDefinition: 67 | DESCRIPTION: Omschrijving 68 | TITLE: Titel 69 | WorkflowField: 70 | CreateLabel: Aanmaken 71 | DeleteAction: Verwijder 72 | EditAction: Bewerken 73 | WorkflowInstance: 74 | TitleLabel: Titel 75 | WorkflowList: 76 | TableHeaderActions: Acties 77 | WorkflowReminderEmail: 78 | HeadingTitle: Titel 79 | WorkflowReminderTask: 80 | SAVE: Opslaan 81 | WorkflowTransition: 82 | TYPE: 'Soort veld' 83 | -------------------------------------------------------------------------------- /lang/id.yml: -------------------------------------------------------------------------------- 1 | id: 2 | AdvancedWorkflowAdmin: 3 | LastEdited: Diubah 4 | Title: Judul 5 | AllowEditing: 6 | NoString: Tidak 7 | AssignUsersToWorkflowAction: 8 | GROUPS: Grup 9 | USERS: Pengguna 10 | NotifyUsersWorkflowAction: 11 | EMAILFROM: 'Surel dari' 12 | EMAILSUBJECT: 'Judul surel' 13 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 14 | many_many_Groups: Kelompok 15 | many_many_Users: Pengguna 16 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 17 | db_EmailFrom: 'Surel dari' 18 | db_EmailSubject: 'Subyek email' 19 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 20 | db_Value: Nilai 21 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 22 | db_Content: Konten 23 | db_Filename: 'Nama berkas' 24 | db_Name: Nama 25 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 26 | db_Comment: Komentar 27 | db_Title: Judul 28 | db_Type: Tipe 29 | has_many_Transitions: Transisi 30 | has_one_Member: Pengguna 31 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 32 | db_Comment: Komentar 33 | has_one_Member: Pengguna 34 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 35 | db_Description: Deskripsi 36 | db_Title: Judul 37 | has_many_Actions: Tindakan 38 | many_many_Groups: Kelompok 39 | many_many_Users: Pengguna 40 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 41 | db_Title: Judul 42 | has_many_Actions: Tindakan 43 | many_many_Groups: Kelompok 44 | many_many_Users: Pengguna 45 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 46 | db_Title: Judul 47 | db_Type: Tipe 48 | has_one_Action: Aksi 49 | many_many_Groups: Kelompok 50 | many_many_Users: Pengguna 51 | Symbiote\AdvancedWorkflow\Forms\GridField\GridFieldExportAction: 52 | Export: Ekspor 53 | UnpublishItemWorkflowAction: 54 | DELAYUNPUBDAYSAFTER: hari 55 | WorkflowAction: 56 | Author: Pengarang 57 | COMMENT: Komentar 58 | CommentLabel: Komentar 59 | FRONTENDCOMMENT: Komentar 60 | TITLE: Judul 61 | Transitions: Transisi 62 | TypeLabel: Tipe 63 | WorkflowActionInstance: 64 | Title: Judul 65 | WorkflowDefinition: 66 | DESCRIPTION: Deskripsi 67 | TITLE: Judul 68 | WorkflowEmbargoExpiryExtension: 69 | ActiveWorkflowStateTitle: Aktif 70 | WorkflowField: 71 | CreateLabel: Buat 72 | DeleteAction: Hapus 73 | WorkflowInstance: 74 | TitleLabel: Judul 75 | WorkflowList: 76 | TableHeaderActions: Tindakan 77 | WorkflowReminderEmail: 78 | HeadingTitle: Judul 79 | WorkflowReminderTask: 80 | SAVE: Simpan 81 | WorkflowTransition: 82 | ACTION: Aksi 83 | Active: Aktif 84 | Passive: Pasiv 85 | SELECTONE: '(Pilih satu)' 86 | TYPE: Tipe 87 | -------------------------------------------------------------------------------- /lang/fi_FI.yml: -------------------------------------------------------------------------------- 1 | fi_FI: 2 | AdvancedWorkflow: 3 | ADVANCED_WORKFLOW: 'Edistynyt työnkulku' 4 | APPLY_WORKFLOW: 'Ota työnkulku käyttöön' 5 | CREATE_WORKFLOW: 'Luo työnkulku' 6 | DELETE_WORKFLOW: 'Poista työnkulku' 7 | REASSIGNACTIVE: 'Vastuuta uudelleen aktiiviset työnkulut' 8 | VIEWACTIVE: 'Näytä aktiiviset työnkulut' 9 | AdvancedWorkflowAdmin: 10 | GridFieldTitleAssignedAll: 'Kaikki odottavat kohteet' 11 | LastEdited: Muokattu 12 | Title: Otsikko 13 | AllowEditing: 14 | NoString: Ei 15 | AssignUsersToWorkflowAction: 16 | GROUPS: Ryhmät 17 | NotifyUsersWorkflowAction: 18 | EMAILSUBJECT: Otsikko 19 | EMAILTEMPLATE: Sähköpostipohja 20 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 21 | many_many_Groups: Ryhmät 22 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 23 | PLURALNAME: 'Informoi käyttäjiä työnkulun toiminnoista' 24 | db_EmailSubject: Otsikko 25 | db_EmailTemplate: Sähköpostipohja 26 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 27 | db_Value: Arvo 28 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 29 | db_Content: Sisältö 30 | db_Name: Nimi 31 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 32 | db_Title: Otsikko 33 | db_Type: Tyyppi 34 | has_one_Member: Käyttäjä 35 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 36 | db_Finished: Valmistunut 37 | has_one_Member: Käyttäjä 38 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 39 | db_Description: Kuvaus 40 | db_Title: Otsikko 41 | has_many_Actions: Toimenpiteet 42 | many_many_Groups: Ryhmät 43 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 44 | db_Title: Otsikko 45 | has_many_Actions: Toimenpiteet 46 | many_many_Groups: Ryhmät 47 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 48 | db_Title: Otsikko 49 | db_Type: Tyyppi 50 | many_many_Groups: Ryhmät 51 | WorkflowAction: 52 | Author: Tekijä 53 | FinishedLabel: Valmistunut 54 | TITLE: Otsikko 55 | TypeLabel: Tyyppi 56 | WorkflowActionInstance: 57 | Title: Otsikko 58 | WorkflowDefinition: 59 | DESCRIPTION: Kuvaus 60 | TITLE: Otsikko 61 | WorkflowEmbargoExpiryExtension: 62 | ActiveWorkflowStateTitle: Aktiivinen 63 | CompletedWorkflowStateTitle: Valmistunut 64 | WorkflowField: 65 | CreateLabel: Luo 66 | DeleteAction: Poista 67 | EditAction: Muokkaa 68 | WorkflowInstance: 69 | ActionLogTitle: Loki 70 | TargetClassLabel: Kohdeluokka 71 | TargetIDLabel: Kohde 72 | TitleLabel: Otsikko 73 | WorkflowList: 74 | TableHeaderActions: Toimenpiteet 75 | TableHeaderSubmitted: Lähetetty 76 | WorkflowReminderEmail: 77 | HeadingTitle: Otsikko 78 | WorkflowReminderTask: 79 | SAVE: Tallenna 80 | WorkflowTransition: 81 | Active: Aktiivinen 82 | NEXT_ACTION: 'Seuraava toimenpide' 83 | Passive: Passiivinen 84 | TYPE: Tyyppi 85 | -------------------------------------------------------------------------------- /lang/pt_BR.yml: -------------------------------------------------------------------------------- 1 | pt_BR: 2 | AdvancedWorkflow: 3 | ADVANCED_WORKFLOW: 'Workflow avançado' 4 | APPLY_WORKFLOW: 'Aplicar workflow' 5 | APPLY_WORKFLOW_HELP: 'Os usuários podem aplicar workflow aos itens' 6 | CREATE_WORKFLOW: 'Criar workflow' 7 | CREATE_WORKFLOW_HELP: 'Os usuários podem criar definições de workflow' 8 | DELETE_WORKFLOW: 'Apagar workflow' 9 | DELETE_WORKFLOW_HELP: 'Os usuários podem excluir definições de workflow e workflows ativos' 10 | REASSIGNACTIVE: 'Reatribuir workflows ativos' 11 | VIEWACTIVE: 'Exibir workflows ativos' 12 | AdvancedWorkflowActionController: 13 | ACTION_ERROR: 'Você precisa estar logado' 14 | AdvancedWorkflowAdmin: 15 | GridFieldTitleAssignedAll: 'Todos os itens pendentes' 16 | GridFieldTitleAssignedYour: 'Seus itens pendentes' 17 | IMPORT: 'Importar workflow' 18 | LastEdited: Alterado 19 | Title: Título 20 | WorkflowStatus: 'Ação atual' 21 | AllowEditing: 22 | ContentSettings: 'Configurações de conteúdo' 23 | NoString: Não 24 | AssignUsersToWorkflowAction: 25 | ASSIGNUSERS: 'Atribuir usuários' 26 | GROUPS: Grupos 27 | USERS: Usuários 28 | FrontEndWorkflowController: 29 | FRONTENDACTION_TRANSITION_EXCEPTION: 'Você não tem permissão para executar esta ação' 30 | NotifyUsersWorkflowAction: 31 | EMAILFROM: 'Email de' 32 | EMAILSUBJECT: 'Assunto do email' 33 | FIELDNAME: 'Nome do campo' 34 | SetPropertyWorkflowAction: 35 | PROPERTY: Propriedade 36 | Symbiote\AdvancedWorkflow\Actions\AssignUsersToWorkflowAction: 37 | many_many_Groups: Grupos 38 | many_many_Users: Usuários 39 | Symbiote\AdvancedWorkflow\Actions\NotifyUsersWorkflowAction: 40 | db_EmailFrom: 'Email de' 41 | db_EmailSubject: 'Assunto do email' 42 | Symbiote\AdvancedWorkflow\Actions\SetPropertyWorkflowAction: 43 | db_Property: Propriedade 44 | Symbiote\AdvancedWorkflow\DataObjects\ImportedWorkflowTemplate: 45 | db_Content: Conteúdo 46 | db_Filename: 'Nome do Arquivo' 47 | db_Name: Nome 48 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction: 49 | db_Title: Título 50 | has_one_Member: Membro 51 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowActionInstance: 52 | has_one_Member: Membro 53 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition: 54 | db_Description: Descrição 55 | db_Title: Título 56 | many_many_Groups: Grupos 57 | many_many_Users: Usuários 58 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance: 59 | db_Title: Título 60 | has_one_CurrentAction: 'Ação atual' 61 | many_many_Groups: Grupos 62 | many_many_Users: Usuários 63 | Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition: 64 | db_Title: Título 65 | many_many_Groups: Grupos 66 | many_many_Users: Usuários 67 | WorkflowAction: 68 | Author: Autor 69 | TITLE: Título 70 | WorkflowActionInstance: 71 | Title: Título 72 | WorkflowDefinition: 73 | DESCRIPTION: Descrição 74 | TITLE: Título 75 | WorkflowField: 76 | DeleteAction: Excluir 77 | WorkflowInstance: 78 | TitleLabel: Título 79 | WorkflowReminderEmail: 80 | HeadingTitle: Título 81 | WorkflowReminderTask: 82 | SAVE: Salvar 83 | -------------------------------------------------------------------------------- /src/Tasks/WorkflowReminderTask.php: -------------------------------------------------------------------------------- 1 | count()) { // Don't attempt the filter if no instances -- prevents a crash 32 | $active = WorkflowInstance::get() 33 | ->innerJoin('WorkflowDefinition', '"DefinitionID" = "WorkflowDefinition"."ID"') 34 | ->filter(array( 35 | 'WorkflowStatus' => array('Active', 'Paused') 36 | ))->where('RemindDays > 0'); 37 | 38 | if ($active->exists()) { 39 | foreach ($active as $instance) { 40 | $edited = strtotime($instance->LastEdited ?? ''); 41 | $days = $instance->Definition()->RemindDays; 42 | 43 | if ($edited + $days * 3600 * 24 > DBDatetime::now()->getTimestamp()) { 44 | continue; 45 | } 46 | 47 | $email = new Email(); 48 | $bcc = ''; 49 | $members = $instance->getAssignedMembers(); 50 | $target = $instance->getTarget(); 51 | 52 | if (!$members || !count($members ?? [])) { 53 | continue; 54 | } 55 | 56 | $email->setSubject("Workflow Reminder: $instance->Title"); 57 | $email->setBCC($members->column('Email')); 58 | $email->setHTMLTemplate('email\\WorkflowReminderEmail'); 59 | $email->setData(array( 60 | 'Instance' => $instance, 61 | 'Link' => $target instanceof SiteTree ? "admin/show/$target->ID" : '', 62 | 'Diff' => $instance->getTargetDiff() 63 | )); 64 | 65 | $email->send(); 66 | 67 | 68 | $sent++; 69 | 70 | $instance->LastEdited = DBDatetime::now()->getTimestamp(); 71 | $instance->write(); 72 | } 73 | } 74 | } 75 | $output->writeln("Sent $sent workflow reminder emails."); 76 | return Command::SUCCESS; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/FormFields/WorkflowFieldActionController.php: -------------------------------------------------------------------------------- 1 | 'handleAdd', 19 | 'item/$ID' => 'handleItem' 20 | ); 21 | 22 | private static $allowed_actions = array( 23 | 'handleAdd', 24 | 'handleItem' 25 | ); 26 | 27 | protected $parent; 28 | protected $name; 29 | 30 | public function __construct($parent, $name) 31 | { 32 | $this->parent = $parent; 33 | $this->name = $name; 34 | 35 | parent::__construct(); 36 | } 37 | 38 | public function handleAdd() 39 | { 40 | $class = $this->unsanitiseClassName($this->request->param('Class')); 41 | 42 | if (!class_exists($class ?? '') || !is_subclass_of($class, WorkflowAction::class)) { 43 | $this->httpError(400); 44 | } 45 | 46 | $reflector = new ReflectionClass($class); 47 | 48 | if ($reflector->isAbstract() || !singleton($class)->canCreate()) { 49 | $this->httpError(400); 50 | } 51 | 52 | $record = new $class(); 53 | $record->WorkflowDefID = $this->parent->Definition()->ID; 54 | 55 | return new WorkflowFieldItemController( 56 | $this, 57 | Controller::join_links('new', $this->sanitiseClassName($class)), 58 | $record 59 | ); 60 | } 61 | 62 | public function handleItem() 63 | { 64 | $id = $this->request->param('ID'); 65 | $defn = $this->parent->Definition(); 66 | $action = $defn->Actions()->byID($id); 67 | 68 | if (!$action) { 69 | $this->httpError(404); 70 | } 71 | 72 | if (!$action->canEdit()) { 73 | $this->httpError(403); 74 | } 75 | 76 | return new WorkflowFieldItemController($this, "item/$id", $action); 77 | } 78 | 79 | public function RootField() 80 | { 81 | return $this->parent; 82 | } 83 | 84 | public function Link($action = null) 85 | { 86 | return Controller::join_links($this->parent->Link(), $this->name, $action); 87 | } 88 | 89 | /** 90 | * Sanitise a model class' name for inclusion in a link 91 | * 92 | * @param string $class 93 | * @return string 94 | */ 95 | protected function sanitiseClassName($class) 96 | { 97 | return str_replace('\\', '-', $class ?? ''); 98 | } 99 | 100 | /** 101 | * Unsanitise a model class' name from a URL param 102 | * 103 | * @param string $class 104 | * @return string 105 | */ 106 | protected function unsanitiseClassName($class) 107 | { 108 | return str_replace('-', '\\', $class ?? ''); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/FormFields/WorkflowFieldItemController.php: -------------------------------------------------------------------------------- 1 | parent = $parent; 32 | $this->name = $name; 33 | $this->record = $record; 34 | 35 | parent::__construct(); 36 | } 37 | 38 | public function index() 39 | { 40 | return $this->edit(); 41 | } 42 | 43 | public function edit() 44 | { 45 | return $this->Form()->forTemplate(); 46 | } 47 | 48 | public function Form() 49 | { 50 | $record = $this->record; 51 | $fields = $record->getCMSFields(); 52 | $validator = $record->hasMethod('getValidator') ? $record->getValidator() : null; 53 | 54 | $save = FormAction::create('doSave', _t('WorkflowReminderTask.SAVE', 'Save')); 55 | $save->addExtraClass('btn btn-primary') 56 | ->setIcon('save') 57 | ->setUseButtonTag(true); 58 | 59 | $form = Form::create($this, 'Form', $fields, FieldList::create($save), $validator); 60 | if ($record && $record instanceof DataObject && $record->exists()) { 61 | $form->loadDataFrom($record); 62 | } 63 | return $form; 64 | } 65 | 66 | public function doSave($data, $form) 67 | { 68 | $record = $form->getRecord(); 69 | 70 | if (!$record || !$record->exists()) { 71 | $record = $this->record; 72 | } 73 | 74 | if (!$record->canEdit()) { 75 | $this->httpError(403); 76 | } 77 | 78 | if (!$record->isInDb()) { 79 | $record->write(); 80 | } 81 | 82 | $form->saveInto($record); 83 | $record->write(); 84 | 85 | return $this->RootField()->forTemplate(); 86 | } 87 | 88 | public function delete($request) 89 | { 90 | if (!SecurityToken::inst()->checkRequest($request)) { 91 | $this->httpError(400); 92 | } 93 | 94 | if (!$request->isPOST()) { 95 | $this->httpError(400); 96 | } 97 | 98 | if (!$this->record->canDelete()) { 99 | $this->httpError(403); 100 | } 101 | 102 | $this->record->delete(); 103 | return $this->RootField()->forTemplate(); 104 | } 105 | 106 | public function RootField() 107 | { 108 | return $this->parent->RootField(); 109 | } 110 | 111 | public function Link($action = null) 112 | { 113 | return Controller::join_links($this->parent->Link(), $this->name, $action); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Actions/UnpublishItemWorkflowAction.php: -------------------------------------------------------------------------------- 1 | 'Int' 28 | ); 29 | 30 | private static $icon = 'symbiote/silverstripe-advancedworkflow:images/unpublish.png'; 31 | 32 | private static $table_name = 'UnpublishItemWorkflowAction'; 33 | 34 | public function execute(WorkflowInstance $workflow) 35 | { 36 | if (!$target = $workflow->getTarget()) { 37 | return true; 38 | } 39 | 40 | if (class_exists(AbstractQueuedJob::class) && $this->UnpublishDelay) { 41 | $job = new WorkflowPublishTargetJob($target, "unpublish"); 42 | $days = $this->UnpublishDelay; 43 | $after = date('Y-m-d H:i:s', strtotime("+$days days")); 44 | singleton(QueuedJobService::class)->queueJob($job, $after); 45 | } elseif ($target->hasExtension(WorkflowEmbargoExpiryExtension::class)) { 46 | // setting future date stuff if needbe 47 | 48 | // set these values regardless 49 | $target->DesiredUnPublishDate = ''; 50 | $target->DesiredPublishDate = ''; 51 | $target->write(); 52 | 53 | if ($target->hasMethod('doUnpublish')) { 54 | $target->doUnpublish(); 55 | } 56 | } else { 57 | if ($target->hasMethod('doUnpublish')) { 58 | $target->doUnpublish(); 59 | } 60 | } 61 | 62 | return true; 63 | } 64 | 65 | public function getCMSFields() 66 | { 67 | $fields = parent::getCMSFields(); 68 | 69 | if (class_exists(AbstractQueuedJob::class)) { 70 | $before = _t('UnpublishItemWorkflowAction.DELAYUNPUBDAYSBEFORE', 'Delay unpublishing by '); 71 | $after = _t('UnpublishItemWorkflowAction.DELAYUNPUBDAYSAFTER', ' days'); 72 | 73 | $fields->addFieldToTab('Root.Main', new FieldGroup( 74 | _t('UnpublishItemWorkflowAction.UNPUBLICATIONDELAY', 'Delay Un-publishing'), 75 | new LabelField('UnpublishDelayBefore', $before), 76 | new NumericField('UnpublishDelay', ''), 77 | new LabelField('UnpublishDelayAfter', $after) 78 | )); 79 | } 80 | 81 | return $fields; 82 | } 83 | 84 | /** 85 | * @param DataObject $target 86 | * @return bool 87 | */ 88 | public function canPublishTarget(DataObject $target) 89 | { 90 | return false; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Forms/gridfield/GridFieldWorkflowRestrictedEditButton.php: -------------------------------------------------------------------------------- 1 | 'col-buttons'); 48 | if ($record instanceof WorkflowInstance) { 49 | $isAdmin = Permission::check('ADMIN'); 50 | $isAssigned = $record->getAssignedMembers()->find('ID', Security::getCurrentUser()->ID); 51 | if (!$isAdmin && !$isAssigned) { 52 | $atts['class'] = $defaultAtts['class'].' disabled'; 53 | return $atts; 54 | } 55 | return $defaultAtts; 56 | } 57 | return $defaultAtts; 58 | } 59 | 60 | /** 61 | * Add the title 62 | * 63 | * @param GridField $gridField 64 | * @param string $columnName 65 | * @return array 66 | */ 67 | public function getColumnMetadata($gridField, $columnName) 68 | { 69 | if ($columnName == 'Actions') { 70 | return array('title' => ''); 71 | } 72 | } 73 | 74 | /** 75 | * Which columns are handled by this component 76 | * 77 | * @param type $gridField 78 | * @return type 79 | */ 80 | public function getColumnsHandled($gridField) 81 | { 82 | return array('Actions'); 83 | } 84 | 85 | /** 86 | * @param GridField $gridField 87 | * @param DataObject $record 88 | * @param string $columnName 89 | * 90 | * @return string - the HTML for the column 91 | */ 92 | public function getColumnContent($gridField, $record, $columnName) 93 | { 94 | $data = new ArrayData(array( 95 | 'Link' => Controller::join_links($gridField->Link('item'), $record->ID, 'edit') 96 | )); 97 | return $data->renderWith(GridFieldEditButton::class); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/Extensions/FileWorkflowApplicable.php: -------------------------------------------------------------------------------- 1 | owner->ID) { 29 | return $fields; 30 | } 31 | parent::updateCMSFields($fields); 32 | 33 | // add the workflow fields directly. It's a requirement of workflow on file objects 34 | // that CMS admins mark the workflow step as being editable for files to be administerable 35 | $active = $this->getWorkflowService()->getWorkflowFor($this->owner); 36 | if ($active) { 37 | $current = $active->CurrentAction(); 38 | $wfFields = $active->getWorkflowFields(); 39 | 40 | // loading data in a somewhat hack way 41 | $form = new Form($this, 'DummyForm', $wfFields, new FieldList()); 42 | $form->loadDataFrom($current); 43 | 44 | $fields->findOrMakeTab( 45 | 'Root.WorkflowActions', 46 | _t('Workflow.WorkflowActionsTabTitle', 'Workflow Actions') 47 | ); 48 | $fields->addFieldsToTab('Root.WorkflowActions', $wfFields->toArray()); 49 | } 50 | } 51 | 52 | protected function onAfterWrite() 53 | { 54 | parent::onAfterWrite(); 55 | 56 | $workflow = $this->getWorkflowService()->getWorkflowFor($this->owner); 57 | $rawData = $this->owner->toMap(); 58 | if ($workflow && $this->owner->TransitionID) { 59 | // we want to transition, so do so if that's a valid transition to take. 60 | $action = $workflow->CurrentAction(); 61 | if (!$this->canEditWorkflow()) { 62 | return; 63 | } 64 | 65 | $allowedFields = $workflow->getWorkflowFields()->saveableFields(); 66 | unset($allowedFields['TransitionID']); 67 | 68 | $allowed = array_keys($allowedFields ?? []); 69 | 70 | foreach ($allowed as $field) { 71 | if (isset($rawData[$field])) { 72 | $action->$field = $rawData[$field]; 73 | } 74 | } 75 | 76 | $action->write(); 77 | 78 | if (isset($rawData['TransitionID']) && $rawData['TransitionID']) { 79 | // unset the transition ID so this doesn't get re-executed 80 | $this->owner->TransitionID = null; 81 | $this->getWorkflowService()->executeTransition($this->owner, $rawData['TransitionID']); 82 | } else { 83 | // otherwise, just try to execute the current workflow to see if it 84 | // can now proceed based on user input 85 | $workflow->execute(); 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1_bug_report.yml: -------------------------------------------------------------------------------- 1 | name: 🪳 Bug Report 2 | description: Tell us if something isn't working the way it's supposed to 3 | 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | We strongly encourage you to [submit a pull request](https://docs.silverstripe.org/en/contributing/code/) which fixes the issue. 9 | Bug reports which are accompanied with a pull request are a lot more likely to be resolved quickly. 10 | - type: input 11 | id: affected-versions 12 | attributes: 13 | label: Module version(s) affected 14 | description: | 15 | What version of _this module_ have you reproduced this bug on? 16 | Run `composer info` to see the specific version of each module installed in your project. 17 | If you don't have access to that, check inside the help menu in the bottom left of the CMS. 18 | placeholder: x.y.z 19 | validations: 20 | required: true 21 | - type: textarea 22 | id: description 23 | attributes: 24 | label: Description 25 | description: A clear and concise description of the problem 26 | validations: 27 | required: true 28 | - type: textarea 29 | id: how-to-reproduce 30 | attributes: 31 | label: How to reproduce 32 | description: | 33 | ⚠️ This is the most important part of the report ⚠️ 34 | Without a way to easily reproduce your issue, there is little chance we will be able to help you and work on a fix. 35 | - Please, take the time to show us some code and/or configuration that is needed for others to reproduce the problem easily. 36 | - If the bug is too complex to reproduce with some short code samples, please reproduce it in a public repository and provide a link to the repository along with steps for setting up and reproducing the bug using that repository. 37 | - If part of the bug includes an error or exception, please provide a full stack trace. 38 | - If any user interaction is required to reproduce the bug, please add an ordered list of steps that are required to reproduce it. 39 | - Be as clear as you can, but don't miss any steps out. Simply saying "create a page" is less useful than guiding us through the steps you're taking to create a page, for example. 40 | placeholder: | 41 | 42 | #### Code sample 43 | ```php 44 | 45 | ``` 46 | 47 | #### Reproduction steps 48 | 1. 49 | validations: 50 | required: true 51 | - type: textarea 52 | id: possible-solution 53 | attributes: 54 | label: Possible Solution 55 | description: | 56 | *Optional: only if you have suggestions on a fix/reason for the bug* 57 | Please consider [submitting a pull request](https://docs.silverstripe.org/en/contributing/code/) with your solution! It helps get faster feedback and greatly increases the chance of the bug being fixed. 58 | - type: textarea 59 | id: additional-context 60 | attributes: 61 | label: Additional Context 62 | description: "*Optional: any other context about the problem: log messages, screenshots, etc.*" 63 | - type: checkboxes 64 | id: validations 65 | attributes: 66 | label: Validations 67 | description: "Before submitting the issue, please make sure you do the following:" 68 | options: 69 | - label: Check that there isn't already an issue that reports the same bug 70 | required: true 71 | - label: Double check that your reproduction steps work in a fresh installation of [`silverstripe/installer`](https://github.com/silverstripe/silverstripe-installer) (with any code examples you've provided) 72 | required: true 73 | -------------------------------------------------------------------------------- /src/Admin/WorkflowDefinitionImporter.php: -------------------------------------------------------------------------------- 1 | Content) { 35 | continue; 36 | } 37 | $structure = unserialize($import->Content ?? ''); 38 | $struct = $structure[Injector::class]['ExportedWorkflow']; 39 | $template = Injector::inst()->createWithArgs(WorkflowTemplate::class, $struct['constructor']); 40 | $template->setStructure($struct['properties']['structure']); 41 | if ($name) { 42 | if ($struct['constructor'][0] == trim($name ?? '')) { 43 | return $template; 44 | } 45 | continue; 46 | } 47 | $importedDefs[] = $template; 48 | } 49 | return $importedDefs; 50 | } 51 | 52 | /** 53 | * Handles finding and parsing YAML input as a string or from the contents of a file. 54 | * 55 | * @see addYAMLConfigFile() on {@link SS_ConfigManifest} from where this logic was taken and adapted. 56 | * @param string $source YAML as a string or a filename 57 | * @return array 58 | */ 59 | public function parseYAMLImport($source) 60 | { 61 | if (is_file($source ?? '')) { 62 | $source = file_get_contents($source ?? ''); 63 | } 64 | 65 | // Make sure the linefeeds are all converted to \n, PCRE '$' will not match anything else. 66 | $convertLF = str_replace(array("\r\n", "\r"), "\n", $source ?? ''); 67 | /* 68 | * Remove illegal colons from Transition/Action titles, otherwise sfYamlParser will barf on them 69 | * Note: The regex relies on there being single quotes wrapped around these in the export template 70 | */ 71 | $converted = preg_replace("#('[^:\n][^']+)(:)([^']+')#", "$1;$3", $convertLF ?? ''); 72 | $parts = preg_split('#^---$#m', $converted ?? '', -1, PREG_SPLIT_NO_EMPTY); 73 | 74 | // If we got an odd number of parts the config, file doesn't have a header. 75 | // We know in advance the number of blocks imported content will have so we settle for a count()==2 check. 76 | if (count($parts ?? []) != 2) { 77 | $msg = _t('WorkflowDefinitionImporter.INVALID_YML_FORMAT_NO_HEADER', 'Invalid YAML format.'); 78 | throw new ValidationException($msg); 79 | } 80 | 81 | try { 82 | $parsed = Yaml::parse($parts[1]); 83 | return $parsed; 84 | } catch (Exception $e) { 85 | $msg = _t( 86 | 'WorkflowDefinitionImporter.INVALID_YML_FORMAT_NO_PARSE', 87 | 'Invalid YAML format. Unable to parse.' 88 | ); 89 | throw new ValidationException($msg); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Dev/WorkflowBulkLoader.php: -------------------------------------------------------------------------------- 1 | processAll($filepath, true); 31 | } 32 | 33 | /** 34 | * @param string $filepath 35 | * @param boolean $preview 36 | */ 37 | protected function processAll($filepath, $preview = false) 38 | { 39 | $results = new BulkLoader_Result(); 40 | 41 | try { 42 | $yml = singleton(WorkflowDefinitionImporter::class)->parseYAMLImport($filepath); 43 | $this->processRecord($yml, $this->columnMap, $results, $preview); 44 | return $results; 45 | } catch (ValidationException $e) { 46 | return new BulkLoader_Result(); 47 | } 48 | } 49 | 50 | /** 51 | * @param array $record 52 | * @param array $columnMap 53 | * @param BulkLoader_Result $results 54 | * @param boolean $preview 55 | * @return number 56 | */ 57 | protected function processRecord($record, $columnMap, &$results, $preview = false) 58 | { 59 | $posted = Controller::curr()->getRequest()->postVars(); 60 | $default = WorkflowDefinitionExporter::$export_filename_prefix.'0.yml'; 61 | $filename = (isset($posted['_CsvFile']['name']) ? $posted['_CsvFile']['name'] : $default); 62 | 63 | // @todo is this the best way to extract records (nested array keys)?? 64 | $struct = $record[Injector::class]['ExportedWorkflow']; 65 | $name = $struct['constructor'][0]; 66 | $import = $this->createImport($name, $filename, $record); 67 | 68 | $template = Injector::inst()->createWithArgs(WorkflowTemplate::class, $struct['constructor']); 69 | $template->setStructure($struct['properties']['structure']); 70 | 71 | $def = WorkflowDefinition::create(); 72 | $def->workflowService = singleton(WorkflowService::class); 73 | $def->Template = $template->getName(); 74 | $obj = $def->workflowService->defineFromTemplate($def, $def->Template); 75 | 76 | $results->addCreated($obj, ''); 77 | $objID = $obj->ID; 78 | 79 | // Update the import 80 | $import->DefinitionID = $objID; 81 | $import->write(); 82 | 83 | $obj->destroy(); 84 | unset($obj); 85 | 86 | return $objID; 87 | } 88 | 89 | /** 90 | * Create the ImportedWorkflowTemplate record for the uploaded YML file. 91 | * 92 | * @param string $name 93 | * @param string $filename 94 | * @param array $record 95 | * @return ImportedWorkflowTemplate $import 96 | */ 97 | protected function createImport($name, $filename, $record) 98 | { 99 | // This is needed to feed WorkflowService#getNamedTemplate() 100 | $import = ImportedWorkflowTemplate::create(); 101 | $import->Name = $name; 102 | $import->Filename = $filename; 103 | $import->Content = serialize($record); 104 | $import->write(); 105 | 106 | return $import; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Forms/AWRequiredFieldsValidator.php: -------------------------------------------------------------------------------- 1 | validate() all over the place. 10 | * Note specifically $this->getExtendedValidationRoutines() - anti-pattern anyone? 11 | * 12 | * @author Russell Michell russell@silverstripe.com 13 | * @package advancedworkflow 14 | */ 15 | class AWRequiredFieldsValidator extends RequiredFieldsValidator 16 | { 17 | protected $data = array(); 18 | protected static $caller; 19 | 20 | public function php($data) 21 | { 22 | $valid = parent::php($data); 23 | $this->setData($data); 24 | 25 | // Fetch any extended validation routines on the caller 26 | $extended = $this->getExtendedValidationRoutines(); 27 | 28 | // Only deal-to extended routines once the parent is done 29 | if ($valid && $extended['fieldValid'] !== true) { 30 | $fieldName = $extended['fieldName']; 31 | $formField = $extended['fieldField']; 32 | $errorMessage = sprintf( 33 | $extended['fieldMsg'] ?? '', 34 | strip_tags('"'.(($formField && $formField->Title()) ? $formField->Title() : $fieldName).'"') 35 | ); 36 | 37 | if ($formField && $msg = $formField->getCustomValidationMessage()) { 38 | $errorMessage = $msg; 39 | } 40 | 41 | $this->validationError( 42 | $fieldName, 43 | $errorMessage, 44 | "required" 45 | ); 46 | $valid = false; 47 | } 48 | return $valid; 49 | } 50 | 51 | /** 52 | * Allows for the addition of an arbitrary no. additional, dedicated and "extended" validation methods on classes 53 | * that call AWRequiredFieldsValidator. 54 | * To add specific validation methods to a caller: 55 | * 56 | * 1). Write each checking method using this naming prototype: public function extendedRequiredFieldsXXX(). All 57 | * methods so named will be called. 58 | * 2). Call AWRequiredFieldsValidator->setCaller($this) 59 | * 60 | * Each extended method thus called, should return an array of a specific format. (See: static 61 | * $extendedMethodReturn on the caller) 62 | * 63 | * @return array $return 64 | */ 65 | public function getExtendedValidationRoutines() 66 | { 67 | // Setup a return array 68 | $return = array( 69 | 'fieldValid' => true, 70 | 'fieldName' => null, 71 | 'fieldField' => null, 72 | 'fieldMsg' => null, 73 | ); 74 | $caller = $this->getCaller(); 75 | $methods = get_class_methods($caller ?? ''); 76 | if (!$methods) { 77 | return $return; 78 | } 79 | foreach ($methods as $method) { 80 | if (!preg_match("#extendedRequiredFields#", $method ?? '')) { 81 | continue; 82 | } 83 | // One of the DO's validation methods has failed 84 | $extended = $caller->$method($this->getData()); 85 | if ($extended['fieldValid'] !== true) { 86 | $return['fieldValid'] = $extended['fieldValid']; 87 | $return['fieldName'] = $extended['fieldName']; 88 | $return['fieldField'] = $extended['fieldField']; 89 | $return['fieldMsg'] = $extended['fieldMsg']; 90 | break; 91 | } 92 | } 93 | return $return; 94 | } 95 | 96 | protected function setData($data) 97 | { 98 | $this->data = $data; 99 | } 100 | 101 | protected function getData() 102 | { 103 | return $this->data; 104 | } 105 | 106 | public function setCaller($caller) 107 | { 108 | AWRequiredFieldsValidator::$caller = $caller; 109 | } 110 | 111 | public function getCaller() 112 | { 113 | return AWRequiredFieldsValidator::$caller; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Jobs/WorkflowReminderJob.php: -------------------------------------------------------------------------------- 1 | 19 | * @license BSD License http://www.silverstripe.org/bsd-license 20 | */ 21 | class WorkflowReminderJob extends AbstractQueuedJob 22 | { 23 | const DEFAULT_REPEAT = 600; 24 | 25 | /** 26 | * 27 | * @var QueuedJobService 28 | */ 29 | public $queuedJobService; 30 | 31 | public function __construct($repeatInterval = 0) 32 | { 33 | if (!$this->repeatInterval) { 34 | $this->repeatInterval = $repeatInterval ? $repeatInterval : WorkflowReminderJob::DEFAULT_REPEAT; 35 | $this->totalSteps = 2; 36 | $this->currentStep = 1; 37 | } 38 | } 39 | 40 | public function getTitle() 41 | { 42 | return _t('AdvancedWorkflow.WORKFLOW_REMINDER_JOB', 'Workflow Reminder Job'); 43 | } 44 | 45 | /** 46 | * We only want one instance of this job ever 47 | * 48 | * @return string 49 | */ 50 | public function getSignature() 51 | { 52 | return md5($this->getTitle() ?? ''); 53 | } 54 | 55 | public function process() 56 | { 57 | $sent = 0; 58 | $filter = [ 59 | 'WorkflowStatus' => ['Active', 'Paused'], 60 | 'Definition.RemindDays:GreaterThan' => 0 61 | ]; 62 | 63 | $active = WorkflowInstance::get()->filter($filter); 64 | 65 | foreach ($active as $instance) { 66 | $edited = strtotime($instance->LastEdited ?? ''); 67 | $days = $instance->Definition()->RemindDays; 68 | 69 | if ($edited + ($days * 3600 * 24) > time()) { 70 | continue; 71 | } 72 | 73 | $email = Email::create(); 74 | $bcc = ''; 75 | $members = $instance->getAssignedMembers(); 76 | $target = $instance->getTarget(); 77 | 78 | if (!$members || !$members->exists()) { 79 | continue; 80 | } 81 | 82 | $email->setSubject("Workflow Reminder: $instance->Title"); 83 | $email->setBcc(implode(', ', $members->column('Email'))); 84 | $email->setHTMLTemplate('WorkflowReminderEmail'); 85 | $email->setData(array( 86 | 'Instance' => $instance, 87 | 'Link' => $target instanceof SiteTree ? "admin/show/$target->ID" : '' 88 | )); 89 | 90 | try { 91 | $email->send(); 92 | } catch (Exception $ex) { 93 | Injector::inst()->get(LoggerInterface::class)->warning($ex->getMessage()); 94 | } 95 | 96 | $sent++; 97 | 98 | // add a comment to the workflow if possible 99 | $action = $instance->CurrentAction(); 100 | 101 | $currentComment = $action->Comment; 102 | $action->Comment = sprintf(_t( 103 | 'AdvancedWorkflow.JOB_REMINDER_COMMENT', 104 | '%s: Reminder email sent\n\n' 105 | ) ?? '', date('Y-m-d H:i:s')) . $currentComment; 106 | try { 107 | $action->write(); 108 | } catch (Exception $ex) { 109 | Injector::inst()->get(LoggerInterface::class)->warning($ex->getMessage()); 110 | } 111 | 112 | $instance->LastEdited = time(); 113 | try { 114 | $instance->write(); 115 | } catch (Exception $ex) { 116 | Injector::inst()->get(LoggerInterface::class)->warning($ex->getMessage()); 117 | } 118 | } 119 | 120 | $this->currentStep = 2; 121 | $this->isComplete = true; 122 | 123 | $nextDate = date('Y-m-d H:i:s', time() + $this->repeatInterval); 124 | $this->queuedJobService->queueJob(new WorkflowReminderJob($this->repeatInterval), $nextDate); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/Actions/AssignUsersToWorkflowAction.php: -------------------------------------------------------------------------------- 1 | Users() 26 | * @method ManyManyList Groups() 27 | */ 28 | class AssignUsersToWorkflowAction extends WorkflowAction 29 | { 30 | private static $db = array( 31 | 'AssignInitiator' => 'Boolean', 32 | ); 33 | 34 | private static $many_many = array( 35 | 'Users' => Member::class, 36 | 'Groups' => Group::class, 37 | ); 38 | 39 | private static $icon = 'symbiote/silverstripe-advancedworkflow:images/assign.png'; 40 | 41 | private static $table_name = 'AssignUsersToWorkflowAction'; 42 | 43 | public function execute(WorkflowInstance $workflow) 44 | { 45 | $workflow->Users()->removeAll(); 46 | //Due to http://open.silverstripe.org/ticket/8258, there are errors occuring if Group has been extended 47 | //We use a direct delete query here before ticket 8258 fixed 48 | //$workflow->Groups()->removeAll(); 49 | $workflowID = $workflow->ID; 50 | $query = <<Users()->addMany($this->Users()); 55 | $workflow->Groups()->addMany($this->Groups()); 56 | if ($this->AssignInitiator) { 57 | $workflow->Users()->add($workflow->Initiator()); 58 | } 59 | return true; 60 | } 61 | 62 | public function getCMSFields() 63 | { 64 | $fields = parent::getCMSFields(); 65 | 66 | $cmsUsers = Member::mapInCMSGroups(); 67 | 68 | $fields->addFieldsToTab('Root.Main', array( 69 | new HeaderField('AssignUsers', $this->fieldLabel('AssignUsers')), 70 | new CheckboxField('AssignInitiator', $this->fieldLabel('AssignInitiator')), 71 | $users = CheckboxSetField::create('Users', $this->fieldLabel('Users'), $cmsUsers), 72 | new TreeMultiselectField('Groups', $this->fieldLabel('Groups'), Group::class) 73 | )); 74 | 75 | // limit to the users which actually can access the CMS 76 | $users->setSource(Member::mapInCMSGroups()); 77 | 78 | return $fields; 79 | } 80 | 81 | public function fieldLabels($relations = true) 82 | { 83 | return array_merge(parent::fieldLabels($relations), array( 84 | 'AssignUsers' => _t('AssignUsersToWorkflowAction.ASSIGNUSERS', 'Assign Users'), 85 | 'Users' => _t('AssignUsersToWorkflowAction.USERS', 'Users'), 86 | 'Groups' => _t('AssignUsersToWorkflowAction.GROUPS', 'Groups'), 87 | 'AssignInitiator' => _t('AssignUsersToWorkflowAction.INITIATOR', 'Assign Initiator'), 88 | )); 89 | } 90 | 91 | /** 92 | * Returns a set of all Members that are assigned to this WorkflowAction subclass, either directly or via a group. 93 | * 94 | * @return ArrayList 95 | */ 96 | public function getAssignedMembers() 97 | { 98 | $members = $this->Users(); 99 | $groups = $this->Groups(); 100 | 101 | // Can't merge instances of DataList so convert to something where we can 102 | $_members = ArrayList::create(); 103 | $members->each(function ($item) use ($_members) { 104 | $_members->push($item); 105 | }); 106 | 107 | $_groups = ArrayList::create(); 108 | $groups->each(function ($item) use ($_groups) { 109 | $_groups->push($item); 110 | }); 111 | 112 | foreach ($_groups as $group) { 113 | $_members->merge($group->Members()); 114 | } 115 | 116 | $_members->removeDuplicates(); 117 | return $_members; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/Forms/gridfield/GridFieldExportAction.php: -------------------------------------------------------------------------------- 1 | 'grid-field__col-compact'); 54 | } 55 | 56 | /** 57 | * Add the title 58 | * 59 | * @param GridField $gridField 60 | * @param string $columnName 61 | * @return array 62 | */ 63 | public function getColumnMetadata($gridField, $columnName) 64 | { 65 | if ($columnName == 'Actions') { 66 | return array('title' => ''); 67 | } 68 | } 69 | 70 | /** 71 | * Which columns are handled by this component 72 | * 73 | * @param type $gridField 74 | * @return type 75 | */ 76 | public function getColumnsHandled($gridField) 77 | { 78 | return array('Actions'); 79 | } 80 | 81 | /** 82 | * Which GridField actions are this component handling 83 | * 84 | * @param GridField $gridField 85 | * @return array 86 | */ 87 | public function getActions($gridField) 88 | { 89 | return array('exportrecord'); 90 | } 91 | 92 | /** 93 | * 94 | * @param GridField $gridField 95 | * @param DataObject $record 96 | * @param string $columnName 97 | * @return string - the HTML for the column 98 | */ 99 | public function getColumnContent($gridField, $record, $columnName) 100 | { 101 | // Disable the export icon if current user doesn't have access to view CMS Security settings 102 | if (!Permission::check('CMS_ACCESS_SecurityAdmin')) { 103 | return ''; 104 | } 105 | 106 | $field = GridField_FormAction::create( 107 | $gridField, 108 | 'ExportRecord' . $record->ID, 109 | false, 110 | "exportrecord", 111 | array('RecordID' => $record->ID) 112 | ) 113 | ->setIcon('export') 114 | ->addExtraClass('btn btn--no-text btn--icon-md'); 115 | 116 | $segment1 = Director::baseURL(); 117 | $segment2 = Config::inst()->get(AdvancedWorkflowAdmin::class, 'url_segment'); 118 | $segment3 = str_replace('\\', '-', $record->getClassName() ?? ''); 119 | $data = new ArrayData(array( 120 | 'Link' => Controller::join_links($segment1, 'admin', $segment2, $segment3, 'export', $record->ID), 121 | 'ExtraClass' => $field->extraClass(), 122 | )); 123 | 124 | $template = SSViewer::get_templates_by_class($this, '', __CLASS__); 125 | return $data->renderWith($template); 126 | } 127 | 128 | /** 129 | * Handle the actions and apply any changes to the GridField 130 | * 131 | * @param GridField $gridField 132 | * @param string $actionName 133 | * @param mixed $arguments 134 | * @param array $data - form data 135 | * @return void 136 | */ 137 | public function handleAction(GridField $gridField, $actionName, $arguments, $data) 138 | { 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /client/src/styles/WorkflowField.scss: -------------------------------------------------------------------------------- 1 | .workflow-field { 2 | position: relative; 3 | padding-bottom: 0; 4 | 5 | .workflow-field-header { 6 | background: $med-blue; 7 | border: 1px solid rgba(0, 0, 0, .1); 8 | border-radius: $wf-radius $wf-radius 0 0; 9 | 10 | h3 { 11 | background: $dark-blue; 12 | border-bottom: 1px solid rgba(0, 0, 0, .1); 13 | color: $white; 14 | text-shadow: 0 1px 0 rgba(0, 0, 0, .1); 15 | margin: 0; 16 | padding: $wf-grid; 17 | } 18 | 19 | .workflow-field-do-create { 20 | margin-left: calc($wf-grid / 2); 21 | } 22 | } 23 | 24 | .workflow-field-create-container { 25 | display: flex; 26 | } 27 | 28 | .workflow-field-create { 29 | padding: calc($wf-grid / 2) $wf-grid; 30 | } 31 | 32 | .workflow-field-do-create-button { 33 | flex: inherit; 34 | } 35 | 36 | .workflow-field-actions { 37 | background: $white; 38 | border: 1px solid rgba(0, 0, 0, .2); 39 | border-top: 0; 40 | border-radius: 0 0 $wf-radius $wf-radius; 41 | padding: $wf-grid; 42 | 43 | .workflow-field-action { 44 | margin-bottom: calc($wf-grid / 2); 45 | 46 | &:last-child { 47 | margin-bottom: 0; 48 | } 49 | 50 | .workflow-field-action-disabled { 51 | opacity: 0.35; 52 | filter: alpha(Opacity=35); 53 | cursor: default; 54 | 55 | // These default styles are taken from .ss-ui-button (_forms.scss) so we don't end up with mousover/focus states on disabled buttons. 56 | // @todo These styles need to be dynamcally included from CMS, they are obviousely "hard-coded" for now. 57 | &.ui-state-hover, 58 | &.ui-state-focus { 59 | text-decoration: none; 60 | background: linear-gradient($white, $grey-lightish); 61 | text-shadow: $white 0 1px 1px; 62 | -webkit-box-shadow: none; 63 | -moz-box-shadow: none; 64 | box-shadow: none; 65 | } 66 | } 67 | } 68 | 69 | .workflow-field-action-header { 70 | background: $light-blue; 71 | border: 1px solid $med-blue; 72 | border-left: 0; 73 | overflow: auto; 74 | padding: calc($wf-grid / 4) $wf-grid calc($wf-grid / 4) 0; 75 | 76 | .workflow-field-action-icon, 77 | .workflow-field-action-drag { 78 | display: block; 79 | float: left; 80 | } 81 | 82 | .workflow-field-action-drag { 83 | background: $med-blue; 84 | cursor: move; 85 | margin: -(calc($wf-grid / 4)) 0; 86 | width: 4px; 87 | height: $wf-height + calc($wf-grid / 2) + 4; 88 | } 89 | 90 | .workflow-field-action-icon { 91 | width: 16px; 92 | height: 16px; 93 | margin: calc($wf-height / 4) $wf-grid 0; 94 | } 95 | 96 | h4 { 97 | float: left; 98 | margin: calc($wf-height / 4) $wf-grid 0 0; 99 | min-width: $wf-min-width; 100 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4); 101 | } 102 | } 103 | 104 | .workflow-field-action-transitions { 105 | padding-left: 0; 106 | 107 | li { 108 | background: $light-grey; 109 | border: 1px solid $light-blue; 110 | border-left: 0; 111 | border-top: 0; 112 | overflow: auto; 113 | padding: calc($wf-grid / 2) calc($wf-grid / 2) calc($wf-grid / 2) 0; 114 | 115 | .workflow-field-action-drag { 116 | background: $light-blue; 117 | cursor: move; 118 | float: left; 119 | margin: -(calc($wf-grid / 2)) 0; 120 | width: 4px; 121 | height: 41px; 122 | } 123 | 124 | .workflow-field-transition-title { 125 | float: left; 126 | min-width: $wf-min-width + 30px; 127 | overflow: auto; 128 | } 129 | 130 | .workflow-field-transition-text { 131 | margin-top: 6px; 132 | } 133 | 134 | span { 135 | float: left; 136 | } 137 | 138 | .workflow-transition-actions { 139 | display: inline; 140 | float: none; 141 | } 142 | } 143 | } 144 | } 145 | 146 | .workflow-placeholder { 147 | margin-bottom: calc($wf-grid / 2); 148 | height: calc($wf-grid * 4); 149 | } 150 | 151 | .workflow-field-loading { 152 | background: rgba(0, 0, 0, .15) url("../images/spinner.gif") no-repeat center center; 153 | border-radius: 0 0 $wf-radius $wf-radius; 154 | inset: 0; 155 | display: none; 156 | position: absolute; 157 | z-index: 999; 158 | } 159 | } 160 | 161 | .cms { 162 | table.ss-gridfield-table { 163 | .btn-icon-download-csv { 164 | display: inline-block; 165 | vertical-align: middle; 166 | width: 16px; 167 | height: 16px; 168 | margin: -2px 0 0 10px; 169 | } 170 | } 171 | 172 | .workflow-field-editor-dialog { 173 | .tab-content { 174 | clear: both; 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/Actions/PublishItemWorkflowAction.php: -------------------------------------------------------------------------------- 1 | 'Int', 29 | 'AllowEmbargoedEditing' => 'Boolean', 30 | ); 31 | 32 | private static $defaults = array( 33 | 'AllowEmbargoedEditing' => true 34 | ); 35 | 36 | private static $icon = 'symbiote/silverstripe-advancedworkflow:images/publish.png'; 37 | 38 | private static $table_name = 'PublishItemWorkflowAction'; 39 | 40 | public function execute(WorkflowInstance $workflow) 41 | { 42 | if (!$target = $workflow->getTarget()) { 43 | return true; 44 | } 45 | 46 | if (class_exists(AbstractQueuedJob::class) && $this->PublishDelay) { 47 | $job = new WorkflowPublishTargetJob($target); 48 | $days = $this->PublishDelay; 49 | $after = date('Y-m-d H:i:s', strtotime("+$days days")); 50 | 51 | // disable editing, and embargo the delay if using WorkflowEmbargoExpiryExtension 52 | if ($target->hasExtension(WorkflowEmbargoExpiryExtension::class)) { 53 | $target->AllowEmbargoedEditing = $this->AllowEmbargoedEditing; 54 | $target->PublishOnDate = $after; 55 | $target->write(); 56 | } else { 57 | singleton(QueuedJobService::class)->queueJob($job, $after); 58 | } 59 | } elseif ($target->hasExtension(WorkflowEmbargoExpiryExtension::class)) { 60 | $target->AllowEmbargoedEditing = $this->AllowEmbargoedEditing; 61 | // setting future date stuff if needbe 62 | 63 | // set this value regardless 64 | $target->UnPublishOnDate = $target->DesiredUnPublishDate; 65 | $target->DesiredUnPublishDate = ''; 66 | 67 | // Publish dates 68 | if ($target->DesiredPublishDate) { 69 | // Hand-off desired publish date 70 | $target->PublishOnDate = $target->DesiredPublishDate; 71 | $target->DesiredPublishDate = ''; 72 | $target->write(); 73 | } else { 74 | // Ensure previously modified DesiredUnPublishDate values are written 75 | $target->write(); 76 | if ($target->hasMethod('publishRecursive')) { 77 | $target->publishRecursive(); 78 | $this->extend('onAfterWorkflowPublish', $target); 79 | } 80 | } 81 | } else { 82 | if ($target->hasMethod('publishRecursive')) { 83 | $target->publishRecursive(); 84 | $this->extend('onAfterWorkflowPublish', $target); 85 | } 86 | } 87 | 88 | return true; 89 | } 90 | 91 | public function getCMSFields() 92 | { 93 | $fields = parent::getCMSFields(); 94 | 95 | if (class_exists(AbstractQueuedJob::class)) { 96 | $fields->addFieldsToTab('Root.Main', [ 97 | CheckboxField::create( 98 | 'AllowEmbargoedEditing', 99 | _t( 100 | __CLASS__ . '.ALLOWEMBARGOEDEDITING', 101 | 'Allow editing while item is embargoed? (does not apply without embargo)' 102 | ) 103 | ), 104 | NumericField::create( 105 | 'PublishDelay', 106 | _t('PublishItemWorkflowAction.PUBLICATIONDELAY', 'Publication Delay') 107 | )->setDescription(_t( 108 | __CLASS__ . '.PublicationDelayDescription', 109 | 'Delay publiation by the specified number of days' 110 | )) 111 | ]); 112 | } 113 | 114 | return $fields; 115 | } 116 | 117 | /** 118 | * Publish action allows a user who is currently assigned at this point of the workflow to 119 | * 120 | * @param DataObject $target 121 | * @return bool 122 | */ 123 | public function canPublishTarget(DataObject $target) 124 | { 125 | return true; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/FormFields/WorkflowField.php: -------------------------------------------------------------------------------- 1 | definition = $definition; 39 | $this->addExtraClass('workflow-field'); 40 | 41 | parent::__construct($name, $title); 42 | } 43 | 44 | public function action() 45 | { 46 | return new WorkflowFieldActionController($this, 'action'); 47 | } 48 | 49 | public function transition() 50 | { 51 | return new WorkflowFieldTransitionController($this, 'transition'); 52 | } 53 | 54 | public function sort($request) 55 | { 56 | if (!SecurityToken::inst()->checkRequest($request)) { 57 | $this->httpError(404); 58 | } 59 | 60 | $class = $request->postVar('class'); 61 | $ids = $request->postVar('id'); 62 | 63 | if ($class == WorkflowAction::class) { 64 | $objects = $this->Definition()->Actions(); 65 | } elseif ($class == WorkflowTransition::class) { 66 | $parent = $request->postVar('parent'); 67 | $action = $this->Definition()->Actions()->byID($parent); 68 | 69 | if (!$action) { 70 | $this->httpError(400, _t( 71 | 'AdvancedWorkflowAdmin.INVALIDPARENTID', 72 | 'An invalid parent ID was specified.' 73 | )); 74 | } 75 | 76 | $objects = $action->Transitions(); 77 | } else { 78 | $this->httpError(400, _t( 79 | 'AdvancedWorkflowAdmin.INVALIDCLASSTOORDER', 80 | 'An invalid class to order was specified.' 81 | )); 82 | } 83 | 84 | if (!$ids || array_diff($ids ?? [], $objects->column('ID'))) { 85 | $this->httpError(400, _t('AdvancedWorkflowAdmin.INVALIDIDLIST', 'An invalid list of IDs was provided.')); 86 | } 87 | 88 | singleton(WorkflowService::class)->reorder($objects, $ids); 89 | 90 | return new HTTPResponse( 91 | null, 92 | 200, 93 | _t('AdvancedWorkflowAdmin.SORTORDERSAVED', 'The sort order has been saved.') 94 | ); 95 | } 96 | 97 | public function getTemplate() 98 | { 99 | return __CLASS__; 100 | } 101 | 102 | public function FieldHolder($properties = array()) 103 | { 104 | Requirements::javascript('symbiote/silverstripe-advancedworkflow:client/dist/js/advancedworkflow.js'); 105 | Requirements::css('symbiote/silverstripe-advancedworkflow:client/dist/styles/advancedworkflow.css'); 106 | 107 | return $this->Field($properties); 108 | } 109 | 110 | public function Definition() 111 | { 112 | return $this->definition; 113 | } 114 | 115 | public function ActionLink() 116 | { 117 | $parts = func_get_args(); 118 | array_unshift($parts, 'action'); 119 | 120 | return $this->Link(implode('/', $parts)); 121 | } 122 | 123 | public function TransitionLink() 124 | { 125 | $parts = func_get_args(); 126 | array_unshift($parts, 'transition'); 127 | 128 | return $this->Link(implode('/', $parts)); 129 | } 130 | 131 | public function CreateableActions() 132 | { 133 | $list = ArrayList::create(); 134 | $classes = ClassInfo::subclassesFor(WorkflowAction::class); 135 | 136 | array_shift($classes); 137 | sort($classes); 138 | 139 | foreach ($classes as $class) { 140 | $reflect = new ReflectionClass($class); 141 | $can = singleton($class)->canCreate() && !$reflect->isAbstract(); 142 | 143 | if ($can) { 144 | $list->push(ArrayData::create([ 145 | 'Title' => singleton($class)->singular_name(), 146 | 'Class' => $this->sanitiseClassName($class), 147 | ])); 148 | } 149 | } 150 | 151 | return $list; 152 | } 153 | 154 | /** 155 | * Sanitise a model class' name for inclusion in a link 156 | * 157 | * @param string $class 158 | * @return string 159 | */ 160 | protected function sanitiseClassName($class) 161 | { 162 | return str_replace('\\', '-', $class ?? ''); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /templates/Symbiote/AdvancedWorkflow/FormFields/WorkflowField.ss: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |

$Title

7 |
8 |
9 | 17 | 21 |
22 |
23 |
24 |
25 | <% loop $Definition.Actions %> 26 |
27 | 51 | 52 | <% if $Transitions %> 53 |
    54 | <% loop $Transitions %> 55 |
  1. 56 |
    57 | 58 | 59 |
    60 | $Title 61 | 62 | $NextAction.Title 63 |
    64 |
    65 | 78 |
  2. 79 | <% end_loop %> 80 |
81 | <% end_if %> 82 |
83 | <% end_loop %> 84 |
85 |
86 | --------------------------------------------------------------------------------