Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions includes/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,9 @@ public static function set_columns( array $columns ): array {
public static function render_column( string $column, int $post_id ): void {
switch ( $column ) {
case 'odw_license':
// License is now stored per distribution (Änderung 7); show label from first distribution.
$dists = carbon_get_post_meta( $post_id, 'odw_distributions' );
$lic = '';
if ( is_array( $dists ) ) {
foreach ( $dists as $dist ) {
$candidate = (string) ( $dist['license'] ?? '' );
if ( '' !== $candidate ) {
$lic = ( 'sonstige' === $candidate && ! empty( $dist['license_custom'] ) )
? (string) $dist['license_custom']
: $candidate;
break;
}
}
$lic = (string) carbon_get_post_meta( $post_id, 'odw_license' );
if ( 'sonstige' === $lic ) {
$lic = (string) carbon_get_post_meta( $post_id, 'odw_license_custom' );
}
echo esc_html( '' !== $lic ? ODW_Fields::get_license_label( $lic ) : '—' );
break;
Expand Down
149 changes: 64 additions & 85 deletions includes/class-fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,55 +118,44 @@ private static function register_required_fields(): void {
->add_tab(
__( '3 — Datenbereitstellung', 'open-data-wizard' ),
array(
Field::make( 'complex', 'odw_distributions', __( 'Wo können die Daten heruntergeladen werden?', 'open-data-wizard' ) )
->set_min( 1 )
->set_collapsed( false )
->add_fields(
Field::make( 'text', 'odw_access_url', __( 'Wo kann ich die Datei herunterladen?', 'open-data-wizard' ) )
->set_required( true )
->set_attribute( 'placeholder', 'https://beispiel.de/daten/datei.csv' )
->set_attribute( 'type', 'url' )
->set_help_text( __( 'ZUGRIFFS-URL (dcat:accessURL)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: https://beispiel.de/daten/datei.csv', 'open-data-wizard' ) ),

Field::make( 'select', 'odw_format', __( 'In welchem Format ist die Datei?', 'open-data-wizard' ) )
->add_options( self::get_format_options() )
->set_help_text( __( 'FORMAT (dct:format)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: CSV, JSON, PDF', 'open-data-wizard' ) ),

Field::make( 'text', 'odw_byte_size', __( 'Dateigröße (Bytes)', 'open-data-wizard' ) )
->set_attribute( 'type', 'number' )
->set_attribute( 'min', '0' )
->set_attribute( 'data-odw-backing', 'byte_size' ),

Field::make( 'select', 'odw_license', __( 'Unter welcher Lizenz sind diese Daten verfügbar?', 'open-data-wizard' ) )
->set_required( true )
->set_default_value( class_exists( 'ODW_Settings' ) ? (string) ODW_Settings::get( 'default_license' ) : '' )
->add_options( self::get_license_options() )
->set_help_text( __( 'LIZENZ (dct:license)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: CC0 1.0, CC-BY 4.0 – Diese bestimmt, wie andere die Daten nutzen dürfen.', 'open-data-wizard' ) ),

Field::make( 'text', 'odw_license_custom', __( 'Lizenz-URI eingeben oder auswählen', 'open-data-wizard' ) )
->set_attribute( 'placeholder', __( 'https://example.org/meine-lizenz', 'open-data-wizard' ) )
->set_attribute( 'data-odw-autosuggest', 'license_custom' )
->set_help_text( __( 'EIGENE LIZENZ-URI', 'open-data-wizard' ) . "\n\n" . __( 'Vollständige URI der Lizenz eingeben oder aus der Liste auswählen. Beispiel: https://creativecommons.org/licenses/by/4.0/', 'open-data-wizard' ) )
->set_conditional_logic(
array(
Field::make( 'text', 'access_url', __( 'Wo kann ich die Datei herunterladen?', 'open-data-wizard' ) )
->set_required( true )
->set_attribute( 'placeholder', 'https://beispiel.de/daten/datei.csv' )
->set_attribute( 'type', 'url' )
->set_help_text( __( 'ZUGRIFFS-URL (dcat:accessURL)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: https://beispiel.de/daten/datei.csv', 'open-data-wizard' ) ),

Field::make( 'select', 'format', __( 'In welchem Format ist die Datei?', 'open-data-wizard' ) )
->add_options( self::get_format_options() )
->set_help_text( __( 'FORMAT (dct:format)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: CSV, JSON, PDF', 'open-data-wizard' ) ),

Field::make( 'text', 'byte_size', __( 'Dateigröße (Bytes)', 'open-data-wizard' ) )
->set_attribute( 'type', 'number' )
->set_attribute( 'min', '0' )
->set_attribute( 'data-odw-backing', 'byte_size' ),

Field::make( 'select', 'license', __( 'Unter welcher Lizenz sind diese Daten verfügbar?', 'open-data-wizard' ) )
->set_required( true )
->set_default_value( class_exists( 'ODW_Settings' ) ? (string) ODW_Settings::get( 'default_license' ) : '' )
->add_options( self::get_license_options() )
->set_help_text( __( 'LIZENZ (dct:license)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: CC0 1.0, CC-BY 4.0 – Diese bestimmt, wie andere die Daten nutzen dürfen.', 'open-data-wizard' ) ),

Field::make( 'text', 'license_custom', __( 'Lizenz-URI eingeben oder auswählen', 'open-data-wizard' ) )
->set_attribute( 'placeholder', __( 'https://example.org/meine-lizenz', 'open-data-wizard' ) )
->set_attribute( 'data-odw-autosuggest', 'license_custom' )
->set_help_text( __( 'EIGENE LIZENZ-URI', 'open-data-wizard' ) . "\n\n" . __( 'Vollständige URI der Lizenz eingeben oder aus der Liste auswählen. Beispiel: https://creativecommons.org/licenses/by/4.0/', 'open-data-wizard' ) )
->set_conditional_logic(
array(
array(
'field' => 'license',
'value' => 'sonstige',
'compare' => '=',
),
)
),

Field::make( 'text', 'attribution_text', __( 'Welcher Namensnennungstext soll bei Weiternutzung angegeben werden?', 'open-data-wizard' ) )
->set_attribute( 'placeholder', __( 'optional – nur bei CC BY oder CC BY-SA', 'open-data-wizard' ) )
->set_help_text( __( 'NAMENSNENNUNGSTEXT (dcatde:licenseAttributionByText)', 'open-data-wizard' ) . "\n\n" . __( 'Empfohlen bei CC BY und CC BY-SA Lizenzen. Beispiel: Datensatz von Musterorganisation e.V., bereitgestellt unter CC BY 4.0', 'open-data-wizard' ) ),
array(
'field' => 'odw_license',
'value' => 'sonstige',
'compare' => '=',
),
)
)
->set_help_text(
__( 'DISTRIBUTIONEN (dcat:distribution)', 'open-data-wizard' ) . "\n\n" .
__( 'Eine Distribution beschreibt eine konkrete Bereitstellungsform — z.B. eine CSV-Datei, eine JSON-API oder ein PDF. Ein Datensatz kann mehrere Distributionen in verschiedenen Formaten haben. Jede Distribution erhält eine eigene Lizenz.', 'open-data-wizard' )
),

Field::make( 'text', 'odw_attribution_text', __( 'Welcher Namensnennungstext soll bei Weiternutzung angegeben werden?', 'open-data-wizard' ) )
->set_attribute( 'placeholder', __( 'optional – nur bei CC BY oder CC BY-SA', 'open-data-wizard' ) )
->set_help_text( __( 'NAMENSNENNUNGSTEXT (dcatde:licenseAttributionByText)', 'open-data-wizard' ) . "\n\n" . __( 'Empfohlen bei CC BY und CC BY-SA Lizenzen. Beispiel: Datensatz von Musterorganisation e.V., bereitgestellt unter CC BY 4.0', 'open-data-wizard' ) ),
)
)

Expand Down Expand Up @@ -684,7 +673,12 @@ function odw_build_dataset_jsonld( int $post_id ): ?array {
$theme = carbon_get_post_meta( $post_id, 'odw_theme' );
$issued = carbon_get_post_meta( $post_id, 'odw_issued' );
$modified = get_post_meta( $post_id, '_odw_modified', true );
$distributions = carbon_get_post_meta( $post_id, 'odw_distributions' );
$dist_access_url = (string) carbon_get_post_meta( $post_id, 'odw_access_url' );
$dist_format = (string) carbon_get_post_meta( $post_id, 'odw_format' );
$dist_byte_size = (string) carbon_get_post_meta( $post_id, 'odw_byte_size' );
$dist_license = (string) carbon_get_post_meta( $post_id, 'odw_license' );
$dist_license_custom = (string) carbon_get_post_meta( $post_id, 'odw_license_custom' );
$dist_attribution = (string) carbon_get_post_meta( $post_id, 'odw_attribution_text' );
$cessda_topic = (string) carbon_get_post_meta( $post_id, 'odw_cessda_topic' );

// Extended DCAT-AP fields (Tab 4).
Expand Down Expand Up @@ -759,50 +753,35 @@ function odw_build_dataset_jsonld( int $post_id ): ?array {
);
}

if ( ! empty( $distributions ) && is_array( $distributions ) ) {
$dist_list = array();

foreach ( $distributions as $dist ) {
$access_url = esc_url_raw( (string) ( $dist['access_url'] ?? '' ) );

if ( empty( $access_url ) ) {
continue;
}

$dist_item = array(
'@type' => 'dcat:Distribution',
'dcat:accessURL' => $access_url,
);

if ( ! empty( $dist['format'] ) ) {
$dist_item['dct:format'] = array( '@id' => ODW_Fields::get_format_eu_uri( $dist['format'] ) );
}

// File size: prefer new composite fields (byte_size_value + unit), fall back to legacy byte_size.
$byte_size = odw_compute_byte_size( $dist );
if ( $byte_size > 0 ) {
$dist_item['dcat:byteSize'] = $byte_size;
}
$dist_access_url_safe = esc_url_raw( $dist_access_url );
if ( ! empty( $dist_access_url_safe ) ) {
$dist_item = array(
'@type' => 'dcat:Distribution',
'dcat:accessURL' => $dist_access_url_safe,
);

// Lizenz pro Distribution (Änderung 7).
$dist_license = (string) ( $dist['license'] ?? '' );
if ( 'sonstige' === $dist_license && ! empty( $dist['license_custom'] ) ) {
$dist_license = (string) $dist['license_custom'];
}
if ( ! empty( $dist_license ) && 'sonstige' !== $dist_license ) {
$dist_item['dct:license'] = array( '@id' => $dist_license );
}
if ( ! empty( $dist_format ) ) {
$dist_item['dct:format'] = array( '@id' => ODW_Fields::get_format_eu_uri( $dist_format ) );
}

if ( ! empty( $dist['attribution_text'] ) ) {
$dist_item['dcatde:licenseAttributionByText'] = (string) $dist['attribution_text'];
}
$byte_size_int = (int) $dist_byte_size;
if ( $byte_size_int > 0 ) {
$dist_item['dcat:byteSize'] = $byte_size_int;
}

$dist_list[] = $dist_item;
$effective_license = $dist_license;
if ( 'sonstige' === $dist_license && ! empty( $dist_license_custom ) ) {
$effective_license = $dist_license_custom;
}
if ( ! empty( $effective_license ) && 'sonstige' !== $effective_license ) {
$dist_item['dct:license'] = array( '@id' => $effective_license );
}

if ( ! empty( $dist_list ) ) {
$dataset['dcat:distribution'] = $dist_list;
if ( ! empty( $dist_attribution ) ) {
$dist_item['dcatde:licenseAttributionByText'] = $dist_attribution;
}

$dataset['dcat:distribution'] = array( $dist_item );
}

// Extended DCAT-AP fields (Tab 4).
Expand Down
39 changes: 7 additions & 32 deletions includes/class-quality.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,33 +192,17 @@ private static function check_indicator( string $key, \WP_Post $post ): bool {
return '' !== trim( (string) carbon_get_post_meta( $post->ID, 'odw_publisher' ) );

case 'license':
// License is now per-distribution (Änderung 7).
$dists = carbon_get_post_meta( $post->ID, 'odw_distributions' );
if ( ! is_array( $dists ) ) {
return false;
$lic = (string) carbon_get_post_meta( $post->ID, 'odw_license' );
if ( '' !== $lic && 'sonstige' !== $lic ) {
return true;
}
foreach ( $dists as $dist ) {
$lic = (string) ( $dist['license'] ?? '' );
if ( '' !== $lic && 'sonstige' !== $lic ) {
return true;
}
if ( 'sonstige' === $lic && ! empty( $dist['license_custom'] ) ) {
return true;
}
if ( 'sonstige' === $lic ) {
return '' !== (string) carbon_get_post_meta( $post->ID, 'odw_license_custom' );
}
return false;

case 'distribution':
$dists = carbon_get_post_meta( $post->ID, 'odw_distributions' );
if ( ! is_array( $dists ) ) {
return false;
}
foreach ( $dists as $dist ) {
if ( ! empty( $dist['access_url'] ) ) {
return true;
}
}
return false;
return '' !== (string) carbon_get_post_meta( $post->ID, 'odw_access_url' );

case 'language':
return '' !== trim( (string) carbon_get_post_meta( $post->ID, 'odw_language' ) );
Expand All @@ -235,16 +219,7 @@ private static function check_indicator( string $key, \WP_Post $post ): bool {
return '' !== trim( (string) carbon_get_post_meta( $post->ID, 'odw_issued' ) );

case 'dist_format':
$dists = carbon_get_post_meta( $post->ID, 'odw_distributions' );
if ( ! is_array( $dists ) ) {
return false;
}
foreach ( $dists as $dist ) {
if ( ! empty( $dist['format'] ) ) {
return true;
}
}
return false;
return '' !== (string) carbon_get_post_meta( $post->ID, 'odw_format' );
}

return false;
Expand Down
16 changes: 6 additions & 10 deletions includes/class-shortcode.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,14 @@ public static function render( $atts ): string {
$theme = (string) get_post_meta( $post_id, '_odw_theme', true );
$file_id = (int) get_post_meta( $post_id, '_odw_file_id', true );

// License from first distribution (per-distribution architecture).
// License from post meta.
$license_label = '';
if ( function_exists( 'carbon_get_post_meta' ) ) {
$distributions = carbon_get_post_meta( $post_id, 'odw_distributions' );
if ( is_array( $distributions ) && ! empty( $distributions ) ) {
$first_dist = $distributions[0];
$license_uri = isset( $first_dist['license'] ) ? (string) $first_dist['license'] : '';
if ( 'sonstige' === $license_uri && ! empty( $first_dist['license_custom'] ) ) {
$license_label = (string) $first_dist['license_custom'];
} elseif ( '' !== $license_uri ) {
$license_label = ODW_Fields::get_license_label( $license_uri );
}
$license_uri = (string) carbon_get_post_meta( $post_id, 'odw_license' );
if ( 'sonstige' === $license_uri ) {
$license_label = (string) carbon_get_post_meta( $post_id, 'odw_license_custom' );
} elseif ( '' !== $license_uri ) {
$license_label = ODW_Fields::get_license_label( $license_uri );
}
}

Expand Down
83 changes: 16 additions & 67 deletions includes/class-validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,94 +139,43 @@ private static function get_field_value( int $post_id, array $cf_input, string $
}

/**
* Check whether the post has at least one distribution with a non-empty access_url.
* Check whether the post has a valid access_url.
*
* @param int $post_id Post ID.
* @param array<string, mixed> $cf_input Decoded Carbon Fields compact input.
*/
private static function has_valid_distribution( int $post_id, array $cf_input ): bool {
// Check CF compact input for new distributions.
foreach ( $cf_input as $key => $value ) {
// CF compact keys for complex fields look like: _odw_distributions[0][access_url].
if ( str_contains( (string) $key, '_odw_distributions' ) && str_contains( (string) $key, 'access_url' ) ) {
if ( ! empty( $value ) && self::is_valid_url( (string) $value ) ) {
return true;
}
}
// Check CF compact input first.
$access_url = (string) ( $cf_input['_odw_access_url'] ?? '' );
if ( ! empty( $access_url ) && self::is_valid_url( $access_url ) ) {
return true;
}

// Fall back to existing meta.
$distributions = carbon_get_post_meta( $post_id, 'odw_distributions' );

if ( ! is_array( $distributions ) ) {
return false;
}

foreach ( $distributions as $dist ) {
if ( ! empty( $dist['access_url'] ) && self::is_valid_url( (string) $dist['access_url'] ) ) {
return true;
}
}

return false;
$access_url = (string) carbon_get_post_meta( $post_id, 'odw_access_url' );
return ! empty( $access_url ) && self::is_valid_url( $access_url );
}

/**
* Check that every distribution with an access_url also has a license.
* Check that if an access_url is set, a license is also set.
*
* @param int $post_id Post ID.
* @param array<string, mixed> $cf_input Decoded Carbon Fields compact input.
*/
private static function all_distributions_have_license( int $post_id, array $cf_input ): bool {
// Collect licenses from CF compact input.
$url_keys = array();
$license_keys = array();

foreach ( $cf_input as $key => $value ) {
$key = (string) $key;
if ( str_contains( $key, '_odw_distributions' ) && str_contains( $key, 'access_url' ) && ! empty( $value ) ) {
// Extract group index from key like _odw_distributions[0][access_url].
preg_match( '/\[(\d+)\]/', $key, $matches );
if ( isset( $matches[1] ) ) {
$url_keys[] = $matches[1];
}
}
if ( str_contains( $key, '_odw_distributions' ) && str_contains( $key, '][license]' ) && ! empty( $value ) ) {
preg_match( '/\[(\d+)\]/', $key, $matches );
if ( isset( $matches[1] ) ) {
$license_keys[] = $matches[1];
}
}
}

// If we found distribution data in CF compact input, check it.
if ( ! empty( $url_keys ) ) {
foreach ( $url_keys as $idx ) {
if ( ! in_array( $idx, $license_keys, true ) ) {
return false;
}
}
$access_url = (string) ( $cf_input['_odw_access_url'] ?? carbon_get_post_meta( $post_id, 'odw_access_url' ) );
if ( empty( $access_url ) ) {
return true;
}

// Fall back to existing meta.
$distributions = carbon_get_post_meta( $post_id, 'odw_distributions' );

if ( ! is_array( $distributions ) ) {
return true;
$license = (string) ( $cf_input['_odw_license'] ?? carbon_get_post_meta( $post_id, 'odw_license' ) );
if ( '' === $license ) {
return false;
}

foreach ( $distributions as $dist ) {
if ( empty( $dist['access_url'] ) ) {
continue;
}
$lic = (string) ( $dist['license'] ?? '' );
if ( '' === $lic ) {
return false;
}
if ( 'sonstige' === $lic && empty( $dist['license_custom'] ) ) {
return false;
}
if ( 'sonstige' === $license ) {
$custom = (string) ( $cf_input['_odw_license_custom'] ?? carbon_get_post_meta( $post_id, 'odw_license_custom' ) );
return ! empty( $custom );
}

return true;
Expand Down
Loading
Loading