Commit realizado el 12:13:52 08-04-2024
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
/**
|
||||
* The KML File.
|
||||
*
|
||||
* @since 1.0.24
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Local_Seo
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Local_Seo;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Traits\Ajax;
|
||||
use RankMath\Traits\Hooker;
|
||||
use RankMath\Helpers\Str;
|
||||
use RankMath\Sitemap\Router;
|
||||
use RankMath\Helpers\Param;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* KML_File class.
|
||||
*/
|
||||
class KML_File {
|
||||
|
||||
use Ajax, Hooker;
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->action( 'init', 'init', 1 );
|
||||
$this->filter( 'rank_math/sitemap/http_headers', 'remove_x_robots_tag' );
|
||||
$this->filter( 'rank_math/sitemap/index', 'add_local_sitemap' );
|
||||
$this->filter( 'rank_math/sitemap/local/content', 'local_sitemap_content' );
|
||||
$this->filter( 'rank_math/sitemap/locations/content', 'kml_file_content' );
|
||||
$this->action( 'cmb2_save_options-page_fields_rank-math-options-titles_options', 'update_sitemap', 25, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up rewrite rules.
|
||||
*/
|
||||
public function init() {
|
||||
add_rewrite_rule( Router::get_sitemap_base() . 'locations\.kml$', 'index.php?sitemap=locations', 'top' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to remove x-robots tag from Locations KML file.
|
||||
*
|
||||
* @param array $headers HTTP headers.
|
||||
*/
|
||||
public function remove_x_robots_tag( $headers ) {
|
||||
if ( ! isset( $headers['X-Robots-Tag'] ) ) {
|
||||
return $headers;
|
||||
}
|
||||
|
||||
$url = array_filter( explode( '/', Param::server( 'REQUEST_URI' ) ) );
|
||||
if ( 'locations.kml' !== end( $url ) ) {
|
||||
return $headers;
|
||||
}
|
||||
|
||||
unset( $headers['X-Robots-Tag'] );
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the Local SEO Sitemap to the sitemap index.
|
||||
*
|
||||
* @return string $xml The sitemap index with the Local SEO Sitemap added.
|
||||
*/
|
||||
public function add_local_sitemap() {
|
||||
$item = $this->do_filter(
|
||||
'sitemap/index/entry',
|
||||
[
|
||||
'loc' => Router::get_base_url( 'local-sitemap.xml' ),
|
||||
'lastmod' => $this->get_modified_date(),
|
||||
],
|
||||
'local',
|
||||
);
|
||||
|
||||
if ( ! $item ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$xml = $this->newline( '<sitemap>', 1 );
|
||||
$xml .= $this->newline( '<loc>' . htmlspecialchars( $item['loc'] ) . '</loc>', 2 );
|
||||
$xml .= empty( $item['lastmod'] ) ? '' : $this->newline( '<lastmod>' . htmlspecialchars( $item['lastmod'] ) . '</lastmod>', 2 );
|
||||
$xml .= $this->newline( '</sitemap>', 1 );
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* The content of the Local SEO Sitemap.
|
||||
*
|
||||
* @return string $urlset Local SEO Sitemap XML content.
|
||||
*/
|
||||
public function local_sitemap_content() {
|
||||
$item = $this->do_filter(
|
||||
'sitemap/entry',
|
||||
[
|
||||
'loc' => Router::get_base_url( 'locations.kml' ),
|
||||
'mod' => $this->get_modified_date(),
|
||||
],
|
||||
'local',
|
||||
[]
|
||||
);
|
||||
|
||||
if ( ! $item ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$output = $this->newline( '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">', 1 );
|
||||
$output .= $this->newline( '<url>', 2 );
|
||||
$output .= $this->newline( '<loc>' . htmlspecialchars( $item['loc'] ) . '</loc>', 3 );
|
||||
$output .= empty( $item['mod'] ) ? '' : $this->newline( '<lastmod>' . htmlspecialchars( $item['mod'] ) . '</lastmod>', 3 );
|
||||
$output .= $this->newline( '</url>', 2 );
|
||||
$output .= $this->newline( '</urlset>', 1 );
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the KML file contents.
|
||||
*
|
||||
* @return string $kml KML file content.
|
||||
*/
|
||||
public function kml_file_content() {
|
||||
$locations = $this->get_local_seo_data();
|
||||
if ( empty( $locations ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$business_name = Helper::get_settings( 'titles.knowledgegraph_name' );
|
||||
$business_url = Helper::get_settings( 'titles.url' );
|
||||
|
||||
$kml = $this->newline( '<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">' );
|
||||
$kml .= $this->newline( '<Document>', 1 );
|
||||
$kml .= $this->newline( '<name>Locations for ' . esc_html( $business_name ) . '</name>', 2 );
|
||||
$kml .= $this->newline( '<open>1</open>', 2 );
|
||||
$kml .= $this->newline( '<Folder>', 2 );
|
||||
|
||||
if ( ! empty( $business_url ) ) {
|
||||
$kml .= $this->newline( '<atom:link href="' . $business_url . '" />', 3 );
|
||||
}
|
||||
|
||||
foreach ( $locations as $location ) {
|
||||
$address = ! empty( $location['address'] ) ? Helper::replace_vars( implode( ', ', array_filter( $location['address'] ) ) ) : '';
|
||||
$has_coord = ! empty( $location['coords']['latitude'] ) && ! empty( $location['coords']['longitude'] );
|
||||
|
||||
$kml .= $this->newline( '<Placemark>', 3 );
|
||||
$kml .= $this->newline( '<name><![CDATA[' . html_entity_decode( $location['name'] ) . ']]></name>', 4 );
|
||||
$kml .= $this->newline( '<description><![CDATA[' . html_entity_decode( $location['description'] ) . ']]></description>', 4 );
|
||||
$kml .= $this->newline( '<address><![CDATA[' . $address . ']]></address>', 4 );
|
||||
$kml .= $this->newline( '<phoneNumber><![CDATA[' . $location['phone'] . ']]></phoneNumber>', 4 );
|
||||
$kml .= $this->newline( '<atom:link href="' . $location['url'] . '"/>', 4 );
|
||||
$kml .= $this->newline( '<LookAt>', 4 );
|
||||
|
||||
if ( $has_coord ) {
|
||||
$kml .= $this->newline( '<latitude>' . $location['coords']['latitude'] . '</latitude>', 5 );
|
||||
$kml .= $this->newline( '<longitude>' . $location['coords']['longitude'] . '</longitude>', 5 );
|
||||
}
|
||||
|
||||
$kml .= $this->newline( '<altitude>0</altitude>', 5 );
|
||||
$kml .= $this->newline( '<range></range>', 5 );
|
||||
$kml .= $this->newline( '<tilt>0</tilt>', 5 );
|
||||
$kml .= $this->newline( '</LookAt>', 4 );
|
||||
$kml .= $this->newline( '<Point>', 4 );
|
||||
if ( $has_coord ) {
|
||||
$kml .= $this->newline( '<coordinates>' . $location['coords']['longitude'] . ',' . $location['coords']['latitude'] . '</coordinates>', 5 );
|
||||
}
|
||||
$kml .= $this->newline( '</Point>', 4 );
|
||||
$kml .= $this->newline( '</Placemark>', 3 );
|
||||
}
|
||||
|
||||
$kml .= $this->newline( '</Folder>', 2 );
|
||||
$kml .= $this->newline( '</Document>', 1 );
|
||||
$kml .= $this->newline( '</kml>' );
|
||||
|
||||
return $kml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the sitemap when the Local SEO settings are changed.
|
||||
*
|
||||
* @param int $object_id The ID of the current object.
|
||||
* @param array $updated Array of field IDs that were updated.
|
||||
* Will only include field IDs that had values change.
|
||||
*/
|
||||
public function update_sitemap( $object_id, $updated ) { // phpcs:ignore
|
||||
$local_seo_fields = [
|
||||
'knowledgegraph_name',
|
||||
'url',
|
||||
'email',
|
||||
'local_address',
|
||||
'local_business_type',
|
||||
'opening_hours',
|
||||
'phone_numbers',
|
||||
'price_range',
|
||||
'geo',
|
||||
];
|
||||
|
||||
if ( count( array_intersect( $local_seo_fields, $updated ) ) ) {
|
||||
update_option( 'rank_math_local_seo_update', date( 'c' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Local SEO data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_local_seo_data() {
|
||||
$geo = Str::to_arr( Helper::get_settings( 'titles.geo' ) );
|
||||
$cords = [
|
||||
'latitude' => isset( $geo[0] ) ? $geo[0] : '',
|
||||
'longitude' => isset( $geo[1] ) ? $geo[1] : '',
|
||||
];
|
||||
|
||||
$phone_numbers = Helper::get_settings( 'titles.phone_numbers' );
|
||||
$number = ! empty( $phone_numbers ) && isset( $phone_numbers[0]['number'] ) ? $phone_numbers[0]['number'] : '';
|
||||
|
||||
$locations = [
|
||||
[
|
||||
'name' => Helper::get_settings( 'titles.knowledgegraph_name' ),
|
||||
'description' => get_option( 'blogname' ) . ' - ' . get_option( 'blogdescription' ),
|
||||
'email' => Helper::get_settings( 'titles.email' ),
|
||||
'phone' => $number,
|
||||
'url' => Helper::get_settings( 'titles.url' ),
|
||||
'address' => Helper::get_settings( 'titles.local_address' ),
|
||||
'coords' => $cords,
|
||||
'author' => get_option( 'blogname' ),
|
||||
],
|
||||
];
|
||||
|
||||
return $this->do_filter( 'sitemap/locations/data', $locations );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Modified Date.
|
||||
*
|
||||
* @return $date
|
||||
*/
|
||||
private function get_modified_date() {
|
||||
if ( ! $date = get_option( 'rank_math_local_seo_update' ) ) { // phpcs:ignore
|
||||
$date = date( 'c' );
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a newline with indent count.
|
||||
*
|
||||
* @param string $content Content to write.
|
||||
* @param integer $indent Count of indent.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function newline( $content, $indent = 0 ) {
|
||||
return str_repeat( "\t", $indent ) . $content . "\n";
|
||||
}
|
||||
}
|
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
/**
|
||||
* The Local SEO module.
|
||||
*
|
||||
* @since 0.9.0
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Local_Seo
|
||||
* @author Rank Math <support@rankmath.com>
|
||||
*/
|
||||
|
||||
namespace RankMath\Local_Seo;
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\Traits\Ajax;
|
||||
use RankMath\Traits\Hooker;
|
||||
use RankMath\Helpers\Str;
|
||||
use RankMath\Helpers\Param;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Local_Seo class.
|
||||
*/
|
||||
class Local_Seo {
|
||||
|
||||
use Ajax, Hooker;
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->action( 'after_setup_theme', 'location_sitemap' );
|
||||
$this->filter( 'rank_math/settings/title', 'add_settings' );
|
||||
$this->filter( 'rank_math/json_ld', 'organization_or_person', 9, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Local SEO Sitemap.
|
||||
*/
|
||||
public function location_sitemap() {
|
||||
if (
|
||||
Helper::is_module_active( 'sitemap' ) &&
|
||||
'company' === Helper::get_settings( 'titles.knowledgegraph_type' ) &&
|
||||
$this->do_filter( 'sitemap/locations', false )
|
||||
) {
|
||||
new KML_File();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add module settings in Titles & Meta panel.
|
||||
*
|
||||
* @param array $tabs Array of option panel tabs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_settings( $tabs ) {
|
||||
$tabs['local']['file'] = dirname( __FILE__ ) . '/views/titles-options.php';
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Person/Organization schema.
|
||||
*
|
||||
* @param array $data Array of JSON-LD data.
|
||||
* @param JsonLD $json_ld The JsonLD instance.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function organization_or_person( $data, $json_ld ) {
|
||||
if ( ! $json_ld->can_add_global_entities( $data ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$entity = [
|
||||
'@type' => '',
|
||||
'@id' => '',
|
||||
'name' => '',
|
||||
'url' => get_home_url(),
|
||||
];
|
||||
|
||||
$social_profiles = $json_ld->get_social_profiles();
|
||||
if ( ! empty( $social_profiles ) ) {
|
||||
$entity['sameAs'] = $social_profiles;
|
||||
}
|
||||
|
||||
$json_ld->add_prop( 'email', $entity );
|
||||
$json_ld->add_prop( 'url', $entity );
|
||||
$json_ld->add_prop( 'address', $entity );
|
||||
$json_ld->add_prop( 'image', $entity );
|
||||
|
||||
switch ( Helper::get_settings( 'titles.knowledgegraph_type' ) ) {
|
||||
case 'company':
|
||||
$this->add_place_entity( $data, $json_ld );
|
||||
$data['publisher'] = $this->organization( $entity, $data );
|
||||
break;
|
||||
case 'person':
|
||||
$data['publisher'] = $this->person( $entity, $json_ld );
|
||||
break;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add place entity to use in the Organization schema.
|
||||
*
|
||||
* @param array $data Array of JSON-LD data.
|
||||
* @param JsonLD $jsonld The JsonLD instance.
|
||||
*/
|
||||
private function add_place_entity( &$data, $jsonld ) {
|
||||
$properties = [];
|
||||
$this->add_geo_cordinates( $properties );
|
||||
$jsonld->add_prop( 'address', $properties );
|
||||
if ( empty( $properties ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data['place'] = array_merge(
|
||||
[
|
||||
'@type' => 'Place',
|
||||
'@id' => home_url( '/#place' ),
|
||||
],
|
||||
$properties
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Structured data for Organization.
|
||||
*
|
||||
* @param array $entity Array of JSON-LD entity.
|
||||
* @param array $data Array of JSON-LD data.
|
||||
*/
|
||||
private function organization( $entity, $data ) {
|
||||
$name = Helper::get_settings( 'titles.knowledgegraph_name' );
|
||||
$type = Helper::get_settings( 'titles.local_business_type' );
|
||||
$entity['@type'] = $type ? $type : 'Organization';
|
||||
$entity['@id'] = home_url( '/#organization' );
|
||||
$entity['name'] = $name ? $name : get_bloginfo( 'name' );
|
||||
|
||||
if ( is_singular() && 'Organization' !== $type ) {
|
||||
$entity['@type'] = \array_values( array_filter( [ $type, 'Organization' ] ) );
|
||||
}
|
||||
|
||||
// Price Range.
|
||||
if ( $price_range = Helper::get_settings( 'titles.price_range' ) ) { // phpcs:ignore
|
||||
$entity['priceRange'] = $price_range;
|
||||
}
|
||||
|
||||
$this->add_contact_points( $entity );
|
||||
$this->add_business_hours( $entity );
|
||||
$this->add_additional_details( $entity );
|
||||
|
||||
// Add reference to the place entity.
|
||||
if ( isset( $data['place'] ) ) {
|
||||
$entity['location'] = [ '@id' => $data['place']['@id'] ];
|
||||
}
|
||||
|
||||
return $this->sanitize_organization_schema( $entity, $type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Structured data for Person.
|
||||
*
|
||||
* @param array $entity Array of JSON-LD entity.
|
||||
* @param JsonLD $json_ld JsonLD instance.
|
||||
*/
|
||||
private function person( $entity, $json_ld ) {
|
||||
$name = Helper::get_settings( 'titles.knowledgegraph_name' );
|
||||
if ( ! $name ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$entity['@type'] = is_singular()
|
||||
? [
|
||||
'Organization',
|
||||
'Person',
|
||||
]
|
||||
: 'Person';
|
||||
$entity['@id'] = home_url( '/#person' );
|
||||
$entity['name'] = $name;
|
||||
$json_ld->add_prop( 'phone', $entity );
|
||||
|
||||
if ( isset( $entity['logo'] ) ) {
|
||||
$entity['image'] = [ '@id' => $entity['logo']['@id'] ];
|
||||
|
||||
if ( ! is_singular() ) {
|
||||
$entity['image'] = $entity['logo'];
|
||||
unset( $entity['logo'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Contact points in the Organization schema.
|
||||
*
|
||||
* @param array $entity Array of JSON-LD entity.
|
||||
*/
|
||||
private function add_contact_points( &$entity ) {
|
||||
$phone_numbers = Helper::get_settings( 'titles.phone_numbers' );
|
||||
if ( empty( $phone_numbers ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$numbers = [];
|
||||
foreach ( $phone_numbers as $number ) {
|
||||
if ( empty( $number['number'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$numbers[] = [
|
||||
'@type' => 'ContactPoint',
|
||||
'telephone' => $number['number'],
|
||||
'contactType' => $number['type'],
|
||||
];
|
||||
}
|
||||
|
||||
if ( ! empty( $numbers ) ) {
|
||||
$entity['contactPoint'] = $numbers;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add geo coordinates in Place entity.
|
||||
*
|
||||
* @param array $entity Array of JSON-LD entity.
|
||||
*/
|
||||
private function add_geo_cordinates( &$entity ) {
|
||||
$geo = Str::to_arr( Helper::get_settings( 'titles.geo' ) );
|
||||
if ( ! isset( $geo[0], $geo[1] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$entity['geo'] = [
|
||||
'@type' => 'GeoCoordinates',
|
||||
'latitude' => $geo[0],
|
||||
'longitude' => $geo[1],
|
||||
];
|
||||
|
||||
$entity['hasMap'] = 'https://www.google.com/maps/search/?api=1&query=' . join( ',', $geo );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add business hours in the Organization schema.
|
||||
*
|
||||
* @param array $entity Array of JSON-LD entity.
|
||||
*/
|
||||
private function add_business_hours( &$entity ) {
|
||||
$opening_hours = $this->get_opening_hours();
|
||||
if ( empty( $opening_hours ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$entity['openingHours'] = [];
|
||||
foreach ( $opening_hours as $time => $days ) {
|
||||
$entity['openingHours'][] = join( ',', $days ) . ' ' . $time;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Business opening hours.
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
private function get_opening_hours() {
|
||||
$hours = Helper::get_settings( 'titles.opening_hours' );
|
||||
if ( ! is_array( $hours ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$opening_hours = [];
|
||||
foreach ( $hours as $hour ) {
|
||||
if ( empty( $hour['time'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$opening_hours[ $hour['time'] ][] = $hour['day'];
|
||||
}
|
||||
|
||||
return $opening_hours;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional details in the Organization schema.
|
||||
*
|
||||
* @param array $entity Array of JSON-LD entity.
|
||||
*/
|
||||
private function add_additional_details( &$entity ) {
|
||||
$description = Helper::get_settings( 'titles.organization_description' );
|
||||
if ( $description ) {
|
||||
$entity['description'] = $description;
|
||||
}
|
||||
|
||||
$properties = Helper::get_settings( 'titles.additional_info' );
|
||||
if ( empty( $properties ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $properties as $property ) {
|
||||
if ( empty( $property['value'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$type = $property['type'];
|
||||
if ( 'numberOfEmployees' === $type ) {
|
||||
$parts = explode( '-', $property['value'] );
|
||||
if ( empty( $parts[1] ) ) {
|
||||
$entity['numberOfEmployees'] = [
|
||||
'@type' => 'QuantitativeValue',
|
||||
'value' => $parts[0],
|
||||
];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$entity['numberOfEmployees'] = [
|
||||
'@type' => 'QuantitativeValue',
|
||||
'minValue' => $parts[0],
|
||||
'maxValue' => $parts[1],
|
||||
];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$entity[ $type ] = $property['value'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize structured data for different organization types.
|
||||
*
|
||||
* @param array $entity Array of Schema structured data.
|
||||
* @param string $type Type of organization.
|
||||
*
|
||||
* @return array Sanitized data.
|
||||
*/
|
||||
private function sanitize_organization_schema( $entity, $type ) {
|
||||
$types = [
|
||||
'op' => [ 'Organization', 'Corporation', 'EducationalOrganization', 'CollegeOrUniversity', 'ElementarySchool', 'HighSchool', 'MiddleSchool', 'Preschool', 'School', 'SportsTeam', 'MedicalOrganization', 'DiagnosticLab', 'Pharmacy', 'VeterinaryCare', 'PerformingGroup', 'DanceGroup', 'MusicGroup', 'TheaterGroup', 'GovernmentOrganization', 'NGO', 'Airline', 'Consortium', 'Funding Scheme', 'FundingAgency', 'LibrarySystem', 'NewsMediaOrganization', 'Project', 'SportsOrganization', 'WorkersUnion' ],
|
||||
'logo' => [ 'AnimalShelter', 'AutomotiveBusiness', 'Campground', 'ChildCare', 'DryCleaningOrLaundry', 'Dentist', 'EmergencyService', 'FireStation', 'PoliceStation', 'EntertainmentBusiness', 'AdultEntertainment', 'AmusementPark', 'ArtGallery', 'Casino', 'ComedyClub', 'MovieTheater', 'NightClub', 'EmploymentAgency', 'TravelAgency', 'Store', 'AutoPartsStore', 'BikeStore', 'BookStore', 'ClothingStore', 'ComputerStore', 'ConvenienceStore', 'DepartmentStore', 'ElectronicsStore', 'Florist', 'FurnitureStore', 'GardenStore', 'GroceryStore', 'HardwareStore', 'HobbyShop', 'HomeGoodsStore', 'JewelryStore', 'LiquorStore', 'MensClothingStore', 'MobilePhoneStore', 'MovieRentalStore', 'MusicStore', 'OfficeEquipmentStore', 'OutletStore', 'PawnShop', 'PetStore', 'ShoeStore', 'SportingGoodsStore', 'TireShop', 'ToyStore', 'WholesaleStore', 'FinancialService', 'Hospital', 'MovieTheater', 'HomeAndConstructionBusiness', 'Electrician', 'GeneralContractor', 'Plumber', 'InternetCafe', 'Library', 'LocalBusiness', 'LodgingBusiness', 'Hostel', 'Hotel', 'Motel', 'BedAndBreakfast', 'Campground', 'RadioStation', 'RealEstateAgent', 'RecyclingCenter', 'SelfStorage', 'ShoppingCenter', 'SportsActivityLocation', 'BowlingAlley', 'ExerciseGym', 'GolfCourse', 'HealthClub', 'PublicSwimmingPool', 'Resort', 'SkiResort', 'SportsClub', 'TennisComplex', 'StadiumOrArena', 'TelevisionStation', 'TouristInformationCenter', 'MovingCompany', 'InsuranceAgency', 'ProfessionalService', 'HVACBusiness', 'AutoBodyShop', 'AutoDealer', 'AutoPartsStore', 'AutoRental', 'AutoRepair', 'AutoWash', 'GasStation', 'MotorcycleDealer', 'MotorcycleRepair', 'AccountingService', 'AutomatedTeller', 'FoodEstablishment', 'Bakery', 'BarOrPub', 'Brewery', 'CafeOrCoffeeShop', 'FastFoodRestaurant', 'IceCreamShop', 'Restaurant', 'Winery', 'GovernmentOffice', 'PostOffice', 'HealthAndBeautyBusiness', 'BeautySalon', 'DaySpa', 'HairSalon', 'HealthClub', 'NailSalon', 'TattooParlor', 'HousePainter', 'Locksmith', 'Notary', 'RoofingContractor', 'LegalService', 'Physician', 'Optician', 'MedicalBusiness', 'MedicalClinic', 'BankOrCreditUnion', 'CovidTestingFacility', 'ArchiveOrganization', 'Optician' ],
|
||||
];
|
||||
|
||||
$perform = false;
|
||||
foreach ( $types as $func => $to_check ) {
|
||||
if ( in_array( $type, $to_check, true ) ) {
|
||||
$perform = 'sanitize_organization_' . $func;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $perform ? $this->$perform( $entity ) : $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove `openingHours`, `priceRange` properties
|
||||
* from the Schema entity.
|
||||
*
|
||||
* @param array $entity Array of Schema structured data.
|
||||
*
|
||||
* @return array Sanitized data.
|
||||
*/
|
||||
private function sanitize_organization_op( $entity ) {
|
||||
unset( $entity['openingHours'], $entity['priceRange'] );
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change `logo` property to `image` & `contactPoint` to `telephone`.
|
||||
*
|
||||
* @param array $entity Array of schema data.
|
||||
*
|
||||
* @return array Sanitized data.
|
||||
*/
|
||||
private function sanitize_organization_logo( $entity ) {
|
||||
if ( isset( $entity['logo'] ) ) {
|
||||
$entity['image'] = [ '@id' => $entity['logo']['@id'] ];
|
||||
}
|
||||
if ( isset( $entity['contactPoint'] ) ) {
|
||||
$entity['telephone'] = $entity['contactPoint'][0]['telephone'];
|
||||
unset( $entity['contactPoint'] );
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden.
|
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden.
|
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
/**
|
||||
* The local SEO settings.
|
||||
*
|
||||
* @package RankMath
|
||||
* @subpackage RankMath\Local_Seo
|
||||
*/
|
||||
|
||||
use RankMath\Helper;
|
||||
use RankMath\KB;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
$rank_math_company = [ [ 'knowledgegraph_type', 'company' ] ];
|
||||
$rank_math_person = [ [ 'knowledgegraph_type', 'person' ] ];
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'knowledgegraph_type',
|
||||
'type' => 'radio_inline',
|
||||
'name' => esc_html__( 'Person or Company', 'rank-math' ),
|
||||
'options' => [
|
||||
'person' => esc_html__( 'Person', 'rank-math' ),
|
||||
'company' => esc_html__( 'Organization', 'rank-math' ),
|
||||
],
|
||||
'desc' => esc_html__( 'Choose whether the site represents a person or an organization.', 'rank-math' ),
|
||||
'default' => 'person',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'website_name',
|
||||
'type' => 'text',
|
||||
'name' => esc_html__( 'Website Name', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Enter the name of your site to appear in search results.', 'rank-math' ),
|
||||
'default' => get_bloginfo( 'name' ),
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'website_alternate_name',
|
||||
'type' => 'text',
|
||||
'name' => esc_html__( 'Website Alternate Name', 'rank-math' ),
|
||||
'desc' => esc_html__( 'An alternate version of your site name (for example, an acronym or shorter name).', 'rank-math' ),
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'knowledgegraph_name',
|
||||
'type' => 'text',
|
||||
'name' => esc_html__( 'Person/Organization Name', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Your name or company name intended to feature in Google\'s Knowledge Panel.', 'rank-math' ),
|
||||
'default' => get_bloginfo( 'name' ),
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'organization_description',
|
||||
'type' => 'textarea_small',
|
||||
'name' => esc_html__( 'Description', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Provide a detailed description of your organization.', 'rank-math' ),
|
||||
'dep' => $rank_math_company,
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'knowledgegraph_logo',
|
||||
'type' => 'file',
|
||||
'name' => esc_html__( 'Logo', 'rank-math' ),
|
||||
'desc' => __( '<strong>Min Size: 112Χ112px</strong>.<br /> A squared image is preferred by the search engines.', 'rank-math' ),
|
||||
'options' => [ 'url' => false ],
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'url',
|
||||
'type' => 'text_url',
|
||||
'name' => esc_html__( 'URL', 'rank-math' ),
|
||||
'desc' => esc_html__( 'URL of your website or your company’s website.', 'rank-math' ),
|
||||
'default' => home_url(),
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'email',
|
||||
'type' => 'text',
|
||||
'name' => esc_html__( 'Email', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Enter the contact email address that could be displayed on search engines.', 'rank-math' ),
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'phone',
|
||||
'type' => 'text',
|
||||
'name' => esc_html__( 'Phone', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Search engines may prominently display your contact phone number for mobile users.', 'rank-math' ),
|
||||
'dep' => $rank_math_person,
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'local_address',
|
||||
'type' => 'address',
|
||||
'name' => esc_html__( 'Address', 'rank-math' ),
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'local_address_format',
|
||||
'type' => 'textarea_small',
|
||||
'name' => esc_html__( 'Address Format', 'rank-math' ),
|
||||
'desc' => wp_kses_post( __( 'Format used when the address is displayed using the <code>[rank_math_contact_info]</code> shortcode.<br><strong>Available Tags: {address}, {locality}, {region}, {postalcode}, {country}, {gps}</strong>', 'rank-math' ) ),
|
||||
'default' => '{address} {locality}, {region} {postalcode}',
|
||||
'classes' => 'rank-math-address-format',
|
||||
'attributes' => [
|
||||
'rows' => 2,
|
||||
'placeholder' => '{address} {locality}, {region} {country}. {postalcode}.',
|
||||
],
|
||||
'dep' => $rank_math_company,
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'local_business_type',
|
||||
'type' => 'select',
|
||||
'name' => esc_html__( 'Business Type', 'rank-math' ),
|
||||
'options' => Helper::choices_business_types( true ),
|
||||
'attributes' => ( 'data-s2' ),
|
||||
'dep' => $rank_math_company,
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'opening_hours_format',
|
||||
'type' => 'switch',
|
||||
'name' => esc_html__( 'Opening Hours Format', 'rank-math' ),
|
||||
'options' => [
|
||||
'off' => '24:00',
|
||||
'on' => '12:00',
|
||||
],
|
||||
'desc' => esc_html__( 'Time format used in the contact shortcode.', 'rank-math' ),
|
||||
'default' => 'off',
|
||||
'dep' => $rank_math_company,
|
||||
]
|
||||
);
|
||||
|
||||
$rank_math_opening_hours = $cmb->add_field(
|
||||
[
|
||||
'id' => 'opening_hours',
|
||||
'type' => 'group',
|
||||
'name' => esc_html__( 'Opening Hours', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Select opening hours. You can add multiple sets if you have different opening or closing hours on some days or if you have a mid-day break. Times are specified using 24:00 time.', 'rank-math' ),
|
||||
'options' => [
|
||||
'add_button' => esc_html__( 'Add time', 'rank-math' ),
|
||||
'remove_button' => esc_html__( 'Remove', 'rank-math' ),
|
||||
],
|
||||
'dep' => $rank_math_company,
|
||||
'classes' => 'cmb-group-text-only',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_group_field(
|
||||
$rank_math_opening_hours,
|
||||
[
|
||||
'id' => 'day',
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
'Monday' => esc_html__( 'Monday', 'rank-math' ),
|
||||
'Tuesday' => esc_html__( 'Tuesday', 'rank-math' ),
|
||||
'Wednesday' => esc_html__( 'Wednesday', 'rank-math' ),
|
||||
'Thursday' => esc_html__( 'Thursday', 'rank-math' ),
|
||||
'Friday' => esc_html__( 'Friday', 'rank-math' ),
|
||||
'Saturday' => esc_html__( 'Saturday', 'rank-math' ),
|
||||
'Sunday' => esc_html__( 'Sunday', 'rank-math' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_group_field(
|
||||
$rank_math_opening_hours,
|
||||
[
|
||||
'id' => 'time',
|
||||
'type' => 'text',
|
||||
'attributes' => [ 'placeholder' => esc_html__( 'e.g. 09:00-17:00', 'rank-math' ) ],
|
||||
'time_format' => 'H:i',
|
||||
]
|
||||
);
|
||||
|
||||
$rank_math_phones = $cmb->add_field(
|
||||
[
|
||||
'id' => 'phone_numbers',
|
||||
'type' => 'group',
|
||||
'name' => esc_html__( 'Phone Number', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Search engines may prominently display your contact phone number for mobile users.', 'rank-math' ),
|
||||
'options' => [
|
||||
'add_button' => esc_html__( 'Add number', 'rank-math' ),
|
||||
'remove_button' => esc_html__( 'Remove', 'rank-math' ),
|
||||
],
|
||||
'dep' => $rank_math_company,
|
||||
'classes' => 'cmb-group-text-only',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_group_field(
|
||||
$rank_math_phones,
|
||||
[
|
||||
'id' => 'type',
|
||||
'type' => 'select',
|
||||
'options' => Helper::choices_phone_types(),
|
||||
'default' => 'customer_support',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_group_field(
|
||||
$rank_math_phones,
|
||||
[
|
||||
'id' => 'number',
|
||||
'type' => 'text',
|
||||
'attributes' => [ 'placeholder' => esc_html__( 'Format: +1-401-555-1212', 'rank-math' ) ],
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'price_range',
|
||||
'type' => 'text',
|
||||
'name' => esc_html__( 'Price Range', 'rank-math' ),
|
||||
'desc' => esc_html__( 'The price range of the business, for example $$$.', 'rank-math' ),
|
||||
'dep' => $rank_math_company,
|
||||
]
|
||||
);
|
||||
|
||||
$rank_math_additional_info = $cmb->add_field(
|
||||
[
|
||||
'id' => 'additional_info',
|
||||
'type' => 'group',
|
||||
'name' => esc_html__( 'Additional Info', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Provide relevant details of your company to include in the Organization Schema.', 'rank-math' ),
|
||||
'options' => [
|
||||
'add_button' => esc_html__( 'Add', 'rank-math' ),
|
||||
'remove_button' => esc_html__( 'Remove', 'rank-math' ),
|
||||
],
|
||||
'dep' => $rank_math_company,
|
||||
'classes' => 'cmb-group-text-only',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_group_field(
|
||||
$rank_math_additional_info,
|
||||
[
|
||||
'id' => 'type',
|
||||
'type' => 'select',
|
||||
'options' => Helper::choices_additional_organization_info(),
|
||||
'default' => '',
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_group_field(
|
||||
$rank_math_additional_info,
|
||||
[
|
||||
'id' => 'value',
|
||||
'type' => 'text',
|
||||
]
|
||||
);
|
||||
|
||||
$rank_math_about_page = Helper::get_settings( 'titles.local_seo_about_page' );
|
||||
$rank_math_about_options = [ '' => __( 'Select Page', 'rank-math' ) ];
|
||||
|
||||
if ( $rank_math_about_page ) {
|
||||
$rank_math_about_options[ $rank_math_about_page ] = get_the_title( $rank_math_about_page );
|
||||
}
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'local_seo_about_page',
|
||||
'type' => 'select',
|
||||
'options' => $rank_math_about_options,
|
||||
'name' => esc_html__( 'About Page', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Select a page on your site where you want to show the LocalBusiness meta data.', 'rank-math' ),
|
||||
'attributes' => ( 'data-s2-pages' ),
|
||||
]
|
||||
);
|
||||
|
||||
$rank_math_contact_page = Helper::get_settings( 'titles.local_seo_contact_page' );
|
||||
$rank_math_contact_options = [ '' => __( 'Select Page', 'rank-math' ) ];
|
||||
|
||||
if ( $rank_math_contact_page ) {
|
||||
$rank_math_contact_options[ $rank_math_contact_page ] = get_the_title( $rank_math_contact_page );
|
||||
}
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'local_seo_contact_page',
|
||||
'type' => 'select',
|
||||
'options' => $rank_math_contact_options,
|
||||
'name' => esc_html__( 'Contact Page', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Select a page on your site where you want to show the LocalBusiness meta data.', 'rank-math' ),
|
||||
'attributes' => ( 'data-s2-pages' ),
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'maps_api_key',
|
||||
'type' => 'text',
|
||||
'name' => esc_html__( 'Google Maps API Key', 'rank-math' ),
|
||||
/* translators: %s expands to "Google Maps Embed API" https://developers.google.com/maps/documentation/embed/ */
|
||||
'desc' => sprintf( esc_html__( 'An API Key is required to display embedded Google Maps on your site. Get it here: %s', 'rank-math' ), '<a href="https://developers.google.com/maps/documentation/javascript/get-api-key" target="_blank">' . __( 'Google Maps Embed API', 'rank-math' ) . '</a>' ),
|
||||
'dep' => $rank_math_company,
|
||||
'attributes' => [ 'type' => 'password' ],
|
||||
]
|
||||
);
|
||||
|
||||
$cmb->add_field(
|
||||
[
|
||||
'id' => 'geo',
|
||||
'type' => 'text',
|
||||
'name' => esc_html__( 'Geo Coordinates', 'rank-math' ),
|
||||
'desc' => esc_html__( 'Latitude and longitude values separated by comma.', 'rank-math' ),
|
||||
'dep' => $rank_math_company,
|
||||
/* Translators: placeholder is a link to the Pro version */
|
||||
'after' => '<strong style="margin-top:20px; display:block; text-align:right;">' . sprintf( __( 'Multiple Locations are available in the %s.', 'rank-math' ), '<a href="' . KB::get( 'pro', 'Multiple Location Notice' ) . '" target="_blank">PRO Version</a>' ) . '</strong>',
|
||||
]
|
||||
);
|
Reference in New Issue
Block a user