Skip to content

PHP API

On this page

PHP API: the osfec_* functions

These functions are the plugin’s public API. They live in includes/functions.php, load on plugins_loaded and are
available anywhere in the theme.

Every function that takes a $post_id defaults to the current post in the loop.

#Reading fields

#osfec_field( string $key, ?int $post_id = null ): mixed

One meta value, without the _osfec_ prefix. The workhorse.

$price = osfec_field( 'price' );        // '540000' or ''
$city  = osfec_field( 'city', $id );    // 'Białystok'

Missing fields return '', because empty values are never stored. See the data model for the
full key list.

#osfec_photos( ?int $post_id = null ): array

The full-size photo URLs, decoded from JSON. Empty array when the offer has none.

foreach ( osfec_photos() as $url ) { … }

#osfec_photo_thumb( string $url ): string

Converts a full-size Esti URL into its thumbnail variant (_max_min). There is no _small.

#osfec_agent( ?int $post_id = null ): array

The agent behind the offer, merged from two sources: the offer’s own meta carries the name, e-mail and phone; the photo,
role and office come from the directory synchronized separately, matched on the Esti agent ID. The directory wins on
every field it actually carries.

Returns name, photo, position, office, email, phone — always all six keys, '' where unknown.

$agent = osfec_agent();

if ( $agent['name'] ) {
    printf( '<a href="tel:%s">%s</a>', esc_attr( $agent['phone'] ), esc_html( $agent['name'] ) );
}

#Formatting

#osfec_format_price( $price, string $currency = '' ): string

Localised number plus the currency code. An empty price returns the translated “Price on request”, so guard the
value yourself if you need a different empty state.

osfec_format_price( '540000', 'PLN' );  // '540 000 PLN'
osfec_format_price( '' );               // 'Price on request'

#osfec_format_area( $area ): string

Localised number plus ; whole numbers lose their decimals. Empty input returns ''.

#osfec_location( ?int $post_id = null ): string

Street, city and commune as one line, empties and duplicates removed: Lipowa, Białystok.

#osfec_type_label( ?int $post_id = null ): string

The short type label, without the bracketed variant: Działka (Rolna)Działka. Use osfec_field( 'type_label' )
for the full one.

#osfec_transaction_label( string $slug ): string

sale → “Sale”, rent → “Rent”, purchase → “Purchase”, lease → “Lease”. Unknown slugs return ''.

#osfec_market_label( string $slug ): string

primary → “Primary market”, secondary → “Secondary market”.

Both label functions are translated through the plugin’s text domain.

#Dictionary-backed attributes

Some Esti fields arrive as bare numeric IDs. Never print them raw.

#osfec_attribute_label( string $key, ?int $post_id = null ): string

Reads the meta key and resolves it in one step. Returns '' when the dictionary cannot name the ID — the template
is expected to drop the row in that case.

$heating = osfec_attribute_label( 'building_heating' );

if ( '' !== $heating ) {
    echo esc_html( $heating );
}

#osfec_dictionary_label( $id ): string

The lower-level version: resolves an ID you already have.

#Building filter controls

#osfec_type_options(): array

Type slug → label, for the offers currently in the catalogue. The slugs match the type filter parameter. Cached for 6
hours.

#osfec_subtype_options(): array

Subtype slug → label (rolnaRolna). Built the same way, so it fills up after the first synchronization.

#osfec_slug_map( string $key ): array

Slug → raw value for any meta key, built from the values actually stored. This is what makes ?city=bialystok find
offers whose stored city is Białystok.

$cities = osfec_slug_map( 'city' );   // [ 'bialystok' => 'Białystok', … ]

Cached for 6 hours and flushed at the end of every successful run. Each call runs a DISTINCT query on wp_postmeta
when the cache is cold, so call it once and reuse the result.

#Templates and page structure

#osfec_get_template( string $name, array $args = array() ): void

Includes a template part, letting the theme override it. $name is relative to the plugin’s templates/ directory; the
theme’s copy lives under osfec/ in the theme root. The array reaches the template as $args.
See Overriding templates.

osfec_get_template( 'parts/card.php', array( 'post_id' => get_the_ID() ) );

Open and close a plugin page with the active theme’s own chrome.

On a classic theme they are get_header() and get_footer(). On a block theme they render the theme’s header and
footer template parts inside a .wp-site-blocks wrapper, and open a <main class="osfec-main"> between them — because
get_header() on a block theme falls back to the theme-compatibility stub, an ancient markup block carrying none of the
theme’s navigation, colours or fonts.

Use them in any full-page template you write for the offer post type, and always in pairs.

#Class-level entry points you may need

Not helper functions, but part of the surface a custom UI uses:

Call Purpose
OSFEC_Query::request() The whitelisted, sanitized GET parameters as an array
OSFEC_Query::build_args( $request, $base ) Those parameters as WP_Query arguments merged into your own
OSFEC_Query::archive_url( $request ) The archive URL with filters applied
OSFEC_Settings::value( $key, $default ) One setting
OSFEC_CPT::POST_TYPE 'osfec_offer'
OSFEC_Mapper::thumbnail_url( $url ) The same conversion osfec_photo_thumb() performs

#Escaping

None of these functions escape their output — they return data, not markup. Escape at the point of printing:
esc_html() for text, esc_url() for URLs, esc_attr() for attributes.