diff --git a/module/Core/config/module.config.php b/module/Core/config/module.config.php
index f645549f8..4700339c4 100644
--- a/module/Core/config/module.config.php
+++ b/module/Core/config/module.config.php
@@ -554,6 +554,7 @@
\Core\View\Helper\Snippet::class => \Core\Factory\View\Helper\SnippetFactory::class,
\Core\View\Helper\Proxy::class => \Laminas\ServiceManager\Factory\InvokableFactory::class,
\Core\View\Helper\ModuleVersion::class => \Core\View\Helper\ModuleVersionFactory::class,
+ \Core\View\Helper\FormatLocation::class => \Laminas\ServiceManager\Factory\InvokableFactory::class,
),
'initializers' => array(
// '\Core\View\Helper\Service\HeadScriptInitializer',
@@ -564,6 +565,7 @@
'proxy' => \Core\View\Helper\Proxy::class,
'form_element' => 'formElement',
'moduleVersion' => \Core\View\Helper\ModuleVersion::class,
+ 'formatLocation' => \Core\View\Helper\FormatLocation::class,
],
),
diff --git a/module/Core/src/View/Helper/FormatLocation.php b/module/Core/src/View/Helper/FormatLocation.php
new file mode 100644
index 000000000..49b558081
--- /dev/null
+++ b/module/Core/src/View/Helper/FormatLocation.php
@@ -0,0 +1,119 @@
+
+ * TODO: write tests
+ */
+class FormatLocation extends AbstractHelper
+{
+ protected $defaultFormat = '%S%Z%r%C';
+
+ public function __invoke($location = null, ?string $format = null, $separator = '
')
+ {
+ if ($location === null) {
+ return $this;
+ }
+
+ if ($location instanceof Collection) {
+ return $this->formatCollection($location, $format, $separator);
+ }
+
+ return $this->format($location, $format);
+ }
+
+ public function format(LocationInterface $location, ?string $format = null)
+ {
+ if ($format == null) {
+ $format = $this->defaultFormat;
+ }
+
+ $placeholders = [];
+ preg_match_all('~%[cCzZrsSn](?::[^\s%]*)?~s', $format, $matches);
+
+ $variables = [
+ '%c' => "getCity",
+ '%C' => "getCountry",
+ '%z' => "getPostalCode",
+ '%Z' => ["getPostalCode", "getCity"],
+ '%r' => "getRegion",
+ '%s' => "getStreetname",
+ '%S' => ["getStreetname", "getStreetnumber"],
+ '%n' => "getStreetnumber",
+ ];
+
+ $str = str_replace('%%', ':percent:', $format);
+
+ foreach ($matches[0] as $var) {
+ if (strpos($var, ':') !== false) {
+ [$ph, $sep] = explode(':', $var, 2);
+ } else {
+ $ph = $var;
+ $sep = null;
+ }
+
+ $method = $variables[$ph];
+ if (is_array($method)) {
+ $val = [];
+ foreach ($method as $m) {
+ $val[] = $location->$m();
+ }
+ $val = join(' ', $val);
+ } else {
+ $val = $location->$method();
+ }
+
+ $val = trim((string) $val);
+
+ if (!$val) {
+ $str = str_replace($var, '', $str);
+ continue;
+ }
+
+ $placeholders[] = [$var, $val, $sep];
+ }
+
+ while ($placeholder = array_shift($placeholders)) {
+ [$var, $val, $sep] = $placeholder;
+
+ if (count($placeholders)) {
+ $val .= $sep === null ? ', ' : $sep;
+ }
+
+ $str = str_replace($var, $val, $str);
+ }
+
+ if (strpos($format, '%lon') !== false || strpos($format, '%lat' !== false)) {
+ $coords = $location->getCoordinates()->getCoordinates();
+ $str = str_replace(['%lon', '%lat'], [$coords[0], $coords[1]], $str);
+ }
+
+ $str = str_replace([':percent:', ':s:'], ['%', ' '], $str);
+ return $str;
+ }
+
+ public function formatCollection($locations, $format, $separator = '
')
+ {
+ $loc = [];
+
+ foreach ($locations as $l) {
+ $loc[] = $this->format($l, $format);
+ }
+
+ return join($separator, $loc);
+ }
+}
diff --git a/module/Jobs/view/jobs/index/index.ajax.phtml b/module/Jobs/view/jobs/index/index.ajax.phtml
index a02857b70..7fb1e8b72 100644
--- a/module/Jobs/view/jobs/index/index.ajax.phtml
+++ b/module/Jobs/view/jobs/index/index.ajax.phtml
@@ -15,7 +15,7 @@ $snapshots = $this->services('repositories.Jobs/JobSnapshot');