*/ namespace RankMath\Schema; use RankMath\Helper; use RankMath\Admin\Database\Database; defined( 'ABSPATH' ) || exit; /** * DB class. */ class DB { /** * Get query builder object. * * @param string $table Meta table name. * * @return Query_Builder */ private static function table( $table = 'postmeta' ) { return Database::table( $table ); } /** * Get all schemas by Object ID. * * @param int $object_id Object ID. * @param string $table Meta table name. * @param bool $from_db If set to true, the schema will be retrieved from the database. * * @return array */ public static function get_schemas( $object_id, $table = 'postmeta', $from_db = false ) { static $schema_cache = []; // Add exception handler. if ( is_null( $object_id ) ) { return []; } // Get from cache. if ( ! $from_db && isset( $schema_cache[ $table . '_' . $object_id ] ) ) { return $schema_cache[ $table . '_' . $object_id ]; } $key = 'termmeta' === $table ? 'term_id' : 'post_id'; $data = self::table( $table ) ->select( 'meta_id' ) ->select( 'meta_value' ) ->where( $key, $object_id ) ->whereLike( 'meta_key', 'rank_math_schema', '' ) ->get(); $schemas = []; foreach ( $data as $schema ) { $value = maybe_unserialize( $schema->meta_value ); if ( empty( $value ) ) { continue; } $id = 'schema-' . $schema->meta_id; $schemas[ $id ] = maybe_unserialize( $schema->meta_value ); } // Add to cache. $schema_cache[ $table . '_' . $object_id ] = $schemas; return $schemas; } /** * Get Schema types by Object ID. * * @param int $object_id Object ID. * @param bool $sanitize Sanitize schema types. * @param bool $translate Whether to get the schema name. * * @return array */ public static function get_schema_types( $object_id, $sanitize = false, $translate = true ) { $schemas = self::get_schemas( $object_id ); if ( empty( $schemas ) && Helper::get_default_schema_type( $object_id ) ) { $schemas[] = [ '@type' => ucfirst( Helper::get_default_schema_type( $object_id ) ) ]; } if ( has_block( 'rank-math/faq-block', $object_id ) ) { $schemas[] = [ '@type' => 'FAQPage' ]; } if ( has_block( 'rank-math/howto-block', $object_id ) ) { $schemas[] = [ '@type' => 'HowTo' ]; } if ( empty( $schemas ) ) { return false; } $types = array_reduce( wp_list_pluck( $schemas, '@type' ), function( $carry, $type ) { if ( is_array( $type ) ) { return array_merge( $carry, $type ); } $carry[] = $type; return $carry; }, [] ); $types = array_unique( $types ); if ( $sanitize ) { $types = array_map( function ( $type ) use ( $translate ) { return Helper::sanitize_schema_title( $type, $translate ); }, $types ); } return implode( ', ', $types ); } /** * Get schema by shortcode id. * * @param string $id Shortcode unique id. * @param bool $from_db If set to true, the schema will be retrieved from the database. * @return array */ public static function get_schema_by_shortcode_id( $id, $from_db = false ) { /** * Keep Schema data in memory after querying by shortcode ID, to avoid * unnecessary queries. * * @var array */ static $cached_schema_shortcodes = []; if ( ! $from_db && isset( $cached_schema_shortcodes[ $id ] ) ) { return $cached_schema_shortcodes[ $id ]; } // First, check for meta_key matches for a "shortcut" to the schema. $shortcut = false; if ( strpos( self::table()->table, 'post' ) !== false ) { // Only check for shortcuts if we're querying for a post. $shortcut = self::table() ->select( 'meta_value' ) ->where( 'meta_key', 'rank_math_shortcode_schema_' . $id ) ->one(); } if ( ! empty( $shortcut ) ) { $data = self::table() ->select( 'post_id' ) ->select( 'meta_value' ) ->where( 'meta_id', $shortcut->meta_value ) ->one(); if ( ! empty( $data ) ) { $schema = [ 'post_id' => $data->post_id, 'schema' => maybe_unserialize( $data->meta_value ), ]; // Cache the schema for future use. $cached_schema_shortcodes[ $id ] = $schema; return $schema; } } $data = self::table() ->select( 'post_id' ) ->select( 'meta_value' ) ->whereLike( 'meta_value', $id, '%:"' ) ->one(); if ( ! empty( $data ) ) { $schema = [ 'post_id' => $data->post_id, 'schema' => maybe_unserialize( $data->meta_value ), ]; // Cache the schema for future use. $cached_schema_shortcodes[ $id ] = $schema; return $schema; } return false; } /** * Get schema type for template. * * @param int $post_id Post id. * * @return string */ public static function get_template_type( $post_id ) { $data = self::table() ->select( 'meta_value' ) ->where( 'post_id', $post_id ) ->whereLike( 'meta_key', 'rank_math_schema', '' ) ->one(); if ( empty( $data ) ) { return ''; } $schema = maybe_unserialize( $data->meta_value ); return [ 'type' => isset( $schema['@type'] ) ? $schema['@type'] : '', 'schema' => $schema, ]; } /** * Delete Schema data using Post ID. * * @param int $post_id Post ID. * * @return string */ public static function delete_schema_data( $post_id ) { return self::table()->where( 'post_id', $post_id )->whereLike( 'meta_key', 'rank_math_schema_' )->delete(); } /** * Unpublish job posting when expired. * * @param JsonLD $jsonld JsonLD Instance. * @param array $schemas Array of JSON-LD entity. */ public static function unpublish_jobposting_post( $jsonld, $schemas ) { if ( ! is_singular() ) { return; } $job_postings = array_map( function( $schema ) { return isset( $schema['@type'] ) && 'JobPosting' === $schema['@type'] ? $schema : false; }, $schemas ); if ( empty( $job_postings ) ) { return; } foreach ( $job_postings as $job_posting ) { if ( empty( $job_posting['metadata']['unpublish'] ) || 'on' !== $job_posting['metadata']['unpublish'] || empty( $job_posting['validThrough'] ) || date_create( 'now' )->getTimestamp() < strtotime( $job_posting['validThrough'] ) ) { continue; } wp_update_post( [ 'ID' => $jsonld->post_id, 'post_status' => 'draft', ] ); break; } } }