Compare commits

...

22 Commits

Author SHA1 Message Date
AlMaVizca 3774afee32
Merge development image into a single Dockerfile
Changes based on PR review
2023-12-29 23:15:10 +07:00
AlMaVizca 53fd5ebbbb
Relocate php unit configuration 2023-12-23 14:00:19 +07:00
AlMaVizca 635adf1a04
Refactor composer dependencies to create the production image
Use docker stages to install dependencies and simplify the building script.
Prepare production image while keeping compatibility with the development image.

Fix typo

Relocate arguments to improve cache

Make single line for each env definition

Remove composer home path

Avoid installing recommended packages
2023-12-23 14:00:19 +07:00
AlMaVizca 3a25ca5d71
Avoid repeating common path
Use common path on entrypoint
2023-12-23 14:00:19 +07:00
AlMaVizca 4803e40043
Define baseimage with arguments required in multiple stages
Change versions, add common paths

Keep drupal path

Fix comment
2023-12-23 14:00:19 +07:00
wotnak a2bd7136cf Configure www service to wait for db service to be healthy instead of only started #758 2023-12-22 06:17:47 -05:00
wotnak 1773a2eae5 Add healthcheck to MariaDB container to ensure it is ready to accept external connections before reporting as ready #758 2023-12-22 06:17:37 -05:00
Paul Weidner 0e211cb33c Increase weight of Asset and Log tasks on canonical user route #757
The current weight of these menu items is 0 and makes it challenging to
place other menu tasks between Edit and Asset. I would like to add a
Notifications task item and keep it closer to the edit task.
2023-12-09 07:08:03 -08:00
Michael Stenta 8147d47c88 Move quick form Kernel tests directory into src directory. 2023-12-07 14:32:13 -05:00
Paul Weidner d16bc107ad Use strict identical operator when checking geometry format #756 2023-11-30 14:02:13 -05:00
Paul Weidner 56b3b4de95 Correct alter hook to add password grant to static scopes #755 2023-11-30 13:55:52 -05:00
Michael Stenta a07a491903 farmOS 3.0.0-beta3 2023-11-27 14:42:12 -05:00
Michael Stenta 845ee7f6cb Update drupal/state_machine to ^1.9 and remove merged patch. 2023-11-27 13:59:03 -05:00
Michael Stenta 9d8dc8dd1f Only create releases on tag pushes to the official repository. 2023-11-27 13:40:49 -05:00
Michael Stenta 485908beb0 Fix composer require farmos/farmos version constraint in build-farmOS.sh. 2023-11-27 13:40:49 -05:00
Michael Stenta c0804bb22d Only add farmOS repository to composer.json for non-tag versions. 2023-11-27 13:40:23 -05:00
Michael Stenta 19f227a8f6 Fix KML serialization #753 2023-11-27 11:47:09 -05:00
Michael Stenta 7e3422cd4d Add CHANGELOG.md line for #753. 2023-11-27 11:44:53 -05:00
Paul Weidner b97184d165 Use ContentEntityInterface as type when normalizing to geometry_* formats 2023-11-27 11:44:53 -05:00
Paul Weidner 94c9fe9ed0 Use GeometryWrapper as type when normalizing to geometry_kml format 2023-11-27 11:44:53 -05:00
Michael Stenta 8f2efe2724 Add default view_builder handler for plan type, for consistency.
Both asset type and plan type use a "canonical" link.
2023-11-27 11:44:31 -05:00
Paul Weidner 808a6abb58 Add default view_builder handler for asset type #752
This fixes a potential bug where the canonical route is not created if a view_builder is not provided.
2023-11-27 10:28:55 -05:00
22 changed files with 233 additions and 218 deletions

View File

@ -48,7 +48,7 @@ jobs:
# farmOS Composer project 3.x branch is always used.
- name: Build and save farmOS dev Docker image
run: |
docker build --build-arg FARMOS_REPO=https://github.com/${FARMOS_REPO} --build-arg FARMOS_VERSION=${FARMOS_VERSION} -t farmos/farmos:3.x-dev docker/dev
docker build --build-arg FARMOS_REPO=https://github.com/${FARMOS_REPO} --build-arg FARMOS_VERSION=${FARMOS_VERSION} -t farmos/farmos:3.x-dev --target dev docker
docker save farmos/farmos:3.x-dev > /tmp/farmos-dev.tar
- name: Cache farmOS dev Docker image
uses: actions/cache@v3
@ -127,8 +127,10 @@ jobs:
- name: Test Drush site install with all modules
run: docker compose exec -u www-data -T www drush site-install --db-url=${{ matrix.DB_URL }} farm farm.modules='all'
release:
name: Create GitHub release
if: github.event_name == 'push' && github.ref_type == 'tag'
name: Create release
# We only create a release if this is a tag push event to the official
# repository.
if: github.repository == 'farmOS/farmOS' && github.event_name == 'push' && github.ref_type == 'tag'
runs-on: ubuntu-latest
needs:
- build

View File

@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Changed
- [Increase weight of Asset and Log tasks on canonical user route #757](https://github.com/farmOS/farmOS/pull/757)
### Fixed
- [Correct alter hook to add password grant to static scopes #755](https://github.com/farmOS/farmOS/pull/755)
- [Use strict identical operator when checking geometry format #756](https://github.com/farmOS/farmOS/pull/756)
## [3.0.0-beta3] 2023-11-27
### Fixed
- [Fix KML serialization #753](https://github.com/farmOS/farmOS/pull/753)
## [3.0.0-beta2] 2023-11-03
### Fixed
@ -636,7 +651,8 @@ moving forward.
Drupal 7, which required a complete refactor of the codebase. By comparison,
updating from Drupal 9 to 10 will simply involve updating deprecated code.
[Unreleased]: https://github.com/farmOS/farmOS/compare/3.0.0-beta2...HEAD
[Unreleased]: https://github.com/farmOS/farmOS/compare/3.0.0-beta3...HEAD
[3.0.0-beta3]: https://github.com/farmOS/farmOS/releases/tag/3.0.0-beta3
[3.0.0-beta2]: https://github.com/farmOS/farmOS/releases/tag/3.0.0-beta2
[3.0.0-beta1]: https://github.com/farmOS/farmOS/releases/tag/3.0.0-beta1
[2.2.2]: https://github.com/farmOS/farmOS/releases/tag/2.2.2

View File

@ -44,7 +44,7 @@
"drupal/role_delegation": "^1.2",
"drupal/simple_oauth": "6.0.0-beta5",
"drupal/simple_oauth_password_grant": "^1.0@RC",
"drupal/state_machine": "1.8",
"drupal/state_machine": "^1.9",
"drupal/subrequests": "^3.0.6",
"drupal/token": "^1.11",
"drupal/views_geojson": "^1.2",
@ -84,9 +84,6 @@
"Issue #3322325: Cannot authorize clients with empty string set as secret": "https://www.drupal.org/files/issues/2023-10-31/3322325-8.patch",
"Issue #3397590: Add method to check if scope has permission": "https://www.drupal.org/files/issues/2023-10-30/3397590-5_0.patch"
},
"drupal/state_machine": {
"Issue #3396186: State constraint is not validated on new entities": "https://www.drupal.org/files/issues/2023-10-23/3396186-2.patch"
},
"itamair/geophp": {
"Use BCMath (where available) for all float arithmetic #115": "https://patch-diff.githubusercontent.com/raw/phayes/geoPHP/pull/115.patch"
}

View File

@ -1,7 +1,14 @@
# Use the official Drupal 10 image to build GEOS PHP extension.
FROM drupal:10.1 as php-dependencies
# Use the official Drupal 10 as base image.
FROM drupal:10.1 as baseimage
# Define common paths.
ENV FARMOS_PATH=/var/farmOS
ENV DRUPAL_PATH=/opt/drupal
##
# Build PHP extensions, GEOS and bcmath.
FROM baseimage as php-dependencies
# Build and install the GEOS PHP extension.
# See https://git.osgeo.org/gitea/geos/php-geos
ARG PHP_GEOS_VERSION=e77d5a16abbf89a59d947d1fe49381a944762c9d
ADD https://github.com/libgeos/php-geos/archive/${PHP_GEOS_VERSION}.tar.gz /opt/php-geos.tar.gz
@ -17,51 +24,119 @@ RUN apt-get update && apt-get install -y libgeos-dev \
# Install the BCMath PHP extension.
RUN docker-php-ext-install bcmath
# Inherit from the official Drupal 10 image.
FROM drupal:10.1
# Setup dependencies and sources for composer installations.
FROM baseimage as composer-file
# Set the farmOS and composer project repository URLs and versions.
ARG FARMOS_REPO=https://github.com/farmOS/farmOS.git
ARG FARMOS_VERSION=3.x
ARG PROJECT_REPO=https://github.com/farmOS/composer-project.git
ARG PROJECT_VERSION=3.x
ARG PROJECT_REPO=https://github.com/farmOS/composer-project/raw/${PROJECT_VERSION}/composer.json
# Set the COMPOSER_MEMORY_LIMIT environment variable to unlimited.
ENV COMPOSER_MEMORY_LIMIT=-1
# Allow root to install plugins.
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV COMPOSER_NO_INTERACTION=1
# Install apt dependencies.
RUN apt-get update && apt-get install -y --no-install-recommends\
# Install git and unzip (needed by Composer).
git unzip
# Add the build-farmOS.sh script.
COPY build-farmOS.sh /usr/local/bin/
# Setup composer file for non interactive installation.
WORKDIR ${FARMOS_PATH}
RUN build-farmOS.sh
##
# Create layer with farmOS sources.
FROM composer-file as farmos-sources
# Install sources.
RUN composer install --no-dev
# Set the version in farm.info.yml.
RUN sed -i "s|version: 3.x|version: ${FARMOS_VERSION}|g" ${FARMOS_PATH}/web/profiles/farm/farm.info.yml
##
# Create layer with farmOS dev sources.
FROM farmos-sources as farmos-dev-sources
# Install sources.
RUN composer update
##
# Dependencies layer.
FROM baseimage as farmos-baseimage
# Set Apache ServerName directive globally to suppress AH00558 message.
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
# Install and enable geos.
# Enable PHP dependencies.
COPY --from=php-dependencies /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
RUN docker-php-ext-enable geos bcmath
# Add custom PHP configurations.
COPY conf.d/ /usr/local/etc/php/conf.d
# Install apt dependencies.
RUN apt-get update && apt-get install -y \
# Install git and unzip (needed by Composer).
git unzip \
# Install apt dependencies and clean up.
RUN apt-get update && apt-get install -y --no-install-recommends\
# Install postgresql-client so Drush can connect to the database.
postgresql-client \
# Install libgeos-c1v5 so geos php extension can use libgeos_c.so.1.
libgeos-c1v5 \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
# Set the COMPOSER_MEMORY_LIMIT environment variable to unlimited.
ENV COMPOSER_MEMORY_LIMIT=-1
# Add the build-farmOS.sh script.
COPY build-farmOS.sh /usr/local/bin/
RUN chmod a+x /usr/local/bin/build-farmOS.sh
# Build the farmOS codebase in /var/farmoS with the --no-dev flag.
# Change the ownership of the sites directory and copy the farmOS codebase into /opt/drupal.
RUN mkdir /var/farmOS \
&& /usr/local/bin/build-farmOS.sh --no-dev \
&& chown -R www-data:www-data /var/farmOS/web/sites \
&& rm -r /opt/drupal && cp -rp /var/farmOS /opt/drupal
# Install git and unzip (needed by Composer).
git unzip \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean \
# Clean up ${DRUPAL_PATH}.
&& rm -r ${DRUPAL_PATH} \
&& mkdir ${DRUPAL_PATH}
# Set the entrypoint.
COPY docker-entrypoint.sh /usr/local/bin/
COPY --chown=www-data docker-entrypoint.sh /usr/local/bin/
# Set the working directory, entrypoint and command.
WORKDIR ${DRUPAL_PATH}
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["apache2-foreground"]
##
# Development image.
FROM farmos-baseimage as dev
# Change the user/group IDs of www-data inside the image to match the ID of the
# developer's user on the host machine. This allows Composer to create files
# owned by www-data inside the container, while keeping those files editable by
# the developer outside of the container.
# This defaults to 1000, based on the assumption that the developer is running
# as UID 1000 on the host machine. It can be overridden at image build time with:
# --build-arg WWW_DATA_ID=$(id -u)
ARG WWW_DATA_ID=1000
RUN usermod -u ${WWW_DATA_ID} www-data && groupmod -g ${WWW_DATA_ID} www-data
# Install and configure XDebug.
RUN yes | pecl install xdebug \
&& docker-php-ext-enable xdebug
# Add opcache revalidation frequency configuration.
COPY dev/conf.d/ /usr/local/etc/php/conf.d
# Add Configurations for PHP CodeSniffer, PHPStan
COPY --chown=www-data:www-data ./dev/files/ ${FARMOS_PATH}
# Add farmOS dev sources.
COPY --from=farmos-dev-sources --chown=www-data:www-data ${FARMOS_PATH} ${FARMOS_PATH}
# Configure PHPUnit.
RUN ${FARMOS_PATH}/phpunit.sh
##
# Final image.
FROM farmos-baseimage
# Add farmOS sources.
COPY --from=farmos-sources --chown=www-data:www-data ${FARMOS_PATH} ${DRUPAL_PATH}

53
docker/build-farmOS.sh Normal file → Executable file
View File

@ -2,43 +2,43 @@
set -e
###
# This script will build the farmOS codebase in /var/farmOS.
# This script will build the farmOS codebase in ${FARMOS_PATH},
# by default it is /var/farmOS.
###
# If /var/farmOS is not empty, bail.
if [ "$(ls -A /var/farmOS/)" ]; then
# If ${FARMOS_PATH} is not empty, bail.
if [ "$(ls -A ${FARMOS_PATH})" ]; then
echo "The ${FARMOS_PATH} is not empty, terminate."
exit 1
fi
# Make /var/farmOS the working directory.
cd /var/farmOS
# Fetch composer template
curl -L ${PROJECT_REPO} -o composer.json
# Generate an empty Composer project project and checkout a specific version.
git clone ${PROJECT_REPO} project
mv project/.git ./.git
rm -rf project
git checkout ${PROJECT_VERSION}
git reset --hard
# If FARMOS_VERSION is a valid semantic versioning string, we assume that it is
# a tagged version.
IS_TAGGED_RELEASE=false
if [[ "${FARMOS_VERSION}" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$ ]]; then
IS_TAGGED_RELEASE=true
fi
# Create a temporary Composer cache directory.
export COMPOSER_HOME="$(mktemp -d)"
# Add the farmOS repository to composer.json.
composer config repositories.farmos git ${FARMOS_REPO}
# Add the farmOS repository to composer.json (if this is not a tagged release).
if [ "${IS_TAGGED_RELEASE}" = false ]; then
composer config repositories.farmos git ${FARMOS_REPO}
fi
# Require the correct farmOS version in composer.json.
# If FARMOS_VERSION is 3.x, we will require 3.x-dev.
if [ "${FARMOS_VERSION}" = "3.x" ]; then
FARMOS_COMPOSER_VERSION="3.x-dev"
# Or, if FARMOS_VERSION is a valid semantic versioning string, we assume that it
# is a tagged version and require that version.
elif [[ "${FARMOS_VERSION}" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$ ]]; then
# Or, if this is a tagged release, require the tag version.
elif [ "${IS_TAGGED_RELEASE}" = true ]; then
FARMOS_COMPOSER_VERSION="${FARMOS_VERSION}"
# Otherwise, we assume that FARMOS_VERSION is a branch, and prepend "dev-".
else
FARMOS_COMPOSER_VERSION="dev-${FARMOS_VERSION}"
fi
composer require farmos/farmos ${FARMOS_COMPOSER_VERSION} --no-install
composer require farmos/farmos:${FARMOS_COMPOSER_VERSION} --no-install
# Add allow-plugins config.
allowedPlugins=(
@ -53,16 +53,3 @@ allowedPlugins=(
for plugin in ${allowedPlugins[@]}; do
composer config --no-plugins allow-plugins.$plugin true
done
# Run composer install with optional arguments passed into this script.
if [ $# -eq 0 ]; then
composer install
else
composer install "$*"
fi
# Set the version in farm.info.yml.
sed -i "s|version: 3.x|version: ${FARMOS_VERSION}|g" /var/farmOS/web/profiles/farm/farm.info.yml
# Remove the Composer cache directory.
rm -rf "$COMPOSER_HOME"

View File

@ -1,63 +0,0 @@
# Inherit from the farmOS 3.x image.
FROM farmos/farmos:3.x
# Set the farmOS and composer project repository URLs and versions.
ARG FARMOS_REPO=https://github.com/farmOS/farmOS.git
ARG FARMOS_VERSION=3.x
ARG PROJECT_REPO=https://github.com/farmOS/composer-project.git
ARG PROJECT_VERSION=3.x
# Install and enable XDebug extension.
RUN yes | pecl install xdebug \
&& docker-php-ext-enable xdebug
# Add opcache revalidation frequency configuration.
COPY conf.d/ /usr/local/etc/php/conf.d
# Change the user/group IDs of www-data inside the image to match the ID of the
# developer's user on the host machine. This allows Composer to create files
# owned by www-data inside the container, while keeping those files editable by
# the developer outside of the container.
# This defaults to 1000, based on the assumption that the developer is running
# as UID 1000 on the host machine. It can be overridden at image build time with:
# --build-arg WWW_DATA_ID=$(id -u)
ARG WWW_DATA_ID=1000
RUN usermod -u ${WWW_DATA_ID} www-data && groupmod -g ${WWW_DATA_ID} www-data
# Create a fresh /var/farmOS directory owned by www-data.
# We do this in two steps because of a known issue with Moby.
# @see https://github.com/farmOS/farmOS/pull/440
RUN rm -r /var/farmOS
RUN mkdir /var/farmOS && chown www-data:www-data /var/farmOS
# Change to the www-data user.
USER www-data
# Build the farmOS codebase in /var/farmOS.
RUN /usr/local/bin/build-farmOS.sh
# Add Configurartions for PHP CodeSniffer, PHPStan.
COPY --chown=www-data ./files/ /var/farmOS/
# Configure PHPUnit.
RUN cp -p /var/farmOS/web/core/phpunit.xml.dist /var/farmOS/phpunit.xml \
&& sed -i 's|bootstrap="tests/bootstrap.php"|bootstrap="web/core/tests/bootstrap.php"|g' /var/farmOS/phpunit.xml \
&& sed -i '/failOnWarning="true"/a \ failOnIncomplete="true"' /var/farmOS/phpunit.xml \
&& sed -i '/failOnWarning="true"/a \ failOnSkipped="true"' /var/farmOS/phpunit.xml \
&& sed -i 's|name="SIMPLETEST_BASE_URL" value=""|name="SIMPLETEST_BASE_URL" value="http://www"|g' /var/farmOS/phpunit.xml \
&& sed -i 's|name="SIMPLETEST_DB" value=""|name="SIMPLETEST_DB" value="pgsql://farm:farm@db/farm"|g' /var/farmOS/phpunit.xml \
&& sed -i 's|name="BROWSERTEST_OUTPUT_DIRECTORY" value=""|name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/html/sites/simpletest/browser_output"|g' /var/farmOS/phpunit.xml \
&& sed -i 's|name="MINK_DRIVER_ARGS_WEBDRIVER" value='\'''\''|name="MINK_DRIVER_ARGS_WEBDRIVER" value='\''["chrome", { "chromeOptions": { "w3c": false, "args": ["--disable-gpu","--headless", "--no-sandbox"] } }, "http://chrome:4444/wd/hub"]'\''|g' /var/farmOS/phpunit.xml \
&& sed -i 's|\./|\./web/core/|g' /var/farmOS/phpunit.xml \
&& sed -i 's|\.\./web/core/|\./web/|g' /var/farmOS/phpunit.xml \
&& sed -i 's| </php>| <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/>'"\n"' </php>|g' /var/farmOS/phpunit.xml \
&& mkdir -p /var/farmOS/web/sites/simpletest/browser_output
# Change back to the root user.
USER root
# Copy the farmOS codebase into /opt/drupal.
RUN rm -r /opt/drupal && cp -rp /var/farmOS /opt/drupal
# Create a Composer config directory for the www-data user.
RUN mkdir /var/www/.composer && chown www-data:www-data /var/www/.composer

19
docker/dev/files/phpunit.sh Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env sh
cp -p ${FARMOS_PATH}/web/core/phpunit.xml.dist ${FARMOS_PATH}/phpunit.xml
sed -i 's|bootstrap="tests/bootstrap.php"|bootstrap="web/core/tests/bootstrap.php"|g' ${FARMOS_PATH}/phpunit.xml
sed -i '/failOnWarning="true"/a \ failOnIncomplete="true"' ${FARMOS_PATH}/phpunit.xml
sed -i '/failOnWarning="true"/a \ failOnSkipped="true"' ${FARMOS_PATH}/phpunit.xml
sed -i 's|name="SIMPLETEST_BASE_URL" value=""|name="SIMPLETEST_BASE_URL" value="http://www"|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|name="SIMPLETEST_DB" value=""|name="SIMPLETEST_DB" value="pgsql://farm:farm@db/farm"|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|name="BROWSERTEST_OUTPUT_DIRECTORY" value=""|name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/html/sites/simpletest/browser_output"|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|name="MINK_DRIVER_ARGS_WEBDRIVER" value='\'''\''|name="MINK_DRIVER_ARGS_WEBDRIVER" value='\''["chrome", { "chromeOptions": { "w3c": false, "args": ["--disable-gpu","--headless", "--no-sandbox"] } }, "http://chrome:4444/wd/hub"]'\''|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|\./|\./web/core/|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|\.\./web/core/|\./web/|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's| </php>| <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/>'"\n"' </php>|g' ${FARMOS_PATH}/phpunit.xml
# Create output directory for phpunit tests and permissions for testing user.
mkdir -p ${FARMOS_PATH}/web/sites/simpletest/browser_output
chown -R www-data:www-data ${FARMOS_PATH}/web/sites/simpletest
rm ${FARMOS_PATH}/phpunit.sh

View File

@ -12,7 +12,15 @@ services:
MYSQL_DATABASE: farm
MYSQL_USER: farm
MYSQL_PASSWORD: farm
healthcheck:
test: [ "CMD", "healthcheck.sh", "--connect", "--innodb_initialized" ]
start_period: 1m
start_interval: 10s
interval: 1m
timeout: 5s
retries: 3
www:
depends_on:
- db
db:
condition: service_healthy

View File

@ -8,15 +8,15 @@ set -e
###
# If the Drupal directory is empty, populate it from pre-built files.
if [ -d /opt/drupal ] && ! [ "$(ls -A /opt/drupal/)" ]; then
if [ -d ${DRUPAL_PATH} ] && ! [ "$(ls -A ${DRUPAL_PATH}/)" ]; then
echo "farmOS codebase not detected. Copying from pre-built files in the Docker image."
cp -rp /var/farmOS/. /opt/drupal
cp -rp ${FARMOS_PATH}/. ${DRUPAL_PATH}
fi
# If the sites directory is empty, populate it from pre-built files.
if [ -d /opt/drupal/web/sites ] && ! [ "$(ls -A /opt/drupal/web/sites/)" ]; then
if [ -d ${DRUPAL_PATH}/web/sites ] && ! [ "$(ls -A ${DRUPAL_PATH}/web/sites/)" ]; then
echo "farmOS sites directory not detected. Copying from pre-built files in the Docker image."
cp -rp /var/farmOS/web/sites/. /opt/drupal/web/sites
cp -rp ${FARMOS_PATH}/web/sites/. ${DRUPAL_PATH}/web/sites
fi
if [ -n "$FARMOS_FS_READY_SENTINEL_FILENAME" ]; then

View File

@ -17,7 +17,9 @@ Available arguments and their default values are described below:
check out.
- Default: `3.x`
The `3.x-dev` image also provides the following:
## Development image
The `3.x-dev` image also provides the following build arguments:
- `WWW_DATA_ID` - The ID to use for the `www-data` user and group inside the
image. Setting this to the ID of the developer's user on the host machine
@ -26,3 +28,8 @@ The `3.x-dev` image also provides the following:
container. If your user ID is not `1000`, build the image with:
`--build-arg WWW_DATA_ID=$(id -u)`
- Default: `1000`
To build the development image, you will have to define the target dev,
for example:
`docker build --build-arg WWW_DATA_ID=$(id -u) -t farmos/farmos:3.x-dev --target dev docker`

View File

@ -20,6 +20,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
* ),
* handlers = {
* "list_builder" = "Drupal\asset\AssetTypeListBuilder",
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "form" = {
* "add" = "Drupal\asset\Form\AssetTypeForm",
* "edit" = "Drupal\asset\Form\AssetTypeForm",

View File

@ -52,54 +52,48 @@ class ContentEntityGeometryNormalizer implements NormalizerInterface, Serializer
return $geometries;
}
// Check the entity geofield.
$geofield = $context['geofield'];
$entities = is_array($object) ? $object : [$object];
foreach ($entities as $entity) {
$entity = $object;
if (!$entity->hasField($geofield)) {
return NULL;
}
// If the entity doesn't have the configured geofield field, bail.
if (!$entity->hasField($geofield)) {
continue;
}
// If the geofield is empty, bail.
if ($entity->get($geofield)->isEmpty()) {
return NULL;
}
// If the geofield is empty, bail.
if ($entity->get($geofield)->isEmpty()) {
continue;
}
// Check WKT value.
$field_value = $entity->get($geofield)->first();
$wkt = $field_value->get('value')->getValue();
if (empty($wkt)) {
return NULL;
}
$field_value = $entity->get($geofield)->first();
$wkt = $field_value->get('value')->getValue();
if (!empty($wkt)) {
// Load WKT as a GeoPHP Geometry object.
$geometry = $this->geoPHP->load($wkt, 'wkt');
// Load WKT as a GeoPHP Geometry object.
$geometry = $this->geoPHP->load($wkt, 'wkt');
// Build geometry properties.
$properties = [
'id' => $entity->uuid(),
'name' => htmlspecialchars($entity->label()),
'entity_type' => $entity->getEntityTypeId(),
'bundle' => $entity->bundle(),
'internal_id' => $entity->id(),
];
// Build geometry properties.
$properties = [
'id' => $entity->uuid(),
'name' => htmlspecialchars($entity->label()),
'entity_type' => $entity->getEntityTypeId(),
'bundle' => $entity->bundle(),
'internal_id' => $entity->id(),
];
// Add entity notes as the description.
if ($entity->hasField('notes')) {
$notes = $entity->get('notes')->first()->getValue();
if (!empty($notes['value'])) {
$properties['description'] = $notes['value'];
}
}
// Create the GeometryWrapper.
$geometry_wrapper = new GeometryWrapper($geometry, $properties);
$geometries[] = $geometry_wrapper;
// Add entity notes as the description.
if ($entity->hasField('notes')) {
$notes = $entity->get('notes')->first()->getValue();
if (!empty($notes['value'])) {
$properties['description'] = $notes['value'];
}
}
// Normalize the GeometryWrapper objects to their target type.
return array_map(function (GeometryWrapper $geom) use ($format, $context) {
return $this->serializer->normalize($geom, $format, $context);
}, $geometries);
// Normalize the GeometryWrapper object to the target type.
$geometry_wrapper = new GeometryWrapper($geometry, $properties);
return $this->serializer->normalize($geometry_wrapper, $format, $context);
}
/**
@ -107,25 +101,10 @@ class ContentEntityGeometryNormalizer implements NormalizerInterface, Serializer
*/
public function supportsNormalization($data, $format = NULL) {
// First check if the format is supported.
// Check that the data is a content entity.
// Only formats that are prefixed with "geometry_" are supported.
// This makes it easier for other modules to provide geometry encoders.
if (strpos($format, 'geometry_') !== 0) {
return FALSE;
}
// Change data to an array.
if (!is_array($data)) {
$data = [$data];
}
// Count how many objects are not content entities.
$invalid_count = count(array_filter($data, function ($object) {
return !$object instanceof ContentEntityInterface;
}));
// Ensure all items are content entities.
return $invalid_count === 0;
return $data instanceof ContentEntityInterface && strpos($format, 'geometry_') === 0;
}
/**
@ -133,7 +112,7 @@ class ContentEntityGeometryNormalizer implements NormalizerInterface, Serializer
*/
public function getSupportedTypes(?string $format): array {
return [
GeometryWrapper::class => TRUE,
ContentEntityInterface::class => TRUE,
];
}

View File

@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\farm_geo\GeometryWrapper;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Serializer\SerializerInterface;
@ -148,7 +149,7 @@ class KmlImporter extends FormBase {
// Deserialize the KML placemarks into WKT geometry.
/** @var \Drupal\farm_geo\GeometryWrapper[] $geometries */
$geometries = $this->serializer->deserialize($data, 'geometry_wrapper', 'geometry_kml');
$geometries = $this->serializer->deserialize($data, GeometryWrapper::class, 'geometry_kml');
// Bail if no geometries were found.
if (empty($geometries)) {

View File

@ -32,7 +32,7 @@ class Kml extends XmlEncoder {
$xml = [
'@xmlns' => 'http://earth.google.com/kml/2.1',
'Document' => [
'Placemark' => $data,
'Placemark' => array_filter(array_values($data)),
],
];

View File

@ -22,7 +22,7 @@ class KmlNormalizer implements NormalizerInterface, DenormalizerInterface {
/**
* The supported type to denormalize to.
*/
const TYPE = 'geometry_wrapper';
const TYPE = GeometryWrapper::class;
/**
* The GeoPHP service.
@ -84,22 +84,7 @@ class KmlNormalizer implements NormalizerInterface, DenormalizerInterface {
* {@inheritdoc}
*/
public function supportsNormalization($data, $format = NULL) {
// First check if the format is supported.
if ($format !== static::FORMAT) {
return FALSE;
}
// Change data to an array.
if (!is_array($data)) {
$data = [$data];
}
// Ensure all items are GeometryWrappers.
$invalid_count = count(array_filter($data, function ($object) {
return !$object instanceof GeometryWrapper;
}));
return $invalid_count === 0;
return $data instanceof GeometryWrapper && $format == static::FORMAT;
}
/**
@ -168,7 +153,7 @@ class KmlNormalizer implements NormalizerInterface, DenormalizerInterface {
*/
public function getSupportedTypes(?string $format): array {
return [
GeometryWrapper::class => TRUE,
static::TYPE => TRUE,
];
}

View File

@ -20,6 +20,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
* ),
* handlers = {
* "list_builder" = "Drupal\plan\PlanTypeListBuilder",
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "form" = {
* "add" = "Drupal\plan\Form\PlanTypeForm",
* "edit" = "Drupal\plan\Form\PlanTypeForm",

View File

@ -18,7 +18,7 @@ function farm_role_roles_oauth2_scope_info_alter(array &$scopes) {
'farm_viewer',
];
foreach ($target_scopes as $scope_id) {
if (isset($target_scopes[$scope_id])) {
if (isset($scopes[$scope_id])) {
$scopes[$scope_id]['grant_types']['password'] = [
'status' => TRUE,
];

View File

@ -1786,7 +1786,7 @@ display:
type: tab
title: Assets
description: ''
weight: 0
weight: 40
expanded: false
menu_name: account
parent: ''

View File

@ -2790,7 +2790,7 @@ display:
type: tab
title: Logs
description: ''
weight: 0
weight: 50
expanded: false
menu_name: main
parent: ''