Skip to main content

GFPDF\Plugins\PdfForGravityView\Pdf\Maps\StaticMapRenderer

Resolves a Static Maps PNG for a (View, Entry) pair and embeds it in the document.

The orchestrator that the field-template override (field-entry_map-html.php) delegates to.

Nothing is kept once the render is over. Google's Maps Platform terms don't permit storing or caching Static Maps imagery, while the Geo print guidelines do permit it inside a printed document — so the PNGs go to \ImageStore, a scratch directory that this request created and that this request deletes. Repeat renders are spared by Pdf\Cache, which stores the finished PDF rather than the tiles.

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:40

Details

  • Kind: class
  • Namespace: GFPDF\Plugins\PdfForGravityView\Pdf\Maps

Properties

PropertyTypeDescription
$fetchesintStatic Maps fetched from Google so far this request.
$memosarrayRequest-lifetime memos, keyed by name (and View id where the answer is per-View). A Multiple Entry PDF calls \render once per row, and most of what it needs is constant across the whole document: the API key, the View's map options and default pin, the locale. Resolving those per row is expensive out of proportion to what they are — ApiKey::resolve() and Admin::get_map_settings() each rebuild every GravityKit plugin's settings tree — so they are resolved once and reused. Reset between tests by TestCase::flush_request_memos().
$url_builderUrlBuilder
$api_keyApiKey
$imagesImageStore
$httpHttpClient

Methods

MethodDescription
__construct()
init()
render_widget()Draw the Multiple Entries Map widget, when that is the widget being asked about.
hide_view_only_widget()Buffer the add-on's front-end Map widget output away when the widget is "PDF only".
restore_view_only_widget()Discard the buffer {@see hide_view_only_widget()} opened, dropping the add-on's front-end map markup.
render()Draw the map for the given View+Entry — a tile, or the error box when the site is set up for maps
render_collection()Render one map covering a whole result set — the Multiple Entries Map widget's document-wide map,
map_widgets()Every Multiple Entries Map widget on the View, in zone order.
is_map_widget()
is_map_field()Whether a resolved View field is the add-on's Entry Map.
prefetch()Fetch a whole directory result set's maps in one batch, before any row renders.
normalize_viewport()Validate, clamp and round a viewport down to the one value that can reach a tile.

Method Reference

__construct()

public function __construct( UrlBuilder $url_builder, ApiKey $api_key, ImageStore $images, HttpClient $http )

Parameters

NameTypeDefaultDescription
$url_builderUrlBuilder
$api_keyApiKey
$imagesImageStore
$httpHttpClient

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:203

init()

public function init(): void

Returns

  • void

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:215

render_widget()

public function render_widget( $html, $widget, $view, $entries ): string

Draw the Multiple Entries Map widget, when that is the widget being asked about.

DirectoryWriter walks the zone and asks; knowing what a map widget is belongs here.

Parameters

NameTypeDefaultDescription
$htmlstringMarkup another listener already supplied, if any.
$widgetmixedThe widget being rendered.
$viewView
$entriesEntry_CollectionThe rows this document is drawing.

Returns

  • string

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:244

hide_view_only_widget()

public function hide_view_only_widget( $widget_args ): void

Buffer the add-on's front-end Map widget output away when the widget is "PDF only".

Paired with \restore_view_only_widget around the add-on's own priority-10 render; both read the same $widget_args, so the open and the discard cannot come apart within one dispatch.

Parameters

NameTypeDefaultDescription
$widget_argsarrayThe widget's saved configuration.

Returns

  • void

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:277

restore_view_only_widget()

public function restore_view_only_widget( $widget_args ): void

Discard the buffer {@see hide_view_only_widget()} opened, dropping the add-on's front-end map markup.

Parameters

NameTypeDefaultDescription
$widget_argsarrayThe widget's saved configuration.

Returns

  • void

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:294

render()

public function render( View $view, array $entry, $field=null, string $context=RenderContext::SINGLE ): string

Draw the map for the given View+Entry — a tile, or the error box when the site is set up for maps

and one didn't arrive. Empty when there is nothing to draw (mirroring upstream entry_map.php).

Parameters

NameTypeDefaultDescription
$viewView
$entryarrayGravity Forms entry array (must contain id).
$field\GV\Field | nullnullThe GV field. Carries the layout/height settings, and is forwarded to the marker/viewport filters for per-field control.
$contextstringRenderContext::SINGLERenderContext::SINGLE or RenderContext::DIRECTORY — which document this map is being drawn into. Passed rather than inferred, and passed as \RenderContext::for_field() answers it, which is what makes \prefetch and the row it warmed agree on the hash: the same function over the same field, from either side.

Returns

  • string — HTML.

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:351

render_collection()

public function render_collection( View $view, Entry_Collection $entries, \GV\Widget $widget ): string

Render one map covering a whole result set — the Multiple Entries Map widget's document-wide map,

with a marker per entry, as against \render's one map per entry.

Returns an empty string when nothing can be drawn, and never an error box: this is a widget the View owner added to a page, not a field they put in a row, so a page with no locatable entries should look like a page without the widget rather than a page with something broken on it.

Parameters

NameTypeDefaultDescription
$viewView
$entriesEntry_CollectionThe rows this document is drawing, in render order.
$widget\GV\WidgetThe Map widget. Carries the layout setting, and is forwarded to the marker filter in the field's place.

Returns

  • string — HTML.

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:538

map_widgets()

public static function map_widgets( View $view ): array

Every Multiple Entries Map widget on the View, in zone order.

The one place that knows how a map widget is recognised and where one can live. Both the thing that draws them (\widget_map_inputs) and the thing that keys the cache on them (\CacheKey::map_views()) read it, so they cannot disagree — a gate that admitted a zone the renderer never walks would key a map that never draws, and the reverse would serve a stale one.

A widget marked "exclude from PDF" is dropped here, so it counts as a map widget for neither: the prefetch never fetches it and the cache key never keys on it, matching the nothing \render_widget draws. Every caller is PDF-side, so this is where "not in the PDF" belongs.

Parameters

NameTypeDefaultDescription
$viewView

Returns

  • \GV\Widget[]

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:888

is_map_widget()

public static function is_map_widget( $widget ): bool

Parameters

NameTypeDefaultDescription
$widgetmixed

Returns

  • bool

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:914

is_map_field()

public static function is_map_field( $field ): bool

Whether a resolved View field is the add-on's Entry Map.

Parameters

NameTypeDefaultDescription
$fieldmixed

Returns

  • bool

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:927

prefetch()

public function prefetch( View $view, Entry_Collection $entries, callable $resolve_fields ): void

Fetch a whole directory result set's maps in one batch, before any row renders.

A row's map depends on nothing but its own entry, so the only reason they were ever fetched one after another is that each was resolved at the moment its row rendered. Resolved together they can be issued together, and the render waits once for the slowest rather than once for each.

Two things beyond the concurrency make this cheaper than the sum of its rows. Identical input sets collapse — a directory of entries at the same address, or the same entry appearing twice, is one request — and that saving is money, not just time. And the fetch ceiling is applied to the deduped set, so it bounds distinct maps rather than rows.

Failure is not handled here on purpose: anything this doesn't warm is fetched by the row that needs it, through the ordinary sequential path, with its retry. The prefetch is an optimisation and never a precondition.

Parameters

NameTypeDefaultDescription
$viewView
$entriesEntry_CollectionThe resolved rows, in render order.
$resolve_fieldscallableRow → its field set, as \GFPDF\Plugins\PdfForGravityView\Pdf\Unions::resolver() returns.

Returns

  • void

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:1005

normalize_viewport()

public static function normalize_viewport( $viewport ): ?array

Validate, clamp and round a viewport down to the one value that can reach a tile.

Rounding to \UrlBuilder::COORDINATE_PRECISION() is what collapses the request's cardinality onto the set of distinguishable images: 5 dp is ~1.1m, still an order of magnitude finer than a 640px tile resolves at any zoom Google serves.

Parameters

NameTypeDefaultDescription
$viewportmixed

Returns

  • array{lat:float, — lng:float, zoom:int|null}|null

Since: 2.0

Source: src/Pdf/Maps/StaticMapRenderer.php:1540