| | |
| | | <?php |
| | | namespace JVBase\registrar\config\seo; |
| | | |
| | | use JVBase\base\SchemaHelper; |
| | | use JVBase\managers\Cache; |
| | | use JVBase\managers\SEO\render; |
| | | use JVBase\meta\Meta; |
| | |
| | | ]; |
| | | |
| | | protected array $defaultArchive = [ |
| | | 'type' => 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage', |
| | | 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\CollectionPage', |
| | | 'title' => '{{registrar.plural}}' |
| | | ]; |
| | | |
| | |
| | | |
| | | switch ($registrar->getType()) { |
| | | case 'term': |
| | | $this->defaultSchema['type'] = 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage'; |
| | | $this->defaultSchema['type'] = 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\CollectionPage'; |
| | | break; |
| | | case 'user': |
| | | $this->defaultSchema['type'] = 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\ProfilePage'; |
| | |
| | | |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | $this->defaultArchive = [ |
| | | 'type' => 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage', |
| | | 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\CollectionPage', |
| | | 'name' => $registrar->getPlural(), |
| | | 'description' => $registrar->getDescription() |
| | | ]; |
| | |
| | | public function outputSchema():void |
| | | { |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | |
| | | if (is_singular()) { |
| | | $this->outputSingularSchema(); |
| | | } elseif (is_post_type_archive(jvbCheckBase($this->slug) || is_tax(jvbCheckBase($this->slug)))) { |
| | |
| | | $this->cache->flush(); |
| | | } |
| | | |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | |
| | | return $this->cache->remember( |
| | | $ID, |
| | | function () use ($ID) { |
| | | function () use ($ID, $registrar) { |
| | | $meta = Meta::forPost($ID); |
| | | if ($registrar->hasFeature('is_faq')) { |
| | | return $this->outputQASchema($ID, $meta); |
| | | } |
| | | if ($registrar->hasFeature('is_timeline')) { |
| | | return $this->outputTimelineSchema($ID, $meta); |
| | | } |
| | | |
| | | $config = $this->getConfig(); |
| | | |
| | | $class = JVB()->schemaHelper()::classFromConfig($config, $meta); |
| | |
| | | $config = JVB()->schemaHelper()::schema($action); |
| | | |
| | | if (!array_key_exists('type', $config)) { |
| | | $config['type'] = 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage'; |
| | | $config['type'] = 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\CollectionPage'; |
| | | } |
| | | if (!class_exists($config['type'])) { |
| | | error_log('No class found for archive schema output: '.$config['type']); |
| | |
| | | $action = BASE.ucfirst($this->slug).'Archive'; |
| | | $config = JVB()->schemaHelper()->archive($this->slug); |
| | | if (!array_key_exists('type', $config)) { |
| | | $config['type'] = 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage'; |
| | | $config['type'] = 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\CollectionPage'; |
| | | } |
| | | if (!class_exists($config['type'])) { |
| | | error_log('No class found for archive schema output: '.$config['type']); |
| | | return []; |
| | | } |
| | | |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | if ($registrar->hasFeature('is_glossary')) { |
| | | return $this->outputGlossarySchema(); |
| | | } else if ($registrar->hasFeature('is_faq')) { |
| | | return $this->outputFAQSchema(); |
| | | } |
| | | if ($registrar->hasFeature('is_timeline')) { |
| | | return $this->outputTimelineArchiveSchema(); |
| | | } |
| | | $obj = get_queried_object(); |
| | | $meta = (property_exists($obj, 'taxonomy')) ? Meta::forTerm($obj->term_id) : null; |
| | | |
| | |
| | | foreach ($items->posts as $ID) { |
| | | $item = $this->outputReferenceSchema($ID, 'post',false); |
| | | $listItem = new render\Thing\Intangible\ListItem(); |
| | | $listItem->setId('listitem-'.$ID); |
| | | $listItem->setPosition($pos); |
| | | $listItem->setItem($item); |
| | | $itemListItems[] = $listItem; |
| | |
| | | error_log('Invalid type used for reference: '.print_r($type, true)); |
| | | $meta = null; |
| | | } |
| | | $config = $this->getConfig('archive'); |
| | | $config = $this->getConfig(); |
| | | $class = JVB()->schemaHelper()::classFromConfig($config, $meta); |
| | | $class->delete('about'); |
| | | |
| | |
| | | return JVB()->schemaHelper()::getConfig($this->slug, $type); |
| | | } |
| | | |
| | | public function resolveMeta(array $config, Meta $meta):array |
| | | { |
| | | foreach ($config as $property => $value) { |
| | | if (is_array($value)) { |
| | | $config[$property] = $this->resolveMeta($value, $meta); |
| | | if ($property === 'additionalProperty' && (!array_key_exists('value', $config[$property]) || empty($config[$property]['value']))) { |
| | | unset($config[$property]); |
| | | } |
| | | } |
| | | if (is_string($value) && str_contains($value, '{{')) { |
| | | $value = Resolver::resolve($value, $meta); |
| | | if (empty($value)){ |
| | | unset($config[$property]); |
| | | } else { |
| | | $config[$property] = $value; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return $config; |
| | | } |
| | | |
| | | public function define(string $property, string $value):void |
| | | { |
| | | $class = $this->getConfig('schema')['type']; |
| | |
| | | if (is_singular($based)){ |
| | | $config = $this->getConfig('meta'); |
| | | $meta = Meta::forPost(get_the_ID()); |
| | | $title = Resolver::resolve($config['name'], $meta); |
| | | $title = Resolver::resolve($config['name']??$config['title'], $meta); |
| | | } elseif (is_post_type_archive($based) ) { |
| | | $config = $this->getConfig('archive'); |
| | | $title = $config['name']; |
| | |
| | | } |
| | | return $title; |
| | | } |
| | | public function outputQASchema(int $ID, Meta $meta):array |
| | | { |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | global $wp; |
| | | $current = get_home_url(null, $wp->request).'/'; |
| | | $config = $this->getConfig(); |
| | | |
| | | $config['type'] = 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\QAPage'; |
| | | $page = SchemaHelper::classFromConfig($config, $meta); |
| | | |
| | | $post = get_queried_object(); |
| | | $question = [ |
| | | 'id' => $current.'#question-'.$post->post_name, |
| | | 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\Comment\Question', |
| | | 'name' => $meta->get('post_title'), |
| | | 'acceptedAnswer' => [ |
| | | 'id' => $current.'#answer-'.$post->post_name, |
| | | 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\Comment\Answer', |
| | | 'text' => wp_strip_all_tags(str_replace("\n", '', $meta->get('post_content'))), |
| | | ], |
| | | ]; |
| | | $question = SchemaHelper::classFromConfig($question); |
| | | $page->setMainEntity($question); |
| | | $page->setAuthor(JVB()->seo()->getCreator(true)); |
| | | return $page->outputSchema(); |
| | | |
| | | } |
| | | public function outputTimelineSchema(int $ID, Meta $meta):array |
| | | { |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | global $wp; |
| | | $current = get_home_url(null, $wp->request).'/'; |
| | | $config = $this->getConfig(); |
| | | |
| | | $config['type'] = 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\ImageGallery'; |
| | | $this->resolveMeta($config, $meta); |
| | | $page = SchemaHelper::classFromConfig($config, $meta); |
| | | |
| | | $post = get_queried_object(); |
| | | $images = []; |
| | | $children = new WP_Query([ |
| | | 'post_type'=> jvbCheckBase($this->slug), |
| | | 'post_status' => 'publish', |
| | | 'post_parent' => $post->ID, |
| | | ]); |
| | | $children = $children->posts; |
| | | array_unshift($children, $post); |
| | | |
| | | foreach ($children as $index => $child) { |
| | | $meta = Meta::forPost($child->ID); |
| | | |
| | | $image = render\Thing\Thing::createImageFromID($meta->get('post_thumbnail')); |
| | | $image->setId(($index === 0) ? '#before-treatment' : '#treatment-'.$index); |
| | | $image->setPosition($index+1); |
| | | $image->setName(($index === 0) ? 'Before Laser Tattoo Removal' : 'After '.$index.' Laser Tattoo Removal Treatments'); |
| | | if (!empty ($meta->get('post_excerpt'))){ |
| | | $image->setDescription($meta->get('post_excerpt')); |
| | | } |
| | | |
| | | $images[] = $image; |
| | | } |
| | | |
| | | $page->setImage($images); |
| | | $page->setAuthor(JVB()->seo()->getCreator(true)); |
| | | return $page->outputSchema(); |
| | | |
| | | } |
| | | |
| | | /********************************************* |
| | | * Archive Presets |
| | | *********************************************/ |
| | | public function outputFAQSchema():array |
| | | { |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | global $wp; |
| | | $current = get_home_url(null, $wp->request).'/'; |
| | | $config = $this->getConfig('archive'); |
| | | $page = [ |
| | | 'id' => $current.'#'.$registrar->getSlug(), |
| | | 'type' => 'JVBase\managers\SEO\render\Thing\CreativeWork\WebPage\FAQPage', |
| | | 'name' => array_key_exists('name', $config) ? $config['name'] : $registrar->getPlural(), |
| | | 'description' => array_key_exists('description', $config) ? $config['description'] : $registrar->getDescription(), |
| | | 'url' => $current, |
| | | ]; |
| | | |
| | | $page = SchemaHelper::classFromConfig($page); |
| | | |
| | | $args = [ |
| | | 'post_type' => $registrar->getBased(), |
| | | 'posts_per_page'=> -1, |
| | | 'post_status' => 'publish', |
| | | ]; |
| | | $obj = get_queried_object(); |
| | | |
| | | if (property_exists($obj, 'taxonomy')) { |
| | | $page->setName('FAQ on '.$obj->name); |
| | | |
| | | $args['post_type'] = array_map('jvbCheckBase', $registrar->registrar->for); |
| | | |
| | | $args['tax_query'] = [ |
| | | [ |
| | | 'taxonomy' => $obj->taxonomy, |
| | | 'terms' => $obj->term_id, |
| | | ] |
| | | ]; |
| | | } |
| | | |
| | | $questions = []; |
| | | $posts = new WP_Query($args); |
| | | foreach ($posts->posts as $post) { |
| | | $meta = Meta::forPost($post->ID); |
| | | $question = [ |
| | | 'id' => $current.'#question-'.$post->post_name, |
| | | 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\Comment\Question', |
| | | 'name' => $meta->get('post_title'), |
| | | 'acceptedAnswer' => [ |
| | | 'id' => $current.'#answer-'.$post->post_name, |
| | | 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\Comment\Answer', |
| | | 'text' => $meta->get('post_excerpt'), |
| | | ], |
| | | 'url' => get_the_permalink($post->ID), |
| | | ]; |
| | | $questions[] = SchemaHelper::classFromConfig($question); |
| | | } |
| | | wp_reset_postdata(); |
| | | $page->setMainEntity($questions); |
| | | |
| | | return $page->outputSchema(); |
| | | |
| | | } |
| | | public function outputTimelineArchiveSchema():array |
| | | { |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | global $wp; |
| | | $current = get_home_url(null, $wp->request).'/'; |
| | | $config = $this->getConfig('archive'); |
| | | $page = array_merge($config, [ |
| | | 'id' => $current.'#'.$registrar->getSlug(), |
| | | 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\CollectionPage', |
| | | 'name' => array_key_exists('name', $config) ? $config['name'] : $registrar->getPlural(), |
| | | 'description' => array_key_exists('description', $config) ? $config['description'] : $registrar->getDescription(), |
| | | 'url' => $current, |
| | | ]); |
| | | $page = SchemaHelper::classFromConfig($page); |
| | | |
| | | $parts = []; |
| | | $timelines = new WP_Query([ |
| | | 'post_type' => $registrar->getBased(), |
| | | 'posts_per_page'=> 50, |
| | | 'post_status' => 'publish', |
| | | 'post_parent' => 0, |
| | | ]); |
| | | foreach ($timelines->posts as $post) { |
| | | $item = $this->outputReferenceSchema($post->ID, 'post', false); |
| | | $item->setId($current.'#'.$post->post_name); |
| | | $item->setName($post->post_title); |
| | | $item->setUrl(get_the_permalink($post->ID)); |
| | | $parts[] = $item; |
| | | } |
| | | |
| | | $page->setHasPart($parts); |
| | | return $page->outputSchema(); |
| | | } |
| | | public function outputGlossarySchema():array |
| | | { |
| | | $registrar = Registrar::getInstance($this->slug); |
| | | global $wp; |
| | | $current = get_home_url(null, $wp->request).'/'; |
| | | $config = $this->getConfig('archive'); |
| | | $page = [ |
| | | 'id' => $current.'#'.$registrar->getSlug(), |
| | | 'type' => 'JVBase\inc\managers\SEO\render\Thing\CreativeWork\WebPage\CollectionPage\CollectionPage', |
| | | 'name' => array_key_exists('name', $config) ? $config['name'] : $registrar->getPlural(), |
| | | 'description' => array_key_exists('description', $config) ? $config['description'] : $registrar->getDescription(), |
| | | 'url' => $current, |
| | | ]; |
| | | $page = SchemaHelper::classFromConfig($page); |
| | | |
| | | |
| | | //Defined Termset |
| | | $termset = [ |
| | | 'type' => 'JVBase\managers\SEO\render\Thing\CreativeWork\DefinedTermSet', |
| | | 'id' => $current.'#definedtermset', |
| | | 'name' => $registrar->getPlural(), |
| | | 'description' => $registrar->getDescription(), |
| | | ]; |
| | | $termset = SchemaHelper::classFromConfig($termset); |
| | | |
| | | $terms = new WP_Query([ |
| | | 'post_type' => $registrar->getBased(), |
| | | 'posts_per_page' => -1, |
| | | 'post_status' => 'publish', |
| | | ]); |
| | | |
| | | $outputTerms = []; |
| | | foreach ($terms->posts as $post) { |
| | | $item = $this->outputReferenceSchema($post->ID, 'post', false); |
| | | $item->setId($current.'#'.$post->post_name); |
| | | $item->setName($post->post_title); |
| | | $outputTerms[] = $item; |
| | | } |
| | | $termset->setHasDefinedTerm($outputTerms); |
| | | |
| | | $page->setMainEntity($termset); |
| | | return $page->outputSchema(); |
| | | } |
| | | } |