8 Commits

Author SHA1 Message Date
asus
fdba54cdb7 resolve an error in makefile when trying to add url to host 2024-02-01 02:24:47 +01:00
asus
11270c5e69 added complete url variable in .env 2024-02-01 01:52:16 +01:00
asus
cab7757043 makefile retrieve volumes directories from env variables 2024-02-01 01:44:26 +01:00
asus
8b024074f1 solved error in path to env file in env generator AND remove debian conf file in mariadb 2024-01-31 22:26:42 +01:00
asus
9a259a93ca some explanations in create_env 2024-01-31 22:18:34 +01:00
asus
f53faf934b added a env file generator with expansions 2024-01-31 22:12:24 +01:00
asus
3d765cd3bd port gestion ok 2024-01-31 15:21:39 +01:00
asus
47dcaad60f trying to understand why ports dont work 2024-01-31 12:05:07 +01:00
49 changed files with 597 additions and 3382 deletions

155
Makefile
View File

@@ -1,125 +1,91 @@
GRAY = "\e[0;30m"
RED = "\e[0;31m"
GREEN = "\e[0;32m"
YELLOW = "\e[0;33m"
BLUE = "\e[0;34m"
PURPLE = "\e[0;35m"
CYAN = "\e[0;36m"
WHITE = "\e[0;37m"
GRAY := "\e[0;30m"
RED := "\e[0;31m"
GREEN := "\e[0;32m"
YELLOW := "\e[0;33m"
BLUE := "\e[0;34m"
PURPLE := "\e[0;35m"
CYAN := "\e[0;36m"
WHITE := "\e[0;37m"
B_GRAY = "\e[1;30m"
B_RED = "\e[1;31m"
B_GREEN = "\e[1;32m"
B_YELLOW = "\e[1;33m"
B_BLUE = "\e[1;34m"
B_PURPLE = "\e[1;35m"
B_CYAN = "\e[1;36m"
B_WHITE = "\e[1;37m"
B_GRAY := "\e[1;30m"
B_RED := "\e[1;31m"
B_GREEN := "\e[1;32m"
B_YELLOW := "\e[1;33m"
B_BLUE := "\e[1;34m"
B_PURPLE := "\e[1;35m"
B_CYAN := "\e[1;36m"
B_WHITE := "\e[1;37m"
RESET = "\e[0m"
RESET := "\e[0m"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# . name = value \ . := no reevaluat when used #
# VARIABLES . value . != set result of command #
# . name is case sensitive . ?= set if not already set #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
COMPOSE = ./srcs/docker-compose.yml
# in makefile you can use an env variable directly as a make variable :
# -> https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_6.html#SEC68
# so if you want to get the home directory you can use $(HOME)
# however, this will not give the same result if you run make in sudo, ex :
# make : /home/asususus
# sudo make : /root
# but you can use this command `eval echo "~$SUDO_USER"` to get
# the home directory of the user using sudo, it works in non-sudo also :
# - echo "$SUDO_USER" :
# - in normal mode it output : ""
# - in sudo mode it output the user : "username"
# - same as $USER in normal mode
# - echo "~$SUDO_USER" :
# - in linux "~USER" is the home directory of a user
# - but echo "something" will treat ~ as a string litteral
# - so the output in mormal mode will be : "~"
# - and in sudo mode it will be : "~username"
# - eval echo "~$SUDO_USER" :
# - eval will evaluate the expression and perform expansion one more time
# - so it will evaluate the output of `echo "~$SUDO_USER"`
# - in normal mode :
# - it will evaluate : "~"
# - and ouptput : "/home/username"
# - in sudo mode :
# - it will evaluate : "~username"
# - and output : "/home/username"
# - because "~username" expand in the home (~) directory of given user
# https://stackoverflow.com/questions/77088135/makefile-subst-doesnt-use-make-variable-as-expected
USER_HOME := $(shell eval echo "~$$SUDO_USER")
# extract env variables in .env file
# then expend the home path
# then expend the pwd path
# and finally remove the leading "EXPEND_" word
EXPENDED_ENV_VAR := $(shell grep "^#EXPEND_" ./srcs/.env)
EXPENDED_ENV_VAR := $(subst $$HOME_PATH,$(USER_HOME),$(EXPENDED_ENV_VAR))
EXPENDED_ENV_VAR := $(subst $$PWD_PATH,$(shell pwd),$(EXPENDED_ENV_VAR))
EXPENDED_ENV_VAR := $(EXPENDED_ENV_VAR:#EXPEND_%=%)
# this creates a list of the path from the list of the variables :
# VAR_1=/path/to_1 VAR_2=/path/to_2
# becomes :
# /path/to_1 /path/to_2
# first, foreach execute an action on each space separated parts : the variables
# - VAR_1=/path/to_1
# - VAR_2=/path/to_2
# then on each of them, it substitute the "=" with a space " " :
# - VAR_1 /path/to_1
# - VAR_2 /path/to_2
# and it only keeps the second word :
# - /path/to_1
# - /path/to_2
VOLUMES_D = $(foreach val,$(EXPENDED_ENV_VAR),$(word 2, $(subst =, ,$(val))))
COMPOSE_FILE := ./srcs/docker-compose.yml
ENV_PATH := ./srcs/.env
# get env variables from .env file :
SOURCE_ENV := . $(ENV_PATH)
# list of volumes
VOLUME_ENV := set | grep "^HOST_VOLUME_" | cut -d "=" -f 2
VOLUMES_D = $(shell $(SOURCE_ENV) ; $(VOLUME_ENV) )
# url for wordpress, use in makefile to change local
WP_URL = $(shell grep "WP_URL" ./srcs/.env | cut -d "=" -f 2)
WP_URL = $(shell $(SOURCE_ENV) ; echo $$WP_URL )
WP_COMPLETE_URL = $(shell $(SOURCE_ENV) ; echo $$WP_COMPLETE_URL )
# list of running containers, see : https://stackoverflow.com/questions/10024279/how-to-use-shell-commands-in-makefile
RUNNING = $(shell docker ps -q)
RUNNING := $(shell docker ps -q)
# list of volumes
VOLUMES = $(shell docker volume ls -q)
VOLUMES := $(shell docker volume ls -q)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# . target: prerequisites . $@ : target #
# RULES . recipe . $< : 1st prerequisite #
# . recipe . $^ : all prerequisites #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
all: require build up
logs: require build_logs up
require:
# remove all the lines starting with "HOST_VOLUME_" in .env
@echo $(B_PURPLE)"removes all lines starting with 'HOST_VOLUMES' in .env"$(RESET)
@sed -i "/^HOST_VOLUME_/d" ./srcs/.env
# add new expended lines starting with "HOST_VOLUME_" after the line "# EXPENDED LINES :" in .env
@echo $(B_PURPLE)"add new expended lines starting with 'HOST_VOLUME_' in .env"$(RESET)
@$(foreach val,$(EXPENDED_ENV_VAR),sed -i "/^# EXPENDED LINES/a\$(val)" ./srcs/.env;)
# create .env file
@echo $(B_PURPLE)"create the .env file"$(RESET)
./srcs/env_generator/create_env.sh ./srcs/model.env
# create the volumes directories
@echo $(B_PURPLE)"create the volumes directories"$(RESET)
@mkdir -p $(VOLUMES_D)
# create the ssl folder to avoid pbm at nginx docker creation
@echo $(B_PURPLE)"create the ssl folder"$(RESET)
@mkdir -p ./srcs/requirements/nginx/conf/ssl
mkdir -p $(VOLUMES_D)
# verify if the wordpress url is added to the local path
@echo $(B_PURPLE)"verify if the wordpress url is added to the local path"$(RESET)
@- if ! grep "127.0.0.1 $(WP_URL)" /etc/hosts 2> /dev/null; then \
@echo $(B_PURPLE)"nop ! adding it"$(RESET) \
bash -c 'echo -e "\n# adding for lejourduprof (you can delete it)\n127.0.0.1 $(WP_URL)" >> /etc/hosts'; \
-@ if ! awk "/127.0.0.1/ && /$(WP_URL)/" /etc/hosts 2> /dev/null; then \
echo $(B_PURPLE)"nop ! trying to add it (might need sudo)"$(RESET); \
bash -c 'echo -e "\n adding for lejourduprof (you can delete it)\n127.0.0.1 $(WP_URL)" >> /etc/hosts'; \
if ! awk "/127.0.0.1/ && /$(WP_URL)/" /etc/hosts 2> /dev/null; then \
echo $(B_RED)"it didn't succeed :/ try again with sudo"$(RESET); \
else \
echo $(B_GREEN)"it has been succesfully added :)"$(RESET); \
fi \
fi
build:
docker compose -f $(COMPOSE) build
docker compose -f $(COMPOSE_FILE) build
# --progress plain : everything will be output at build time, you can see commands like "echo" or "ls" in RUN command in dockerfile
# --no-cache : this will prevent builder to use previous cached action, so it rebuild everything
build_logs:
docker compose -f $(COMPOSE_FILE) build --progress plain --no-cache
up:
docker compose -f $(COMPOSE) up -d
@echo $(B_PURPLE)"you can now connect at "$(B_YELLOW)"https://$(WP_URL)"$(B_PURPLE)" or 127.0.0.1"$(RESET)
docker compose -f $(COMPOSE_FILE) up -d
@echo $(B_PURPLE)"you can now connect at "$(B_YELLOW)"https://$(WP_COMPLETE_URL)"$(B_PURPLE)" or 127.0.0.1"$(RESET)
down:
docker compose -f $(COMPOSE) down
docker compose -f $(COMPOSE_FILE) down
# list images, containers, volumes
list:
@@ -152,9 +118,10 @@ fclean: fclean-images fclean-volumes
re: fclean all
# !! remove everything everything
erase_v:
erase:
- rm -rf $(VOLUMES_D)
new: erase_v re
$(MAKE) fclean
new: erase $(NAME)
.PHONY : all $(VOLUMES_D) require build up list clean fclean re erase_v new
.PHONY : all $(VOLUMES_D) require build up list clean fclean re erase new require

View File

@@ -1,3 +1,9 @@
debug :
- **docker ps** : to see all the containers running
- **docker logs <container name>** : to see if there is logs of errors
---
# toc :
- 1. MAP

303
notes.md Normal file
View File

@@ -0,0 +1,303 @@
# toc :
- 1. MAP
- 1.1. v2 2023
- 1.2. todo
- 1.3. temps de travail
- 2. docker
- 2.1. install docker
- 2.2. docker ressources
- 3. old versions
- 3.1. v1 2022
- 3.1.1. todo
- 3.1.2. verifications
- 3.1.3. improvement suggestions
- 3.1.4. questions traitees
- 3.1.5. todo
---
- I made a script that goes through all posts each time the map is loaded,
extracts the right info, creates the "locations" object as a global variable,
and serves it to the front end js. It also get the coordinates, but only
when a post is published, and it adds them in the meta field of the post
- that's absurd, all the info should be added to the meta field, and only
reevaluated when post is saved or change status
- I made a rapid check of some errors in plugin menu, but that would be much
better to add the errors to a common place, maybe a post meta fiel, during
the processing of the data
---
# 1. MAP
## 1.1. v2 2023
## 1.2. todo
- [/] create wp plugin menu
- [/] add infos in menu
- [/] gmaps api key
- [/] missing addresses
- [/] error strlen
- [/] add counter
- [/] menu select published posts
- [/] menu show error format in categories
## 1.3. temps de travail
30€/h * 8h = 240€/j
- 03/09/23
- begin: 14h30
- mes: "setting up docker"
- end: 16h00
- len: 1h30
- begin: 16h30
- mes: "launch worpdress"
- end: 18h00
- len: 1h30
- total: 3h00
- money: 90€
- 09/09/23
- begin: 16h30
- mes: "trying to copy wp site"
- end: 17h30
- len: 1h00
- total: 1h00
- money: 30€
- 10/09/23
- begin: 10h00
- mes: "trying to fix makefile and .env volume variable"
- end: 12h00
- len: 2h00
- total: 2h00
- money: 60€
- 11/09/23
- begin: 10h00
- mes: "fixed volume variable"
- end: 13h30
- len: 3h30
- total: 3h30
- money: 105€
- 12/09/23
- begin: 9h30
- mes: "resolve some env var pbm"
- end: 12h15
- len: 2h45
- total: 2h45
- money: 82€50
- 14/09/23
- begin: 11h30
- mes: "resolve env pbm with sudo"
- end: 12h00
- len: 0h30
- begin: 13h00
- mes: "env pbm with sudo resolved"
- end: 13h45
- len: 0h45
- begin: 13h45
- mes: "launch process duplicator"
- end: 14h30
- len: 0h45
- begin: 14h45
- mes: "copy site duplicator"
- end: 15h30
- len: 0h45
- total: 2h45
- money: 82€50
- 18/09/23
- begin: 10h00
- mes: "rediscover plugin"
- end: 12h00
- len: 2h00
- begin: 13h00
- mes: "try to get acf fields"
- end: 15h45
- len: 2h45
- total: 4h45
- money: 142€50
- 20/09/23
- begin: 14h00
- mes: "pbm api keys and acf7 form"
- end: 15h30
- len: 1h30
- total: 1h30
- money: 45€
- 21/09/23
- begin: 9h45
- mes: "understand how custom fields works"
- end: 12h45
- len: 3h00
- begin: 15h15
- mes: "create plugin menu"
- end: 19h30
- len: 4h15
- total: 7h15
- money: 217€50
- 21/09/23
- begin: 11h30
- mes: ""
- end: h
- len: h
- total: h
- money: €
#### total : 90 + 30 = 120€
## 1.4. duplicator wordpress
- https://duplicator.com/knowledge-base/classic-install/
- installer.php has two errors :
- delete first blank line
- close last line comment
---
# 2. docker :
## 2.1. install docker
- [install docker engine](https://docs.docker.com/engine/install/ubuntu/)
- [uninstall docker engine](https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine)
- [docker engine vs docker desktop](https://docs.docker.com/desktop/faqs/linuxfaqs/#what-is-the-difference-between-docker-desktop-for-linux-and-docker-engine)
- [manage docker as non root user](https://docs.docker.com/engine/install/linux-postinstall/)
## 2.2. docker ressources
- [docker compose man](https://docs.docker.com/compose/compose-file/#volumes)
- [Dockerfile man](https://docs.docker.com/engine/reference/builder/)
- [determine the parent image](https://forums.docker.com/t/determine-the-parent-image/48611)
- [docker image from scratch](https://codeburst.io/docker-from-scratch-2a84552470c8)
- [build context and image context](https://stackoverflow.com/questions/55108649/what-is-app-working-directory-for-a-dockerfile/55109065#55109065)
- [run without sudo on linux](https://docs.docker.com/engine/install/linux-postinstall/)
- [run docker deamon rootless](https://docs.docker.com/engine/security/rootless/)
- [dangling images '<none>'](https://projectatomic.io/blog/2015/07/what-are-docker-none-none-images/)
- [go inside docker to debug it](https://docs.docker.com/engine/reference/commandline/container_exec/)
- [docker debug image with "docker run -it"](https://blog.devgenius.io/how-to-debug-docker-build-6c2588401188)
- `docker exec -ti <container-name> bash` to run bash inside a running container
- [docker CMD vs ENTRYPOINT](https://phoenixnap.com/kb/docker-cmd-vs-entrypoint)
- [use env variable with compose](https://docs.docker.com/compose/environment-variables/)
- [using DEBIAN_FRONTEND=noninteractive disouraged in dockerfile](https://bobcares.com/blog/debian_frontendnoninteractive-docker/)
- [docker network](https://docs.docker.com/network/)
- [depends_on](https://docs.docker.com/compose/compose-file/#depends_on)
- [compose and env var](https://docs.docker.com/compose/environment-variables/)
- [specify path to named volumes](https://docs.docker.com/compose/compose-file/#volumes-top-level-element)
- [pass secret to container](https://medium.com/@zdk/simple-and-secure-way-to-pass-secrets-and-credentials-into-docker-containers-c2f66175b0a4)
---
# 3. old versions
## 3.1. v1 2022
### 3.1.1. todo
- [/] copy recent site version
- [/] create links
- [/] make links having map
- [/] transform filter list in inputs
- [/] zoom in
- [/] style input filters
- [x] enlever le bandeau de scroll des menus
- [/] effacer -> bouton carre, fond violet, ecriture blanche, en capitale, arrondis de 3px sur les coins
- [/] ne pas ouvrir sur un nouvel onglet
- [/] "effacer" au lieu de "sans filtre"
- [/] accents et majuscules : "Effacer", "Pays" et "Categories"
- [/] responsive
- pays
- categories
- irl / online
- effacer
- [/] sur ordi carte hauteur 600px, sur telephone 500px
- [/] make two infowindow size
- [/] infowindow with date in background color purple, and croice white
- [/] check errors on real site
- [/] create action to publish all
- [/] deal with multiplication of filters
- [/] deal with window size
- [/] la carte ne s'affiche pas sur les pages
- [/] filtres sur chrome
- [/] infowindow new design
- [/] infowindow enlever scroll border
- [/] hide filters before css ready
- [x] reduire hauteur du select menu
- [/] dans categories, placer "autres" en bas
- [/] dans categories, transformer fleches en "autres"
- [/] effacer les fenetres, au moins sur le bouton effacer, ou sur mouvement
- [/] zoom sur cluster problem
- [/] transform names without space
- [/] change appearance of filter according to other filters
- [/] change title of select options that appears on cursor hover
- [ ] deal with error double event irl and online
### 3.1.2. verifications:
- api only for this site on fabien's google account
- erased tmp css on site headers
### 3.1.3. improvement suggestions:
- add a field "more infos" to address
- localise on map when form is filled
### 3.1.4. questions traitees:
- zoom : toujours zoomer, pour un seul marqueur pas trop, et enlever les villes
- resoudre probleme mauvais markers de pays
- faire un bouton select (afficher la seletion plutot que le nom du menu)
- bound la carte limite pour ne pas voir la zone grise
- quelles infos on mets dans les infowindow
- adresse en haut (surtout pour les markers avec plusieurs evenements)
- filtres: au dessus de la carte
- zoom : on reste avec le fonctionnement par defaut
- est-ce qu'on peut changer la phrase "ctrl + scroll" pour un truc en francais ?
- comment gerer les mauvaises adresses
- verifier la maniere dont je les recuperes, tous les posts devraient avoir un pays
- comportement des infowindows
- centrees, c nickel
- markers avec plusieurs evenements a la meme adresse
- utiliser uniquement les markers qui servent actuellement pour les clusters
- quand c'est un cluster, on zoom,
- quand c'est plusieurs evenements au meme endroit, on les affiche
### 3.1.5. todo:
- add info-window
- add filter options
- deal with bad address
- redsign + and - for zoom -> color and thickness
- how to put the map on other pages
- how to send plugin to fabien
- [changed plugin directory in wp](https://wordpress.stackexchange.com/questions/120075/how-to-change-location-of-the-plugins-wordpress-themes-folder)
- googlemap api key : AIzaSyCvdGV2ssD4ov4a9CuIlQhoJyz5gWWiSvE
- [discussion on googlemap wp implementation](https://wordpress.org/support/topic/google-maps-where-to-place-api-key/)
- [exemple of googlemap plugin creation](https://www.inkthemes.com/implement-google-map-plugin-for-wordpress/)
- [Error: not a valid JSON response](https://wordpress.org/support/topic/publishing-failed-error-message-the-response-is-not-a-valid-json-response-2/)
- [permalink broken](https://wordpress.org/support/topic/permalinks-change-breaks-all-links/)
- [console.log in php](https://stackify.com/how-to-log-to-console-in-php/)
- [plugins_url with symlink pbm](https://wordpress.stackexchange.com/questions/102681/plugins-url-file-wp-plugin-url-with-sym-links)
- [make nginx follow symlinks](https://unix.stackexchange.com/questions/157022/make-nginx-follow-symlinks)
- [nginx not following symlink maybe due to permissions](https://stackoverflow.com/questions/12624358/nginx-not-following-symlinks)
- [symlink pbm with php-fpm](https://joshtronic.com/2019/07/29/symlinks-with-nginx-and-php-fpm/)
- [my post on unix stack](https://unix.stackexchange.com/questions/722503/symlink-doent-works-with-nginx-and-php-fpm-and-docker/722511#722511)
- [my post on wordpress stack](https://wordpress.stackexchange.com/questions/410735/i-dont-understand-how-symlinks-in-plugin-work)
- [maps api in php](http://www.learningaboutelectronics.com/Articles/Google-maps-API-JSON-PHP.php)
- [google maps api url parameters](https://developers.google.com/maps/documentation/javascript/url-params)
- [google maps api references](https://developers.google.com/maps/documentation/javascript/reference)
- [remove marker cluster](https://googlemaps.github.io/js-markerclusterer/classes/MarkerClusterer.html#removeMarker)

View File

@@ -1,49 +1,19 @@
# NGINX SETUP
NG_VOLUME_CERTS=/etc/ssl
# MARIADB SETUP
DB_HOST=mariadb
DB_NAME=db_wp_inception
DB_USER=user_wp_inception
DB_PSWD="too bad you have read this now i have to erase your memory"
# WORDPRESS SETUP
WP_URL=local_lejourduprof.com
WP_VOLUME_DIR=/var/www/html
WP_VOLUME_PLUGINS=/home/www-data
WP_TITLE=title
WP_ADMIN=hulamy
WP_ADMIN_PSWD="you shall not password !"
WP_ADMIN_EMAIL=hulamy@42.fr
WP_USER=moehu36
WP_USER_PSWD="it's a secret for nobody"
WP_USER_EMAIL=moehu36@42.fr
# MAP
MAX_UPLOAD_SIZE=512
DB_NAME=db_wp_jipf
DB_PSWD='you dont want to know'
DB_USER=user_wp_jipf
EXECUTION_TIME=300
# env file does not have expension capacity, so we simulate it with makefile :
# 1. the lines starting with "#EXPEND_" will be retrieved by the makefile
# 2. then it will expend the $HOME_PATH and $PWD_PATH
# 3. then it will remove the leading "#EXPEND_" word
# 4. then it will erase all the line starting with "HOST_VOLUME_" if they exist
# 5. and finally it will add the expended lines after the line "EXPENDED LINES :"
# LINES TO EXPEND :
#EXPEND_HOST_VOLUME_WP=$HOME_PATH/data/lejourduprof/wp_volume
#EXPEND_HOST_VOLUME_DB=$HOME_PATH/data/lejourduprof/db_volume
#EXPEND_HOST_VOLUME_PLUGINS=$PWD_PATH/srcs/plugins
#EXPEND_HOST_VOLUME_CERTS=$PWD_PATH/srcs/requirements/nginx/conf/ssl
# EXPENDED LINES :
HOST_VOLUME_CERTS=/home/asususus/nextcloud_backup/backup_planethoster_server/nextclouddata/hugogogo/files/informatique/lejourduprof/srcs/requirements/nginx/conf/ssl
HOST_VOLUME_PLUGINS=/home/asususus/nextcloud_backup/backup_planethoster_server/nextclouddata/hugogogo/files/informatique/lejourduprof/srcs/plugins
HOME_PATH=/home/asususus
HOST_VOLUME_DB=/home/asususus/data/lejourduprof/db_volume
HOST_VOLUME_WP=/home/asususus/data/lejourduprof/wp_volume
MAX_UPLOAD_SIZE=512
NG_VOLUME_CERTS=/etc/ssl
PROJECT=jipf
WP_ADMIN=admin
WP_ADMIN_EMAIL=admin@email.fr
WP_ADMIN_PSWD='you shall not password !'
WP_COMPLETE_URL=local_lejourduprof.com:3003
WP_PORT=3003
WP_TITLE=title
WP_URL=local_lejourduprof.com
WP_VOLUME_DIR=/var/www/html

View File

@@ -8,31 +8,21 @@
version: "3.8"
services:
# ---------------------------------
# test:
# build:
# context: ./requirements/test
# dockerfile: Dockerfile
# image: test
# container_name: test_container
# ---------------------------------
nginx:
restart: on-failure
networks:
- inception
ports:
- "443:443"
- "${WP_PORT}:443"
volumes:
- wp_volume:${WP_VOLUME_DIR}
- wp_plugins:${WP_VOLUME_PLUGINS}
- ng_certs:${NG_VOLUME_CERTS}
build:
context: ./requirements/nginx
args:
- WP_URL=${WP_URL}
- MAX_UPLOAD_SIZE=${MAX_UPLOAD_SIZE}
- WP_VOLUME_DIR=${WP_VOLUME_DIR}
- WP_VOLUME_PLUGINS=${WP_VOLUME_PLUGINS}
- NG_VOLUME_CERTS=${NG_VOLUME_CERTS}
image: nginx
container_name: nginx_container
@@ -64,17 +54,15 @@ services:
# ---------------------------------
wordpress:
restart: on-failure
env_file: ./.env
env_file: .env
networks:
- inception
volumes:
- wp_volume:${WP_VOLUME_DIR}
- wp_plugins:${WP_VOLUME_PLUGINS}
build:
context: ./requirements/wordpress
args:
- WP_VOLUME_DIR=${WP_VOLUME_DIR}
- WP_VOLUME_PLUGINS=${WP_VOLUME_PLUGINS}
- MAX_UPLOAD_SIZE=${MAX_UPLOAD_SIZE}
- EXECUTION_TIME=${EXECUTION_TIME}
image: wordpress
@@ -97,18 +85,6 @@ volumes:
type: none
o: "bind"
device: ${HOST_VOLUME_WP}
wp_plugins:
driver: local
driver_opts:
type: none
o: "bind"
device: ${HOST_VOLUME_PLUGINS}
ng_certs:
driver: local
driver_opts:
type: none
o: "bind"
device: ${HOST_VOLUME_CERTS}
networks:
inception:

View File

@@ -0,0 +1,47 @@
#!/bin/bash
# - this script creates a .env file in the same directory of the model.env
# - the model.env file is given in argument, otherwise it default to current path
# change to where the script is relatively to where the execution is made
#cd $(dirname $0)
CURRENT_PATH=$(dirname $0)
if [ $# -eq 0 ]; then
FILE_PATH="${CURRENT_PATH}/model.env"
ENV_PATH=${CURRENT_PATH}
else
FILE_PATH="$1"
ENV_PATH=$(dirname $FILE_PATH)
fi
if [ ! -f "$FILE_PATH" ]; then
echo ""
echo " no file 'model.env' found"
echo ""
echo " you need to create one in the same directory of this script,"
echo " or to give the path to a valide one in argument"
echo ""
echo " like './create_env path/to/model.env'"
echo " "
echo " note that the .env file will be created where the model.env is"
echo ""
exit 1
fi
TMP_FILE="tmpfile_3289442091310922474928"
TMP_BEFORE="env_before.tmp"
TMP_AFTER="env_after.tmp"
# add lines at beginning and end of a temp env file
echo "set | sort > ${TMP_BEFORE}" > ${TMP_FILE}
cat ${FILE_PATH} >> ${TMP_FILE}
echo "set | sort > ${TMP_AFTER}" >> ${TMP_FILE}
source ${TMP_FILE}
# diff between the two set files == the newly created env var
NEW_ENV=$(comm -13 ${TMP_BEFORE} ${TMP_AFTER} | grep -v "^_=")
echo "${NEW_ENV}" > ${ENV_PATH}/.env
rm -f ${TMP_BEFORE} ${TMP_AFTER} ${TMP_FILE}

67
srcs/model.env Normal file
View File

@@ -0,0 +1,67 @@
PROJECT=jipf
# NGINX SETUP
NG_VOLUME_CERTS=/etc/ssl
MAX_UPLOAD_SIZE=512
# MARIADB SETUP
DB_HOST=mariadb
DB_NAME=db_wp_${PROJECT}
DB_USER=user_wp_${PROJECT}
DB_PSWD="you dont want to know"
# WORDPRESS SETUP
WP_URL=local_lejourduprof.com
WP_PORT=3003
# concat url with port if not 443
WP_COMPLETE_URL="${WP_URL}"
if [ ! ${WP_PORT} -eq 443 ]; then
WP_COMPLETE_URL="${WP_URL}:${WP_PORT}"
fi
WP_VOLUME_DIR=/var/www/html
#WP_VOLUME_PLUGINS=/home/www-data
WP_TITLE=title
WP_ADMIN=admin
WP_ADMIN_PSWD="you shall not password !"
WP_ADMIN_EMAIL=admin@email.fr
# MAP
EXECUTION_TIME=300
# if you want to get the home directory you can use $(HOME)
# however, this will not give the same result if you use sudo, ex :
# ./create_env : /home/asususus
# sudo ./create_env : /root
# but you can use this command `eval echo "~$SUDO_USER"` to get
# the home directory of the user using sudo, it works in non-sudo also :
# - echo "$SUDO_USER" :
# - in normal mode it outputs : ""
# - in sudo mode it outputs the user : "username"
# - same as $USER in normal mode
# - echo "~$SUDO_USER" :
# - in linux "~USER" is the home directory of a user
# - but echo "something" will treat ~ as a string litteral
# - so the output in mormal mode will be : "~"
# - and in sudo mode it will be : "~username"
# - eval echo "~$SUDO_USER" :
# - eval will evaluate the expression and perform expansion one more time
# - so it will evaluate the output of `echo "~$SUDO_USER"`
# - in normal mode :
# - it will evaluate : "~"
# - and ouptput : "/home/username"
# - in sudo mode :
# - it will evaluate : "~username"
# - and output : "/home/username"
# - because "~username" expand in the home (~) directory of given user
# https://stackoverflow.com/questions/77088135/makefile-subst-doesnt-use-make-variable-as-expected
HOME_PATH=$(eval echo "~$SUDO_USER")
HOST_VOLUME_WP=${HOME_PATH}/data/lejourduprof/wp_volume
HOST_VOLUME_DB=${HOME_PATH}/data/lejourduprof/db_volume

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,170 +0,0 @@
<?php
/*
Plugin Name: map_prof
Plugin URI:
Description: add/remove locations on map at publication/deletion of posts
Author: hugogogo
Version: 1.2.0
Author URI:
*/
/**
* inclusions :
*/
include_once(dirname(__FILE__) . '/utils/mp_console_log.php');
include_once(dirname(__FILE__) . '/utils/mp_get_ip.php');
require_once(dirname(__FILE__) . '/mp_enqueue.php');
require_once(dirname(__FILE__) . '/settings/mp_required.php');
require_once(dirname(__FILE__) . '/settings/mp_optionnals.php');
require_once(dirname(__FILE__) . '/settings/mp_globals.php');
require_once(dirname(__FILE__) . '/settings/mp_url_api.php');
require_once(dirname(__FILE__) . '/srcs/errors/mp_address_errors.php');
require_once(dirname(__FILE__) . '/srcs/map/mp_add_to_scripts.php');
require_once(dirname(__FILE__) . '/srcs/map/mp_create_div.php');
require_once(dirname(__FILE__) . '/srcs/map/mp_get_events.php');
require_once(dirname(__FILE__) . '/srcs/map/mp_get_filters.php');
require_once(dirname(__FILE__) . '/srcs/map/mp_get_locations.php');
require_once(dirname(__FILE__) . '/srcs/map_posts/mp_post_events_pages.php');
require_once(dirname(__FILE__) . '/srcs/publish/mp_get_coordinates.php');
require_once(dirname(__FILE__) . '/srcs/publish/mp_update_publish.php');
require_once(dirname(__FILE__) . '/srcs/menu/mp_menu_content.php');
/**
* when 'shortcode' found in page, enqueue scripts and styles,
* run php script, and replace shortcode by return value
*/
function mp_ljdp_map() {
mp_enqueue_scripts_and_styles();
$events = mp_get_published_events(); // mp_get_events.php
//mp_console_log("events: ");
//mp_console_log($events);
//foreach ($events as $event) {
// if (gettype($event->categorie) === "array") {
// mp_console_log($event->categorie);
// }
// if (str_starts_with($event->categorie, '["')) {
// mp_console_log($event->categorie);
// }
//}
$locations = mp_sort_events($events); // mp_get_locations.php
//mp_console_log("locations: ");
//mp_console_log($locations);
$filters = mp_get_filters($events); // mp_get_filters.php
// if post event instead of map page, change coordinate and zoom
mp_post_event_pages_setting();
mp_add_to_scripts(array(
"locations" => $locations,
"filters" => $filters,
"jipf_events" => $events,
));
return mp_create_div($filters);
}
add_shortcode('lejourduprof_map', 'mp_ljdp_map');
/*
script in divi :
<script type="text/javascript">
console.log("events:");
console.log(events);
document.addEventListener("DOMContentLoaded", () => {
let counter = document.getElementById('jipf_activity_counter_map');
console.log(counter);
counter.dataset.numberValue = 20;
});
</script>
*/
/**
* re-publish posts
*/
// function mp_add_update_button() {
// return mp_create_republish_button();
// }
// add_shortcode('ljdp_update_publish', 'mp_add_update_button');
/**
* errors map
*/
function mp_errors_map() {
return mp_find_address_errors();
}
add_shortcode('ljdp_errors_map', 'mp_errors_map');
/**
* when a post is saved or published or updated,
* find its coordinates
*/
function post_published_coordinates($id, $post) {
$location = mp_get_coordinates($id);
//mp_console_log("location: ");
//mp_console_log($location);
if ( ! add_post_meta( $id, 'location', $location, true ) )
update_post_meta( $id, 'location', $location );
}
add_action( 'publish_post', 'post_published_coordinates', 10, 2 );
/**
* menu plugin
*/
function ljdp_map_menu() {
add_menu_page(
'JIPF map', // page_title
'JIPF map', // menu_title
'manage_options', // capability
'ljdp-map-plugin', // menu_slug
'ljdp_map_plugin_content' // callback function to display page content
);
}
add_action('admin_menu', 'ljdp_map_menu');
?>

View File

@@ -1,26 +0,0 @@
<?php
function mp_enqueue_scripts_and_styles() {
// https://developers.google.com/maps/documentation/javascript/marker-clustering
$marker_clusterer = "https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js";
wp_enqueue_style('mp__style', plugins_url('styles/mp__style.css' , __FILE__), '', '', false);
// enqueue header
wp_enqueue_script('mp_info_window', plugins_url('scripts/mp_info_window.js' , __FILE__), '', '', false);
wp_enqueue_script('mp_errors_map', plugins_url('scripts/mp_errors_map.js' , __FILE__), '', '', false);
wp_enqueue_script('mp_create_filters', plugins_url('scripts/mp_create_filters.js' , __FILE__), '', '', false);
wp_enqueue_script('mp_create_markers', plugins_url('scripts/mp_create_markers.js' , __FILE__), '', '', false);
wp_enqueue_script('mp_create_map', plugins_url('scripts/mp_create_map.js' , __FILE__), '', '', false);
wp_enqueue_script('mp_draw_clusters', plugins_url('scripts/mp_draw_clusters.js' , __FILE__), '', '', false);
wp_enqueue_script('mp_filter_events', plugins_url('scripts/mp_filter_events.js' , __FILE__), '', '', false);
// enqueue footer
wp_enqueue_script('mp_marker_clusterer', $marker_clusterer, '', '', true);
wp_enqueue_script('mp_init_map', plugins_url('scripts/mp_init_map.js' , __FILE__), ['mp_marker_clusterer'],'', true);
wp_enqueue_script('mp_google_api', mp_url_api(), ['mp_init_map'], '', true);
}
?>

View File

@@ -1,103 +0,0 @@
function fill_filters(filters_div) {
/*
* following variable are created by mp_add_to_script.php
*
* { }
* { [ ] }
* - filters: { - pays : [ { - _name : "" } ] }
* { [ { - villes : [] } ] }
* { [ { - categories: [] } ] }
* { [ { - mode : [] }, ...] }
* { [ ] }
* { }
* { [ ] }
* { - villes : [ { - _name : "" } ] }
* { [ { - pays : [] } ] }
* { [ { - categories: [] } ] }
* { [ { - mode : [] }, ...] }
* { [ ] }
* { }
* { [ ] }
* { - categories: [ { - _name : "" } ] }
* { [ { - pays : [] } ] }
* { [ { - villes : [] } ] }
* { [ { - mode : [] }, ...] }
* { [ ] }
* { }
* { }
* { [ ] }
* { - mode : [ { - _name : "" } ] }
* { [ { - pays : [] } ] }
* { [ { - villes : [] } ] }
* { [ { - categories: [] }, ...] }
* { [ ] }
* { }
*
*/
let content = "";
// use Object.keys to obtain an array of object keys
let keys = Object.keys(filters);
keys.forEach((key) => {
// // version input checkbox
//
// content += `
// <div class="filter_menu">
// <input id="filter_menu_title_${key}" class="filter_menu_title" type="checkbox" />
// <label for="filter_menu_title_${key}" class="filter_menu_title">
// <p>${key}</p>
// </label>
// <div class="filter_menu_drop">
// `;
// for (value of filters[key]) {
// content += `
// <p>${value._name}</p>
// `;
// }
// content += `
// </div>
// </div>
// `;
// // version select
//
// content += `
// <div class="filter_menu">
// <select id="filter_menu_drop_${key}" class="filter_menu_drop" name="${key}">
// `;
// for (value of filters[key]) {
// content += `
// <option value="${value._name}"><p>${value._name}</p></option>
// `;
// }
// content += `
// </select>
// </div>
// `;
// // version div
//
content += `
<div class="filter_menu">
<div class="filter_menu_title" tabindex=0>
<p>${key}</p>
</div>
<div class="filter_menu_drop" tabindex=0>
<p>PAS DE FILTRE</p>
`;
for (value of filters[key]) {
content += `
<p>${value._name}</p>
`;
}
content += `
</div>
</div>
`;
});
filters_div.innerHTML = content;
}

View File

@@ -1,41 +0,0 @@
function restrict_map(restrict) {
let map_restriction = {
latLngBounds: g_world_bound,
strictBounds: true,
};
if (restrict)
g_map.setOptions({restriction: map_restriction,});
else
g_map.setOptions({restriction: null,});
};
function create_map(map_div) {
// default map center to france
let map_center = coordinates_default;
// map_center = {lat:-2.515748362923059, lng:32.93366215464864};
let map_restriction = {
latLngBounds: g_world_bound,
strictBounds: true,
};
let map_options = {
/* map options : https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions */
disableDefaultUI: true,
zoomControl: true,
scaleControl: true,
zoom: map_zoom,
//gestureHandling: "cooperative",
gestureHandling: "greedy",
//gestureHandling: "none",
//gestureHandling: "auto",
//disableDoubleClickZoom: "false", // deprecated
//draggable: "true", // deprecated
center: map_center,
restriction: map_restriction,
}
return new google.maps.Map(map_div, map_options);
}

View File

@@ -1,57 +0,0 @@
function create_markers(map, locations, infowindow) {
/*
* following variable are created by mp_add_to_script.php
* - let icon_color = ""
* - let icon_color_back = ""
* - let icon_size = [x, y]
* - let cluster_size_factor = Number
* - let icon_stroke_width = Number
*/
let icon_circle_radius = 40 - icon_stroke_width / 2;
let markers = [];
for (loc of locations) {
if (loc.coordinates == null)
continue;
let count = loc.events.length;
let marker_icon_size = [
icon_size[0] + ( icon_size_factor * (count - 2) ),
icon_size[1] + ( icon_size_factor * (count - 2) )
];
let svg_icon = window.btoa(`
<svg xmlns="http://www.w3.org/2000/svg" width="${marker_icon_size[0]}" height="${marker_icon_size[1]}">
<circle cx="50%" cy="50%" r="${icon_circle_radius}%" stroke="${icon_color}" stroke-width="${icon_stroke_width}" fill="${icon_color_back}" />
</svg>
`);
let icon_options = {
url: `data:image/svg+xml;base64,${svg_icon}`,
scaledSize: new google.maps.Size(marker_icon_size[0], marker_icon_size[1]),
};
let marker_label = {
text: String(count),
color: icon_color,
fontSize: "12px",
fontWeight: "bold",
};
let marker_title = `address of ${count} events`;
let marker = new google.maps.Marker({
position: loc.coordinates,
map: map,
icon: icon_options,
title: marker_title,
label: marker_label,
});
attach_info_window(map, marker, loc.events, infowindow);
markers.push(marker);
};
return markers;
}

View File

@@ -1,58 +0,0 @@
function draw_clusters(map, markers) {
/*
* following variable are created by mp_add_to_script.php
* - let icon_color = ""
* - let icon_color_back = ""
* - let icon_size = [x, y]
* - let icon_size_factor = Number
* - let icon_stroke_width = Number
*/
let icon_circle_radius = 40 - icon_stroke_width / 2;
let renderer = {
render({ count, position }, stats) {
/* CLUSTERS SETTINGS */
let marker_icon_size = [
icon_size[0] + ( icon_size_factor * (count - 2) ),
icon_size[1] + ( icon_size_factor * (count - 2) )
];
let cluster_svg = window.btoa(`
<svg xmlns="http://www.w3.org/2000/svg" width="${marker_icon_size[0]}" height="${marker_icon_size[1]}">
<circle cx="50%" cy="50%" r="${icon_circle_radius}%" stroke="${icon_color}" stroke-width="${icon_stroke_width}" fill="${icon_color_back}" />
</svg>
`);
let cluster_icon = {
url: `data:image/svg+xml;base64,${cluster_svg}`,
scaledSize: new google.maps.Size(marker_icon_size[0], marker_icon_size[1]),
};
let cluster_label = {
text: String(count),
color: icon_color,
fontSize: "12px",
fontWeight: "bold",
};
let cluster_title = `Cluster of ${count} markers`;
let cluster_zIndex = Number(google.maps.Marker.MAX_ZINDEX) + count;
return new google.maps.Marker({
position,
icon: cluster_icon,
label: cluster_label,
title: cluster_title,
zIndex: cluster_zIndex,
});
}
}
let onClusterClick = (_, cluster, map) => {
restrict_map(false);
map.fitBounds(cluster.bounds);
restrict_map(true);
};
return new markerClusterer.MarkerClusterer({ map, markers, renderer, onClusterClick });
}

View File

@@ -1,7 +0,0 @@
function print_error(error) {
let div_map = document.getElementById("ljdp_map");
let p_err = document.createElement('p');
p_err.textContent = error;
div_map.after(p_err);
}

View File

@@ -1,278 +0,0 @@
// https://googlemaps.github.io/js-markerclusterer/classes/MarkerClusterer.html
// add true for noDraw
// bounds : https://stackoverflow.com/questions/19304574/center-set-zoom-of-map-to-cover-all-visible-markers/19304625#19304625
function array_first_not_in_second(first, second) {
let temp_array = [];
for (let index of first) {
if (second.indexOf(index) == -1) {
temp_array.push(index);
}
}
return temp_array;
}
function filter_selection_indexes(menu, indexes, reverse, add) {
if (indexes.length === 0) {
// if array of index is empty, delete menu
delete g_indexes[menu];
}
else if (reverse) {
// if reverse is true, delete all indexes in g_indexes.menu
// https://stackoverflow.com/questions/5113374/javascript-check-if-variable-exists-is-defined-initialized
if ( typeof(g_indexes[menu]) !== "undefined" && g_indexes[menu] !== null ) {
// creates an array with all values of g_indexes[menu] minus indexes
let temp_array = array_first_not_in_second(g_indexes[menu], indexes);
if (temp_array.length === 0)
delete g_indexes[menu];
else
g_indexes[menu] = [].concat(temp_array);
}
}
else {
if (add && typeof(g_indexes[menu]) !== "undefined") {
// add array of menus to g_indexes{}
// creates an array with all values of indexes that are not in g_indexes[menu] already
let temp_array = array_first_not_in_second(indexes, g_indexes[menu]);
g_indexes[menu] = g_indexes[menu].concat(temp_array);
}
else {
// replace or create array of menu in g_indexes{}
g_indexes[menu] = [].concat(indexes);
}
}
// loop through all arrays of g_indexes to find intersection
// take first one as comparison
let keys = Object.keys(g_indexes);
let intersection = [];
let compare = [];
keys.forEach((key, i) => {
if (i == 0) {
intersection = g_indexes[key];
}
else {
let temp = [];
compare = g_indexes[key];
for (let index of intersection) {
if (compare.indexOf(index) != -1)
temp.push(index);
}
intersection = [].concat(temp);
}
});
return intersection;
}
function redraw_clusters(indexes) {
let indexes_count = indexes.length;
if (indexes_count !== 0) {
// if index array, hide all other markers, and if zoomin, zoom to new markers
g_marker_cluster.clearMarkers(true);
let marker = g_markers[0];
let current_bounds = g_map.getBounds();
let bounds = new google.maps.LatLngBounds();
let outside_bounds = false;
for (let index of indexes) {
marker = g_markers[index];
position = marker.getPosition();
if (! current_bounds.contains(position))
outside_bounds = true;
bounds.extend(position);
g_marker_cluster.addMarker(marker, true);
}
if (outside_bounds) {
if (indexes_count === 1) {
g_map.setCenter(position);
g_map.setZoom(max_zoom);
}
else if (indexes_count > 1) {
g_map.fitBounds(bounds);
}
}
}
else if ( Object.keys(g_indexes).length === 0 ) {
// object is empty, there are no filters
g_map.setCenter(coordinates_default);
g_map.setZoom(2);
g_marker_cluster.addMarkers(g_markers, true);
}
else {
// filters intersection lets no markers on the map
g_marker_cluster.clearMarkers(true);
}
g_marker_cluster.render();
}
function html_item(menu_name, menu_item) {
let item = menu_item.replace(/ /g, "_");
let html_id = `filter_${menu_name}_${item}`;
return document.getElementById(html_id);
}
function toggle_menu_items(menu_name, x_abled) {
let name = menu_name.replace(/ /g, "_");
let class_name = `filter_menu_${name}`;
let items = document.getElementsByClassName(class_name);
if (x_abled === "disable") {
for (let item of items) {
// if item is a menu title (like 'categorie' or 'pays')
// don't remove 'enable', instead add it, because it's not in the list of 'to_enable'
if (item.selected) {
item.classList.add('enable');
}
else {
item.classList.remove('enable');
}
if (item.classList.contains('to_enable')) {
item.classList.replace('to_enable', 'enable');
item.removeAttribute('disabled');
}
else if (! item.selected)
item.setAttribute('disabled', '');
}
}
else {
for (let item of items) {
item.classList.remove('enable');
item.removeAttribute('disabled');
}
}
}
function disable_menus(menu_name_ori, menu_item_ori, reverse, menu_index) {
let menu_item_name = "";
if (menu_item_ori == null) // it's a menu name
menu_item_name = menu_name_ori;
else
menu_item_name = menu_item_ori._name;
let item_ori_html = html_item(menu_name_ori, menu_item_name);
let is_enabled = item_ori_html.classList.contains('enable');
// in case it's a menu title, like "Pays" or "Categories",
// and it does'nt contains 'enable'
// just act like Reset button
// it's too bad it will also go through this menu items even though it's unnecessary
if (menu_index == 'menu_name') { // it's a menu name
if (! is_enabled) {
// "item" as a menu name will select all items in all menus
toggle_menu_items("item", "enable");
}
return;
}
// if it's Mode menu,
// and it was the first selection, meaning it does'nt contains 'enable'
// and both (irl and online) are abled or disabled,
// just act like Reset button
// it's too bas it will also go through this menu items even though it's unnecessary
if (menu_name_ori === "mode") {
let mode_menus = document.getElementsByClassName("filter_menu_mode");
let state = 0;
for (let mode_menu of mode_menus) {
if (mode_menu.checked)
state++;
else
state--;
}
if (state != 0) { // state equal 0 if both have a different state, because (0 + 1 - 1 = 0) and (0 - 1 + 1 = 0)
if (! is_enabled) {
// "item" as a menu name will select all items in all menus
toggle_menu_items("item", "enable");
return;
}
}
else if (reverse) { // menu is "mode" and only one item is selected and the action was to deselect one, so the action has trigered one item but really we want to see the options of the other item, so let's switch them
if (menu_index == 0)
menu_index++;
else
menu_index--;
menu_item_ori = filters[menu_name_ori][menu_index];
}
}
let keys = Object.keys(menu_item_ori);
// loop through list of other menu_items available for this menu_item
// loop though menu names (pays, categories, mode)
for (let menu_name of keys) {
if (menu_name === "_name")
continue;
if (menu_name === "indexes")
continue;
else if (! is_enabled) {
// // it's too bad it will disable all and then enable certains, it would be better to check each time
// toggle_menu_items(menu_name, "disable");
// // loop through items in menu names (ex. for "pays" : france, chili, cuba)
// for (let item of menu_item_ori[menu_name]) {
// let item_html = html_item(menu_name, item);
// item_html.classList.add('enable');
// item_html.removeAttribute('disabled');
// }
for (let item of menu_item_ori[menu_name]) {
let item_html = html_item(menu_name, item);
item_html.classList.add('to_enable');
}
toggle_menu_items(menu_name, "disable");
}
}
}
function filter_show_only(element, menu_name) {
g_infowindow.close();
let menu_index = element.getAttribute("data-menu_index");
let menu_item = null;
let indexes = [];
if (menu_index != "menu_name") {
menu_item = filters[menu_name][menu_index];
indexes = menu_item.indexes;
}
add = false;
reverse = false;
if (element.type === "checkbox") {
reverse = ! element.checked;
add = true;
}
disable_menus(menu_name, menu_item, reverse, menu_index);
let index_array = filter_selection_indexes(menu_name, indexes, reverse, add);
redraw_clusters(index_array);
}
function filter_show_all() {
g_infowindow.close();
// "item" as a menu name will select all items in all menus
toggle_menu_items("item", "enable");
g_indexes = {};
g_marker_cluster.clearMarkers(true);
g_marker_cluster.addMarkers(g_markers);
/* dont use fitBounds because it's not well centered */
/* instead use setCenter and setZoom */
//g_map.fitBounds(g__init_bounds);
g_map.setCenter(coordinates_default);
g_map.setZoom(2);
}

View File

@@ -1,82 +0,0 @@
function attach_info_window(map, marker, events, infowindow) {
/*
* https://developers.google.com/maps/documentation/javascript/infowindows
* https://stackoverflow.com/questions/11106671/google-maps-api-multiple-markers-with-infowindows
*/
let window_content = `
<div id="infowindow_limits">
<div class="infowindow">
<div class="infowindow_head">
<p>${events[0].location.address}</p>
<div id="infowindow_close" onclick="g_infowindow.close()"></div>
</div>
`;
for (key in events) {
window_content += `
<a class="infowindow_body" href="${events[key].url}">
<p>${events[key].title}</p>
</a>
`;
};
window_content += `
</div>
</div>
`;
marker.addListener('click', () => {
let view_center = map.getCenter();
// height must be half css value (mp_info_windows.css -> '--size: XXXpx;')
let window_offset = { width: 0, height: 275 };
infowindow.setOptions({
//disableAutoPan: true,
disableAutoPan: false,
content: window_content,
/* dimensions */
//maxWidth: 400,
//minWidth: 400,
/* center window */
position: view_center,
pixelOffset: window_offset,
//shouldFocus: false,
});
infowindow.open(map);
});
}
/*
event : {}
- heure_de_debut : "";
- heure_de_fin : "";
- categorie : "";
- date : "";
- pays : "";
- ville : "";
- adresse : "";
- prenom : "";
- nom : "";
- irl : bool;
- id : x;
- index : x (default null);
- title : "";
- url : "";
- location : {}
- street : "";
- city : "";
- country : "";
- address : "";
- approximate : bool;
- coordinates : {}
- lat : x;
- lng : x;
*/

View File

@@ -1,72 +0,0 @@
let g_map = {};
let g_markers = [];
let g_marker_cluster = {};
let g_indexes = {};
let g_infowindow = {};
const g_world_bound = {
north: 80,
south: -80,
west: -180,
east: 180,
};
/*
* following variable are created by mp_add_to_script.php
* - let events
* - let locations = [
* {
* coordinates: {}
* events : [{}, ...]
* },
* ...
* ]
*
* { }
* { [ ] }
* - let filters: { - pays : [ { - _name : "" } ] }
* { [ { - villes : [] } ] }
* { [ { - categories: [] } ] }
* { [ { - indexes : [] } ] }
* { [ { - mode : [] }, ...] }
* { [ ] }
* { }
* { - villes : ... }
* { - categories: ... }
* { - mode : ... }
* { }
*
* - let coordinates_default = {lat: ,lng: }
* - let icon_color = ""
* - let icon_color_back = ""
* - let icon_size = [x, y]
* - let cluster_size_factor = Number
* - let map_zoom = x
* - let max_zoom = x
*/
function mp_init_map() {
let map_div = document.getElementById("ljdp_map");
//let filters_div = document.getElementById("ljdp_map_filters");
g_infowindow = new google.maps.InfoWindow();
g_map = create_map(map_div);
g_markers = create_markers(g_map, locations, g_infowindow);
g_marker_cluster = draw_clusters(g_map, g_markers);
// add listener to close infowindow
// https://developers.google.com/maps/documentation/javascript/events
g_map.addListener('click', function() {
g_infowindow.close();
});
g_map.addListener('drag', function() {
g_infowindow.close();
});
g_map.addListener('zoom_changed', function() {
g_infowindow.close();
});
//g_map.addListener('clusteringbegin', restrict_map(false));
}

View File

@@ -1,21 +0,0 @@
console.log("publish error");
wp.data.dispatch( 'core/notices' ).createNotice(
'error', // Can be one of: success, info, warning, error.
'impossible de publier : le pays est invalide', // Text string to display.
{
isDismissible: true, // Whether the user can dismiss the notice.
}
);
//( function ( wp ) {
// console.log("publish error");
// wp.data.dispatch( 'core/notices' ).createNotice(
// 'error', // Can be one of: success, info, warning, error.
// 'impossible de publie : le pays est invalide', // Text string to display.
// {
// isDismissible: true, // Whether the user can dismiss the notice.
// }
// );
//} )( window.wp );

View File

@@ -1,80 +0,0 @@
<?php
/**
* global variables :
*
* DO NOT MODIFY !
* modify mp_optionnals.php or mp_required.php instead
*/
/* ICON SIZE
*/
$mp_icon_size = [40, 40];
if (isset($mp_settings_icon_size)) {
if (is_array($mp_settings_icon_size)) {
if (count($mp_settings_icon_size) === 2) {
if ( is_numeric($mp_settings_icon_size[0]) && is_numeric($mp_settings_icon_size[1]) ) {
$mp_icon_size = $mp_settings_icon_size;
}
}
}
}
/* ICON COLOR
*/
$mp_icon_color = "#ba197a";
if (isset($mp_settings_icon_color))
$mp_icon_color = $mp_settings_icon_color;
/* ICON FACTOR SIZE
*/
$mp_icon_size_factor = 2.5;
if (isset($mp_settings_icon_size_factor))
$mp_icon_size_factor = $mp_settings_icon_size_factor;
/* DEFAULT ZOOM
*/
$mp_zoom_set = [2, 5];
if (isset($mp_settings_zoom_set))
$mp_zoom_set = $mp_settings_zoom_set;
// also create the variable, and set to map page by default
$mp_zoom = $mp_zoom_set[0];
/* DEFAULT COORDINATES
*/
$mp_coordinates_default = (object)["lat" => 46.227638, "lng" => 2.213749]; // france
if (isset($mp_settings_coordinates_default))
$mp_coordinates_default = $mp_settings_coordinates_default;
/* ICON COLOR
*/
$mp_icon_color = "#ba197a";
$mp_icon_color_back = "#ffffff99";
if (isset($mp_settings_icon_color))
$mp_icon_color = $mp_settings_icon_color;
if (isset($mp_settings_icon_color_back))
$mp_icon_color_back = $mp_settings_icon_color_back;
/* ICON STROKE WIDTH
*/
$mp_icon_stroke_width = 6;
if (isset($mp_settings_icon_stroke_width))
$mp_icon_stroke_width = $mp_settings_icon_stroke_width;
/* MAX ZOOM
*/
$mp_max_zoom = 5;
if (isset($mp_settings_max_zoom))
$mp_max_zoom = $mp_settings_max_zoom;
?>

View File

@@ -1,86 +0,0 @@
<?php
/*
* de-commenter les parametres pour les appliquer
*
* les parametres suivants sont optionnels pour le fonctionnement du plugin
* le plugin fonctionne sans eux, grace a des valeurs par defauts
*/
/* ************************************
facteur de taille des clusters
_
valeur par defaut "2.5"
************************************ */
//$mp_settings_icon_size_factor = 4;
/* ************************************
zoom initial
- pour les pages
- pour les posts
_
valeur par defaut [2, 5]
************************************ */
//$mp_settings_zoom_set = [1, 6];
/* ************************************
coordonnees par defaut
(pour centrer la carte globale,
et en cas de mauvaises adresses)
_
valeur par defaut "france"
************************************ */
$mp_settings_coordinates_default = (object)["lat" => 30.0, "lng" => -1.0]; // carte mieux centree
/* ************************************
couleurs d'icones
- couleur de contour
- couleur de remplissage
_
valeurs par defaut "#ba197a"
"#ffffff99"
************************************ */
//$mp_settings_icon_color = "#d168a8";
//$mp_settings_icon_color_back = "#ffffff80"; // transparency :
// 0.0 : 00
// 0.1 : 1a
// 0.2 : 33
// 0.3 : 4d
// 0.4 : 66
// 0.5 : 80
// 0.6 : 99
// 0.7 : b3
// 0.8 : cc
// 0.9 : e6
/* ************************************
epaisseur de trait des icones
_
valeurs par defaut "6"
************************************ */
$mp_settings_icon_stroke_width = 8;
/* ************************************
zoom automatique maximum sur les
marqueurs
_
valeurs par defaut "5"
************************************ */
$mp_settings_max_zoom = 4;
?>

View File

@@ -1,17 +0,0 @@
<?php
/*
* les parametres suivants sont necessaires pour le fonctionnement du plugin
*/
/* cle api google maps pour carte
"Maps Javascript API" */
//$mp_api_key = 'AIzaSyCvdGV2ssD4ov4a9CuIlQhoJyz5gWWiSvE'; // fabien
$mp_api_key = 'AIzaSyDAZv8QNRQjnVY6kdzJRxWmZDaNIcgYp9E'; // hugo
/* cle api google maps pour serveur
"Geocoding API" */
//$mp_api_key_geo = 'AIzaSyAEMZHpMxBQaovU_so_RH7p_pZbjaB2jO8'; // fabien
$mp_api_key_geo = 'AIzaSyBskxuBhowQdLjJmIj2gc66KoP1GLO3SEg'; // hugo
?>

View File

@@ -1,23 +0,0 @@
<?php
function mp_url_api() {
global $mp_api_key;
$mp_url = array(
'src' => 'https://maps.googleapis.com/maps/api/js',
'key' => $mp_api_key,
'callback' => 'mp_init_map',
);
$mp_src = "";
foreach ($mp_url as $url_key => $url_value) {
if ($url_key === 'src') {
$mp_src .= $url_value;
if (count($mp_url) > 1)
$mp_src .= "?";
}
else
$mp_src .= "&" . $url_key . "=" . $url_value;
};
return $mp_src;
}
?>

View File

@@ -1,96 +0,0 @@
<?php
function mp_is_precise($post, $id, $location) {
// is presentiel but not complete address ?
$presentiel = get_field("mode", $id);
if ($presentiel[0] === "En présentiel") {
if ($location->approximate) {
return false;
}
}
return true;
}
function mp_is_address_complete($post, $id, $location) {
// is presentiel but not complete address ?
$presentiel = get_field("mode", $id);
if ($presentiel[0] === "En présentiel") {
if (strlen($location->street) == 0) {
return false;
}
if (strlen($location->city) == 0) {
return false;
}
}
return true;
}
function mp_is_valid_address($post, $id, $location) {
// is coordinates ?
if ($location->coordinates == null)
return false;
return true;
}
function mp_fill_address_message($post, $id, $location) {
$message = '<br /><p>article : "'
. $post->post_title . '"</p><p>- adresse fournie : "'
. get_field('adresse', $id) . ', '
. get_field('ville', $id) . ', '
. get_field('pays', $id)
. '"</p><p>- adresse trouvée : "'
. $location->address
. '"</p>';
return $message;
}
function mp_find_address_errors() {
$errors = "";
$incompletes = "";
$approximates = "";
$count_errors = 0;
$count_incompletes = 0;
$count_approximates = 0;
$get_posts_args = array(
'numberposts' => -1,
'post_status' => 'publish',
'post_type' => 'post',
);
$posts = get_posts($get_posts_args);
foreach ($posts as $post) {
$id = $post->ID;
$location = get_field('location', $id);
if (! mp_is_valid_address($post, $id, $location)) {
$count_errors++;
$errors .= mp_fill_address_message($post, $id, $location);
}
// else if (! mp_is_address_complete($post, $id, $location)) {
// $count_incompletes++;
// $incompletes .= mp_fill_address_message($post, $id, $location);
// }
else if (! mp_is_precise($post, $id, $location)) {
$count_approximates++;
$approximates .= mp_fill_address_message($post, $id, $location);
}
}
$message = "<h2>nombre d'erreurs : " . $count_errors . "</h2>";
// $message .= "<h2>nombre d'adresses incompletes pour des evenements en presentiels : " . $count_incompletes . "</h2>";
$message .= "<h2>nombre d'adresses approximatives pour des evenements en presentiels : " . $count_approximates . "</h2>";
$message .= "<br /><h2>erreurs :</h2>" . $errors;
// $message .= "<br /><h2>adresses incompletes:</h2>" . $incompletes;
$message .= "<br /><h2>approximatives :</h2>" . $approximates;
return $message;
}
?>

View File

@@ -1,34 +0,0 @@
<?php
function mp_php_to_js($php_var, $js_var_name) {
$js_var = 'let ' . $js_var_name . ' = ';
$js_var .= json_encode($php_var);
$js_var .= ';';
return $js_var;
}
function mp_add_to_scripts($to_add) {
global $mp_icon_size;
global $mp_icon_color;
global $mp_icon_color_back;
global $mp_icon_size_factor;
global $mp_zoom;
global $mp_coordinates_default;
global $mp_icon_stroke_width;
global $mp_max_zoom;
wp_add_inline_script('mp_init_map', mp_php_to_js($mp_icon_size, 'icon_size'), 'before');
wp_add_inline_script('mp_init_map', mp_php_to_js($mp_icon_color, 'icon_color'), 'before');
wp_add_inline_script('mp_init_map', mp_php_to_js($mp_icon_color_back, 'icon_color_back'), 'before');
wp_add_inline_script('mp_init_map', mp_php_to_js($mp_icon_size_factor, 'icon_size_factor'), 'before');
wp_add_inline_script('mp_init_map', mp_php_to_js($mp_zoom, 'map_zoom'), 'before');
wp_add_inline_script('mp_init_map', mp_php_to_js($mp_coordinates_default, 'coordinates_default'), 'before');
wp_add_inline_script('mp_init_map', mp_php_to_js($mp_icon_stroke_width, 'icon_stroke_width'), 'before');
wp_add_inline_script('mp_init_map', mp_php_to_js($mp_max_zoom, 'max_zoom'), 'before');
foreach ($to_add as $key => $var) {
wp_add_inline_script('mp_init_map', mp_php_to_js($var, $key), 'before');
}
}
?>

View File

@@ -1,135 +0,0 @@
<?php
function mp_filter_drop_down($key, &$filter) {
/*
onfocusin="filter_show_only_selection(this, '.json_encode($value->indexes).', '."'".$key."'".')"
onclick="filter_show_only_selection(this, '.json_encode($value->indexes).', '."'".$key."'".')"
onfocus="filter_show_only_selection(this, '.json_encode($value->indexes).', '."'".$key."'".')"
onclick="filter_show_only_selection(this, '.json_encode(array()).', '."'".$key."'".')"
onchange="filter_show_only_selection(this, '.json_encode($value->indexes).', '."'".$key."'".')"
onchange="filter_show_only_selection(this, '.json_encode(array()).', '."'".$key."'".')"
onchange="filter_event(this, this.options[this.selectedIndex], \''.$key.'\')"
*/
$menu_name_class = 'filter_menu_'.str_replace(" ", "_", $key).'';
$id = "filter_"
. $key
. "_"
. $key
;
$content = '
<select
form="ljdp_form"
class="filter_menu filter_menu_drop"
onchange="filter_show_only(this.options[this.selectedIndex], \''.$key.'\')"
>
<option
selected
id="'.$id.'"
class="filter_menu_item '.$menu_name_class.'"
data-menu_index="menu_name"
>
'.$key.'
</option>
';
foreach ($filter as $key_filter => $value) {
$id = "filter_"
. $key
. "_"
. str_replace( " ", "_", $value->_name)
;
$content .= '
<option
id="'.$id.'"
class="filter_menu_item '.$menu_name_class.'"
data-menu_index="'.$key_filter.'"
>
'.$value->_name.'
</option>
';
}
$content .= '
</select>
';
return $content;
};
function mp_filter_buttons($key, &$filter) {
/*
onclick="filter_show_only_selection(this, '.json_encode($value->indexes).', '."'".$key."'".', true)"
*/
$menu_name_class = 'filter_menu_'.str_replace(" ", "_", $key).'';
$content = '';
foreach ($filter as $key_filter => $value) {
$id = "filter_"
. $key
. "_"
. str_replace( " ", "_", $value->_name)
;
$content .= '
<input
type="checkbox"
form="ljdp_form"
id="'.$id.'"
class="filter_menu_checkbox filter_menu_item '.$menu_name_class.'"
onclick="filter_show_only(this, \''.$key.'\')"
style="display:none;"
data-menu_index="'.$key_filter.'",
>
<label
for="'.$id.'"
class="filter_menu filter_menu_checkbox"
>
<p>'.$value->_name.'</p>
</label>
';
}
return $content;
};
function mp_create_div(&$filters) {
$mp_map_div = '
<div id="ljdp_map_wrapper">
<form id="ljdp_form" style="display:none;"></form>
<div id="ljdp_map_filters">
';
foreach ($filters as $key => $filter) {
if ($key == "mode")
$mp_map_div .= mp_filter_buttons($key, $filter);
else
$mp_map_div .= mp_filter_drop_down($key, $filter);
};
$mp_map_div .= '
<input
type="reset"
form="ljdp_form"
id="filter_menu_reset"
class="filter_menu_button"
onclick="filter_show_all()"
style="display:none;"
>
<label
for="filter_menu_reset"
class="filter_menu filter_menu_reset"
>
<p>Effacer</p>
</label>
';
$mp_map_div .= '
</div>
<div id="ljdp_map"></div>
</div>
';
return $mp_map_div;
};
?>

View File

@@ -1,196 +0,0 @@
<?php
/*
GET_POST :
1 ID: 29693
2 comment_count: "0"
3 comment_status: "closed"
4 filter: "raw"
5 guid: "https://local_lejourduprof.com/?p=29693"
6 menu_order: 0
7 ping_status: "closed"
8 pinged: ""
9 post_author: "1"
10 post_content: ""
11 post_content_filtered: ""
12 post_date: "2022-11-04 18:05:49"
13 post_date_gmt: "2022-11-04 17:05:49"
14 post_excerpt: "Les enseignants vont présenter les projets développés dans leurs classes et partager leurs pratiques et expériences."
15 post_mime_type: ""
16 post_modified: "2022-11-05 09:39:46"
17 post_modified_gmt: "2022-11-05 08:39:46"
18 post_name: "construisons-ensemble-lavenir"
19 post_parent: 0
20 post_password: ""
21 post_status: "draft"
22 post_title: "Construisons ensemble l'avenir"
23 post_type: "post"
24 to_ping: ""
*/
/*
GET_POST_CUSTOM :
activite_concerne : "les enseignants de français langue étrangère ou français langue seconde"
adresse : "Institut français du Liban, Beirut, Lebanon"
adresse_courriel : "ihoteit@hotmail.com"
adresse_courriel_de_contact : "ihoteit@hotmail.com"
categorie : "Rencontre/Témoignage"
composition : [ "Association de professeurs de français membre du réseau FIPF", "Ambassade de France/Institut français", "Bureau ou représentation de l'OIF" ]
composition_1 : "Association Libanaise des Enseignants de Français, ALEF"
composition_2 : "Institut français au Liban"
composition_3 : "Représentation OIF"
composition_4 : ""
composition_autres : ""
date : "2023-11-23"
depenses_prevues : " collation, pins-souvenirs , déplacements, filmage et photos, affiches, secrétariat et frais divers"
description_courte : "Une rencontre-témoignage festive en présence des décideurs, des acteurs de la francophonie au Liban, pays fier de son plurilinguisme et sa diversité\n"
description_longue : "Enseignants et élèves témoigneront des opportunités et des atouts que lenseignement et lapprentissage du français leur offrent à tous les niveaux : éducatif, personnel, professionnel, social, interculturel et humain. Leur amour pour le français, moyen douverture au monde francophone ainsi quà linternational, est sans égal dans un pays plurilingue comme le Liban !\nUne réception clôturera cette belle journée de tous ceux qui œuvrent pour lexpansion de la langue et des valeurs françaises et francophones.\nProgramme\nOuverture: Discours des officiels\nChansons et musique. Trois performances musicales animeraient la cérémonie, au début, au milieu et à la fin\ntémoignages des enseignants .\n\n\n"
engagement : ""
fichier : "https://lejourdesprofs.org/wp-content/uploads/2023/09/Budget_previsionnel_JIPF_2023-envoye.docx"
financement : [ 'a:1:{i:0;s:3:"oui";}' ]
fonction : "Secrétaire Générale"
heure_de_debut : "16H "
heure_de_fin : "18H"
institution : "Association Libanaise des Enseignants de Français,ALEF"
lien_internet : "http://alef-liban.org"
liste_des_depenses : "collation, pins-souvenirs , déplacements, filmage et photos, gestion de la communication , suivi logistique et technique, affiches , secrétariat et frais divers .\n"
location : { address:"VGJ7+34P, Beyrouth, Liban", approximate:false, city:"Beyrouth", country:"Liban", street:"", coordinates:{ lat:33.8802185, lng:35.5128288 } }
mode : [ "En présentiel" ]
montant_demande : "1400 euros"
nom : "Slim-Hoteit"
participation : "100 participants"
pays : ""
plan_de_communication : "Avant : diffusion très large de l'information concernant la JIPF : réseaux sociaux et sites internet ALEF, FIPF, IFprof et journaux (L'Orient le Jour)\nPendant : présence des journalistes et couverture en directe sur la page facebook de l'ALEF\nAprès : large diffusion des rapports ,photos et vidéos dans la presse et sur les réseaux sociaux"
prenom : "Ilham"
public_vise : "100 personnes: officiels, enseignants, élèves, étudiants "
recettes_prevues : "Participation de l'ALEF: gestion de la communication avant, pendant et après , suivi logistique et technique"
resultat_attendu : " les recettes couvriront les dépenses"
resultats_attendus : "Echanger dans une ambiance festive et rendre hommage aux enseignantes et enseignants le jour de leur fete internationale"
se_connecter : ""
telephone : "009613180576"
*/
function mp_get_published_posts() {
$get_posts_args = array(
'numberposts' => -1,
'post_status' => 'publish',
'post_type' => 'post',
);
$posts_published = get_posts($get_posts_args);
return $posts_published;
}
function mp_fill_fields_value($id) {
/*
* get_field is an ACF function
* in "pure" worpdress use :
* get_post_meta or get_post_custom
* - https://developer.wordpress.org/reference/functions/get_post_meta/
* - https://developer.wordpress.org/reference/functions/get_post_custom/
* if you try to use `get_fields(id)` to retrieve all the acf7 custom fields,
* sometimes it fails eventhough you can get a specific value with `get_field(value, id)`,
* it's because acf7 didn´t insert the field itself and so some hidden data is not there :
* - https://coreysalzano.com/wordpress/acf-get_fields-not-working-but-get_field-does/
*/
// add fields
$fields = array(
"heure_de_debut" => "string",
"heure_de_fin" => "string",
"categorie" => "string",
"date" => "string",
"pays" => "string",
"adresse" => "string",
"prenom" => "string",
"nom" => "string",
"location" => "object",
);
$event = (object)[];
foreach($fields as $field => $of_type) {
$value = get_field($field, $id);
//$actual_type = gettype($value);
//if ($actual_type !== $of_type) {
// mp_console_log("field '" . $field . "' has a value of type '" . $actual_type . "' instead of '" . $of_type . "'");
//}
if ($value === "")
$value = "Autre";
if (gettype($value) === "string")
$value = trim($value, " ");
$event->$field = $value;
}
// add mode irl or online (irl: true | false)
$presentiel = get_field("mode", $id);
$event->irl = false;
if (isset($presentiel[0])) {
if ($presentiel[0] === "En présentiel")
$event->irl = true;
}
// add post url
$event->url = get_post_permalink($id);
return $event;
}
function mp_get_published_events() {
$posts_list = mp_get_published_posts();
$events = [];
foreach ($posts_list as $post) {
$event = mp_fill_fields_value($post->ID);
$event->id = $post->ID;
$event->title = trim($post->post_title, " ");
$event->index = null;
array_push($events, $event);
}
return $events;
}
/*
event : {}
- heure_de_debut : "";
- heure_de_fin : "";
- categorie : "";
- date : "";
- pays : "";
- ville : "";
- adresse : "";
- prenom : "";
- nom : "";
- irl : bool;
- id : x;
- index : x (default null);
- title : "";
- url : "";
- location : {}
- street : "";
- city : "";
- country : "";
- address : "";
- approximate : bool;
- coordinates : {}
- lat : x;
- lng : x;
--------------------------
Object {
}
*/
?>

View File

@@ -1,169 +0,0 @@
<?php
function mp_filter_compare($a, $b) {
$compare = strcmp($a->_name, $b->_name);
if ($a->_name === "Autre") {
if ($compare !== 0)
return 1;
}
if ($b->_name === "Autre") {
if ($compare !== 0)
return -1;
}
return $compare;
}
function mp_already_in_menu(&$menu, $name) {
foreach ($menu as $field) {
if ($field->_name == $name)
return $field;
}
return null;
}
/**
* creates the menus
* from the events fields
* and add the index of the event as it is in location (events when they are sorted)
*
* fields: [ countries:"", cities:"", categories:"", ... ]
* name : field's values -> countries, cities, categories, ...
* menu : [ { _name:"", field_1:[], field_2:[] }, ... ]
* index : index of this event in locations[] array
*/
function mp_fill_name($fields, $name, &$menu, $index, &$event) {
if ($fields[$name] == null)
return;
if (gettype($fields[$name]) != 'string')
return;
if (strlen($fields[$name]) == 0)
return;
// menu_item, ex: for menu "countries" -> france
$menu_item = mp_already_in_menu($menu, $fields[$name]);
if ($menu_item != null) {
// add to this menu item, eg "Austria", the infos of this
// event, like "city" or "category", if not there already
foreach ($fields as $key_field => $value) {
// no need to add name if already exist
if ($key_field == $name)
continue;
if (! isset($menu_item->$key_field) )
$menu_item->$key_field = [];
if (!is_string($value)) {
//mp_console_log("pour l'article '$event->title', le champ '$key_field' est supposé être de type 'string', mais il est de type '" . gettype($value) . "'");
//if ( ! add_post_meta( $id, 'problem', "$value", true ) )
// update_post_meta( $id, 'problem', "" );
continue;
}
if (strlen($value) != 0) {
if (! in_array($value, $menu_item->$key_field) )
array_push($menu_item->$key_field, $value);
}
}
// add location index, if not there already
if (! in_array($index, $menu_item->indexes) ) {
array_push($menu_item->indexes, $index);
}
}
else {
$menu_item = (object)[];
$menu_item->_name = $fields[$name];
// add lists of event info (cities, countries, ...)
foreach ($fields as $key_field => $value) {
if ($key_field == $name)
continue;
$menu_item->$key_field = [];
if (!is_string($value)) {
//mp_console_log("pour l'article '$event->title', le champ '$key_field' est supposé être de type 'string', mais il est de type '" . gettype($value) . "'");
continue;
}
if (strlen($value) != 0)
array_push($menu_item->$key_field, $value);
}
// add list of location index
$menu_item->indexes = [$index];
// and add this item to list of menu
array_push($menu, $menu_item);
}
}
function mp_get_filters(&$events) {
$filters = (object)[];
foreach ($events as $event) {
// no index means no coordinates
$index = $event->index;
if ($index === null)
continue;
// create array of menus
$fields = array(
"Pays" => $event->location->country,
"Catégories" => $event->categorie,
"mode" => ($event->irl)? "En présentiel" : "En ligne",
);
//mp_console_log("event: ");
//mp_console_log($event);
// fill all menu with other menus without doubles
foreach ($fields as $name => $value) {
if (! isset($filters->$name))
$filters->$name = [];
mp_fill_name($fields, $name, $filters->$name, $index, $event);
}
}
foreach ($filters as $key => $value) {
usort($filters->$key, 'mp_filter_compare');
}
return $filters;
}
/*
{ }
{ [ ] }
filters: { - countries : [ { - _name : "" } ] }
{ [ { - categories: [] } ] }
{ [ { - indexes : [] }, ... ] }
{ [ ] }
{ }
{ - categories: }
{ - modes : }
{ }
*/
/*
event : {}
- heure_de_debut : "";
- heure_de_fin : "";
- categorie : "";
- date : "";
- pays : "";
- ville : "";
- adresse : "";
- prenom : "";
- nom : "";
- irl : bool;
- id : x;
- index : x;
- url : "";
- title : "";
- location : {}
- street : "";
- city : "";
- country : "";
- address : "";
- approximate : bool;
- coordinates : {}
- lat : x;
- lng : x;
*/
?>

View File

@@ -1,66 +0,0 @@
<?php
function mp_coord_already_exist(&$coordinates, &$locations) {
foreach ($locations as $location) {
if ($location->coordinates->lat == $coordinates->lat)
if ($location->coordinates->lng == $coordinates->lng)
return $location;
}
return null;
}
function mp_sort_n_insert(&$event, &$locations) {
$coordinates = $event->location->coordinates;
if ($coordinates == null)
return;
$already_exist = mp_coord_already_exist($coordinates, $locations);
if ($already_exist) {
// add index to the event
$index = $already_exist->index;
$event->index = $index;
// add event to events[]
array_push($already_exist->events, $event);
}
else {
// create new location object
$location = (object)[];
$location->events = [];
// add index to the location and event
$index = count($locations);
$location->index = $index;
$event->index = $index;
// add coordinates to the location
$location->coordinates = $coordinates;
// add first event to events[]
array_push($location->events, $event);
// add this location to locations[]
array_push($locations, $location);
}
}
function mp_sort_events(&$events) {
$locations = [];
foreach ($events as $event) {
mp_sort_n_insert($event, $locations);
};
return $locations;
}
/*
locations = [
{
index : x
coordinates: {}
events : [{}, ...]
},
...
]
*/
?>

View File

@@ -1,27 +0,0 @@
<?php
function is_event_post() {
if ( is_admin() )
return false;
if ( get_post_type() != "post" )
return 0;
if ( get_post_status() != "publish" )
return 0;
return true;
}
function mp_post_event_pages_setting() {
global $mp_zoom;
global $mp_zoom_set;
global $mp_coordinates_default;
if (is_event_post()) {
$mp_zoom = $mp_zoom_set[1];
$location = get_field("location");
$coordinates = $location->coordinates;
$mp_coordinates_default = $coordinates;
}
}
?>

View File

@@ -1,405 +0,0 @@
<?php
function mp_get_all_posts() {
$get_posts_args = array(
'numberposts' => -1,
'post_status' => 'any',
'post_type' => 'post',
);
$posts_list = get_posts($get_posts_args);
return $posts_list;
}
function mp_posts_published($posts_list) {
$posts_published = [];
foreach ($posts_list as $post) {
$status = $post->post_status;
if ($status == "publish")
array_push($posts_published, $post);
}
return $posts_published;
}
function mp_have_no_address($posts_list) {
$posts_no_address = [];
foreach ($posts_list as $post) {
$address = mp_get_address($post->ID);
if (empty($address))
array_push($posts_no_address, $post);
}
return $posts_no_address;
}
function mp_have_no_coordinates($posts_list) {
$posts_no_coordinates = [];
foreach ($posts_list as $post) {
$location = get_field("location", $post->ID);
if (empty($location))
array_push($posts_no_coordinates, $post);
else if (empty($location->coordinates))
array_push($posts_no_coordinates, $post);
}
return $posts_no_coordinates;
}
function mp_bad_categories($posts_list) {
$posts_bad_categories = [];
foreach ($posts_list as $post) {
$value = get_field("categorie", $post->ID);
if (! is_string($value)) {
array_push($posts_bad_categories, $post);
//mp_console_log("categorie:");
//mp_console_log($value);
}
if (str_starts_with($value, '["')) {
array_push($posts_bad_categories, $post);
}
}
return $posts_bad_categories;
}
function count_publish($arr_posts) {
return($arr_posts->post_status === "publish");
}
function mp_show_list_posts_no_address($posts) {
$all_posts = count($posts);
$published_posts = count(array_filter($posts, "count_publish"));
echo <<<HTML
<div style="border: 1px solid red; margin: 20px 20px 20px auto; padding: 0px 20px;">
<p style="color: red;">
<b>ATTENTION !</b>
</p>
<input type="checkbox" class="hide_not_published" id="posts_no_address_published">
<label for="posts_no_address_published">afficher uniquement les articles publiés</label>
<p>
<b>
HTML;
echo "<span class='count_all_posts'>$all_posts</span>";
echo "<span class='count_published_posts'>$published_posts</span>";
echo '</b>';
if (count($posts) == 1)
echo " article n'a pas d'adresse :";
else
echo " articles n'ont pas d'adresses :";
echo <<<HTML
</p>
<ul style="list-style: square inside;">
HTML;
foreach ($posts as $post) {
if ($post->post_status === "publish") {
echo <<<HTML
<li class="jipf_post_publish"><b>
HTML;
}
else {
echo <<<HTML
<li><b>
HTML;
}
echo 'id: ';
echo $post->ID;
echo ' (status: ';
echo $post->post_status;
echo ') - ';
if (!empty($post->mode))
echo $post->mode[0];
echo ' : </b>';
echo $post->post_title;
echo <<<HTML
</li>
HTML;
}
echo <<<HTML
</ul>
</div>
HTML;
}
function mp_show_list_posts_bad_categories($posts) {
$all_posts = count($posts);
$published_posts = count(array_filter($posts, "count_publish"));
echo <<<HTML
<div style="border: 1px solid red; margin: 20px 20px 20px auto; padding: 0px 20px;">
<p style="color: red;">
<b>ATTENTION !</b>
</p>
<input type="checkbox" class="hide_not_published" id="posts_bad_categories_published">
<label for="posts_bad_categories_published">afficher uniquement les articles publiés</label>
<p>
<b>
HTML;
echo "<span class='count_all_posts'>$all_posts</span>";
echo "<span class='count_published_posts'>$published_posts</span>";
echo '</b>';
if (count($posts) == 1)
echo " article à sa catégorie mal formatée :";
else
echo " articles ont leur catégorie mal formatée :";
echo <<<HTML
</p>
<ul style="list-style: square inside;">
HTML;
foreach ($posts as $post) {
if ($post->post_status === "publish") {
echo <<<HTML
<li class="jipf_post_publish"><b>
HTML;
}
else {
echo <<<HTML
<li><b>
HTML;
}
echo 'id: ';
echo $post->ID;
echo ' (status: ';
echo $post->post_status;
echo ') - ';
if (!empty($post->mode))
echo $post->mode[0];
echo ' : </b>';
echo $post->post_title;
echo <<<HTML
<p style="margin:0px;">
<span style="color:blue;">catégorie: </span>
HTML;
$categorie = get_field("categorie", $post->ID);
echo '<span>';
var_dump($categorie);
echo '</span>';
echo <<<HTML
</p>
</li>
HTML;
}
echo <<<HTML
</ul>
</div>
HTML;
}
function mp_show_list_posts_no_coordinates($posts) {
$all_posts = count($posts);
$published_posts = count(array_filter($posts, "count_publish"));
echo <<<HTML
<div style="border: 1px solid blue; margin: 20px 20px 20px auto; padding: 0px 20px;">
<p style="color: blue;">
<b>INFORMATION :</b>
</p>
<input type="checkbox" class="hide_not_published" id="posts_no_coordinates_published">
<label for="posts_no_coordinates_published">afficher uniquement les articles publiés</label>
<p>
<b>
HTML;
echo "<span class='count_all_posts'>$all_posts</span>";
echo "<span class='count_published_posts'>$published_posts</span>";
echo '</b>';
if (count($posts) == 1)
echo " article n'a pas de coordonnees :";
else
echo " articles n'ont pas de coordonnees :";
echo <<<HTML
</p>
<ul style="list-style: square inside;">
HTML;
foreach ($posts as $post) {
if ($post->post_status === "publish") {
echo <<<HTML
<li class="jipf_post_publish"><b>
HTML;
}
else {
echo <<<HTML
<li><b>
HTML;
}
echo 'id: ';
echo $post->ID;
echo ' (status: ';
echo $post->post_status;
echo ') - ';
if (!empty($post->mode))
echo $post->mode[0];
echo ' : </b>';
echo $post->post_title;
echo <<<HTML
</li>
HTML;
}
echo <<<HTML
</ul>
<p style="background-color: lightblue; padding: 5px 10px; width: fit-content;">
<b>pour actualiser les coordonnees d'un article, il suffit de le remettre en "brouillon" puis de le publier a nouveau</b>
</p>
</div>
HTML;
}
function mp_show_post_number($posts_list, $posts_published) {
echo <<<HTML
<p>nombre d'articles au total : <b>
HTML;
echo count($posts_list);
echo "</b> (dont <b>";
echo count($posts_published) . "</b>";
if (count($posts_published) == 1)
echo " publié)</p>";
else
echo " publiés)</p>";
}
function mp_show_api_key_n_ip() {
global $mp_api_key;
global $mp_api_key_geo;
echo <<<HTML
<p>l'adresse ip du serveur est : <b>
HTML;
$external_ip = mp_get_ip();
echo $external_ip;
echo <<<HTML
</b></p>
HTML;
echo <<<HTML
<p>les cles api de google maps utilisees sont :</p>
<ul style="list-style: square inside; max-width: 500px;">
<li>pour la carte : <b style='float:right; margin-right: 10px;'>
HTML;
echo $mp_api_key;
echo <<<HTML
</b></li>
<li>pour les coordonnees : <b style='float:right; margin-right: 10px;'>
HTML;
echo $mp_api_key_geo;
echo <<<HTML
</b></li></ul>
<p>(elles sont inscrites dans ./settings/mp_required.php)</p>
HTML;
// need to use an api key with special restrictions :
// https://stackoverflow.com/questions/42167695/api-key-browser-api-keys-cannot-have-referer-restrictions-when-used-with-this-ap
echo <<<HTML
<p style="color: blue;">
<b>&rarr; pour la carte : </b>
cette cle api peut etre restreinte par url, et par api avec l'api <b>"Maps Javascript API"</b>
</p>
<p style="color: blue;">
<b>&rarr; pour les coordonnees : </b>
cette cle api ne doit pas etre restreinte par url, elle peut etre restreinte par adresse ip du serveur, et par api avec l'api <b>"Geocoding API"</b>
</p>
<p style="color: blue;">
<b>&rarr; pour utiliser une seule cle api : </b>
cette cle api ne doit pas etre restreinte ni par url ni par adresse ip, elle peut etre restreinte par api avec les deux apis <b>"Maps Javascript API"</b> et <b>"Geocoding API"</b>
</p>
HTML;
}
function ljdp_map_plugin_content() {
$posts_list = mp_get_all_posts();
//mp_console_log("posts_list: ");
//mp_console_log($posts_list);
$posts_published = mp_posts_published($posts_list);
$posts_no_address = mp_have_no_address($posts_list);
//mp_console_log("posts_no_address: ");
//mp_console_log($posts_no_address);
$posts_no_coordinates = mp_have_no_coordinates($posts_list);
//mp_console_log("posts_no_coordinates: ");
//mp_console_log($posts_no_coordinates);
$posts_bad_categories = mp_bad_categories($posts_list);
//mp_console_log("posts_bad_categories: ");
//mp_console_log($posts_bad_categories);
echo <<<HTML
<style>
li {
list-style-position: outside;
margin-left: 10px;
}
input.hide_not_published:checked ~ ul li:not(.jipf_post_publish) {
display: none;
}
.count_published_posts {
display: none;
}
input.hide_not_published:checked ~ p .count_all_posts {
display: none;
}
input.hide_not_published:checked ~ p .count_published_posts {
display: inline;
}
</style>
<div>
<h2>JIPF map plugin</h2>
HTML;
mp_show_post_number($posts_list, $posts_published);
mp_show_api_key_n_ip();
if (count($posts_no_address) > 0)
mp_show_list_posts_no_address($posts_no_address);
if (count($posts_bad_categories) > 0)
mp_show_list_posts_bad_categories($posts_bad_categories);
if (count($posts_no_coordinates) > 0){
mp_show_list_posts_no_coordinates($posts_no_coordinates);
}
else {
echo <<<HTML
<p style="color: green;">&#10004; tous les articles ont des coordonnees correctes :)</p>
HTML;
}
echo <<<HTML
</div>
HTML;
}
?>

View File

@@ -1,78 +0,0 @@
<?php
function mp_get_address($id) {
$presentiel = get_field("mode", $id);
if (empty($presentiel))
return null;
// irl or online
if ($presentiel[0] === "En présentiel")
$address = get_field("adresse", $id);
else
$address = get_field("pays", $id);
return $address;
}
function mp_get_coordinates($id) {
global $mp_api_key_geo;
$event = (object)[];
$location = (object)[];
$location->coordinates = null;
$location->street = "";
$location->city = "";
$location->country = "";
$location->address = "";
$location->approximate = false;
$address = mp_get_address($id);
//mp_console_log("adresse: " . $address);
// get coordinates from google maps api
$geolocation = 'https://maps.googleapis.com/maps/api/geocode/json'
. '?language=fr'
. '&address=' . urlencode($address)
. '&key=' . $mp_api_key_geo;
//mp_console_log("geolocation: " . $geolocation);
$jsoncontent = file_get_contents($geolocation);
//mp_console_log("jsoncontent: " . $jsoncontent);
// extract coordinates from json
// https://developers.google.com/maps/documentation/geocoding/requests-geocoding#Types
$content = json_decode($jsoncontent);
$location->coordinates = $content->results[0]->geometry->location;
$location->address = $content->results[0]->formatted_address;
foreach ($content->results[0]->address_components as $component) {
if (in_array("street_number", $component->types))
$location->street = $component->long_name;
else if (in_array("route", $component->types)) {
if (strlen($location->street) != 0)
$location->street .= " ";
$location->street .= $component->long_name;
}
else if (in_array("locality", $component->types))
$location->city = $component->long_name;
else if (in_array("postal_town", $component->types)) {
if (strlen($location->city) != 0)
$location->city .= "/";
$location->city .= $component->long_name;
}
else if (in_array("country", $component->types))
$location->country = $component->long_name;
}
if ($content->results[0]->geometry->location_type == "APPROXIMATE")
$location->approximate = true;
// clean strings
foreach ($location as $value) {
if (gettype($value) != "string")
continue;
$value = trim($value, " ");
}
return $location;
}
?>

View File

@@ -1,48 +0,0 @@
<?php
/*
function mp_update_publish() {
$post_args = array(
'numberposts' => -1,
//'post_status' => 'draft',
'post_status' => 'publish',
'post_type' => 'post',
);
$post_list = get_posts($post_args);
foreach ($post_list as $post) {
wp_update_post(array(
'ID' => $post->ID,
//'post_status' => 'draft',
'post_status' => 'publish',
));
};
}
add_action( 'admin_post_update_publish', 'mp_update_publish' );
add_action( 'admin_post_nopriv_update_publish', 'mp_update_publish' );
// https://developer.wordpress.org/reference/hooks/admin_post_action/
// https://wordpress.stackexchange.com/questions/309440/wordpress-plugin-how-to-run-function-when-button-is-clicked
function mp_create_republish_button() {
$content = '
<br />
<div style="border:1px solid black;padding:20px;">
<h2>mettre a jour les publications</h2>
<p>
cliquez sur ce bouton pour mettre a jour toutes les publications
<br />
une nouvelle page vide va s\'ouvrir dans un nouvel onglet, vous pouvez la fermer
</p>
<form action="'.admin_url('admin-post.php').'" method="post" target="_blank">
<input type="hidden" name="action" value="update_publish">
<input type="submit" value="mettre a jour">
</form>
</div>
<br />
';
return $content;
}
*/
?>

View File

@@ -1,22 +0,0 @@
@import "mp_info_windows.css";
@import "mp_zoom.css";
@import "mp_filters.css";
#ljdp_map_wrapper {
position: relative;
}
#ljdp_map {
height: 600px;
width: 100%;
}
@media only screen and (max-width: 700px) {
#ljdp_map {
height: 400px;
}
}

View File

@@ -1,146 +0,0 @@
/*
* FILTERS
*/
/*
#ba197a;
*/
/* **************************************
GENERAL SETTINGS
*/
/*
*/
#ljdp_map_filters,
#ljdp_map_filters * {
display: flex;
flex-direction: row;
position: relative;
margin: auto;
}
#ljdp_map_filters {
display: flex !important;
position: relative;
width: 100%;
z-index: 1;
gap: 10px;
margin-bottom: 10px;
}
#ljdp_map_filters .filter_menu {
display: flex !important;
width: auto;
cursor: pointer;
border-radius: 3px;
white-space: nowrap;
}
/* **************************************
DROP DOWN MENU
*/
/*
*/
#ljdp_map_filters .filter_menu_drop {
width: 100%;
height: auto;
margin: 0px;
padding: 5px;
font-size: 100%;
font-weight: 500;
color: #666;
border: 1px solid #ba197a;
}
#ljdp_map_filters .filter_menu_drop option {
font-size: 100%;
font-weight: 500;
color: #666;
}
/* **************************************
MENU CHECKBOX
*/
#ljdp_map_filters .filter_menu_checkbox p {
--size: 16px;
--left-offset: calc( var(--size) + 5px );
margin-left: var(--left-offset);
}
#ljdp_map_filters .filter_menu_checkbox p::before {
content: "";
position: absolute;
top: calc( 50% - var(--size) / 2 - 1px );
left: calc( var(--left-offset) * -1 );
border: 1px solid #ba197a;
border-radius: 3px;
box-sizing: border-box;
width: var(--size);
height: var(--size);
}
#ljdp_map_filters input.filter_menu_checkbox:checked
+ label.filter_menu_checkbox p::before {
background-color: #ccc;
}
#ljdp_map_filters input.filter_menu_checkbox:disabled
+ label.filter_menu_checkbox {
cursor: default;
}
#ljdp_map_filters input.filter_menu_checkbox:disabled
+ label.filter_menu_checkbox p::before {
border-color: #ccc;
background-color: #ccc;
}
#ljdp_map_filters input.filter_menu_checkbox:disabled
+ label.filter_menu_checkbox p {
color: #ccc;
}
/* **************************************
MENU RESET
*/
#ljdp_map_filters .filter_menu_reset {
/*
flex-shrink: 2;
white-space: nowrap;
*/
border: 1px solid #ba197a;
background-color: #ba197a;
color: #fff;
padding: 5px 10px;
}
/* **************************************
RESONSIVE DESIGN
*/
@media only screen and (max-width: 700px) {
#ljdp_map_filters {
flex-wrap: wrap;
margin: 10px;
width: auto;
}
}

View File

@@ -1,187 +0,0 @@
/*
* INFO WINDOW
*/
/* **************************************
GOOGLE WINDOW
*/
div.gm-style-iw.gm-style-iw-c {
padding: 0px !important;
background-color: transparent;
pointer-events: none;
box-shadow: 0 2px 7px 1px rgba(0,0,0,.3);
box-shadow: none;
border-radius: 0 !important;
max-width: 75vw !important;
}
/* **************************************
GOOGLE TRIANGLE
*/
.gm-style-iw-tc {
display: none !important;
}
/* **************************************
GOOGLE CROICE
*/
button.gm-ui-hover-effect {
display: none !important;
}
/* **************************************
CONTENT
*/
#infowindow_limits,
#infowindow_limits * {
display: flex;
flex-direction: row;
position: relative;
margin: auto;
width: 100%;
}
#infowindow_limits {
/* height must be twice js 'height' value (mp_info_windows.js -> '{ ... height: XXX }' */
height: 550px;
max-width: 380px;
flex-direction: column;
pointer-events: none;
background-color: transparent;
}
#infowindow_limits .infowindow {
pointer-events: auto;
height: auto;
max-height: 400px;
padding: 0px;
overflow: scroll;
flex-direction: column;
border-radius: 3px;
background-color: #fff;
border: 1px solid #ccc;
}
#infowindow_limits #infowindow_close {
position: absolute;
top: 0px;
right: 0px;
width: 30px;
height: 30px;
cursor: pointer;
}
#infowindow_limits #infowindow_close::before {
content: "";
position: absolute;
top: calc(50% - 0.8px);
left: 25%;
width: 50%;
height: 1.6px;
background-color: #fff;
transform: rotate(-45deg);
}
#infowindow_limits #infowindow_close::after {
content: "";
position: absolute;
top: calc(50% - 0.8px);
left: 25%;
width: 50%;
height: 1.6px;
background-color: #fff;
transform: rotate(45deg);
}
#infowindow_limits .infowindow_head {
padding: 5px 10px;
margin: 0px;
background-color: #ab197a;
}
#infowindow_limits .infowindow_head p {
font-size: 115%;
font-weight: 500;
line-height: 1.7em;
color: #fff;
margin-right: 30px;
}
#infowindow_limits .infowindow_body {
padding: 10px 10px 10px 10px;
margin: 0px;
}
#infowindow_limits .infowindow_body::after {
content: "";
position: absolute;
bottom: 0px;
left: 0px;
margin: 0px;
width: 100%;
height: 1px;
background-color: #ccc;
}
#infowindow_limits .infowindow_body p {
font-size: 115%;
font-weight: 500;
line-height: 1.7em;
color: #666;
}
/* **************************************
HIDE SCROLL BARS
*/
/* chrome safari opera */
.gm-style-iw-d::-webkit-scrollbar,
#infowindow_limits::-webkit-scrollbar,
#infowindow_limits .infowindow::-webkit-scrollbar {
display: none;
}
.gm-style-iw-d,
#infowindow_limits,
#infowindow_limits .infowindow {
-ms-overflow-style: none; /* Ie edge */
scrollbar-width: none; /* firefox */
}
/* **************************************
MOBILE RESPONSIVE
*/
@media only screen and (max-width: 400px) {
#infowindow_limits .infowindow_body p,
#infowindow_limits .infowindow_head p {
font-size: 100%;
}
}

View File

@@ -1,24 +0,0 @@
/*
* ZOOM BUTTONS
*/
/* hide the rectangular box container
div.gmnoprint div {
visibility: hidden;
}
*/
/* shape buttons in circles
button.gm-control-active {
visibility: visible;
border-radius: 50% !important;
background-color: rgb(255, 255, 255) !important;
}
*/
/* gap between the buttons
button.gm-control-active ~ div {
height: 10px !important;
}
*/

View File

@@ -1,28 +0,0 @@
<?php
// https://stackify.com/how-to-log-to-console-in-php/
function mp_log($output) {
$type = gettype($output);
if ($type == 'object')
$output = serialize($output);
$time = date('H:i');
$file = '/var/www/html/wp-debug.log';
file_put_contents($file, $time . " " . $output . "\n", FILE_APPEND);
}
function mp_console_log($output) {
$js_code = 'console.log(' . json_encode($output, JSON_HEX_TAG) . ');';
$js_code = '<script>' . $js_code . '</script>';
echo $js_code;
}
// function mp_console_log($output, $with_script_tags = true) {
// $js_code = 'console.log(' . json_encode($output, JSON_HEX_TAG) .
// ');';
// if ($with_script_tags) {
// $js_code = '<script>' . $js_code . '</script>';
// }
// echo $js_code;
// }
?>

View File

@@ -1,18 +0,0 @@
<?php
function mp_get_ip() {
$external_ip = "";
// curl with php :
// https://www.php.net/manual/en/function.curl-init.php
$ch = curl_init('https://ifconfig.me/ip');
// CURLOPT_RETURNTRANSFER is set to true, which means that cURL should return the response from the HTTP request as a string, rather than printing it to the screen
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$external_ip = curl_exec($ch);
//mp_console_log("ip:");
//mp_console_log($external_ip);
curl_close($ch);
return $external_ip;
}
?>

View File

@@ -1,142 +0,0 @@
# inception modifications :
#
# [mysqld] :
# < port = 3306
# > #port = 3306
# ---
# < #bind-address = 127.0.0.1
# > bind-address = 127.0.0.1
#
# These groups are read by MariaDB server.
# Use it for options that only the server (but not clients) should see
#
# See the examples of server my.cnf files in /usr/share/mysql
# this is read by the standalone daemon and embedded servers
[server]
# this is only for the mysqld standalone daemon
[mysqld]
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
#skip-external-locking
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address = 127.0.0.1
#
# * Fine Tuning
#
#key_buffer_size = 16M
#max_allowed_packet = 16M
#thread_stack = 192K
#thread_cache_size = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
#myisam_recover_options = BACKUP
#max_connections = 100
#table_cache = 64
#thread_concurrency = 10
#
# * Query Cache Configuration
#
#query_cache_limit = 1M
query_cache_size = 16M
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#general_log_file = /var/log/mysql/mysql.log
#general_log = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
# Enable the slow query log to see queries with especially long duration
#slow_query_log_file = /var/log/mysql/mariadb-slow.log
#long_query_time = 10
#log_slow_rate_limit = 1000
#log_slow_verbosity = query_plan
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
# other settings you may need to change.
#server-id = 1
#log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
#max_binlog_size = 100M
#binlog_do_db = include_database_name
#binlog_ignore_db = exclude_database_name
#
# * Security Features
#
# Read the manual, too, if you want chroot!
#chroot = /var/lib/mysql/
#
# For generating SSL certificates you can use for example the GUI tool "tinyca".
#
#ssl-ca = /etc/mysql/cacert.pem
#ssl-cert = /etc/mysql/server-cert.pem
#ssl-key = /etc/mysql/server-key.pem
#
# Accept only connections using the latest and most secure TLS protocol version.
# ..when MariaDB is compiled with OpenSSL:
#ssl-cipher = TLSv1.2
# ..when MariaDB is compiled with YaSSL (default in Debian):
#ssl = on
#
# * Character sets
#
# MySQL/MariaDB default is Latin1, but in Debian we rather default to the full
# utf8 4-byte character set. See also client.cnf
#
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
#
# * Unix socket authentication plugin is built-in since 10.0.22-6
#
# Needed so the root database user can authenticate without a password but
# only when running as the unix root user.
#
# Also available for other users if required.
# See https://mariadb.com/kb/en/unix_socket-authentication-plugin/
# this is only for embedded server
[embedded]
# This group is only read by MariaDB servers, not by MySQL.
# If you use the same .cnf file for MySQL and MariaDB,
# you can put MariaDB-only options here
[mariadb]
# This group is only read by MariaDB-10.3 servers.
# If you use the same .cnf file for MariaDB of different versions,
# use this group for options that older servers don't understand
[mariadb-10.3]

View File

@@ -9,8 +9,8 @@ RUN apk update && apk add \
rm -rf /var/cache/apk*
# nginx conf
COPY ./conf/nginx.conf.alpine /etc/nginx/nginx.conf
COPY ./conf/inception_nginx.conf /etc/nginx/http.d/
COPY ./conf/nginx_main.conf.alpine /etc/nginx/nginx.conf
COPY ./conf/nginx_http_server.conf /etc/nginx/http.d/
# dir for logs
RUN mkdir -p /var/log/nginx/
@@ -20,31 +20,37 @@ RUN adduser -S www-data && \
adduser www-data nginx && \
chmod +rwx /var/lib/nginx/tmp
# ARG variables are not persistent after the build process, in opposite to ENV
ARG WP_URL
ARG MAX_UPLOAD_SIZE
ARG WP_VOLUME_DIR
ARG WP_VOLUME_PLUGINS
ARG NG_VOLUME_CERTS
# create and empty volumes dir
RUN mkdir -p ${WP_VOLUME_DIR} ${WP_VOLUME_PLUGINS} ${NG_VOLUME_CERTS} && \
rm -rf ${WP_VOLUME_DIR}/* ${WP_VOLUME_PLUGINS}/* ${NG_VOLUME_CERTS}/*
# replace WP_URL
RUN sed -i "s/\${WP_URL}/${WP_URL}/g" /etc/nginx/http.d/inception_nginx.conf
RUN sed -i "s/\${WP_URL}/${WP_URL}/g" /etc/nginx/http.d/nginx_http_server.conf
# replace max file size upload
RUN sed -i "s/\(client_max_body_size \).*\(m;\)/\1${MAX_UPLOAD_SIZE}\2/g" /etc/nginx/nginx.conf
# create ssl certificate
COPY ./conf/ssl ${NG_VOLUME_CERTS}
RUN if [ -z "$(ls -A ${NG_VOLUME_CERTS} 2>/dev/null)" ]; then \
mkdir ${NG_VOLUME_CERTS}/private ${NG_VOLUME_CERTS}/certs; \
# create ssl certificates
# command openssl :
# - req : create a certificate signing request (CSR) or a self-signed certificate
# - newkey rsa:2048 : generate a new RSA key pair with a key length of 2048 bits
# - nodes : the private key should not be encrypted with a passphrase. This is useful for automated processes where entering a passphrase is not practical
# - x509 : a self-signed certificate should be created
# - days 365 : sets the validity period of the certificate to 365 days
# - subj : sets the subject, information about the entity the certificate is issued to
# - C, ST, L, O, OU, CN : country, state, locality, organization, organizational unit, and common name
# - keyout : the filename for the private key file
# - out : the filename for the output certificate file
ARG SSL_KEY=${NG_VOLUME_CERTS}/private/${WP_URL}.key
ARG SSL_CERT=${NG_VOLUME_CERTS}/certs/${WP_URL}.crt
RUN mkdir -p ${NG_VOLUME_CERTS}; \
cd ${NG_VOLUME_CERTS}; \
mkdir private certs; \
openssl req -newkey rsa:2048 -nodes -x509 -days 365 \
-subj "/C=fr/ST=ile-de-france/L=paris/O=ljdp/OU=lejourdesprofs/CN=${WP_URL}" \
-keyout ${NG_VOLUME_CERTS}/private/${WP_URL}.key \
-out ${NG_VOLUME_CERTS}/certs/${WP_URL}.crt; \
fi
-subj "/C=fr/ST=ile-de-france/L=paris/O=wp/OU=wp_local/CN=${WP_URL}" \
-keyout ${SSL_KEY} \
-out ${SSL_CERT};
ENTRYPOINT [ "nginx", "-g", "daemon off;" ]

View File

@@ -1,91 +0,0 @@
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}

View File

@@ -1,48 +0,0 @@
# doc : https://nginx.org/en/docs/dirindex.html
server {
listen 443 ssl; # for ipv4, on port 443, specifying that accepted connections should works in ssl mode
listen [::]:443 ssl; # for ipv6
server_name ${WP_URL};
ssl_certificate /etc/ssl/certs/${WP_URL}.crt; # specifies the file with the ssl certificate (self signed here) generated by openssl
ssl_certificate_key /etc/ssl/private/${WP_URL}.key; # specifies the file with the secret key of the certificate
root /var/www/html/; # contains default nginx index.nginx-debian.html
index index.html index.php; # defines files that will be used as index (https://nginx.org/en/docs/http/ngx_http_index_module.html)
access_log /var/log/nginx/${WP_URL}.access.log;
error_log /var/log/nginx/${WP_URL}.error.log;
# use fastcgi for all php files
location ~ \.php$ {
fastcgi_pass wordpress:9000;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# followings are from :
# https://www.farinspace.com/wordpress-nginx-rewrite-rules/
# unless the request is for a valid file, send to bootstrap
# without this, permalinks changes don't work
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q=$1 last;
}
## enforce NO www
#if ($host ~* ^www\.(.*)) {
# set $host_without_www $1;
# rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
#}
## catch all
#error_page 404 /index.php;
## deny access to apache .htaccess files
#location ~ /\.ht {
# deny all;
#}
}

View File

@@ -1,98 +0,0 @@
# inception modifications :
#
# ssl_protocols :
# < ssl_protocols TLSv1.3; # Dropping SSLv3, ref: POODLE
# > ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
# gzip :
# < gzip off;
# > gzip on;
# sites-enabled :
# < # include /etc/nginx/sites-enabled/*;
# > include /etc/nginx/sites-enabled/*;
# doc : https://nginx.org/en/docs/dirindex.html
user www-data; # process owner name, can be anything
worker_processes auto; # a worker is a process that handles incoming requests, auto to automatically adjust the number of processes available
pid /run/nginx.pid; # defines a file that will store the process id of the main process
include /etc/nginx/modules-enabled/*.conf; # include a file
events { # section for connection processing directives
worker_connections 768; # max number of connection that can be opened by a worker process
# multi_accept on;
}
http { # section for http server directives
##
# Basic Settings
##
sendfile on; # enable the use of linux sendfil() function, that transfer data directly betzeen fd, so withour copying to intermediate memory buffer, it increases performances in most cases (https://stackoverflow.com/questions/58066785/always-use-sendfile-with-nginx-on-linux)
tcp_nopush on; # enables the socket option TCP_CORK/TCP_NOPUSH, that allows to send packets filled with more datas (https://baus.net/on-tcp_cork/)
tcp_nodelay on; # opposit of TCP_CORK, TCP_NODELAY says the application to send datas as soon as it receives it, both options are exclusives but can work together in modern kernel (https://stackoverflow.com/questions/3761276/when-should-i-use-tcp-nodelay-and-when-tcp-cork)
keepalive_timeout 65; # in seconds, defines time before closing a connexion without activity
types_hash_max_size 2048; # maximum size for the list that stores duplicates of the hash table, size of the hash table is chosen accordingly (https://nginx.org/en/docs/hash.html, hash table : https://www.youtube.com/watch?v=KyUTuwz_b7Q)
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types; # include a file
default_type application/octet-stream; # defines the default MIME type (default is text/plain)
##
# SSL Settings
##
ssl_protocols TLSv1.3; # Dropping SSLv3, ref: POODLE # enables the specified protocols. The TLSv1.1 and TLSv1.2 parameters works only when OpenSSL 1.0.1 or higher is used, and the TLSv1.3 only when OpenSSL 1.1.1 or higher is used
ssl_prefer_server_ciphers on; # Specifies that server ciphers should be preferred over client ciphers when using the SSLv3 and TLS protocols (a cipher is "an algorithm for performing encryption or decryption, a series of [...] steps that can be followed as a procedure" https://en.wikipedia.org/wiki/Cipher_suite)
##
# Logging Settings
##
access_log /var/log/nginx/access.log; # defines where to write the access logs. if gzip is used, the log will be buffered
error_log /var/log/nginx/error.log; # defines where to write the error logs. if gzip is used, the log will be buffered
##
# Gzip Settings
##
gzip off; # enable gzipping of responses. gzip is an algorithm that compress the data (disabled for security reasons : https://bugs.debian.org/773332)
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf; # include the *.conf files found in conf.d folder. do the same as "sites-enabled" with another approach : you put your .conf files for the site inside this folder, and if you want to disable a config file you just rename it to no have a .conf suffix
# include /etc/nginx/sites-enabled/*; # include all the (symlink) files found in sites-enabled folder. do the same as "conf.d" with another approach : you put all your configurations files into a "/etc/nginx/sites-available/" folder, and you put symlinks of a selection of thoses files that you want to use for the site, into "/etc/nginx/sites-enabled/" folder (bad practice : https://serverfault.com/questions/527630/difference-in-sites-available-vs-sites-enabled-vs-conf-d-directories-nginx#answer-870709)
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}

View File

@@ -0,0 +1,52 @@
# doc :
# https://nginx.org/en/docs/dirindex.html
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
server {
listen 443 ssl; # for ipv4, on port 443, specifying that accepted connections should works in ssl mode
listen [::]:443 ssl; # for ipv6
server_name ${WP_URL};
ssl_certificate /etc/ssl/certs/${WP_URL}.crt; # specifies the file with the ssl certificate (self signed here) generated by openssl
ssl_certificate_key /etc/ssl/private/${WP_URL}.key; # specifies the file with the secret key of the certificate
root /var/www/html/; # contains default nginx index.nginx-debian.html
index index.html index.php; # defines files that will be used as index (https://nginx.org/en/docs/http/ngx_http_index_module.html)
access_log /var/log/nginx/${WP_URL}.access.log;
error_log /var/log/nginx/${WP_URL}.error.log;
# use fastcgi for all php files
location ~ \.php$ {
fastcgi_pass wordpress:9000;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# followings are from :
# https://www.farinspace.com/wordpress-nginx-rewrite-rules/
# unless the request is for a valid file, send to bootstrap
# without this, permalinks changes don't work
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q=$1 last;
}
## enforce NO www
#if ($host ~* ^www\.(.*)) {
# set $host_without_www $1;
# rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
#}
## catch all
#error_page 404 /index.php;
## deny access to apache .htaccess files
#location ~ /\.ht {
# deny all;
#}
}

View File

@@ -1,4 +1,4 @@
# inception modifications :
# modifications from original :
#
# user :
# < user www-data

View File

@@ -27,14 +27,9 @@ COPY ./conf/www.conf /etc/php7/php-fpm.d/
RUN mkdir /run/php/
ARG WP_VOLUME_DIR
ARG WP_VOLUME_PLUGINS
ARG MAX_UPLOAD_SIZE
ARG EXECUTION_TIME
# create and empty volumes dir
RUN mkdir -p ${WP_VOLUME_DIR} ${WP_VOLUME_PLUGINS} && \
rm -rf ${WP_VOLUME_DIR}/* ${WP_VOLUME_PLUGINS}/*
# replace max file size upload and execution time
RUN sed -i "s/\(upload_max_filesize = \).*\(M\)/\1${MAX_UPLOAD_SIZE}\2/g" /etc/php7/php.ini && \
sed -i "s/\(post_max_size = \).*\(M\)/\1${MAX_UPLOAD_SIZE}\2/g" /etc/php7/php.ini && \

View File

@@ -10,6 +10,8 @@ CYAN="\e[0;36m"
WHITE="\e[0;37m"
RESET="\e[0m"
# it gets the ENV variables from .env because specified in the docker-compose.yml file
# install wordpress with cli : https://make.wordpress.org/cli/handbook/how-to-install/
# commands : https://developer.wordpress.org/cli/commands/
# bug with wp commands : https://github.com/wp-cli/config-command/issues/31
@@ -27,20 +29,22 @@ else
fi
# install wp if not already installed
if ! wp core is-installed --path="${WP_VOLUME_DIR}" 2> /dev/null
then
echo -e ${YELLOW}installing...${RESET}
echo -e ${YELLOW}wp config create...${RESET}
echo -e ${YELLOW}installing :${RESET}
#wp config create \
echo -e ${YELLOW}wp config create...${RESET}
php wp-cli.phar config create \
--dbhost="${DB_HOST}" \
--dbname="${DB_NAME}" \
--dbuser="${DB_USER}" \
--dbpass="${DB_PSWD}" \
--path="${WP_VOLUME_DIR}" --allow-root
echo -e ${YELLOW}wp core install...${RESET}
#wp core install \
echo -e ${YELLOW}wp core install...${RESET}
php wp-cli.phar core install \
--url="${WP_URL}" \
--title="${WP_TITLE}" \
@@ -49,25 +53,26 @@ then
--admin_password="${WP_ADMIN_PSWD}" \
--skip-email \
--path="${WP_VOLUME_DIR}" --allow-root
echo -e ${YELLOW}wp user create...${RESET}
#wp user create \
php wp-cli.phar user create \
"${WP_USER}" "${WP_USER_EMAIL}" \
--user_pass="${WP_USER_PSWD}" \
--path="${WP_VOLUME_DIR}" --allow-root
echo -e ${YELLOW}chown and chmod...${RESET}
chown -R www-data:www-data /var/www/*
chmod 755 -R /var/www/*
echo -e ${YELLOW}plugins...${RESET}
plugins=$(ls ${WP_VOLUME_PLUGINS})
for dir in $plugins; do
ln -s ${WP_VOLUME_PLUGINS}/$dir ${WP_VOLUME_DIR}/wp-content/plugins/$dir
done
echo -e ${GREEN}done !${RESET}
else
echo -e ${GREEN}wp is installed${RESET}
#https://stackoverflow.com/questions/56344567/wordpress-prevent-redirection-to-main-url
echo -e ${YELLOW}checking config.php file with current url...${RESET}
HOME=$(php wp-cli.phar config get WP_HOME --path=${WP_VOLUME_DIR})
if [ ${HOME} != ${WP_COMPLETE_URL} ] ; then
php wp-cli.phar config set WP_HOME ${WP_COMPLETE_URL} --path=${WP_VOLUME_DIR}
fi
SITEURL=$(php wp-cli.phar config get WP_SITEURL --path=${WP_VOLUME_DIR})
if [ ${SITEURL} != ${WP_COMPLETE_URL} ] ; then
php wp-cli.phar config set WP_SITEURL ${WP_COMPLETE_URL} --path=${WP_VOLUME_DIR}
fi
fi