proxies = array_keys( array_filter( (array) get_option( 'acf_osm_proxy' ) ) ); if ( count( $this->proxies ) ) { add_filter('acf_osm_leaflet_providers', [ $this, 'proxify_providers' ], 50 ); } add_action( 'update_option_acf_osm_provider_tokens', [ $this, 'setup_proxies' ] ); add_action( 'update_option_acf_osm_providers', [ $this, 'setup_proxies' ] ); add_action( 'update_option_acf_osm_proxy', [ $this, 'setup_proxies' ] ); } /** * @return array holding keys of proxied providers */ public function get_proxies() { return $this->proxies; } /** * Apply proxy config to all providers * @filter acf_osm_leaflet_providers */ public function proxify_providers( $providers ) { foreach ( $providers as $provider_key => &$provider ) { if ( ! in_array( $provider_key, $this->proxies ) ) { continue; } $provider = $this->proxify_provider( $provider_key, $provider ); } return $providers; } /** * Apply proxy config to provider * * @param string $provider_key * @param array $provider * @return array */ private function proxify_provider( $provider_key, $provider ) { // make sure variant config is an array $provider = LeafletProviders::instance()->unify_provider_variants( $provider ); $provider = $this->proxify_tileset( $provider, $provider_key ); if ( isset( $provider['variants'] ) ) { foreach ( $provider['variants'] as $variant_key => $variant ) { if ( ! isset( $variant['url'] ) ) { $variant['url'] = $provider['url']; } $provider['variants'][$variant_key] = $this->proxify_tileset( $variant, $provider_key, $variant_key ); } } return $provider; } /** * Apply proxy config to provider or variant * * @param string $provider_key * @param array $provider * @return array */ private function proxify_tileset( $tileset, $provider_key, $variant_key = '' ) { // resolution capability? if ( strpos( $tileset['url'], '{r}') !== false ) { $url_params_part = '{z}/{x}/{y}{r}'; } else { $url_params_part = '{z}/{x}/{y}'; } // remove unneeded props from provider (and hide access tokens on the way) foreach ( array_keys( $tileset['options'] ) as $option ) { if ( strpos( $tileset['url'], "{{$option}}") !== false ) { unset( $tileset['options'][$option] ); } } // reconfigure url $tileset['url'] = content_url( $this->get_proxy_path( $provider_key, $variant_key ) . $url_params_part ); return $tileset; } /** * Setup proxy directory in wp-content/ and save proxy config in uploads. * * @action update_option_acf_osm_provider_tokens * @action update_option_acf_osm_providers * @action update_option_acf_osm_proxy */ public function setup_proxies() { if ( ! WP_Filesystem() ) { return false; } global $wp_filesystem; $this->setup_proxy_dir(); $proxied_providers = LeafletProviders::instance()->get_providers( ['credentials'], true ); $proxy_config = []; foreach ( $proxied_providers as $provider_key => $provider ) { $provider = LeafletProviders::instance()->unify_provider_variants( $provider ); if ( isset( $provider['options']['subdomains'] ) ) { $subdomains = $provider['options']['subdomains']; } else { $subdomains = 'abc'; } $proxy_config[$provider_key] = [ 'base_url' => $this->generate_url( $provider['url'], $provider['options'] ), 'subdomains' => $subdomains, ]; if ( isset( $provider['variants'] ) ) { foreach ( $provider['variants'] as $variant_key => $variant ) { if ( isset( $variant['url'] ) ) { $variant_url = $variant['url']; } else { $variant_url = $provider['url']; } $variant_url = $this->generate_url( $variant_url, $variant['options'] ); $variant_url = $this->generate_url( $variant_url, $provider['options'] ); if ( isset( $variant['options']['subdomains'] ) ) { $variant_subdomains = $variant['options']['subdomains']; } else { $variant_subdomains = $subdomains; } $proxy_config["{$provider_key}.{$variant_key}"] = [ 'base_url' => $variant_url, 'subdomains' => $variant_subdomains, ]; } } } $upload_dir = wp_upload_dir( null, false ); $content = 'put_contents( $upload_dir['basedir'] . '/acf-osm-proxy-config.php', $content ); } /** * */ public function uninstall() { if ( ! WP_Filesystem() ) { return false; } global $wp_filesystem; $wp_filesystem->unlink( $upload_dir['basedir'] . '/acf-osm-proxy-config.php', $content ); $proxy_path = trailingslashit( trailingslashit( WP_CONTENT_DIR ) . $this->get_proxy_path() ) ; $wp_filesystem->rmdir($proxy_path); } /** * @param string $base_url * @param array $options */ private function generate_url( $base_url, $options ) { $url = $base_url; foreach ( $options as $option => $value ) { if ( is_scalar( $value ) ) { $url = str_replace( "{{$option}}", str_replace(' ', '%20', $value), $url ); } } return $url; } /** * Setup proxy directory in wp-content/maps/ */ private function setup_proxy_dir() { global $wp_filesystem; $proxy_path = trailingslashit( trailingslashit( WP_CONTENT_DIR ) . $this->get_proxy_path() ) ; wp_mkdir_p( $proxy_path ); if ( ! $wp_filesystem->exists( $proxy_path . '.htaccess' ) ) { $content = '# Generously generated by ACF OpenStreetMap Field Plugin' . "\n"; $content .= 'RewriteEngine On' . "\n"; $content .= 'RewriteBase /wp-content/maps' . "\n"; $content .= 'RewriteRule . index.php [L]' . "\n"; $wp_filesystem->put_contents( $proxy_path . '.htaccess', $content ); } if ( ! $wp_filesystem->exists( $proxy_path . 'index.php' ) ) { $upload_dir = wp_upload_dir( null, false ); $content = 'get_plugin_dir() ) ); $wp_filesystem->put_contents( $proxy_path . 'index.php', $content ); } } /** * @param string $provider_key * @param string $variant_key * @return string */ private function get_proxy_path( $provider_key = '', $variant_key = '' ) { $path = 'maps'; if ( $provider_key ) { $path .= '/' . $provider_key; if ( $variant_key ) { $path .= '.' . $variant_key; } } return trailingslashit( $path ); } }