Site improvements: nav refactor, CSS readability, hover fixes, remove unverified badges
- Refactored navigation: all 44 pages now use shared includes/nav.php - Added Free Tools link to navigation (was missing from 29+ pages) - CSS readability: darker body text (#333), secondary text (#555), bolder hero subtitle - CSS: darkened link colour (#148a72) for WCAG AA compliance - CSS: increased stat label font size to 1rem - Fixed industry-card hover white-on-white text bug - Removed ICO Registered and Cyber Essentials claims (not yet registered) - Cache version bumped to v1.1.2
This commit is contained in:
198
includes.bak.20260210/includes/schema/article-schema.php
Normal file
198
includes.bak.20260210/includes/schema/article-schema.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* Article Schema Component
|
||||
* Generates Article structured data for blog posts
|
||||
*
|
||||
* Usage:
|
||||
* $articleData = [
|
||||
* 'title' => 'Article Title',
|
||||
* 'description' => 'Article description...',
|
||||
* 'datePublished' => '2024-01-15',
|
||||
* 'dateModified' => '2024-01-20',
|
||||
* 'authorName' => 'John Smith',
|
||||
* 'imageUrl' => 'https://example.com/image.jpg',
|
||||
* 'articleUrl' => 'https://example.com/article'
|
||||
* ];
|
||||
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/article-schema.php');
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate Article Schema JSON-LD
|
||||
*
|
||||
* @param string $title Article title
|
||||
* @param string $description Article description/excerpt
|
||||
* @param string $datePublished Publication date (Y-m-d format)
|
||||
* @param string $dateModified Last modified date (Y-m-d format)
|
||||
* @param string $authorName Author's name
|
||||
* @param string $imageUrl Featured image URL
|
||||
* @param string $articleUrl Canonical article URL
|
||||
* @param string $category Optional article category
|
||||
* @param array $keywords Optional array of keywords
|
||||
* @return string JSON-LD script tag
|
||||
*/
|
||||
function generateArticleSchema($title, $description, $datePublished, $dateModified, $authorName, $imageUrl, $articleUrl, $category = null, $keywords = []) {
|
||||
$baseUrl = 'https://ukdataservices.co.uk';
|
||||
|
||||
$schema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'Article',
|
||||
'@id' => $articleUrl . '#article',
|
||||
'headline' => $title,
|
||||
'description' => $description,
|
||||
'url' => $articleUrl,
|
||||
'datePublished' => $datePublished . 'T09:00:00+00:00',
|
||||
'dateModified' => $dateModified . 'T09:00:00+00:00',
|
||||
'author' => [
|
||||
'@type' => 'Person',
|
||||
'name' => $authorName,
|
||||
'url' => $baseUrl . '/about'
|
||||
],
|
||||
'publisher' => [
|
||||
'@type' => 'Organization',
|
||||
'@id' => $baseUrl . '/#organization',
|
||||
'name' => 'UK Data Services',
|
||||
'logo' => [
|
||||
'@type' => 'ImageObject',
|
||||
'url' => $baseUrl . '/assets/images/ukds-main-logo.png'
|
||||
]
|
||||
],
|
||||
'image' => [
|
||||
'@type' => 'ImageObject',
|
||||
'url' => $imageUrl,
|
||||
'width' => 1200,
|
||||
'height' => 630
|
||||
],
|
||||
'mainEntityOfPage' => [
|
||||
'@type' => 'WebPage',
|
||||
'@id' => $articleUrl
|
||||
],
|
||||
'isPartOf' => [
|
||||
'@type' => 'Blog',
|
||||
'@id' => $baseUrl . '/blog/#blog',
|
||||
'name' => 'UK Data Services Blog',
|
||||
'publisher' => [
|
||||
'@id' => $baseUrl . '/#organization'
|
||||
]
|
||||
],
|
||||
'inLanguage' => 'en-GB'
|
||||
];
|
||||
|
||||
// Add category if provided
|
||||
if ($category) {
|
||||
$schema['articleSection'] = $category;
|
||||
}
|
||||
|
||||
// Add keywords if provided
|
||||
if (!empty($keywords)) {
|
||||
$schema['keywords'] = implode(', ', $keywords);
|
||||
}
|
||||
|
||||
// Add word count estimate based on description length (rough estimate)
|
||||
$schema['wordCount'] = max(500, strlen($description) * 5);
|
||||
|
||||
return '<script type="application/ld+json">' . "\n" .
|
||||
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
|
||||
'</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate BlogPosting Schema (more specific than Article)
|
||||
*/
|
||||
function generateBlogPostingSchema($title, $description, $datePublished, $dateModified, $authorName, $imageUrl, $articleUrl, $category = null, $keywords = []) {
|
||||
$baseUrl = 'https://ukdataservices.co.uk';
|
||||
|
||||
$schema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'BlogPosting',
|
||||
'@id' => $articleUrl . '#blogposting',
|
||||
'headline' => $title,
|
||||
'description' => $description,
|
||||
'url' => $articleUrl,
|
||||
'datePublished' => $datePublished . 'T09:00:00+00:00',
|
||||
'dateModified' => $dateModified . 'T09:00:00+00:00',
|
||||
'author' => [
|
||||
'@type' => 'Person',
|
||||
'name' => $authorName,
|
||||
'url' => $baseUrl . '/about',
|
||||
'worksFor' => [
|
||||
'@type' => 'Organization',
|
||||
'@id' => $baseUrl . '/#organization'
|
||||
]
|
||||
],
|
||||
'publisher' => [
|
||||
'@type' => 'Organization',
|
||||
'@id' => $baseUrl . '/#organization',
|
||||
'name' => 'UK Data Services',
|
||||
'logo' => [
|
||||
'@type' => 'ImageObject',
|
||||
'url' => $baseUrl . '/assets/images/ukds-main-logo.png',
|
||||
'width' => 300,
|
||||
'height' => 100
|
||||
]
|
||||
],
|
||||
'image' => [
|
||||
'@type' => 'ImageObject',
|
||||
'url' => $imageUrl,
|
||||
'width' => 1200,
|
||||
'height' => 630
|
||||
],
|
||||
'mainEntityOfPage' => [
|
||||
'@type' => 'WebPage',
|
||||
'@id' => $articleUrl
|
||||
],
|
||||
'isPartOf' => [
|
||||
'@type' => 'Blog',
|
||||
'@id' => $baseUrl . '/blog/#blog',
|
||||
'name' => 'UK Data Services Blog'
|
||||
],
|
||||
'inLanguage' => 'en-GB'
|
||||
];
|
||||
|
||||
if ($category) {
|
||||
$schema['articleSection'] = $category;
|
||||
}
|
||||
|
||||
if (!empty($keywords)) {
|
||||
$schema['keywords'] = implode(', ', $keywords);
|
||||
}
|
||||
|
||||
return '<script type="application/ld+json">' . "\n" .
|
||||
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
|
||||
'</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Author configurations for the site
|
||||
*/
|
||||
$authorProfiles = [
|
||||
'uk-data-services-team' => [
|
||||
'name' => 'UK Data Services Team',
|
||||
'role' => 'Data Intelligence Experts',
|
||||
'description' => 'Our team of certified data professionals and engineers providing expert guidance on web scraping, data analytics, and business intelligence.'
|
||||
],
|
||||
'technical-team' => [
|
||||
'name' => 'UK Data Services Technical Team',
|
||||
'role' => 'Senior Data Engineers',
|
||||
'description' => 'Expert engineers specializing in web scraping technologies, data pipelines, and enterprise data solutions.'
|
||||
],
|
||||
'compliance-team' => [
|
||||
'name' => 'UK Data Services Compliance Team',
|
||||
'role' => 'Data Protection Specialists',
|
||||
'description' => 'Specialists in GDPR compliance, data protection, and regulatory requirements for data collection.'
|
||||
]
|
||||
];
|
||||
|
||||
// If $articleData is set, output the schema automatically
|
||||
if (isset($articleData) && is_array($articleData)) {
|
||||
echo generateArticleSchema(
|
||||
$articleData['title'],
|
||||
$articleData['description'],
|
||||
$articleData['datePublished'],
|
||||
$articleData['dateModified'] ?? $articleData['datePublished'],
|
||||
$articleData['authorName'] ?? 'UK Data Services Team',
|
||||
$articleData['imageUrl'],
|
||||
$articleData['articleUrl'],
|
||||
$articleData['category'] ?? null,
|
||||
$articleData['keywords'] ?? []
|
||||
);
|
||||
}
|
||||
151
includes.bak.20260210/includes/schema/faq-schema.php
Normal file
151
includes.bak.20260210/includes/schema/faq-schema.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
/**
|
||||
* FAQ Schema Component
|
||||
* Generates FAQPage structured data for FAQ sections
|
||||
*
|
||||
* Usage:
|
||||
* $faqs = [
|
||||
* ['question' => 'What is web scraping?', 'answer' => 'Web scraping is...'],
|
||||
* ['question' => 'How much does it cost?', 'answer' => 'Pricing varies...']
|
||||
* ];
|
||||
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/faq-schema.php');
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate FAQPage Schema JSON-LD
|
||||
*
|
||||
* @param array $faqs Array of Q&A pairs with 'question' and 'answer' keys
|
||||
* @param string|null $pageUrl Optional canonical URL for the FAQ page
|
||||
* @param string|null $pageName Optional name for the FAQ page
|
||||
* @return string JSON-LD script tag
|
||||
*/
|
||||
function generateFAQSchema($faqs, $pageUrl = null, $pageName = null) {
|
||||
if (empty($faqs)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$schema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'FAQPage'
|
||||
];
|
||||
|
||||
// Add page identifier if URL provided
|
||||
if ($pageUrl) {
|
||||
$schema['@id'] = $pageUrl . '#faqpage';
|
||||
$schema['url'] = $pageUrl;
|
||||
}
|
||||
|
||||
// Add page name if provided
|
||||
if ($pageName) {
|
||||
$schema['name'] = $pageName;
|
||||
}
|
||||
|
||||
// Build main entity array
|
||||
$schema['mainEntity'] = array_map(function($faq) {
|
||||
return [
|
||||
'@type' => 'Question',
|
||||
'name' => $faq['question'],
|
||||
'acceptedAnswer' => [
|
||||
'@type' => 'Answer',
|
||||
'text' => $faq['answer']
|
||||
]
|
||||
];
|
||||
}, $faqs);
|
||||
|
||||
return '<script type="application/ld+json">' . "\n" .
|
||||
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
|
||||
'</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Common FAQs for different page types
|
||||
*/
|
||||
$commonFAQs = [
|
||||
'general' => [
|
||||
[
|
||||
'question' => 'What is web scraping and how can it benefit my business?',
|
||||
'answer' => 'Web scraping is the automated process of extracting data from websites. It benefits businesses by providing competitive intelligence, automating data collection, enabling real-time price monitoring, and supporting strategic decision-making with accurate market data.'
|
||||
],
|
||||
[
|
||||
'question' => 'Is web scraping legal in the UK?',
|
||||
'answer' => 'Yes, web scraping is legal in the UK when conducted properly. We ensure full compliance with UK Data Protection Act 2018, GDPR, website terms of service, and industry best practices. We only collect publicly available data and respect robots.txt directives.'
|
||||
],
|
||||
[
|
||||
'question' => 'How do you ensure data accuracy?',
|
||||
'answer' => 'We maintain a 99.8% accuracy rate through advanced validation algorithms, multi-layer verification processes, regular monitoring, and comprehensive testing before delivery. Each dataset undergoes rigorous quality assurance checks.'
|
||||
],
|
||||
[
|
||||
'question' => 'What data formats do you provide?',
|
||||
'answer' => 'We deliver data in multiple formats including Excel (XLSX/XLS), CSV, JSON, XML, SQL database dumps, and custom formats. We also offer real-time data feeds and API access for ongoing projects.'
|
||||
],
|
||||
[
|
||||
'question' => 'How much do your services cost?',
|
||||
'answer' => 'Pricing varies based on project complexity: Simple extraction projects start from £500-£2,000, medium complexity projects range from £2,000-£10,000, and enterprise solutions are £10,000+. We provide custom quotes based on your specific requirements.'
|
||||
]
|
||||
],
|
||||
'pricing' => [
|
||||
[
|
||||
'question' => 'What factors affect the cost of web scraping services?',
|
||||
'answer' => 'Costs depend on several factors: the number and complexity of target websites, data volume required, frequency of updates, anti-bot measures to navigate, data cleaning requirements, and delivery format preferences.'
|
||||
],
|
||||
[
|
||||
'question' => 'Do you offer monthly retainer packages?',
|
||||
'answer' => 'Yes, we offer flexible monthly retainer packages for ongoing data collection needs. These include regular updates, priority support, and often provide better value than one-off projects for continuous monitoring requirements.'
|
||||
],
|
||||
[
|
||||
'question' => 'Is there a minimum project value?',
|
||||
'answer' => 'Our minimum project value is £500. This ensures we can deliver quality work with proper attention to accuracy, compliance, and client requirements.'
|
||||
]
|
||||
],
|
||||
'compliance' => [
|
||||
[
|
||||
'question' => 'How do you handle GDPR compliance?',
|
||||
'answer' => 'GDPR compliance is central to our operations. We only collect personal data when legally justified, follow data minimisation principles, implement robust security measures, maintain clear data retention policies, and respect data subject rights.'
|
||||
],
|
||||
[
|
||||
'question' => 'Do you scrape personal data?',
|
||||
'answer' => 'We only collect personal data when there is a legitimate legal basis, such as legitimate business interests or consent. We follow strict GDPR guidelines and advise clients on compliant data collection strategies.'
|
||||
],
|
||||
[
|
||||
'question' => 'What security measures do you have in place?',
|
||||
'answer' => 'We implement enterprise-grade security including encrypted data transfer (SSL/TLS), secure data storage, access controls, and regular security audits.'
|
||||
]
|
||||
],
|
||||
'property-data' => [
|
||||
[
|
||||
'question' => 'Can you extract data from Rightmove and Zoopla?',
|
||||
'answer' => 'Yes, we can extract publicly available property data from UK property portals including Rightmove, Zoopla, OnTheMarket, and others. We ensure compliance with each platform\'s terms of service and UK data protection laws.'
|
||||
],
|
||||
[
|
||||
'question' => 'What property data can you collect?',
|
||||
'answer' => 'We can collect property listings, prices, property features, location data, historical price changes, rental yields, local area information, and market trends. Custom data requirements can be discussed during consultation.'
|
||||
],
|
||||
[
|
||||
'question' => 'How often can property data be updated?',
|
||||
'answer' => 'We offer daily, weekly, or monthly property data updates depending on your needs. Real-time monitoring is also available for time-sensitive market intelligence requirements.'
|
||||
]
|
||||
],
|
||||
'financial-data' => [
|
||||
[
|
||||
'question' => 'Do you provide FCA-compliant financial data services?',
|
||||
'answer' => 'Yes, our financial data services are designed with FCA regulations in mind. We help hedge funds, asset managers, and investment firms collect market data while maintaining compliance with applicable financial regulations.'
|
||||
],
|
||||
[
|
||||
'question' => 'What types of alternative data do you provide?',
|
||||
'answer' => 'We provide various alternative data sources including web traffic data, sentiment analysis, pricing data, job posting trends, satellite imagery analysis, and custom data feeds tailored to investment strategies.'
|
||||
],
|
||||
[
|
||||
'question' => 'Can you provide historical financial data?',
|
||||
'answer' => 'Yes, we can extract and compile historical financial data where publicly available. This includes historical pricing, company filings, news archives, and market trend data for backtesting and analysis purposes.'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// If $faqs is set, output the schema automatically
|
||||
if (isset($faqs) && is_array($faqs)) {
|
||||
echo generateFAQSchema(
|
||||
$faqs,
|
||||
$faqPageUrl ?? null,
|
||||
$faqPageName ?? null
|
||||
);
|
||||
}
|
||||
233
includes.bak.20260210/includes/schema/local-business-schema.php
Normal file
233
includes.bak.20260210/includes/schema/local-business-schema.php
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
/**
|
||||
* LocalBusiness Schema Component
|
||||
* Generates LocalBusiness structured data for location pages
|
||||
*
|
||||
* Usage:
|
||||
* $locationData = [
|
||||
* 'city' => 'London',
|
||||
* 'region' => 'Greater London',
|
||||
* 'latitude' => 51.5074,
|
||||
* 'longitude' => -0.1278,
|
||||
* 'services' => ['Web Scraping', 'Data Analytics']
|
||||
* ];
|
||||
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/local-business-schema.php');
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate LocalBusiness Schema JSON-LD for city/location pages
|
||||
*
|
||||
* @param string $city The city name
|
||||
* @param string $region The region/county name
|
||||
* @param array $services Array of service names offered in this location
|
||||
* @param float|null $latitude Optional latitude coordinate
|
||||
* @param float|null $longitude Optional longitude coordinate
|
||||
* @return string JSON-LD script tag
|
||||
*/
|
||||
function generateLocalBusinessSchema($city, $region, $services = [], $latitude = null, $longitude = null) {
|
||||
$baseUrl = 'https://ukdataservices.co.uk';
|
||||
$citySlug = strtolower(str_replace(' ', '-', $city));
|
||||
|
||||
$schema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'LocalBusiness',
|
||||
'@id' => $baseUrl . '/locations/' . $citySlug . '#localbusiness',
|
||||
'name' => 'UK Data Services - ' . $city,
|
||||
'description' => 'Professional web scraping, data extraction, and business intelligence services for ' . $city . ' businesses. GDPR-compliant data solutions across ' . $region . '.',
|
||||
'url' => $baseUrl . '/locations/' . $citySlug,
|
||||
'telephone' => '+44 1692 689150',
|
||||
'email' => 'info@ukdataservices.co.uk',
|
||||
'priceRange' => '££-£££',
|
||||
'paymentAccepted' => ['Credit Card', 'Bank Transfer', 'Invoice'],
|
||||
'currenciesAccepted' => 'GBP',
|
||||
'openingHours' => 'Mo-Fr 09:00-17:30',
|
||||
'areaServed' => [
|
||||
'@type' => 'City',
|
||||
'name' => $city,
|
||||
'containedInPlace' => [
|
||||
'@type' => 'AdministrativeArea',
|
||||
'name' => $region,
|
||||
'containedInPlace' => [
|
||||
'@type' => 'Country',
|
||||
'name' => 'United Kingdom'
|
||||
]
|
||||
]
|
||||
],
|
||||
'parentOrganization' => [
|
||||
'@type' => 'Organization',
|
||||
'@id' => $baseUrl . '/#organization',
|
||||
'name' => 'UK Data Services'
|
||||
],
|
||||
'image' => $baseUrl . '/assets/images/ukds-main-logo.png',
|
||||
'sameAs' => [
|
||||
'https://www.linkedin.com/company/ukdataservices',
|
||||
'https://twitter.com/ukdataservices'
|
||||
]
|
||||
];
|
||||
|
||||
// Add geo coordinates if provided
|
||||
if ($latitude && $longitude) {
|
||||
$schema['geo'] = [
|
||||
'@type' => 'GeoCoordinates',
|
||||
'latitude' => $latitude,
|
||||
'longitude' => $longitude
|
||||
];
|
||||
}
|
||||
|
||||
// Add aggregate rating
|
||||
$schema['aggregateRating'] = [
|
||||
'@type' => 'AggregateRating',
|
||||
'ratingValue' => '4.9',
|
||||
'reviewCount' => getReviewCountForCity($city),
|
||||
'bestRating' => '5',
|
||||
'worstRating' => '1'
|
||||
];
|
||||
|
||||
// Add services as offer catalog
|
||||
if (!empty($services)) {
|
||||
$schema['hasOfferCatalog'] = [
|
||||
'@type' => 'OfferCatalog',
|
||||
'name' => 'Data Services in ' . $city,
|
||||
'itemListElement' => array_map(function($service) use ($city) {
|
||||
return [
|
||||
'@type' => 'Offer',
|
||||
'itemOffered' => [
|
||||
'@type' => 'Service',
|
||||
'name' => $service . ' ' . $city
|
||||
]
|
||||
];
|
||||
}, $services)
|
||||
];
|
||||
}
|
||||
|
||||
return '<script type="application/ld+json">' . "\n" .
|
||||
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
|
||||
'</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get estimated review count for a city (for schema purposes)
|
||||
*/
|
||||
function getReviewCountForCity($city) {
|
||||
$reviewCounts = [
|
||||
'London' => 87,
|
||||
'Manchester' => 45,
|
||||
'Birmingham' => 38,
|
||||
'Edinburgh' => 25,
|
||||
'Cardiff' => 18
|
||||
];
|
||||
return $reviewCounts[$city] ?? 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predefined location configurations
|
||||
*/
|
||||
$locationConfigs = [
|
||||
'london' => [
|
||||
'city' => 'London',
|
||||
'region' => 'Greater London',
|
||||
'latitude' => 51.5074,
|
||||
'longitude' => -0.1278,
|
||||
'services' => [
|
||||
'Web Scraping',
|
||||
'Data Analytics',
|
||||
'Financial Data Services',
|
||||
'Competitive Intelligence',
|
||||
'Price Monitoring'
|
||||
],
|
||||
'industries' => [
|
||||
'Financial Services',
|
||||
'Fintech',
|
||||
'E-commerce',
|
||||
'Property',
|
||||
'Legal Services'
|
||||
]
|
||||
],
|
||||
'manchester' => [
|
||||
'city' => 'Manchester',
|
||||
'region' => 'Greater Manchester',
|
||||
'latitude' => 53.4808,
|
||||
'longitude' => -2.2426,
|
||||
'services' => [
|
||||
'Data Analytics',
|
||||
'Web Scraping',
|
||||
'Business Intelligence',
|
||||
'Price Monitoring',
|
||||
'Data Cleaning'
|
||||
],
|
||||
'industries' => [
|
||||
'Manufacturing',
|
||||
'Logistics',
|
||||
'E-commerce',
|
||||
'Media & Digital',
|
||||
'Healthcare'
|
||||
]
|
||||
],
|
||||
'birmingham' => [
|
||||
'city' => 'Birmingham',
|
||||
'region' => 'West Midlands',
|
||||
'latitude' => 52.4862,
|
||||
'longitude' => -1.8904,
|
||||
'services' => [
|
||||
'Data Services',
|
||||
'Web Scraping',
|
||||
'Business Intelligence',
|
||||
'Data Cleaning',
|
||||
'Competitive Intelligence'
|
||||
],
|
||||
'industries' => [
|
||||
'Automotive',
|
||||
'Manufacturing',
|
||||
'Professional Services',
|
||||
'Retail',
|
||||
'Healthcare'
|
||||
]
|
||||
],
|
||||
'edinburgh' => [
|
||||
'city' => 'Edinburgh',
|
||||
'region' => 'Scotland',
|
||||
'latitude' => 55.9533,
|
||||
'longitude' => -3.1883,
|
||||
'services' => [
|
||||
'Data Analytics',
|
||||
'Web Scraping',
|
||||
'Financial Data',
|
||||
'Business Intelligence'
|
||||
],
|
||||
'industries' => [
|
||||
'Financial Services',
|
||||
'Energy',
|
||||
'Technology',
|
||||
'Tourism'
|
||||
]
|
||||
],
|
||||
'cardiff' => [
|
||||
'city' => 'Cardiff',
|
||||
'region' => 'Wales',
|
||||
'latitude' => 51.4816,
|
||||
'longitude' => -3.1791,
|
||||
'services' => [
|
||||
'Data Services',
|
||||
'Web Scraping',
|
||||
'Business Intelligence',
|
||||
'Data Cleaning'
|
||||
],
|
||||
'industries' => [
|
||||
'Public Sector',
|
||||
'Financial Services',
|
||||
'Media',
|
||||
'Manufacturing'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// If $locationData is set, output the schema automatically
|
||||
if (isset($locationData) && is_array($locationData)) {
|
||||
echo generateLocalBusinessSchema(
|
||||
$locationData['city'],
|
||||
$locationData['region'],
|
||||
$locationData['services'] ?? [],
|
||||
$locationData['latitude'] ?? null,
|
||||
$locationData['longitude'] ?? null
|
||||
);
|
||||
}
|
||||
108
includes.bak.20260210/includes/schema/organization-schema.php
Normal file
108
includes.bak.20260210/includes/schema/organization-schema.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* Organization Schema Component
|
||||
* Generates Organization structured data for improved SEO
|
||||
*
|
||||
* Usage: Include this file in the <head> of every page
|
||||
* <?php include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/organization-schema.php'); ?>
|
||||
*/
|
||||
|
||||
$organizationSchema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'Organization',
|
||||
'@id' => 'https://ukdataservices.co.uk/#organization',
|
||||
'name' => 'UK Data Services',
|
||||
'legalName' => 'UK Data Services Limited',
|
||||
'url' => 'https://ukdataservices.co.uk',
|
||||
'logo' => [
|
||||
'@type' => 'ImageObject',
|
||||
'url' => 'https://ukdataservices.co.uk/assets/images/ukds-main-logo.png',
|
||||
'width' => 300,
|
||||
'height' => 100
|
||||
],
|
||||
'image' => 'https://ukdataservices.co.uk/assets/images/ukds-main-logo.png',
|
||||
'description' => 'Enterprise web scraping and data analytics services for UK businesses. Specialising in competitive intelligence, price monitoring, and GDPR-compliant data extraction.',
|
||||
'telephone' => '+44 1692 689150',
|
||||
'email' => 'info@ukdataservices.co.uk',
|
||||
'address' => [
|
||||
'@type' => 'PostalAddress',
|
||||
'streetAddress' => 'Professional Data Services Centre',
|
||||
'addressLocality' => 'London',
|
||||
'addressRegion' => 'England',
|
||||
'postalCode' => 'EC1A 1BB',
|
||||
'addressCountry' => 'GB'
|
||||
],
|
||||
'geo' => [
|
||||
'@type' => 'GeoCoordinates',
|
||||
'latitude' => 51.5074,
|
||||
'longitude' => -0.1278
|
||||
],
|
||||
'areaServed' => [
|
||||
[
|
||||
'@type' => 'Country',
|
||||
'name' => 'United Kingdom'
|
||||
],
|
||||
[
|
||||
'@type' => 'City',
|
||||
'name' => 'London'
|
||||
],
|
||||
[
|
||||
'@type' => 'City',
|
||||
'name' => 'Manchester'
|
||||
],
|
||||
[
|
||||
'@type' => 'City',
|
||||
'name' => 'Birmingham'
|
||||
],
|
||||
[
|
||||
'@type' => 'City',
|
||||
'name' => 'Edinburgh'
|
||||
],
|
||||
[
|
||||
'@type' => 'City',
|
||||
'name' => 'Cardiff'
|
||||
]
|
||||
],
|
||||
'sameAs' => [
|
||||
'https://www.linkedin.com/company/ukdataservices',
|
||||
'https://twitter.com/ukdataservices'
|
||||
],
|
||||
'contactPoint' => [
|
||||
[
|
||||
'@type' => 'ContactPoint',
|
||||
'telephone' => '+44 1692 689150',
|
||||
'contactType' => 'sales',
|
||||
'availableLanguage' => 'English',
|
||||
'areaServed' => 'GB',
|
||||
'hoursAvailable' => [
|
||||
'@type' => 'OpeningHoursSpecification',
|
||||
'dayOfWeek' => ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
|
||||
'opens' => '09:00',
|
||||
'closes' => '17:30'
|
||||
]
|
||||
],
|
||||
[
|
||||
'@type' => 'ContactPoint',
|
||||
'email' => 'info@ukdataservices.co.uk',
|
||||
'contactType' => 'customer service',
|
||||
'availableLanguage' => 'English',
|
||||
'areaServed' => 'GB'
|
||||
]
|
||||
],
|
||||
'foundingDate' => '2018',
|
||||
'numberOfEmployees' => [
|
||||
'@type' => 'QuantitativeValue',
|
||||
'value' => '15'
|
||||
],
|
||||
'aggregateRating' => [
|
||||
'@type' => 'AggregateRating',
|
||||
'ratingValue' => '4.9',
|
||||
'reviewCount' => '127',
|
||||
'bestRating' => '5',
|
||||
'worstRating' => '1'
|
||||
]
|
||||
];
|
||||
?>
|
||||
<script type="application/ld+json">
|
||||
<?php echo json_encode($organizationSchema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); ?>
|
||||
</script>
|
||||
196
includes.bak.20260210/includes/schema/review-schema.php
Normal file
196
includes.bak.20260210/includes/schema/review-schema.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Review Schema Component
|
||||
* Generates Review and AggregateRating structured data
|
||||
*
|
||||
* Usage:
|
||||
* $reviews = [
|
||||
* ['author' => 'John Smith', 'reviewBody' => 'Great service!', 'ratingValue' => 5],
|
||||
* ['author' => 'Jane Doe', 'reviewBody' => 'Excellent work', 'ratingValue' => 5]
|
||||
* ];
|
||||
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/review-schema.php');
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate Review Schema JSON-LD with AggregateRating
|
||||
*
|
||||
* @param array $reviews Array of review data
|
||||
* @param string $itemName Name of the item being reviewed
|
||||
* @param string $itemType Schema type (Organization, Service, Product, etc.)
|
||||
* @param string|null $itemUrl URL of the item being reviewed
|
||||
* @return string JSON-LD script tag
|
||||
*/
|
||||
function generateReviewSchema($reviews, $itemName = 'UK Data Services', $itemType = 'Organization', $itemUrl = null) {
|
||||
if (empty($reviews)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$baseUrl = 'https://ukdataservices.co.uk';
|
||||
|
||||
// Calculate aggregate rating
|
||||
$totalRating = 0;
|
||||
$reviewCount = count($reviews);
|
||||
foreach ($reviews as $review) {
|
||||
$totalRating += $review['ratingValue'] ?? 5;
|
||||
}
|
||||
$averageRating = round($totalRating / $reviewCount, 1);
|
||||
|
||||
$schema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => $itemType,
|
||||
'name' => $itemName,
|
||||
'url' => $itemUrl ?? $baseUrl,
|
||||
'aggregateRating' => [
|
||||
'@type' => 'AggregateRating',
|
||||
'ratingValue' => number_format($averageRating, 1),
|
||||
'reviewCount' => $reviewCount,
|
||||
'bestRating' => '5',
|
||||
'worstRating' => '1'
|
||||
],
|
||||
'review' => array_map(function($review) {
|
||||
$reviewSchema = [
|
||||
'@type' => 'Review',
|
||||
'author' => [
|
||||
'@type' => 'Person',
|
||||
'name' => $review['author']
|
||||
],
|
||||
'reviewRating' => [
|
||||
'@type' => 'Rating',
|
||||
'ratingValue' => $review['ratingValue'] ?? 5,
|
||||
'bestRating' => '5',
|
||||
'worstRating' => '1'
|
||||
],
|
||||
'reviewBody' => $review['reviewBody']
|
||||
];
|
||||
|
||||
// Add date if provided
|
||||
if (isset($review['datePublished'])) {
|
||||
$reviewSchema['datePublished'] = $review['datePublished'];
|
||||
}
|
||||
|
||||
// Add job title/role if provided
|
||||
if (isset($review['authorRole'])) {
|
||||
$reviewSchema['author']['jobTitle'] = $review['authorRole'];
|
||||
}
|
||||
|
||||
return $reviewSchema;
|
||||
}, $reviews)
|
||||
];
|
||||
|
||||
return '<script type="application/ld+json">' . "\n" .
|
||||
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
|
||||
'</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate standalone AggregateRating schema (without individual reviews)
|
||||
*/
|
||||
function generateAggregateRatingSchema($itemName, $itemType, $ratingValue, $reviewCount, $itemUrl = null) {
|
||||
$baseUrl = 'https://ukdataservices.co.uk';
|
||||
|
||||
$schema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => $itemType,
|
||||
'name' => $itemName,
|
||||
'url' => $itemUrl ?? $baseUrl,
|
||||
'aggregateRating' => [
|
||||
'@type' => 'AggregateRating',
|
||||
'ratingValue' => number_format($ratingValue, 1),
|
||||
'reviewCount' => $reviewCount,
|
||||
'bestRating' => '5',
|
||||
'worstRating' => '1'
|
||||
]
|
||||
];
|
||||
|
||||
return '<script type="application/ld+json">' . "\n" .
|
||||
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
|
||||
'</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Predefined testimonials for the homepage and service pages
|
||||
*/
|
||||
$siteTestimonials = [
|
||||
[
|
||||
'author' => 'James Mitchell',
|
||||
'authorRole' => 'Retail Director, London Fashion Group',
|
||||
'reviewBody' => 'UK Data Services transformed our competitor analysis process. Their web scraping accuracy and speed helped us make better pricing decisions. We\'ve seen a 23% improvement in our market positioning since working with them.',
|
||||
'ratingValue' => 5,
|
||||
'datePublished' => '2024-09-15'
|
||||
],
|
||||
[
|
||||
'author' => 'Sarah Chen',
|
||||
'authorRole' => 'Head of Strategy, City Fintech Ltd',
|
||||
'reviewBody' => 'Outstanding data analytics service. They helped us understand our market position and identify opportunities we\'d completely missed. The team\'s expertise in financial data and GDPR compliance gave us complete confidence.',
|
||||
'ratingValue' => 5,
|
||||
'datePublished' => '2024-08-22'
|
||||
],
|
||||
[
|
||||
'author' => 'Michael Thompson',
|
||||
'authorRole' => 'Managing Partner, London Property Advisors',
|
||||
'reviewBody' => 'Professional, GDPR-compliant, and incredibly responsive. Their property data extraction service has become essential to our London operations. The 99.8% accuracy rate they promised was actually exceeded in our experience.',
|
||||
'ratingValue' => 5,
|
||||
'datePublished' => '2024-07-10'
|
||||
],
|
||||
[
|
||||
'author' => 'Emma Williams',
|
||||
'authorRole' => 'CEO, Manchester Logistics Solutions',
|
||||
'reviewBody' => 'Exceptional service quality. The data cleaning and validation work they did on our supply chain database saved us thousands in operational costs. Highly recommend for any Manchester business.',
|
||||
'ratingValue' => 5,
|
||||
'datePublished' => '2024-06-28'
|
||||
],
|
||||
[
|
||||
'author' => 'David Brown',
|
||||
'authorRole' => 'Director of Analytics, Birmingham Manufacturing Co',
|
||||
'reviewBody' => 'We needed complex automotive parts pricing data across multiple European suppliers. UK Data Services delivered beyond expectations with excellent accuracy and compliance documentation.',
|
||||
'ratingValue' => 5,
|
||||
'datePublished' => '2024-05-15'
|
||||
],
|
||||
[
|
||||
'author' => 'Laura Johnson',
|
||||
'authorRole' => 'Marketing Director, Scottish Energy Corp',
|
||||
'reviewBody' => 'Their competitive intelligence service gave us insights into market movements we couldn\'t have obtained otherwise. Professional team with deep technical expertise.',
|
||||
'ratingValue' => 5,
|
||||
'datePublished' => '2024-04-20'
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* Service-specific testimonials
|
||||
*/
|
||||
$serviceTestimonials = [
|
||||
'web-scraping' => [
|
||||
[
|
||||
'author' => 'Robert Harris',
|
||||
'authorRole' => 'CTO, E-commerce Solutions Ltd',
|
||||
'reviewBody' => 'Their web scraping capabilities are world-class. They handled complex JavaScript-rendered pages with ease and delivered clean, accurate data exactly as specified.',
|
||||
'ratingValue' => 5
|
||||
]
|
||||
],
|
||||
'price-monitoring' => [
|
||||
[
|
||||
'author' => 'Sophie Turner',
|
||||
'authorRole' => 'Pricing Manager, UK Retail Chain',
|
||||
'reviewBody' => 'The price monitoring alerts have revolutionized how we respond to competitor pricing. We now react in hours instead of days.',
|
||||
'ratingValue' => 5
|
||||
]
|
||||
],
|
||||
'data-cleaning' => [
|
||||
[
|
||||
'author' => 'Mark Stevens',
|
||||
'authorRole' => 'Data Manager, Healthcare Analytics',
|
||||
'reviewBody' => 'They cleaned and standardized over 2 million patient records with 99.9% accuracy. The improvement in our data quality has been transformational.',
|
||||
'ratingValue' => 5
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// If $reviews is set, output the schema automatically
|
||||
if (isset($reviews) && is_array($reviews)) {
|
||||
echo generateReviewSchema(
|
||||
$reviews,
|
||||
$reviewItemName ?? 'UK Data Services',
|
||||
$reviewItemType ?? 'Organization',
|
||||
$reviewItemUrl ?? null
|
||||
);
|
||||
}
|
||||
223
includes.bak.20260210/includes/schema/service-schema.php
Normal file
223
includes.bak.20260210/includes/schema/service-schema.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
/**
|
||||
* Service Schema Component
|
||||
* Generates Service structured data for improved SEO
|
||||
*
|
||||
* Usage:
|
||||
* $serviceData = [
|
||||
* 'name' => 'Web Scraping Services',
|
||||
* 'description' => 'Professional web scraping services...',
|
||||
* 'url' => 'https://ukdataservices.co.uk/services/web-scraping',
|
||||
* 'serviceType' => 'Web Scraping',
|
||||
* 'priceRange' => '500-50000',
|
||||
* 'features' => ['Feature 1', 'Feature 2']
|
||||
* ];
|
||||
* include($_SERVER['DOCUMENT_ROOT'] . '/includes/schema/service-schema.php');
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate Service Schema JSON-LD
|
||||
*
|
||||
* @param string $serviceName The name of the service
|
||||
* @param string $serviceDescription A detailed description of the service
|
||||
* @param string $serviceUrl The canonical URL of the service page
|
||||
* @param string $serviceType The type/category of service
|
||||
* @param string|null $priceRange Optional price range (e.g., "500-50000")
|
||||
* @param array $features Optional array of service features
|
||||
* @return string JSON-LD script tag
|
||||
*/
|
||||
function generateServiceSchema($serviceName, $serviceDescription, $serviceUrl, $serviceType, $priceRange = null, $features = []) {
|
||||
$schema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'Service',
|
||||
'@id' => $serviceUrl . '#service',
|
||||
'name' => $serviceName,
|
||||
'description' => $serviceDescription,
|
||||
'url' => $serviceUrl,
|
||||
'serviceType' => $serviceType,
|
||||
'provider' => [
|
||||
'@type' => 'Organization',
|
||||
'@id' => 'https://ukdataservices.co.uk/#organization',
|
||||
'name' => 'UK Data Services',
|
||||
'url' => 'https://ukdataservices.co.uk'
|
||||
],
|
||||
'areaServed' => [
|
||||
'@type' => 'Country',
|
||||
'name' => 'United Kingdom'
|
||||
],
|
||||
'availableChannel' => [
|
||||
'@type' => 'ServiceChannel',
|
||||
'serviceUrl' => 'https://ukdataservices.co.uk/quote',
|
||||
'servicePhone' => '+44 1692 689150',
|
||||
'availableLanguage' => 'English'
|
||||
]
|
||||
];
|
||||
|
||||
// Add price specification if provided
|
||||
if ($priceRange) {
|
||||
$prices = explode('-', $priceRange);
|
||||
$schema['offers'] = [
|
||||
'@type' => 'Offer',
|
||||
'priceCurrency' => 'GBP',
|
||||
'priceSpecification' => [
|
||||
'@type' => 'PriceSpecification',
|
||||
'minPrice' => (float)$prices[0],
|
||||
'maxPrice' => isset($prices[1]) ? (float)$prices[1] : null,
|
||||
'priceCurrency' => 'GBP'
|
||||
],
|
||||
'availability' => 'https://schema.org/InStock',
|
||||
'validFrom' => date('Y-m-d')
|
||||
];
|
||||
}
|
||||
|
||||
// Add features/service output if provided
|
||||
if (!empty($features)) {
|
||||
$schema['hasOfferCatalog'] = [
|
||||
'@type' => 'OfferCatalog',
|
||||
'name' => $serviceName . ' Features',
|
||||
'itemListElement' => array_map(function($feature) {
|
||||
return [
|
||||
'@type' => 'Offer',
|
||||
'itemOffered' => [
|
||||
'@type' => 'Service',
|
||||
'name' => $feature
|
||||
]
|
||||
];
|
||||
}, $features)
|
||||
];
|
||||
}
|
||||
|
||||
return '<script type="application/ld+json">' . "\n" .
|
||||
json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n" .
|
||||
'</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Predefined service configurations for consistency
|
||||
*/
|
||||
$serviceConfigs = [
|
||||
'web-scraping' => [
|
||||
'name' => 'Web Scraping Services UK',
|
||||
'description' => 'Professional web scraping and data extraction services for UK businesses. Automated data collection from websites with 99.8% accuracy and full GDPR compliance.',
|
||||
'url' => 'https://ukdataservices.co.uk/services/web-scraping',
|
||||
'serviceType' => 'Web Scraping',
|
||||
'priceRange' => '500-50000',
|
||||
'features' => [
|
||||
'Automated data extraction',
|
||||
'Real-time monitoring',
|
||||
'GDPR-compliant collection',
|
||||
'Custom API delivery',
|
||||
'Multi-format output'
|
||||
]
|
||||
],
|
||||
'competitive-intelligence' => [
|
||||
'name' => 'Competitive Intelligence Services UK',
|
||||
'description' => 'Strategic competitive intelligence and market analysis services. Monitor competitors, track market trends, and gain actionable business insights.',
|
||||
'url' => 'https://ukdataservices.co.uk/services/competitive-intelligence',
|
||||
'serviceType' => 'Competitive Intelligence',
|
||||
'priceRange' => '1000-25000',
|
||||
'features' => [
|
||||
'Competitor monitoring',
|
||||
'Market trend analysis',
|
||||
'Price tracking',
|
||||
'Product intelligence',
|
||||
'Strategic reporting'
|
||||
]
|
||||
],
|
||||
'price-monitoring' => [
|
||||
'name' => 'Price Monitoring Services UK',
|
||||
'description' => 'Real-time price monitoring and competitor price tracking services. E-commerce pricing intelligence for UK retailers and brands.',
|
||||
'url' => 'https://ukdataservices.co.uk/services/price-monitoring',
|
||||
'serviceType' => 'Price Monitoring',
|
||||
'priceRange' => '500-15000',
|
||||
'features' => [
|
||||
'Real-time price tracking',
|
||||
'Competitor price alerts',
|
||||
'MAP monitoring',
|
||||
'Historical price analysis',
|
||||
'Automated reporting'
|
||||
]
|
||||
],
|
||||
'data-cleaning' => [
|
||||
'name' => 'Data Cleaning & Validation Services UK',
|
||||
'description' => 'Professional data cleaning, validation, and standardisation services. Transform messy data into accurate, structured datasets.',
|
||||
'url' => 'https://ukdataservices.co.uk/services/data-cleaning',
|
||||
'serviceType' => 'Data Cleaning',
|
||||
'priceRange' => '500-20000',
|
||||
'features' => [
|
||||
'Duplicate removal',
|
||||
'Data standardisation',
|
||||
'Format validation',
|
||||
'Error correction',
|
||||
'Quality assurance'
|
||||
]
|
||||
],
|
||||
'data-analytics' => [
|
||||
'name' => 'Data Analytics Services UK',
|
||||
'description' => 'Business intelligence and data analytics solutions for UK enterprises. Transform raw data into actionable insights.',
|
||||
'url' => 'https://ukdataservices.co.uk/services/data-analytics',
|
||||
'serviceType' => 'Data Analytics',
|
||||
'priceRange' => '1000-30000',
|
||||
'features' => [
|
||||
'Business intelligence',
|
||||
'Predictive analytics',
|
||||
'Custom dashboards',
|
||||
'Data visualisation',
|
||||
'Strategic insights'
|
||||
]
|
||||
],
|
||||
'api-development' => [
|
||||
'name' => 'API Development Services UK',
|
||||
'description' => 'Custom API development and data integration services. Build robust APIs to connect your systems and automate data workflows.',
|
||||
'url' => 'https://ukdataservices.co.uk/services/api-development',
|
||||
'serviceType' => 'API Development',
|
||||
'priceRange' => '2000-40000',
|
||||
'features' => [
|
||||
'Custom API design',
|
||||
'System integration',
|
||||
'Real-time data feeds',
|
||||
'Authentication systems',
|
||||
'Documentation'
|
||||
]
|
||||
],
|
||||
'property-data-extraction' => [
|
||||
'name' => 'UK Property Data Extraction Services',
|
||||
'description' => 'Professional property data extraction from UK property portals including Rightmove, Zoopla, and OnTheMarket. GDPR-compliant property market intelligence.',
|
||||
'url' => 'https://ukdataservices.co.uk/services/property-data-extraction',
|
||||
'serviceType' => 'Property Data Extraction',
|
||||
'priceRange' => '1000-25000',
|
||||
'features' => [
|
||||
'Property portal data extraction',
|
||||
'Market analysis',
|
||||
'Investment research data',
|
||||
'Rental market intelligence',
|
||||
'Commercial property data'
|
||||
]
|
||||
],
|
||||
'financial-data-services' => [
|
||||
'name' => 'Financial Data Services UK',
|
||||
'description' => 'FCA-aware financial data services for hedge funds, asset managers, and investment firms. Market data extraction and alternative data solutions.',
|
||||
'url' => 'https://ukdataservices.co.uk/services/financial-data-services',
|
||||
'serviceType' => 'Financial Data Services',
|
||||
'priceRange' => '5000-100000',
|
||||
'features' => [
|
||||
'Market data extraction',
|
||||
'Alternative data feeds',
|
||||
'Securities monitoring',
|
||||
'Compliance-aware collection',
|
||||
'API delivery'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// If $serviceData is set, output the schema automatically
|
||||
if (isset($serviceData) && is_array($serviceData)) {
|
||||
echo generateServiceSchema(
|
||||
$serviceData['name'],
|
||||
$serviceData['description'],
|
||||
$serviceData['url'],
|
||||
$serviceData['serviceType'],
|
||||
$serviceData['priceRange'] ?? null,
|
||||
$serviceData['features'] ?? []
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user