HEX
Server: nginx/1.18.0
System: Linux vcwordpress 5.15.0-174-generic #184-Ubuntu SMP Fri Mar 13 18:41:50 UTC 2026 x86_64
User: root (0)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/viitorx.stgviitor.com/wp-content/themes/viitorx/inc/seo-schema.php
<?php

/**
 * SEO Schema – JSON-LD (Server-Side)
 *
 * Outputs a consolidated @graph block in <head> via wp_head.
 * All URLs are dynamic via home_url() / get_the_permalink().
 *
 * @package ViitorX
 */

if (! defined('ABSPATH')) exit;

// -----------------------------------------------------------------------
// Helper: Breadcrumbs
// -----------------------------------------------------------------------
function viitorx_get_breadcrumbs($site_url, $curr_url)
{
    $items = [];
    $pos   = 1;

    $items[] = [
        '@type'    => 'ListItem',
        'position' => $pos++,
        'name'     => 'Home',
        'item'     => $site_url,
    ];

    if (is_front_page()) {
        return $items;
    }

    if (is_single()) {
        $post_type = get_post_type();

        if ($post_type === 'post') {
            $cats = get_the_category();
            if (! empty($cats)) {
                $items[] = [
                    '@type'    => 'ListItem',
                    'position' => $pos++,
                    'name'     => $cats[0]->name,
                    'item'     => get_category_link($cats[0]->term_id),
                ];
            }
        }

        if ($post_type === 'case_study') {
            $archive_url = get_post_type_archive_link('case_study');
            if ($archive_url) {
                $items[] = [
                    '@type'    => 'ListItem',
                    'position' => $pos++,
                    'name'     => 'Case Studies',
                    'item'     => $archive_url,
                ];
            }
        }

        $items[] = [
            '@type'    => 'ListItem',
            'position' => $pos++,
            'name'     => get_the_title(),
            'item'     => get_permalink(),
        ];

        return $items;
    }

    if (is_page()) {
        $post    = get_queried_object();
        $parents = [];
        $parent  = $post->post_parent;

        while ($parent) {
            $p         = get_post($parent);
            $parents[] = [
                'name' => get_the_title($p),
                'item' => get_permalink($p),
            ];
            $parent = $p->post_parent;
        }

        foreach (array_reverse($parents) as $p) {
            $items[] = [
                '@type'    => 'ListItem',
                'position' => $pos++,
                'name'     => $p['name'],
                'item'     => $p['item'],
            ];
        }

        $items[] = [
            '@type'    => 'ListItem',
            'position' => $pos++,
            'name'     => get_the_title(),
            'item'     => get_permalink(),
        ];

        return $items;
    }

    if (is_post_type_archive()) {
        $items[] = [
            '@type'    => 'ListItem',
            'position' => $pos++,
            'name'     => post_type_archive_title('', false),
            'item'     => $curr_url,
        ];
        return $items;
    }

    if (is_category() || is_tag() || is_tax()) {
        $term    = get_queried_object();
        $items[] = [
            '@type'    => 'ListItem',
            'position' => $pos++,
            'name'     => $term->name,
            'item'     => $curr_url,
        ];
        return $items;
    }

    $items[] = [
        '@type'    => 'ListItem',
        'position' => $pos++,
        'name'     => wp_title('', false) ?: get_bloginfo('name'),
        'item'     => $curr_url,
    ];

    return $items;
}

// -----------------------------------------------------------------------
// Master function — assembles and outputs the @graph
// -----------------------------------------------------------------------
function viitorx_output_schema()
{
    $site_url = trailingslashit(home_url());
    $org_id   = $site_url . '#organization';
    $site_id  = $site_url . '#website';
    $local_id = $site_url . '#localbusiness';
    $curr_url = esc_url(home_url(add_query_arg(null, null)));
    $page_id  = $curr_url . '#webpage';

    $is_offerings = is_page('offerings');
    $is_insights  = is_page('insights');

    $graph = [];

    // -----------------------------------------------------------------------
    // 1. WebSite
    // -----------------------------------------------------------------------
    $graph[] = [
        '@type'           => 'WebSite',
        '@id'             => $site_id,
        'url'             => $site_url,
        'name'            => 'ViitorX',
        'description'     => 'ViitorX engineers immersive digital experience solutions, from permanent museum installations and VR simulations to 3D brand websites and event activations.',
        'publisher'       => ['@id' => $org_id],
        'potentialAction' => [
            '@type'       => 'SearchAction',
            'target'      => [
                '@type'       => 'EntryPoint',
                'urlTemplate' => $site_url . '?s={search_term_string}',
            ],
            'query-input' => 'required name=search_term_string',
        ],
        'inLanguage' => 'en-IN',
    ];

    // -----------------------------------------------------------------------
    // 2. Organization — Always present (referenced by others)
    // -----------------------------------------------------------------------
    $graph[] = [
        '@type'              => 'Organization',
        '@id'                => $org_id,
        'name'               => 'ViitorX',
        'legalName'          => 'ViitorX',
        'url'                => $site_url,
        'logo'               => [
            '@type'  => 'ImageObject',
            'url'    => $site_url . 'wp-content/uploads/2026/04/logo-x.svg',
            'width'  => 200,
            'height' => 60,
        ],
        'description'        => 'ViitorX is an immersive experience design company building digital brand experiences, immersive experience centres, event activations, and simulation-based learning environments across India and globally.',
        'foundingDate'       => '2016',
        'address'            => [
            '@type'           => 'PostalAddress',
            'streetAddress'   => 'Avdhesh House, 301-303, opp. Gurudwara, Bodakdev',
            'addressLocality' => 'Ahmedabad',
            'addressRegion'   => 'Gujarat',
            'postalCode'      => '380054',
            'addressCountry'  => 'IN',
        ],
        'contactPoint'       => [
            '@type'             => 'ContactPoint',
            'telephone'         => '+91-84889-64723',
            'contactType'       => 'customer service',
            'email'             => 'contact@viitorx.com',
            'availableLanguage' => ['English', 'Hindi'],
        ],
        'sameAs'             => [
            'https://www.linkedin.com/company/viitorx/',
            'https://x.com/_ViitorX',
            'https://www.instagram.com/viitorx_official/',
            'https://www.facebook.com/viitorxofficial',
        ],
        'parentOrganization' => [
            '@type' => 'Organization',
            'name'  => 'ViitorCloud',
            'url'   => 'https://viitorcloud.com/',
        ],
        'numberOfEmployees'  => [
            '@type'    => 'QuantitativeValue',
            'minValue' => 50,
            'maxValue' => 200,
        ],
        'areaServed'  => ['India', 'Global'],
        'knowsAbout'  => [
            'Immersive Experience Design',
            'Virtual Reality Training',
            'Augmented Reality',
            'Digital Brand Experience',
            'Experience Centre Design',
            'Simulation-Based Learning',
        ],
    ];

    // -----------------------------------------------------------------------
    // 3. LocalBusiness
    // -----------------------------------------------------------------------
    $graph[] = [
        '@type'     => 'LocalBusiness',
        '@id'       => $local_id,
        'name'      => 'ViitorX',
        'image'     => $site_url . 'wp-content/uploads/2026/04/footer_logo.webp',
        'url'       => $site_url,
        'telephone' => '+91-84889-64723',
        'email'     => 'contact@viitorx.com',
        'address'   => [
            '@type'           => 'PostalAddress',
            'streetAddress'   => 'Avdhesh House, 301-303, opp. Gurudwara, Bodakdev',
            'addressLocality' => 'Ahmedabad',
            'addressRegion'   => 'Gujarat',
            'postalCode'      => '380054',
            'addressCountry'  => 'IN',
        ],
        'geo'       => [
            '@type'     => 'GeoCoordinates',
            'latitude'  => 23.0469,
            'longitude' => 72.5150,
        ],
        'openingHoursSpecification' => [
            '@type'     => 'OpeningHoursSpecification',
            'dayOfWeek' => ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
            'opens'     => '09:00',
            'closes'    => '18:00',
        ],
        'priceRange'      => '₹₹₹',
        'aggregateRating' => [
            '@type'       => 'AggregateRating',
            'ratingValue' => '4.6',
            'bestRating'  => '5',
            'worstRating' => '1',
            'ratingCount' => '100',
        ],
        'hasMap'             => 'https://maps.google.com/?q=Avdhesh+House+Bodakdev+Ahmedabad+Gujarat',
        'sameAs'             => [
            'https://www.linkedin.com/company/viitorx/',
            'https://x.com/_ViitorX',
            'https://www.instagram.com/viitorx_official/',
            'https://www.facebook.com/viitorxofficial',
        ],
        'parentOrganization' => ['@id' => $org_id],
    ];

    // -----------------------------------------------------------------------
    // 4. WebPage — always present
    //    CollectionPage for offerings and insights, WebPage for everything else
    // -----------------------------------------------------------------------
    $graph[] = [
        '@type'      => ($is_offerings || $is_insights) ? 'CollectionPage' : 'WebPage',
        '@id'        => $page_id,
        'url'        => $curr_url,
        'name'       => wp_title('', false) ?: get_bloginfo('name'),
        'isPartOf'   => ['@id' => $site_id],
        'inLanguage' => 'en-IN',
    ];

    // -----------------------------------------------------------------------
    // 5. BreadcrumbList — linked to WebPage
    // -----------------------------------------------------------------------
    $breadcrumbs = viitorx_get_breadcrumbs($site_url, $curr_url);
    if (count($breadcrumbs) > 1) {
        $breadcrumb_id = $curr_url . '#breadcrumb';

        $graph[array_key_last($graph)]['breadcrumb'] = ['@id' => $breadcrumb_id];

        $graph[] = [
            '@type'           => 'BreadcrumbList',
            '@id'             => $breadcrumb_id,
            'itemListElement' => $breadcrumbs,
        ];
    }

    // -----------------------------------------------------------------------
    // 6. Offerings Page → 4 Services
    // -----------------------------------------------------------------------
    if ($is_offerings) {
        $graph[] = [
            '@type'           => 'Service',
            '@id'             => $curr_url . '#digital-brand-experience',
            'name'            => 'Digital Brand Experience',
            'description'     => 'Websites and digital environments built with 3D, motion and immersive storytelling — including 3D brand websites, interactive campaign microsites, AI-personalised web experiences, and digital product showcases.',
            'url'             => $curr_url,
            'provider'        => ['@id' => $org_id],
            'serviceType'     => 'Digital Experience Design',
            'areaServed'      => 'IN',
            'hasOfferCatalog' => [
                '@type'           => 'OfferCatalog',
                'name'            => 'Digital Brand Experience Services',
                'itemListElement' => [
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => '3D & Motion-Rich Brand Websites']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Interactive Campaign Microsites']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'AI-Personalised Web Experiences']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Digital Product Showcases']],
                ],
            ],
        ];

        $graph[] = [
            '@type'           => 'Service',
            '@id'             => $curr_url . '#immersive-experience-centres',
            'name'            => 'Immersive Experience Centres',
            'description'     => 'Permanent spaces that tell stories, engage visitors, and leave a lasting impact — including visitor journey planning, zone-by-zone story design, projection-mapped walls, gesture-reactive displays, and AI-driven interactive installations.',
            'url'             => $curr_url,
            'provider'        => ['@id' => $org_id],
            'serviceType'     => 'Experience Centre Design',
            'areaServed'      => 'IN',
            'hasOfferCatalog' => [
                '@type'           => 'OfferCatalog',
                'name'            => 'Immersive Experience Centre Services',
                'itemListElement' => [
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Visitor Journey Planning']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Projection-Mapped Walls and Floors']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Gesture and Motion-Reactive Displays']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'AI-Driven Interactive Installations']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Visitor Flow and Engagement Analytics']],
                ],
            ],
        ];

        $graph[] = [
            '@type'           => 'Service',
            '@id'             => $curr_url . '#event-brand-experiences',
            'name'            => 'Event & Brand Experiences',
            'description'     => 'Immersive brand moments for events, expos, and product launches — including projection-mapped brand environments, 360° immersive narrative rooms, interactive exhibition stands, and AI-powered engagement analytics.',
            'url'             => $curr_url,
            'provider'        => ['@id' => $org_id],
            'serviceType'     => 'Event Experience Design',
            'areaServed'      => 'IN',
            'hasOfferCatalog' => [
                '@type'           => 'OfferCatalog',
                'name'            => 'Event & Brand Experience Services',
                'itemListElement' => [
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Projection-Mapped Brand Environments']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => '360° Immersive Brand Narrative Rooms']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Interactive Exhibition Stands and Pavilions']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Product Launch Experiences']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'AI-Powered Crowd and Attention Analytics']],
                ],
            ],
        ];

        $graph[] = [
            '@type'           => 'Service',
            '@id'             => $curr_url . '#simulation-based-learning',
            'name'            => 'Simulation-Based Learning',
            'description'     => 'VR training that replaces dangerous or expensive physical practice — including VR safety and compliance training, procedural skill simulations, high-risk scenario training, AI-powered performance analysis, and LMS integration.',
            'url'             => $curr_url,
            'provider'        => ['@id' => $org_id],
            'serviceType'     => 'VR Training and Simulation',
            'areaServed'      => 'IN',
            'hasOfferCatalog' => [
                '@type'           => 'OfferCatalog',
                'name'            => 'Simulation-Based Learning Services',
                'itemListElement' => [
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'VR Safety and Compliance Training']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'Procedural Skill Simulations']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'High-Risk Scenario Training']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'AI-Powered Performance Analysis']],
                    ['@type' => 'Offer', 'itemOffered' => ['@type' => 'Service', 'name' => 'LMS Integration and Compliance Reporting']],
                ],
            ],
        ];
    }

    // -----------------------------------------------------------------------
    // 7. Insights Page → ItemList of Articles
    // -----------------------------------------------------------------------
    if ($is_insights) {
        $insights = get_posts([
            'post_type'      => 'post',
            'posts_per_page' => -1,
            'post_status'    => 'publish',
            'orderby'        => 'date',
            'order'          => 'DESC',
        ]);

        if (! empty($insights)) {
            $list_items = [];
            foreach ($insights as $i => $insight) {
                $item_id = get_permalink($insight);
                $article = [
                    '@type'         => 'Article',
                    '@id'           => $item_id . '#article',
                    'url'           => $item_id,
                    'headline'      => get_the_title($insight),
                    'datePublished' => get_the_date('c', $insight),
                    'dateModified'  => get_the_modified_date('c', $insight),
                    'author'        => [
                        '@type' => 'Organization',
                        'name'  => 'ViitorX',
                        'url'   => $site_url,
                    ],
                    'publisher'     => ['@id' => $org_id],
                ];

                $thumb_url = get_the_post_thumbnail_url($insight, 'full');
                if ($thumb_url) {
                    $article['image'] = [
                        '@type'  => 'ImageObject',
                        'url'    => $thumb_url,
                        'width'  => 1200,
                        'height' => 630,
                    ];
                }

                $list_items[] = [
                    '@type'    => 'ListItem',
                    'position' => $i + 1,
                    'item'     => $article,
                ];
            }

            $graph[] = [
                '@type'           => 'ItemList',
                '@id'             => $curr_url . '#insights-list',
                'name'            => 'ViitorX Insights',
                'description'     => 'Thoughts, case breakdowns and industry perspectives from the ViitorX team on immersive experience design.',
                'url'             => $curr_url,
                'itemListElement' => $list_items,
            ];
        }
    }

    // -----------------------------------------------------------------------
    // 8. Single Post → Article
    // -----------------------------------------------------------------------
    if (is_single() && get_post_type() === 'post' && ! is_front_page()) {
        $post      = get_queried_object();
        $pub_date  = get_the_date('c', $post);
        $mod_date  = get_the_modified_date('c', $post);
        $thumb_url = get_the_post_thumbnail_url($post, 'full');
        $excerpt   = wp_strip_all_tags(get_the_excerpt($post));
        $cats      = get_the_category($post->ID);
        $cat_name  = ! empty($cats) ? $cats[0]->name : 'Insights';

        // Keywords from Tags
        $tags = get_the_tags($post->ID);
        $keywords = [];
        if ($tags) {
            foreach ($tags as $tag) {
                $keywords[] = $tag->name;
            }
        }

        // Word Count
        $word_count = str_word_count(strip_tags($post->post_content));

        $article = [
            '@type'            => 'Article',
            '@id'              => get_permalink($post) . '#article',
            'headline'         => get_the_title($post),
            'description'      => $excerpt,
            'url'              => get_permalink($post),
            'datePublished'    => $pub_date,
            'dateModified'     => $mod_date,
            'author'           => [
                '@type' => 'Organization',
                'name'  => 'ViitorX',
                'url'   => $site_url,
            ],
            'publisher'        => ['@id' => $org_id],
            'mainEntityOfPage' => [
                '@type' => 'WebPage',
                '@id'   => get_permalink($post),
            ],
            'keywords'         => $keywords,
            'articleSection'   => $cat_name,
            'wordCount'        => $word_count,
            'inLanguage'       => 'en-IN',
            'isPartOf'         => [
                '@type' => 'Blog',
                'name'  => 'ViitorX Insights',
                'url'   => $site_url . 'insights/',
            ],
        ];

        if ($thumb_url) {
            $article['image'] = [
                '@type'  => 'ImageObject',
                'url'    => $thumb_url,
                'width'  => 1200,
                'height' => 630,
            ];
        }

        $graph[] = $article;
    }

    // -----------------------------------------------------------------------
    // 9. Single Case Study → CreativeWork
    // -----------------------------------------------------------------------
    if (is_single() && get_post_type() === 'case_study' && ! is_front_page()) {
        $post      = get_queried_object();
        $pub_date  = get_the_date('c', $post);
        $mod_date  = get_the_modified_date('c', $post);
        $thumb_url = get_the_post_thumbnail_url($post, 'full');
        $excerpt   = wp_strip_all_tags(get_the_excerpt($post));

        $creative = [
            '@type'            => 'CreativeWork',
            '@id'              => get_permalink($post) . '#casestudy',
            'name'             => get_the_title($post),
            'description'      => $excerpt,
            'url'              => get_permalink($post),
            'datePublished'    => $pub_date,
            'dateModified'     => $mod_date,
            'creator'          => ['@id' => $org_id],
            'publisher'        => ['@id' => $org_id],
            'mainEntityOfPage' => ['@id' => $page_id],
            'genre'            => 'Case Study',
            'inLanguage'       => 'en-IN',
            'isPartOf'         => [
                '@type' => 'CollectionPage',
                'name'  => 'ViitorX Case Studies',
                'url'   => $site_url . 'case-studies/',
            ],
        ];

        if ($thumb_url) {
            $creative['image'] = [
                '@type'  => 'ImageObject',
                'url'    => $thumb_url,
                'width'  => 1200,
                'height' => 630,
            ];
        }

        $graph[] = $creative;
    }

    // -----------------------------------------------------------------------
    // 10. Case Studies Archive → ItemList
    // -----------------------------------------------------------------------
    if (is_post_type_archive('case_study') && ! is_front_page()) {
        $case_studies = get_posts([
            'post_type'      => 'case_study',
            'posts_per_page' => -1,
            'post_status'    => 'publish',
        ]);

        if (! empty($case_studies)) {
            $list_items = [];
            foreach ($case_studies as $i => $cs) {
                $list_items[] = [
                    '@type'    => 'ListItem',
                    'position' => $i + 1,
                    'url'      => get_permalink($cs),
                    'name'     => get_the_title($cs),
                ];
            }

            $graph[] = [
                '@type'           => 'ItemList',
                '@id'             => $curr_url . '#casestudies-list',
                'name'            => 'ViitorX Case Studies',
                'url'             => $curr_url,
                'itemListElement' => $list_items,
            ];
        }
    }

    // -----------------------------------------------------------------------
    // Output
    // -----------------------------------------------------------------------
    $json = wp_json_encode(
        ['@context' => 'https://schema.org', '@graph' => $graph],
        JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
    );

    echo '<script type="application/ld+json" class="viitorx-seo-schema">' . "\n" . $json . "\n" . '</script>' . "\n";
}
add_action('wp_head', 'viitorx_output_schema', 5);


/**
 * Google Tag Manager – Production only (viitorx.com)
 *
 * @package ViitorX
 */

if (! defined('ABSPATH')) exit;

// Single source of truth for the GTM ID
if (! defined('VIITORX_GTM_ID')) {
    define('VIITORX_GTM_ID', 'GTM-TZ2GBPS2');
}

/**
 * Returns true only on the live production domain.
 */
function viitorx_is_production()
{
    return isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] === 'viitorx.com';
}

/**
 * GTM <head> snippet — fires before any other scripts.
 */
function viitorx_gtm_head()
{
    if (! viitorx_is_production()) return;
?>
    <!-- Google Tag Manager -->
    <script>
        (function(w, d, s, l, i) {
            w[l] = w[l] || [];
            w[l].push({
                'gtm.start': new Date().getTime(),
                event: 'gtm.js'
            });
            var f = d.getElementsByTagName(s)[0],
                j = d.createElement(s),
                dl = l != 'dataLayer' ? '&l=' + l : '';
            j.async = true;
            j.src =
                'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
            f.parentNode.insertBefore(j, f);
        })(window, document, 'script', 'dataLayer', '<?php echo esc_js(VIITORX_GTM_ID); ?>');
    </script>
    <!-- End Google Tag Manager -->
<?php
}
add_action('wp_head', 'viitorx_gtm_head', 1);

/**
 * GTM <body> snippet — fires immediately after <body> opens.
 * Requires wp_body_open() to be called in header.php.
 */
function viitorx_gtm_body()
{
    if (! viitorx_is_production()) return;
?>
    <!-- Google Tag Manager (noscript) -->
    <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<?php echo esc_attr(VIITORX_GTM_ID); ?>"
            height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    <!-- End Google Tag Manager (noscript) -->
<?php
}
add_action('wp_body_open', 'viitorx_gtm_body', 1);