diff --git a/dotCMS/src/main/java/com/dotmarketing/business/VersionableAPI.java b/dotCMS/src/main/java/com/dotmarketing/business/VersionableAPI.java index fc4ee59c4b79..fc9d31054f5a 100644 --- a/dotCMS/src/main/java/com/dotmarketing/business/VersionableAPI.java +++ b/dotCMS/src/main/java/com/dotmarketing/business/VersionableAPI.java @@ -269,7 +269,18 @@ public interface VersionableAPI { * @throws DotSecurityException */ boolean isWorking(Versionable versionable) throws DotDataException, DotStateException,DotSecurityException; - + + /** + * Tells if has working version in any language. + * + * @param versionable + * @return true if it has the working version. False if not + * @throws DotDataException + * @throws DotStateException + * @throws DotSecurityException + */ + boolean hasWorkingVersionInAnyOtherLanguage(Versionable versionable, long versionableLanguageId) throws DotDataException, DotStateException,DotSecurityException; + /** * Sets the versionable as the working version for its identifier * diff --git a/dotCMS/src/main/java/com/dotmarketing/business/VersionableAPIImpl.java b/dotCMS/src/main/java/com/dotmarketing/business/VersionableAPIImpl.java index 199b0ab8c542..ebe78da6f982 100644 --- a/dotCMS/src/main/java/com/dotmarketing/business/VersionableAPIImpl.java +++ b/dotCMS/src/main/java/com/dotmarketing/business/VersionableAPIImpl.java @@ -15,6 +15,7 @@ import com.dotcms.variant.model.Variant; import com.dotmarketing.beans.Identifier; import com.dotmarketing.beans.VersionInfo; +import com.dotmarketing.common.db.DotConnect; import com.dotmarketing.exception.DotDataException; import com.dotmarketing.exception.DotSecurityException; import com.dotmarketing.portlets.contentlet.model.Contentlet; @@ -350,6 +351,25 @@ public boolean isLocked(final Versionable versionable) throws DotDataException, } } + @CloseDBIfOpened + @Override + public boolean hasWorkingVersionInAnyOtherLanguage(Versionable versionable, final long versionableLanguageId) throws DotDataException, DotStateException, DotSecurityException { + + if(!UtilMethods.isSet(versionable) || !InodeUtils.isSet(versionable.getVersionId())) { + return false; + } + + final Identifier identifier = APILocator.getIdentifierAPI().find(versionable); + if(identifier==null || !UtilMethods.isSet(identifier.getId()) || !UtilMethods.isSet(identifier.getAssetType())) { + return false; + } + + // only contents are multi language + return "contentlet".equals(identifier.getAssetType())? + !new DotConnect().setSQL("select working_inode, lang from contentlet_version_info where identifier = ? and lang != ?") + .addParam(identifier.getId()).addParam(versionableLanguageId).loadObjectResults().isEmpty():false; + } + @CloseDBIfOpened @Override public boolean isWorking(final Versionable versionable) throws DotDataException, DotStateException, DotSecurityException { diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java index cbebf07c0965..4558afc66a56 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java @@ -3530,7 +3530,8 @@ public void validateActionStepAndWorkflow(final Contentlet contentlet, final Use try { final boolean isValidContentlet = !InodeUtils.isSet(contentlet.getInode()) - || contentlet.isWorking(); + || contentlet.isWorking() || + APILocator.getVersionableAPI().hasWorkingVersionInAnyOtherLanguage(contentlet, contentlet.getLanguageId()); if (!isValidContentlet) { throw new IllegalArgumentException(LanguageUtil diff --git a/dotcms-integration/src/test/java/com/dotmarketing/business/VersionableAPITest.java b/dotcms-integration/src/test/java/com/dotmarketing/business/VersionableAPITest.java index 4f0121367701..7e44e1cabeab 100644 --- a/dotcms-integration/src/test/java/com/dotmarketing/business/VersionableAPITest.java +++ b/dotcms-integration/src/test/java/com/dotmarketing/business/VersionableAPITest.java @@ -31,6 +31,8 @@ import java.util.List; import java.util.Random; + +import graphql.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -488,4 +490,100 @@ public void getEmptyVariant() throws DotDataException { assertTrue(allByVariant.isEmpty()); } + + /** + * Method to test: {@link VersionableAPI#isWorking(Versionable)} + * When: Create a {@link Contentlet} but do not save it, call the isWorking + * Should: should false + */ + @Test + public void test_is_working_with_non_persisted_contentlet() throws DotDataException, DotSecurityException { + + final ContentType contentType = APILocator.getContentTypeAPI(APILocator.systemUser()).find("webPageContent"); + final Contentlet myContentlet = new ContentletDataGen(contentType).next(); + + Assert.assertFalse(myContentlet.isWorking()); + } + + /** + * Method to test: {@link VersionableAPI#isWorking(Versionable)} + * When: Create a {@link Contentlet} and save it, call the isWorking + * Should: should true + */ + @Test + public void test_is_working_with_persisted_contentlet() throws DotDataException, DotSecurityException { + + final ContentType contentType = APILocator.getContentTypeAPI(APILocator.systemUser()).find("webPageContent"); + final Contentlet myContentlet = new ContentletDataGen(contentType) + .setProperty("title","Test").setProperty("body","Test Body") + .nextPersisted(); + + Assert.assertTrue(myContentlet.isWorking()); + } + + /** + * Method to test: {@link VersionableAPI#isWorking(Versionable)} + * When: Create a {@link Contentlet} and save it, call the isWorking + * Next, create another languages. + * Next, create a version but in that new language, call the isWorking + * Should: should false + */ + @Test + public void test_is_working_with_persisted_in_diff_lang_contentlet() throws DotDataException, DotSecurityException { + + final ContentType contentType = APILocator.getContentTypeAPI(APILocator.systemUser()).find("webPageContent"); + final Contentlet myContentlet = new ContentletDataGen(contentType) + .setProperty("title","Test").setProperty("body","Test Body") + .nextPersisted(); + final String countryCode = "it"; + final String languageCode = "it"; + final Language languageIt = APILocator.getLanguageAPI().getLanguage(languageCode, countryCode)==null? + new LanguageDataGen().countryCode(countryCode).languageCode(languageCode).nextPersisted(): + APILocator.getLanguageAPI().getLanguage(languageCode, countryCode); + + final Contentlet myContentletIt = new ContentletDataGen(contentType) + .setProperty("title","Test").setProperty("body","Test Body") + .languageId(languageIt.getId()) + .next(); + + Assert.assertTrue(myContentlet.isWorking()); + + myContentletIt.setIdentifier(myContentlet.getIdentifier()); + + Assert.assertFalse(myContentletIt.isWorking()); + } + + /** + * Method to test: {@link VersionableAPI#isWorking(Versionable)} + * When: Create a {@link Contentlet} and save it, call the isWorking + * Next, create another languages. + * Next, create a version but in that new language, call the isWorking + * Additionally calls the {@link VersionableAPI#hasWorkingVersionInAnyOtherLanguage(Versionable, long)} that may return true + */ + @Test + public void test_is_working_with_persisted_in_any_lang_contentlet() throws DotDataException, DotSecurityException { + + final ContentType contentType = APILocator.getContentTypeAPI(APILocator.systemUser()).find("webPageContent"); + final Contentlet myContentlet = new ContentletDataGen(contentType) + .setProperty("title","Test").setProperty("body","Test Body") + .nextPersisted(); + final String countryCode = "it"; + final String languageCode = "it"; + final Language languageIt = APILocator.getLanguageAPI().getLanguage(languageCode, countryCode)==null? + new LanguageDataGen().countryCode(countryCode).languageCode(languageCode).nextPersisted(): + APILocator.getLanguageAPI().getLanguage(languageCode, countryCode); + + final Contentlet myContentletIt = new ContentletDataGen(contentType) + .setProperty("title","Test").setProperty("body","Test Body") + .languageId(languageIt.getId()) + .next(); + + Assert.assertTrue(myContentlet.isWorking()); + + myContentletIt.setIdentifier(myContentlet.getIdentifier()); + + Assert.assertFalse(myContentletIt.isWorking()); + + Assert.assertTrue(APILocator.getVersionableAPI().hasWorkingVersionInAnyOtherLanguage(myContentletIt, languageIt.getId())); + } }