diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index f6e0dcfc511fd..112744b894a2e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -54,3 +54,18 @@ plugins/system/webauthn/* @nikosdion
media/plg_system_webauthn/* @nikosdion
language/administrator/en-GB/en-GB.plg_system_webauthn.ini @nikosdion
language/administrator/en-GB/en-GB.plg_system_webauthn.sys.ini @nikosdion
+
+# Workflow
+administrator/components/com_workflow/* @bembelimen @hleithner
+administrator/language/en-GB/com_workflow.ini @bembelimen @hleithner
+administrator/language/en-GB/com_workflow.sys.ini @bembelimen @hleithner
+administrator/language/en-GB/plg_workflow_publishing.ini @bembelimen @hleithner
+administrator/language/en-GB/plg_workflow_publishing.sys.ini @bembelimen @hleithner
+libraries/src/Form/Field/TransitionField.php @bembelimen @hleithner
+libraries/src/Form/Field/Workflow* @bembelimen @hleithner
+libraries/src/HTML/Helpers/Workflow* @bembelimen @hleithner
+libraries/src/MVC/Model/Workflow* @bembelimen @hleithner
+libraries/src/MVC/Model/Workflow* @bembelimen @hleithner
+libraries/src/Workflow/* @bembelimen @hleithner
+build/media_source/com_workflow/* @bembelimen @hleithner
+plugins/workflow/* @bembelimen @hleithner
diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql
index 7bbedc437e6d4..b0c2b3115e08c 100644
--- a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql
+++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql
@@ -10,7 +10,6 @@ CREATE TABLE IF NOT EXISTS `#__workflows` (
`description` text NOT NULL,
`extension` varchar(50) NOT NULL,
`default` tinyint(1) NOT NULL DEFAULT 0,
- `core` tinyint(1) NOT NULL DEFAULT 0,
`ordering` int(11) NOT NULL DEFAULT 0,
`created` datetime NOT NULL,
`created_by` int(10) NOT NULL DEFAULT 0,
@@ -34,8 +33,8 @@ CREATE TABLE IF NOT EXISTS `#__workflows` (
-- Dumping data for table `#__workflows`
--
-INSERT INTO `#__workflows` (`id`, `asset_id`, `published`, `title`, `description`, `extension`, `default`, `core`,`ordering`, `created`, `created_by`, `modified`, `modified_by`, `checked_out_time`, `checked_out`) VALUES
-(1, 0, 1, 'COM_WORKFLOW_DEFAULT_WORKFLOW', '', 'com_content', 1, 1, 1, CURRENT_TIMESTAMP(), 0, CURRENT_TIMESTAMP(), 0, NULL, 0);
+INSERT INTO `#__workflows` (`id`, `asset_id`, `published`, `title`, `description`, `extension`, `default`, `ordering`, `created`, `created_by`, `modified`, `modified_by`, `checked_out_time`, `checked_out`) VALUES
+(1, 0, 1, 'COM_WORKFLOW_BASIC_WORKFLOW', '', 'com_content.article', 1, 1, CURRENT_TIMESTAMP(), 0, CURRENT_TIMESTAMP(), 0, NULL, 0);
--
-- Table structure for table `#__workflow_associations`
@@ -64,7 +63,6 @@ CREATE TABLE IF NOT EXISTS `#__workflow_stages` (
`published` tinyint(1) NOT NULL DEFAULT 0,
`title` varchar(255) NOT NULL,
`description` text NOT NULL,
- `condition` int(10) DEFAULT 0,
`default` tinyint(1) NOT NULL DEFAULT 0,
`checked_out_time` datetime,
`checked_out` int(10) NOT NULL DEFAULT 0,
@@ -80,11 +78,8 @@ CREATE TABLE IF NOT EXISTS `#__workflow_stages` (
-- Dumping data for table `#__workflow_stages`
--
-INSERT INTO `#__workflow_stages` (`id`, `asset_id`, `ordering`, `workflow_id`, `published`, `title`, `description`, `condition`, `default`, `checked_out_time`, `checked_out`) VALUES
-(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 0, 1, NULL, 0),
-(2, 0, 2, 1, 1, 'JPUBLISHED', '', 1, 0, NULL, 0),
-(3, 0, 3, 1, 1, 'JTRASHED', '', -2, 0, NULL, 0),
-(4, 0, 4, 1, 1, 'JARCHIVED', '', 2, 0, NULL, 0);
+INSERT INTO `#__workflow_stages` (`id`, `asset_id`, `ordering`, `workflow_id`, `published`, `title`, `description`, `default`, `checked_out_time`, `checked_out`) VALUES
+(1, 0, 1, 1, 1, 'COM_WORKFLOW_BASIC_STAGE', '', 1, NULL, 0);
--
-- Table structure for table `#__workflow_transitions`
@@ -100,6 +95,7 @@ CREATE TABLE IF NOT EXISTS `#__workflow_transitions` (
`description` text NOT NULL,
`from_stage_id` int(10) NOT NULL,
`to_stage_id` int(10) NOT NULL,
+ `options` text NOT NULL,
`checked_out_time` datetime,
`checked_out` int(10) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
@@ -115,21 +111,31 @@ CREATE TABLE IF NOT EXISTS `#__workflow_transitions` (
-- Dumping data for table `#__workflow_transitions`
--
-INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering`, `workflow_id`, `title`, `description`, `from_stage_id`, `to_stage_id`, `checked_out_time`, `checked_out`) VALUES
-(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1, NULL, 0),
-(2, 0, 1, 2, 1, 'Publish', '', -1, 2, NULL, 0),
-(3, 0, 1, 3, 1, 'Trash', '', -1, 3, NULL, 0),
-(4, 0, 1, 4, 1, 'Archive', '', -1, 4, NULL, 0);
+INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering`, `workflow_id`, `title`, `description`, `from_stage_id`, `to_stage_id`, `options`, `checked_out_time`, `checked_out`) VALUES
+(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1, '{"publishing":"0"}', NULL, 0),
+(2, 0, 1, 2, 1, 'Publish', '', -1, 1, '{"publishing":"1"}', NULL, 0),
+(3, 0, 1, 3, 1, 'Trash', '', -1, 1, '{"publishing":"-2"}', NULL, 0),
+(4, 0, 1, 4, 1, 'Archive', '', -1, 1, '{"publishing":"2"}', NULL, 0),
+(5, 0, 1, 5, 1, 'Feature', '', -1, 1, '{"featuring":"1"}', NULL, 0),
+(6, 0, 1, 6, 1, 'Unfeature', '', -1, 1, '{"featuring":"0"}', NULL, 0),
+(7, 0, 1, 7, 1, 'Publish & Feature', '', -1, 1, '{"publishing":"1","featuring":"1"}', NULL, 0);
--
-- Creating extension entry
--
+-- Note that the old pseudo null dates have to be used for the `checked_out_time`
+-- column because the conversion to real null dates will be done with a later
+-- update SQL script.
+--
INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES
-(0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0);
+(0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 1, '', '{}', 0, '0000-00-00 00:00:00', 0, 0),
+(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0),
+(0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0),
+(0, 'plg_workflow_notification', 'plugin', 'notification', 'workflow', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0);
--
-- Creating Associations for existing content
--
INSERT INTO `#__workflow_associations` (`item_id`, `stage_id`, `extension`)
-SELECT `id`, CASE WHEN `state` = -2 THEN 3 WHEN `state` = 0 THEN 1 WHEN `state` = 2 THEN 4 ELSE 2 END, 'com_content' FROM `#__content`;
+SELECT `id`, 1, 'com_content.article' FROM `#__content`;
diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql
index a41ff39e4f764..ec7f6c3508ae3 100644
--- a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql
+++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql
@@ -10,7 +10,6 @@ CREATE TABLE IF NOT EXISTS "#__workflows" (
"description" text NOT NULL,
"extension" varchar(50) NOT NULL,
"default" smallint NOT NULL DEFAULT 0,
- "core" smallint NOT NULL DEFAULT 0,
"ordering" bigint NOT NULL DEFAULT 0,
"created" timestamp without time zone NOT NULL,
"created_by" bigint DEFAULT 0 NOT NULL,
@@ -31,8 +30,8 @@ CREATE INDEX "#__workflows_idx_modified" ON "#__workflows" ("modified");
CREATE INDEX "#__workflows_idx_modified_by" ON "#__workflows" ("modified_by");
CREATE INDEX "#__workflows_idx_checked_out" ON "#__workflows" ("checked_out");
-INSERT INTO "#__workflows" ("id", "asset_id", "published", "title", "description", "extension", "default", "core", "ordering", "created", "created_by", "modified", "modified_by", "checked_out_time", "checked_out") VALUES
-(1, 0, 1, 'COM_WORKFLOW_DEFAULT_WORKFLOW', '', 'com_content', 1, 1, 1, CURRENT_TIMESTAMP, 0, CURRENT_TIMESTAMP, 0, NULL, 0);
+INSERT INTO "#__workflows" ("id", "asset_id", "published", "title", "description", "extension", "default", "ordering", "created", "created_by", "modified", "modified_by", "checked_out_time", "checked_out") VALUES
+(1, 0, 1, 'COM_WORKFLOW_BASIC_WORKFLOW', '', 'com_content.article', 1, 1, CURRENT_TIMESTAMP, 0, CURRENT_TIMESTAMP, 0, NULL, 0);
--
-- Table structure for table "#__workflow_associations"
@@ -64,7 +63,6 @@ CREATE TABLE IF NOT EXISTS "#__workflow_stages" (
"published" smallint NOT NULL DEFAULT 0,
"title" varchar(255) NOT NULL,
"description" text NOT NULL,
- "condition" bigint DEFAULT 0 NOT NULL,
"default" smallint NOT NULL DEFAULT 0,
"checked_out_time" timestamp without time zone,
"checked_out" bigint DEFAULT 0 NOT NULL,
@@ -80,11 +78,8 @@ CREATE INDEX "#__workflow_stages_idx_checked_out" ON "#__workflow_stages" ("chec
-- Dumping data for table "#__workflow_stages"
--
-INSERT INTO "#__workflow_stages" ("id", "asset_id", "ordering", "workflow_id", "published", "title", "description", "condition", "default", "checked_out_time", "checked_out") VALUES
-(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 0, 1, NULL, 0),
-(2, 0, 2, 1, 1, 'JPUBLISHED', '', 1, 0, NULL, 0),
-(3, 0, 3, 1, 1, 'JTRASHED', '', -2, 0, NULL, 0),
-(4, 0, 4, 1, 1, 'JARCHIVED', '', 2, 0, NULL, 0);
+INSERT INTO "#__workflow_stages" ("id", "asset_id", "ordering", "workflow_id", "published", "title", "description", "default", "checked_out_time", "checked_out") VALUES
+(1, 0, 1, 1, 1, 'COM_WORKFLOW_BASIC_STAGE', '', 1, NULL, 0);
--
-- Table structure for table "#__workflow_transitions"
@@ -100,6 +95,7 @@ CREATE TABLE IF NOT EXISTS "#__workflow_transitions" (
"description" text NOT NULL,
"from_stage_id" bigint DEFAULT 0 NOT NULL,
"to_stage_id" bigint DEFAULT 0 NOT NULL,
+ "options" text NOT NULL,
"checked_out_time" timestamp without time zone,
"checked_out" bigint DEFAULT 0 NOT NULL,
PRIMARY KEY ("id")
@@ -111,21 +107,31 @@ CREATE INDEX "#__workflow_transitions_idx_to_stage_id" ON "#__workflow_transitio
CREATE INDEX "#__workflow_transitions_idx_workflow_id" ON "#__workflow_transitions" ("workflow_id");
CREATE INDEX "#__workflow_transitions_idx_checked_out" ON "#__workflow_transitions" ("checked_out");
-INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering", "workflow_id", "title", "description", "from_stage_id", "to_stage_id", "checked_out_time", "checked_out") VALUES
-(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1, NULL, 0),
-(2, 0, 1, 2, 1, 'Publish', '', -1, 2, NULL, 0),
-(3, 0, 1, 3, 1, 'Trash', '', -1, 3, NULL, 0),
-(4, 0, 1, 4, 1, 'Archive', '', -1, 4, NULL, 0);
+INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering", "workflow_id", "title", "description", "from_stage_id", "to_stage_id", "options", "checked_out_time", "checked_out") VALUES
+(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1, '{"publishing":"0"}', NULL, 0),
+(2, 0, 1, 2, 1, 'Publish', '', -1, 1, '{"publishing":"1"}', NULL, 0),
+(3, 0, 1, 3, 1, 'Trash', '', -1, 1, '{"publishing":"-2"}', NULL, 0),
+(4, 0, 1, 4, 1, 'Archive', '', -1, 1, '{"publishing":"2"}', NULL, 0),
+(5, 0, 1, 5, 1, 'Feature', '', -1, 1, '{"featuring":"1"}', NULL, 0),
+(6, 0, 1, 6, 1, 'Unfeature', '', -1, 1, '{"featuring":"0"}', NULL, 0),
+(7, 0, 1, 7, 1, 'Publish & Feature', '', -1, 1, '{"publishing":"1","featuring":"1"}', NULL, 0);
--
-- Creating extension entry
--
+-- Note that the old pseudo null dates have to be used for the "checked_out_time"
+-- column because the conversion to real null dates will be done with a later
+-- update SQL script.
+--
INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state") VALUES
-(0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0);
+(0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 1, '', '{}', 0, '1970-01-01 00:00:00', 0, 0),
+(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0),
+(0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0),
+(0, 'plg_workflow_notification', 'plugin', 'notification', 'workflow', 0, 1, 1, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0);
--
-- Creating Associations for existing content
--
INSERT INTO "#__workflow_associations" ("item_id", "stage_id", "extension")
-SELECT "id", CASE WHEN "state" = -2 THEN 3 WHEN "state" = 0 THEN 1 WHEN "state" = 2 THEN 4 ELSE 2 END, 'com_content' FROM "#__content";
+SELECT "id", 1, 'com_content.article' FROM "#__content";
diff --git a/administrator/components/com_content/config.xml b/administrator/components/com_content/config.xml
index 67901887c1ead..62b34237ba614 100644
--- a/administrator/components/com_content/config.xml
+++ b/administrator/components/com_content/config.xml
@@ -1039,13 +1039,17 @@
-
+
+