diff --git a/dotCMS/src/integration-test/java/com/dotcms/contenttype/test/ContentTypeAPIImplTest.java b/dotCMS/src/integration-test/java/com/dotcms/contenttype/test/ContentTypeAPIImplTest.java index 35c23609a73a..47ab3da3998c 100644 --- a/dotCMS/src/integration-test/java/com/dotcms/contenttype/test/ContentTypeAPIImplTest.java +++ b/dotCMS/src/integration-test/java/com/dotcms/contenttype/test/ContentTypeAPIImplTest.java @@ -7,6 +7,7 @@ import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.util.Date; import java.util.List; import java.util.UUID; @@ -30,15 +31,12 @@ import com.dotcms.contenttype.model.type.ImmutableSimpleContentType; import com.dotcms.contenttype.model.type.ImmutableWidgetContentType; import com.dotcms.contenttype.model.type.UrlMapable; -import com.dotcms.contenttype.transform.contenttype.StructureTransformer; import com.dotcms.repackage.org.apache.commons.lang.StringUtils; import com.dotmarketing.beans.Host; import com.dotmarketing.business.APILocator; import com.dotmarketing.exception.DotDataException; import com.dotmarketing.exception.DotSecurityException; -import com.dotmarketing.factories.InodeFactory; import com.dotmarketing.portlets.folders.business.FolderAPI; -import com.dotmarketing.portlets.structure.model.Structure; public class ContentTypeAPIImplTest extends ContentTypeBaseTest { @@ -557,4 +555,34 @@ public void testAddingUpdatingDeletingContentTypeWithFixedFields() throws Except //deleting content type delete(type); } + + /** + * Test the updateModDate method of the contenttypeapi + * to help detect the changes on fields and field variables + * @throws Exception + */ + @Test + public void testUpdateContentTypeModDate() throws Exception{ + long time = System.currentTimeMillis(); + int base = BaseContentType.CONTENT.ordinal(); + Thread.sleep(1); + ContentType type = ContentTypeBuilder.builder(BaseContentType.getContentTypeClass(base)) + .description("description" + time).folder(FolderAPI.SYSTEM_FOLDER).host(Host.SYSTEM_HOST) + .name("ContentTypeTestingUpdateModDate" + time).owner("owner").variable("velocityVarNameTesting" + time).build(); + type = contentTypeApi.save(type, null, null); + + Date creationModDate = type.modDate(); + assertThat("contenttypes mod_date is not null", creationModDate != null); + //calling updatemod_date method + Thread.sleep(1000); + contentTypeApi.updateModDate(type); + //getting new mod_date + type = contentTypeApi.find(type.id()); + Date currentModDate = type.modDate(); + assertThat("contenttypes current mod_date is not null", currentModDate != null); + assertThat("contenttypes mod_date is updated", creationModDate != currentModDate); + assertThat("contenttypes mod_date is updated", currentModDate.compareTo(creationModDate) > 0); + //deleting content type + delete(type); + } } diff --git a/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPI.java b/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPI.java index 9a978576f5c3..b91dc99fd0b3 100644 --- a/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPI.java +++ b/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPI.java @@ -269,4 +269,11 @@ List search(String condition, BaseContentType base, String orderBy, * @throws DotSecurityException The user does not have permissions to perform this action. */ ContentType save(ContentType contentType, List fields, List fieldVariables) throws DotDataException, DotSecurityException; + + /** + * Update the Content Type mod_date and clean the cache + * @param type Content Type that is going to be modified + * @return true if the mod_date was updated, false if not + */ + boolean updateModDate(ContentType type); } diff --git a/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPIImpl.java b/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPIImpl.java index d79291e3cbe9..e1ad2b553a27 100644 --- a/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPIImpl.java +++ b/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPIImpl.java @@ -496,5 +496,17 @@ public ContentType save(ContentType contentType, List fields, List search(String search, int limit) throws DotDataException; void validateFields(ContentType type); + + void updateModDate(ContentType type) throws DotDataException; diff --git a/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeFactoryImpl.java b/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeFactoryImpl.java index 88aed2ca1a6c..f3c808a777b7 100644 --- a/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeFactoryImpl.java +++ b/dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeFactoryImpl.java @@ -683,4 +683,21 @@ public void validateFields(ContentType type) { } + @Override + public void updateModDate(ContentType type) throws DotDataException { + ContentTypeBuilder builder = + ContentTypeBuilder.builder(type).modDate(DateUtils.round(new Date(), Calendar.SECOND)); + type = builder.build(); + dbUpdateModDate(type); + cache.remove(type); + } + + private void dbUpdateModDate(ContentType type) throws DotDataException{ + DotConnect dc = new DotConnect(); + dc.setSQL(this.contentTypeSql.UPDATE_TYPE_MOD_DATE_BY_INODE); + dc.addParam(type.modDate()); + dc.addParam(type.id()); + dc.loadResult(); + } + } diff --git a/dotCMS/src/main/java/com/dotcms/contenttype/business/FieldAPIImpl.java b/dotCMS/src/main/java/com/dotcms/contenttype/business/FieldAPIImpl.java index 9a76561d5b04..f909d180649d 100644 --- a/dotCMS/src/main/java/com/dotcms/contenttype/business/FieldAPIImpl.java +++ b/dotCMS/src/main/java/com/dotcms/contenttype/business/FieldAPIImpl.java @@ -182,7 +182,8 @@ public void delete(Field field, User user) throws DotDataException, DotSecurityE } fac.delete(field); - + //update contenttype mod_date to detect the changes done on the field + tapi.updateModDate(type); CacheLocator.getContentTypeCache().remove(structure); StructureServices.removeStructureFile(structure); diff --git a/dotCMS/src/main/java/com/dotcms/contenttype/business/sql/ContentTypeSql.java b/dotCMS/src/main/java/com/dotcms/contenttype/business/sql/ContentTypeSql.java index c9b7d02ff74c..a0de43e1e1bd 100644 --- a/dotCMS/src/main/java/com/dotcms/contenttype/business/sql/ContentTypeSql.java +++ b/dotCMS/src/main/java/com/dotcms/contenttype/business/sql/ContentTypeSql.java @@ -72,5 +72,7 @@ public static ContentTypeSql getInstance() { public static String DELETE_TYPE_BY_INODE = "delete from structure where inode =?"; public static String SELECT_CONTENTLET_IDS_BY_TYPE = "select distinct(identifier) from contentlet where structure_inode = ?"; + + public static String UPDATE_TYPE_MOD_DATE_BY_INODE = "update structure set mod_date = ? where inode = ?"; } diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/structure/ajax/FieldVariableAjax.java b/dotCMS/src/main/java/com/dotmarketing/portlets/structure/ajax/FieldVariableAjax.java index 9fe328e29ade..073110c7c6e3 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/structure/ajax/FieldVariableAjax.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/structure/ajax/FieldVariableAjax.java @@ -7,6 +7,9 @@ import javax.servlet.http.HttpServletRequest; +import com.dotcms.contenttype.business.ContentTypeAPI; +import com.dotcms.contenttype.model.field.Field; +import com.dotcms.contenttype.model.type.ContentType; import com.dotcms.repackage.org.directwebremoting.WebContext; import com.dotcms.repackage.org.directwebremoting.WebContextFactory; @@ -89,6 +92,11 @@ public String saveFieldVariable(String id, String fieldId, String name, String k fieldVariable.setLastModDate(new Date()); try { fieldAPI.saveFieldVariable(fieldVariable, user, respectFrontendRoles); + + Field field = APILocator.getContentTypeFieldAPI().find(fieldVariable.getFieldId()); + ContentTypeAPI tapi = APILocator.getContentTypeAPI(user); + ContentType type = tapi.find(field.contentTypeId()); + tapi.updateModDate(type); } catch (DotSecurityException e) { return LanguageUtil.get(user, "message.fieldvariables.permission.error.save"); } @@ -108,6 +116,10 @@ public String deleteFieldVariable(String fieldVarId) throws DotDataException, Do FieldVariable fieldVar = fieldAPI.findFieldVariable(fieldVarId, user, respectFrontendRoles); fieldAPI.deleteFieldVariable(fieldVar, user, respectFrontendRoles); + Field field = APILocator.getContentTypeFieldAPI().find(fieldVar.getFieldId()); + ContentTypeAPI tapi = APILocator.getContentTypeAPI(user); + ContentType type = tapi.find(field.contentTypeId()); + tapi.updateModDate(type); return LanguageUtil.get(user, "message.fieldvariables.deleted"); }