Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(multi-language) #30591 : Create endpoints to feed the Multi-language Component for the Edit Contentlet sidebar #30606

Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.dotmarketing.portlets.contentlet.model.IndexPolicy;
import com.dotmarketing.portlets.contentlet.transform.DotTransformerBuilder;
import com.dotmarketing.portlets.htmlpageasset.model.IHTMLPage;
import com.dotmarketing.portlets.languagesmanager.business.LanguageAPI;
import com.dotmarketing.portlets.languagesmanager.model.Language;
import com.dotmarketing.portlets.structure.model.ContentletRelationships;
import com.dotmarketing.portlets.structure.model.Relationship;
Expand All @@ -47,6 +48,7 @@
import com.dotmarketing.util.UtilMethods;
import com.dotmarketing.util.json.JSONException;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.liferay.portal.language.LanguageUtil;
import com.liferay.portal.model.User;
import io.swagger.v3.oas.annotations.Operation;
Expand Down Expand Up @@ -77,6 +79,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.LongSupplier;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand All @@ -92,29 +95,30 @@ public class ContentResource {
private final ContentletAPI contentletAPI;
private final IdentifierAPI identifierAPI;
private final LanguageWebAPI languageWebAPI;
private final LanguageAPI languageAPI;

private final Lazy<Boolean> isDefaultContentToDefaultLanguageEnabled = Lazy.of(
() -> Config.getBooleanProperty("DEFAULT_CONTENT_TO_DEFAULT_LANGUAGE", false));


public ContentResource() {

this(new WebResource(),
APILocator.getContentletAPI(),
APILocator.getIdentifierAPI(),
WebAPILocator.getLanguageWebAPI());
WebAPILocator.getLanguageWebAPI(),
APILocator.getLanguageAPI());
}

@VisibleForTesting
public ContentResource(final WebResource webResource,
final ContentletAPI contentletAPI,
final IdentifierAPI identifierAPI,
final LanguageWebAPI languageWebAPI) {

final LanguageWebAPI languageWebAPI,
final LanguageAPI languageAPI) {
this.webResource = webResource;
this.contentletAPI = contentletAPI;
this.identifierAPI = identifierAPI;
this.languageWebAPI = languageWebAPI;
this.languageAPI = languageAPI;
}

/**
Expand Down Expand Up @@ -590,5 +594,70 @@ public Response pullRelated(@Context final HttpServletRequest request,
}


/**
* Receives the Identifier of a {@link Contentlet }, returns all the available languages in
* dotCMS and, for each of them, adds a flag indicating whether the Contentlet is available in
* that language or not. This may be particularly useful when requiring the system to provide a
* specific action when a Contentlet is NOT available in a given language. Here's an example of
* how you can use it:
* <pre>
* GET <a href="http://localhost:8080/api/v1/content/${CONTENT_ID}/languages">http://localhost:8080/api/v1/content/${CONTENT_ID}/languages</a>
* </pre>
*
* @param request The current instance of the {@link HttpServletRequest}.
* @param response The current instance of the {@link HttpServletResponse}.
* @param identifier The Identifier of the Contentlet whose available languages will be
* checked.
*
* @return A {@link Response} object containing the list of languages and the flag indicating
* whether the Contentlet is available in such a language or not.
*
* @throws DotDataException An error occurred when interacting with the database.
*/
@GET
@Path("/{identifier}/languages")
@JSONP
@NoCache
@Produces({MediaType.APPLICATION_JSON, "application/javascript"})
public Response checkContentLanguageVersions(@Context final HttpServletRequest request,
jcastro-dotcms marked this conversation as resolved.
Show resolved Hide resolved
@Context final HttpServletResponse response,
@PathParam("identifier") final String identifier) throws DotDataException {
final User user = new WebResource.InitBuilder(webResource).requestAndResponse(request, response)
.rejectWhenNoUser(true)
.requiredBackendUser(true)
.init().getUser();
Logger.debug(this, () -> String.format("Check the languages that the Contentlet '%s' is available on", identifier));
final List<ExistingLanguagesForContentletView> languagesForContent = this.getExistingLanguagesForContent(identifier, user);
return Response.ok(new ResponseEntityView<>(languagesForContent)).build();
}

/**
* Returns a list of ALL languages in dotCMS and, for each of them, adds a boolean indicating
* whether the specified Contentlet Identifier is available in such a language or not. This is
* particularly useful for the UI layer to be able to easily check what languages a Contentlet
* is available on, and what languages it is not.
*
* @param identifier The Identifier of the {@link Contentlet} whose languages are being
* checked.
* @param user The {@link User} performing this action.
*
* @return The list of languages and the flag indicating whether the Contentlet is available in
* such a language or not.
*
* @throws DotDataException An error occurred when interacting with the database.
*/
private List<ExistingLanguagesForContentletView> getExistingLanguagesForContent(final String identifier, final User user) throws DotDataException {
DotPreconditions.checkNotNull(identifier, "Contentlet ID cannot be null");
DotPreconditions.checkNotNull(user, "User cannot be null");
final ImmutableList.Builder<ExistingLanguagesForContentletView> languagesForContent = new ImmutableList.Builder<>();
final Set<Long> existingContentLanguages =
APILocator.getVersionableAPI().findContentletVersionInfos(identifier)
.stream().map(ContentletVersionInfo::getLang)
.collect(Collectors.toSet());
final List<Language> allLanguages = this.languageAPI.getLanguages();
allLanguages.forEach(language -> languagesForContent.add(new ExistingLanguagesForContentletView(language,
existingContentLanguages.contains(language.getId()))));
return languagesForContent.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.dotcms.rest.api.v1.content;

import com.dotmarketing.portlets.languagesmanager.model.Language;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
* This View is used to indicate what language a
* {@link com.dotmarketing.portlets.contentlet.model.Contentlet} is available on, and what language
* it is not. This is particularly useful for the UI to be aware of such a situation, and then
* provide the user the option to create it using that language.
*
* @author Jose Castro
* @since Jan 5th, 2023
*/
public class ExistingLanguagesForContentletView extends HashMap<String, Object> implements Serializable {

public ExistingLanguagesForContentletView(final Language language, final boolean translated) {
final Map<String, Object> dataMap = new HashMap<>(language.toMap());
this.putAll(dataMap);
this.put("translated", translated);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
*
* @author Jose Castro
* @since Jan 5th, 2023
*
* @deprecated This class is deprecated and will be removed in a future version of dotCMS.
*/
@Deprecated(since = "Nov 7th, 24", forRemoval = true)
public class ExistingLanguagesForPageView extends HashMap<String, Object> implements Serializable {

public ExistingLanguagesForPageView(final Language language, final boolean translated) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1385,12 +1385,16 @@ public ResponseEntityPageWorkflowActionsView findAvailableActions(@Context final
* whether the page is available in such a language or not.
*
* @throws DotDataException An error occurred when interacting with the database.
* @deprecated This method is deprecated and will be removed in future versions. Please use the
* more generic REST Endpoint
* {@link com.dotcms.rest.api.v1.content.ContentResource#getExistingLanguagesForContent(String, User)} instead.
*/
@GET
@Path("/{pageId}/languages")
@JSONP
@NoCache
@Produces({MediaType.APPLICATION_JSON, "application/javascript"})
@Deprecated(since = "Nov 7th, 24", forRemoval = true)
public Response checkPageLanguageVersions(@Context final HttpServletRequest request,
@Context final HttpServletResponse response,
@PathParam("pageId") final String pageId) throws DotDataException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,10 @@ private Tuple2<Contentlet, Contentlet> copyContent(final CopyContentletForm copy
* language or not.
*
* @throws DotDataException An error occurred when interacting with the database.
*
* @deprecated This method is deprecated and will be removed in future versions.
*/
@Deprecated(since = "Nov 7th, 24", forRemoval = true)
public List<ExistingLanguagesForPageView> getExistingLanguagesForPage(final String pageId, final User user) throws DotDataException {
DotPreconditions.checkNotNull(pageId, "Page ID cannot be null");
DotPreconditions.checkNotNull(user, "User cannot be null");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,4 +637,26 @@ public Response getIsoLanguagesAndCountries (
).build();
}

/**
* Returns the current default {@link Language} in the dotCMS instance.
*
* @param request The current instance of the {@link HttpServletRequest}.
* @param response The current instance of the {@link HttpServletResponse}.
*
* @return A {@link Response} object containing the default {@link Language} in the dotCMS
* instance.
*
* @throws DotDataException An error occurred when retrieving the default {@link Language}.
*/
@GET
@Path("/_getdefault")
@JSONP
@NoCache
@Produces({MediaType.APPLICATION_JSON, "application/javascript"})
public Response getDefaultLanguage(@Context final HttpServletRequest request,
jcastro-dotcms marked this conversation as resolved.
Show resolved Hide resolved
@Context final HttpServletResponse response) throws DotDataException {
Logger.debug(this, () -> "Retrieving the current default Language");
return Response.ok(new ResponseEntityView<>(this.languageAPI.getDefaultLanguage())).build();
}

}
Loading