Skip to content

Commit

Permalink
Merge branch '29872-file-field-drag-and-drop-functionality-for-file-u…
Browse files Browse the repository at this point in the history
…pload' of github.com:dotCMS/core into 29872-file-field-drag-and-drop-functionality-for-file-upload
  • Loading branch information
nicobytes committed Sep 26, 2024
2 parents e6a12ab + f272266 commit 99f5ac3
Show file tree
Hide file tree
Showing 16 changed files with 516 additions and 50 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/cicd_1-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ jobs:
postman: ${{ needs.initialize.outputs.backend == 'true' }}
frontend: ${{ needs.initialize.outputs.frontend == 'true' }}
cli: ${{ needs.initialize.outputs.cli == 'true' }}
# TODO: remove this param after testing E2E tests invocation
e2e: true
e2e: ${{ needs.initialize.outputs.build }}
secrets:
DOTCMS_LICENSE: ${{ secrets.DOTCMS_LICENSE }}

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/cicd_2-merge-queue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
postman: ${{ needs.initialize.outputs.backend == 'true' }}
frontend: ${{ needs.initialize.outputs.frontend == 'true' }}
cli: ${{ needs.initialize.outputs.cli == 'true' }}
# This will probably need to be re-evaluated, that is if it makes sense to tun E2E tests at the merge queue
# e2e: ${{ needs.initialize.outputs.build }}
secrets:
DOTCMS_LICENSE: ${{ secrets.DOTCMS_LICENSE }}
finalize:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/cicd_3-trunk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ jobs:
with:
run-all-tests: ${{ inputs.run-all-tests || false }}
artifact-run-id: ${{ needs.initialize.outputs.artifact-run-id }}
e2e: true
secrets:
DOTCMS_LICENSE: ${{ secrets.DOTCMS_LICENSE }}
permissions:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dotcms.analytics.content;

import com.dotcms.analytics.query.AnalyticsQuery;
import com.dotcms.cube.CubeJSQuery;
import com.liferay.portal.model.User;

/**
Expand All @@ -14,6 +15,20 @@
*/
public interface ContentAnalyticsAPI {

/**
* Run a report based on an analytics query
* @param query
* @param user
* @return ReportResponse
*/
ReportResponse runReport(final AnalyticsQuery query, final User user);

/**
* Runs a raw report based on a cubeJS query
* @param cubeJSQuery
* @param user
* @return ReportResponse
*/
ReportResponse runRawReport(CubeJSQuery cubeJSQuery, User user);

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dotcms.analytics.content;

import com.dotcms.analytics.query.AnalyticsQuery;
import com.dotcms.cube.CubeJSQuery;
import com.dotmarketing.util.Logger;
import com.liferay.portal.model.User;

Expand Down Expand Up @@ -31,4 +32,11 @@ public ReportResponse runReport(final AnalyticsQuery query, final User user) {
return this.contentAnalyticsFactory.getReport(query, user);
}

@Override
public ReportResponse runRawReport(CubeJSQuery cubeJSQuery, User user) {
Logger.debug(this, ()-> "Running the report for the raw query: " + cubeJSQuery);
// note: should check any permissions for an user.
return this.contentAnalyticsFactory.getRawReport(cubeJSQuery, user);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dotcms.analytics.content;

import com.dotcms.analytics.query.AnalyticsQuery;
import com.dotcms.cube.CubeJSQuery;
import com.liferay.portal.model.User;

/**
Expand All @@ -20,4 +21,13 @@ public interface ContentAnalyticsFactory {
*/
ReportResponse getReport(final AnalyticsQuery query, final User user);

/**
* Runs the raw report based on the cube js query and user.
*
* @param query the query to run the report.
* @param user the user to run the report.
* @return the report response.
*/
ReportResponse getRawReport(final CubeJSQuery query, final User user);

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ public ReportResponse getReport(final AnalyticsQuery query, final User user) {
Logger.debug(this, ()-> "Getting the report for the query: " + query);
try {
final CubeJSQuery cubeJSQuery = this.queryParser.parseQueryToCubeQuery(query);
return getRawReport(cubeJSQuery, user);
} catch (Exception e) {

Logger.error(this, e.getMessage(), e);
throw new DotRuntimeException(e);
}
}

@Override
public ReportResponse getRawReport(final CubeJSQuery cubeJSQuery, final User user) {

try {

Logger.debug(this, ()-> "Getting the report for the raw query: " + cubeJSQuery);
final CubeJSClient cubeClient = cubeJSClientFactory.create(user);
return toReportResponse(cubeClient.send(cubeJSQuery));
} catch (DotDataException| DotSecurityException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,11 @@ public ReportResponse(final List<ResultSetItem> results){
public List<ResultSetItem> getResults() {
return results;
}

@Override
public String toString() {
return "ReportResponse{" +
"results=" + results +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ public Map<String, Object> getAll(){
return new HashMap<>(item);
}

@Override
public String toString() {
return "ResultSetItem{" +
"item=" + item +
'}';
}
}
169 changes: 169 additions & 0 deletions dotCMS/src/main/java/com/dotcms/analytics/viewtool/AnalyticsTool.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package com.dotcms.analytics.viewtool;

import com.dotcms.analytics.content.ContentAnalyticsAPI;
import com.dotcms.analytics.content.ReportResponse;
import com.dotcms.analytics.query.AnalyticsQuery;
import com.dotcms.analytics.query.AnalyticsQueryParser;
import com.dotcms.cdi.CDIUtils;
import com.dotcms.cube.CubeJSQuery;
import com.dotcms.rest.api.v1.DotObjectMapperProvider;
import com.dotmarketing.business.web.UserWebAPI;
import com.dotmarketing.business.web.WebAPILocator;
import com.dotmarketing.exception.DotRuntimeException;
import com.dotmarketing.util.Logger;
import com.liferay.portal.model.User;
import org.apache.velocity.tools.view.context.ViewContext;
import org.apache.velocity.tools.view.tools.ViewTool;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
* This class is a ViewTool that can be used to access the analytics data.
* @author jsanca
*/
public class AnalyticsTool implements ViewTool {

private final ContentAnalyticsAPI contentAnalyticsAPI;
private final AnalyticsQueryParser analyticsQueryParser;
private final UserWebAPI userWebAPI;

private User user = null;

public AnalyticsTool() {
this(getContentAnalyticsAPI(),
getAnalyticsQueryParser(),
WebAPILocator.getUserWebAPI());
}

private static ContentAnalyticsAPI getContentAnalyticsAPI() {
final Optional<ContentAnalyticsAPI> contentAnalyticsAPI = CDIUtils.getBean(ContentAnalyticsAPI.class);
if (!contentAnalyticsAPI.isPresent()) {
throw new DotRuntimeException("Could not instance ContentAnalyticsAPI");
}
return contentAnalyticsAPI.get();
}

private static AnalyticsQueryParser getAnalyticsQueryParser() {
final Optional<AnalyticsQueryParser> queryParserOptional = CDIUtils.getBean(AnalyticsQueryParser.class);
if (!queryParserOptional.isPresent()) {
throw new DotRuntimeException("Could not instance AnalyticsQueryParser");
}
return queryParserOptional.get();
}

public AnalyticsTool(final ContentAnalyticsAPI contentAnalyticsAPI,
final AnalyticsQueryParser analyticsQueryParser,
final UserWebAPI userWebAPI) {

this.contentAnalyticsAPI = contentAnalyticsAPI;
this.analyticsQueryParser = analyticsQueryParser;
this.userWebAPI = userWebAPI;
}

@Override
public void init(final Object initData) {

if (initData instanceof ViewContext) {

final HttpServletRequest request = ((ViewContext) initData).getRequest();
final HttpSession session = request.getSession(false);

if (session != null) {
try {
user = userWebAPI.getLoggedInUser(request);
} catch (DotRuntimeException e) {
Logger.error(this.getClass(), e.getMessage());
}
}
}
}

/**
* Runs an analytics report based on the string json query.
* example:
* <code>
* #set($query = "{
* "dimensions": ["Events.referer", "Events.experiment", "Events.variant", "Events.utcTime", "Events.url", "Events.lookBackWindow", "Events.eventType"],
* "measures": ["Events.count", "Events.uniqueCount"],
* "filters": "Events.variant = ['B'] or Events.experiments = ['B']",
* "limit":100,
* "offset":1,
* "timeDimensions":"Events.day day",
* "orders":"Events.day ASC"
* }")
*
* $analytics.runReportFromJson($query)
* </code>
* @param query
* @return
*/
public ReportResponse runReportFromJson(final String query) {

Logger.debug(this, () -> "Running report from json: " + query);
return contentAnalyticsAPI.runReport(this.analyticsQueryParser.parseJsonToQuery(query), user);
}

/**
* Runs an analytics report based on Map query.
* example:
* <code>
* #set ($myQuery = {})
* $myMap.put('dimensions', ["Events.referer", "Events.experiment", "Events.variant", "Events.utcTime", "Events.url", "Events.lookBackWindow", "Events.eventType"])
* $myMap.put('measures', ["Events.count", "Events.uniqueCount"])
* $myMap.put('filters', "Events.variant = ['B'] or Events.experiments = ['B']")
* $myMap.put('limit', 100)
* $myMap.put('offset', 1)
* $myMap.put('timeDimensions', "Events.day day")
* $myMap.put('orders', "Events.day ASC")
*
* $analytics.runReportFromMap($myQuery)
* </code>
* @param query
* @return
*/
public ReportResponse runReportFromMap(final Map<String, Object> query) {

if (Objects.isNull(query)) {
throw new IllegalArgumentException("Query can not be null");
}

Logger.debug(this, () -> "Running report from map: " + query);
final AnalyticsQuery analyticsQuery = DotObjectMapperProvider.getInstance()
.getDefaultObjectMapper().convertValue(query, AnalyticsQuery.class);
return contentAnalyticsAPI.runReport(analyticsQuery, user);
}

/**
* Creates a CubeJSQuery.Builder instance
* @return
*/
public CubeJSQuery.Builder createCubeJSQueryBuilder() {
return new CubeJSQuery.Builder();
}

/**
* Runs an analytics report based cube js raw json string query
*
* example:
* <code>
* #set($query = $analytics.createCubeJSQueryBuilder())
* $query.dimensions("Events.experiment", "Events.variant")
* $analytics.runRawReport($query.build())
* </code>
* @param query
* @return
*/
public ReportResponse runRawReport(final CubeJSQuery query) {

if (Objects.isNull(query)) {
throw new IllegalArgumentException("Query can not be null");
}

Logger.debug(this, () -> "Running report from raw query: " + query);
return contentAnalyticsAPI.runRawReport(query, user);
}
}
18 changes: 3 additions & 15 deletions dotCMS/src/main/java/com/dotcms/cube/CubeJSQuery.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.dotcms.cube;



import com.dotcms.api.system.event.SystemEventsFactory;
import com.dotcms.cube.filters.Filter;
import com.dotcms.cube.filters.Filter.Order;
import com.dotcms.cube.filters.LogicalFilter;
import com.dotcms.cube.filters.SimpleFilter;
import com.dotcms.cube.filters.SimpleFilter.Operator;
import com.dotcms.cube.filters.Filter;
import com.dotcms.experiments.business.result.ExperimentResults;
import com.dotcms.experiments.business.result.ExperimentResults.Builder;
import com.dotcms.util.DotPreconditions;
import com.dotcms.util.JsonUtil;
import com.dotmarketing.util.UtilMethods;
import com.google.common.collect.Iterables;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -24,16 +22,6 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


Expand Down
Loading

0 comments on commit 99f5ac3

Please sign in to comment.