• File: structureddata.php
  • Full Path: /home/blwgracecity/jesusexp.org/wp-content/uploads/structureddata.php
  • File size: 12.92 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php
/*
* SITESEO
* https://siteseo.io
* (c) SITSEO Team
*/

namespace SiteSEOPro;

if(!defined('ABSPATH')){
	die('Hacking Attempt !');
}

class StructuredData{
	
	static function enqueue_metabox(){	
		$post_id = get_the_ID();

		wp_enqueue_style('siteseo-structured-data-metabox', SITESEO_PRO_ASSETS_URL.'/css/metabox.css');
		wp_enqueue_script('siteseo-index-highlight', SITESEO_PRO_ASSETS_URL.'/js/index-highlight.js', ['jquery'], SITESEO_PRO_VERSION);
		wp_enqueue_script('siteseo-structured-data-metabox', SITESEO_PRO_ASSETS_URL.'/js/metabox.js', ['jquery'], SITESEO_PRO_VERSION);

		wp_localize_script('siteseo-structured-data-metabox', 'structuredDataMetabox', [
			'propertyTemplates' => \SiteSEOPro\StructuredData::get_schema_properties(),
			'currentPostUrl' => get_permalink($post_id)
		]);
	}

	static function display_metabox(){
		global $post;
		
		if(is_front_page() || is_home()){
			$post_id = get_option('page_on_front');

			if(!$post_id && is_home()){
				$post_id = get_option('page_for_posts');
			}
			
		} else{
			$post_id = $post ? $post->ID : 0;
		}
		
		if(!empty($post_id)){
			$schema_type = !empty(get_post_meta($post_id, '_siteseo_structured_data_type', true)) ? get_post_meta($post_id, '_siteseo_structured_data_type', true) : '';
			$schema_properties = !empty(get_post_meta($post_id, '_siteseo_structured_data_properties', true)) ? get_post_meta($post_id, '_siteseo_structured_data_properties', true) : '';
			$custom_schema = !empty(get_post_meta($post_id, '_siteseo_structured_data_custom', true)) ? get_post_meta($post_id, '_siteseo_structured_data_custom', true) : '';
		}
		
		$schema_types['Article'] = 'Article';
		$schema_types['NewsArticle'] = 'News Article';
		$schema_types['Blogposting'] = 'Blog post';
		$schema_types['Product'] = 'Product';
		$schema_types['Recipe'] = 'Recipe';
		$schema_types['Restaurant'] = 'Restaurant';
		$schema_types['Course'] = 'Course';
		$schema_types['LocalBusiness'] = 'Local Business';
		$schema_types['Person'] = 'Person';
		$schema_types['Organization'] = 'Organization';
		$schema_types['Book'] = 'Book Recording';
		$schema_types['MusicRecording'] = 'Music Album';
		$schema_types['SoftwareApplication'] = 'Software Application';
		$schema_types['VideoObject'] = 'Video';
		$schema_types['Event'] = 'Event';
		$schema_types['JobPosting'] = 'Job Posting';
		$schema_types['CustomSchema'] = 'Custom Schema';
		
		
		$custom_schema_placeholder = json_encode([
			'type' => 'object',
			'properties' => [
				'placeholder' => ['type' => 'string'],
				'description' => ['type' => 'integer']
			]
		], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
		
		echo'<div class="siteseo-metabox-option-wrap">
			<div class="siteseo-metabox-label-wrap">
				<label for="siteseo_structured_data_type">'.esc_html__('Select Schema Types','siteseo-pro').'</label>
			</div>
			<div class="siteseo-metabox-input-wrap">
				<select name="siteseo_structured_data_type" class="siteseo_structured_data_type" id="siteseo_structured_data_type">
					<option value="">'.esc_html__('None').'</option>';
					foreach($schema_types as $type => $label){
						echo '<option value="'.esc_attr($type).'" '.selected($schema_type, $type, false).'>'.esc_html($label).'</option>';
					}
				echo'</select>
				</input>
			</div>
		</div>';
		
		$schema_template = self::get_schema_properties();
		
		echo'<div class="siteseo-metabox-schema">
				<div id="siteseo_schema_properties_container" class="'.(empty($schema_type) || $schema_type === 'CustomSchema' ? 'hidden' : '').'">
					<div class="siteseo-schema-properties">';

					if(!empty($schema_type) && isset($schema_template[$schema_type]) && $schema_type !== 'CustomSchema'){
						
						$is_textarea = ['description', 'instructions', 'reviewBody', 'questions', 'step', 'ingredients', 'recipeInstructions', 'courseDescription', 'bookDescription', 'softwareRequirements', 'menu', 'name'];
						
						$is_date_type = ['datePublished', 'dateModified', 'uploadDate', 'startDate', 'endDate', 'foundingDate', 'releaseDate'];
						
						foreach($schema_template[$schema_type] as $property => $default){
							echo '<p><h4 for="siteseo_schema_property_'.esc_attr($property).'">'.esc_html(ucfirst(preg_replace('/([a-z])([A-Z])/', '$1 $2', $property))).':</h4>';

							if(in_array($property, $is_textarea)){
								echo '<textarea name="schema_properties['.esc_attr($property).']" id="siteseo_schema_property_' .esc_attr($property).'" rows="3" class="widefat">'.esc_textarea(isset($schema_properties[$property]) ? $schema_properties[$property] : '').'</textarea>';
							} else if(in_array($property, $is_date_type)){
								echo '<input type="datetime-local" name="schema_properties['.esc_attr($property).']" id="siteseo_schema_property_'.esc_attr($property).'" value="' .esc_attr(isset($schema_properties[$property]) ? $schema_properties[$property] : '').'" class="widefat">';
							} else {
								echo '<input type="text" name="schema_properties['.esc_attr($property).']" id="siteseo_schema_property_'.esc_attr($property).'" value="' .esc_attr(isset($schema_properties[$property]) ? $schema_properties[$property] : '').'" class="widefat">';
							}

							echo '</p>';
						}
					}
		
				echo '</div>
			</div>
		</div>
		
		<div class="siteseo-metabox-schema">
			<div id="siteseo_custom_schema_container" class="'.($schema_type !== 'CustomSchema' ? 'hidden' : '').'">
			<h4>'.esc_html__('Custom Schema', 'siteseo-pro').'</h4>
				<p>
					<textarea name="siteseo_structured_data_custom" placeholder="'.esc_attr($custom_schema_placeholder).'" rows="10" class="siteseo_structured_data_custom widefat code">'.
					esc_textarea($custom_schema).'</textarea>
				</p>
				<p class="description">'.sprintf(esc_html__('Create your custom schema as per guidelines. %sRead here%s.', 'siteseo-pro'),'<a href="https://schema.org/docs/schemas.html" target="_blank" rel="noopener noreferrer">','</a>').'</p>
			</div>
		</div>
		
		<div class="siteseo-metabox-option-wrap">
			<div class="siteseo-schema-preview">
				<h4>'.esc_html__('JSON-LD Preview', 'siteseo-pro').'</h4>
				<a class="button" id="siteseo_validate_schema">'.esc_html__('Google Validation','siteseo-pro').'</a>
				
				<pre id="siteseo_schema_preview">';
				if($schema_type === 'CustomSchema' && !empty($custom_schema)){
					echo '<div id="siteseo_highlighter">'.esc_html($custom_schema).'</div>';
				} elseif (!empty($schema_type) && !empty($schema_properties)){
					$schema_data = array(
						'@context' => 'https://schema.org',
						'@type' => $schema_type
					);

					foreach($schema_properties as $key => $value){
						if(!empty($value)){
							$schema_data[$key] = $value;
						}
					}
					
					echo'<div id="siteseo_highlighter">'.esc_html(json_encode($schema_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)).'</div>';
				} else{
					echo'<div>'.esc_html__('No schema has been selected.').'</div>';
				}
				echo'</pre>
			</div>
		</div>';		
	}
	
	static function get_schema_properties(){
		
		return [
			'Article'=> [
				'headline' => '',
				'author' => '',
				'datePublished' => '',
				'dateModified' => '',
				'publisher' => '',
				'description' => '',
			],
			'Blogposting' => [
				'headline' => '',
				'author' => '',
				'datePublished' => '',
				'dateModified' => '',
				'publisher' => '',
				'description' => '',
			],
			'Course' => [
				'name' => '',
				'Description' => '',
				'provider' => '',
				'availableLanguage' => '',
				'coursePrerequisites' =>'',
				'courseCode' => '',
				'hasCourseInstance' => '',
				'timeRequired' => '',
				'educationalCredentialAwarded' => '',
			],
			'MusicRecording' => [
				'name' => '',
				'byArtist' => '',
				'duration' => '',
				'recordingOf' => '',
				'inAlbum' => '',
				'datePublished' => '',
				'releasedEvent' => '',
				'abstract' => '',
			],
			'Book' => [
				'name' => '',
				'author' => '',
				'bookEdition' => '',
				'isbn' => '',
				'publisher' => '',
				'datePublished' => '',
				'abstract' => '',
				'inLanguage' => '',
			],
			'Restaurant' => [
				'name' => '',
				'address' => '',
				'hasMenu' => '',
				'telephone' => '',
				'priceRange' => '',
				'openingHours' => '',
			],
			'SoftwareApplication' => [
				'name' => '',
				'applicationCategory' => '',
				'applicationSubCategory' => '',
				'availableOnDevice' => '',
				'operatingSystem' => '',
				'softwareVersion' => '',
				'softwareRequirements' => '',
				'downloadUrl' => '',
			],
			'VideoObject' => [
				'name' => '',
				'description' => '',
				'thumbnailUrl' => '',
				'uploadDate' => '',
				'embedUrl' => '',
				'publisher' =>'',
				'creator' => '',
			],
			'Event' => [
				'name' => '',
				'startDate' => '',
				'endDate' => '',
				'location' => '',
				'description' => '',
				'offers' => '',
				'organizer' => '',
				'performer' => '',
			],
			'Recipe' => [
				'name' => '',
				'author' => '',
				'description' => '',
				'cookTime' => '',
				'cookingMethod' => '',
				'prepTime' => '',
				'totalTime' => '',
				'recipeYield' => '',
				'recipeCategory' => '',
				'recipeCuisine' => '',
				'recipeInstructions' => '',
			],
			'Person' =>[
				'name' => '',
				'jobTitle' => '',
				'email' => '',
				'telephone' => '',
				'address' => '',
			],
			'Organization' => [
				'name' => '',
				'url' =>'',
				'description' => '',
				'email' => '',
				'founder' => '',
				'foundingDate' => '',
				'numberOfEmployees' => '',
				'location' => '',
			],
			'JobPosting' =>[
				'name' => '',
				'industry' => '',
				'title' => '',
				'totalJobOpenings' => '',
				'skills' => '',
				'jobBenefits' => '',
				'jobLocationType' => '',
			],
			'NewsArticle' =>[
				'headline' => '',
				'author' => '',
				'datePublished' => '',
				'dateModified' => '',
				'publisher' => '',
				'description' => '',
			],
			'Product' =>[
				'name' => '',
				'description' => '',
				'brand' => '',
				'category' => '',
				'releaseDate' => '',
				'size' => '',	
			],

			'LocalBusiness' =>[
				'legalName' => '',
				'founder' => '',
				'address' => '',
				'email' => '',
				'numberOfEmployees' => '',
				'telephone' => '',
				'taxID' => '',
				'vatID' => '',
			],
		]; 
	}
	
	static function save_metabox($post_id, $post){
		
		// Security Check
		if(!isset($_POST['siteseo_metabox_nonce']) || !wp_verify_nonce(sanitize_text_field($_POST['siteseo_metabox_nonce']), 'siteseo_metabox_nonce')){
			return $post_id;
		}

		//Post type object
		$post_type = get_post_type_object($post->post_type);

		//Check permission
		if(!current_user_can($post_type->cap->edit_post, $post_id)){
			return $post_id;
		}
		
		if(isset($_POST['siteseo_structured_data_type'])){
			update_post_meta($post_id, '_siteseo_structured_data_type', sanitize_text_field($_POST['siteseo_structured_data_type']));
		} else{
			delete_post_meta($post_id, '_siteseo_structured_data_type');
		}
		
		if(isset($_POST['siteseo_structured_data_custom'])){
			update_post_meta($post_id, '_siteseo_structured_data_custom', wp_kses_post($_POST['siteseo_structured_data_custom']));
		} else{
			delete_post_meta($post_id, '_siteseo_structured_data_custom');
		}
		
		if(isset($_POST['schema_properties']) && is_array($_POST['schema_properties'])){
			
			$properties = array();
			$text_area_fields = array('description', 'instructions', 'reviewBody', 'questions', 'step', 'ingredients','recipeInstructions', 'courseDescription', 'bookDescription', 'softwareRequirements', 'menu');
			
			foreach($_POST['schema_properties'] as $key => $value){
				if(in_array($key, $text_area_fields)){
					$properties[$key] = sanitize_textarea_field($value);
				} else{
					$properties[$key] = sanitize_text_field($value);
				}
			}
			
			update_post_meta($post_id, '_siteseo_structured_data_properties', $properties);
		} else{
			delete_post_meta($post_id, '_siteseo_structured_data_properties');
		}
	}
	
	static function render(){
		global $siteseo, $post;
		
		if(empty($siteseo->pro['enable_structured_data']) || empty($siteseo->pro['toggle_state_stru_data'])){
			return; // disable
		}
		
		if(!is_singular()){
			return;
		}

		$schema_type = !empty(get_post_meta($post->ID , '_siteseo_structured_data_type', true)) ? get_post_meta($post->ID, '_siteseo_structured_data_type', true) : '';
		
		if($schema_type === 'CustomSchema'){
			$custom_schema = !empty(get_post_meta($post->ID , '_siteseo_structured_data_custom', true)) ? get_post_meta($post->ID, '_siteseo_structured_data_custom', true) : '';
			if(!empty($custom_schema)){
				echo'<script type="application/ld+json">'.$custom_schema.'</script>' . "\n";
			}

		} else {
			
			$schema_properties = !empty(get_post_meta($post->ID, '_siteseo_structured_data_properties', true)) ? get_post_meta($post->ID, '_siteseo_structured_data_properties', true) : '';
			
			if(!empty($schema_type) && is_array($schema_properties)){
				$schema_data = array(
					'@context' => 'https://schema.org',
					'@type' => $schema_type
				);
				
				foreach($schema_properties as $key => $value){
					if(!empty($value)){
						$schema_data[$key] = $value;
					}
				}
				
				echo'<script type="application/ld+json">'.json_encode($schema_data, JSON_UNESCAPED_SLASHES).'</script>' . "\n";
				
			}
		}
	}
}