Your IP : 216.73.216.240


Current Path : /home/juvelize/www/plugins/system/vmogmetatag/
Upload File :
Current File : /home/juvelize/www/plugins/system/vmogmetatag/vmogmetatag.php

<?php

/**
 * @package    VM OG Meta Tag - System Plugin
 * @copyright  Copyright (C) 2012-2024 VirtuePlanet Services LLP. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE.txt
 * @author     Abhishek Das <info@virtueplanet.com>
 * @link       https://www.virtueplanet.com
 *
 * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
 */

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * VM OG Meta Tag system plugin class
 *
 * Comaptible to Joomla! 2.5, Joomla! 3 and Joomla! 4
 *
 * @since 4.0
 */
class PlgSystemVmogmetatag extends JPlugin
{
    /**
     * @var  \Joomla\CMS\Application\CMSApplication
     */
    protected $app;

    /**
     * @var  \PlgSystemVmogmetatagHelper
     */
    private $helper;

    /**
     * @var  string
     */
    private $OGType;

    /**
     * @var  array
     */
    private $additionalImages = array();

    /**
     * Constructor.
     *
     * @param   object  &$subject  The object to observe
     * @param   array   $config    An optional associative array of configuration settings.
     */
    public function __construct(&$subject, $config)
    {
        parent::__construct($subject, $config);

        JLoader::register('PlgSystemVmogmetatagHelper', __DIR__ . '/helper.php');

        $this->app    = empty($this->app) ? JFactory::getApplication() : $this->app;
        $this->helper = PlgSystemVmogmetatagHelper::getInstance($this->app, $this->params);

        // For Joomla! 4
        if (version_compare(JVERSION, '4.0.0', 'ge')) {
            $this->registerLegacyListener('plgVmOnProductDisplayPayment');
        }
    }

    /**
     * VirtueMart Product Page Payment Display events
     *
     * @param  $product                 (object)  Product Object
     * @param  $productDisplayPayments  (array)   Payment display HTML array
     *
     * @return void
     */
    public function plgVmOnProductDisplayPayment($product, &$productDisplayPayments)
    {
        if ($this->helper->isAdmin() || !$this->helper->isHTML() || $this->helper->view !== 'productdetails' || $this->helper->isExcluded()) {
            return;
        }

        $this->helper->setProduct($product);
    }

    /**
     * Before content display.
     *
     * @return  void
     */
    public function onContentBeforeDisplay($context, &$content, &$params)
    {
        if ($this->helper->isAdmin() || !$this->helper->isHTML()) {
            return;
        }

        if ($this->helper->isExcluded() || !in_array($context, array('com_content.category', 'com_content.article'))) {
            return;
        }

        $this->helper->setContent($content, $context);
        $this->helper->setContentParams($params, $context);
    }

    /**
     * Triggered on after dispatch
     *
     * @return void
     */
    public function onAfterDispatch()
    {
        if ($this->helper->isAdmin() || !$this->helper->isHTML() || $this->helper->isExcluded()) {
            return;
        }

        // If VirtueMart component.
        if ($this->helper->option === 'com_virtuemart') {
            JLoader::register('VmConfig', JPATH_ADMINISTRATOR . '/components/com_virtuemart/helpers/config.php');

            VmConfig::loadConfig();
            VmConfig::loadJLang('com_virtuemart', true);

            if (version_compare(vmVersion::$RELEASE, '3.8.0', 'ge')) {
                include_once __DIR__ . '/vmincludes.php';
            }

            // If product details view.
            if ($this->helper->view === 'productdetails' && ($product = $this->helper->getProduct())) {
                /** @var CurrencyDisplay $currency */
                $currency = CurrencyDisplay::getInstance();

                $this->helper->setTag('og:type', 'product');

                if (!empty($product->canonical)) {
                    $canonicalUrl = JUri::getInstance()->toString(array('scheme', 'host', 'port')) . JRoute::_($product->canonical);

                    $this->helper->setTag('og:url', $canonicalUrl);
                }

                $this->helper->setFallbackTitle($product->product_name);

                if (!empty($product->product_s_desc)) {
                    $this->helper->setFallbackDescription($product->product_s_desc);
                } else {
                    $this->helper->setFallbackDescription($product->product_desc);
                }

                if (!empty($product->category_name)) {
                    $this->helper->setTag('product:category', $this->helper->escape($product->category_name));
                }

                if (!empty($product->manufacturers) && count($product->manufacturers) == 1 && isset($product->manufacturers[0])) {
                    $this->helper->setTag('product:brand', $this->helper->escape($product->manufacturers[0]->mf_name));
                } elseif (!empty($product->mf_name)) {
                    $this->helper->setTag('product:brand', $this->helper->escape($product->mf_name));
                }

                if (!empty($product->prices['salesPrice'])) {
                    if (method_exists($currency, 'roundForDisplay')) {
                        $this->helper->setTag('product:price:amount', $currency->roundForDisplay($product->prices['salesPrice']));
                    } else {
                        $this->helper->setTag('product:price:amount', $product->prices['salesPrice']);
                    }

                    $this->helper->setTag('product:price:currency', $currency->_vendorCurrency_code_3);

                    if (method_exists($currency, 'roundForDisplay')) {
                        $this->helper->setTag('product:sale_price:amount', $currency->roundForDisplay($product->prices['salesPrice']));
                    } else {
                        $this->helper->setTag('product:sale_price:amount', $product->prices['salesPrice']);
                    }

                    $this->helper->setTag('product:sale_price:currency', $currency->_vendorCurrency_code_3);
                }

                if (!empty($product->product_sku)) {
                    $this->helper->setTag('product:retailer_part_no', $product->product_sku);
                    $this->helper->setTag('product:item_group_id', $product->product_sku);
                }

                $this->helper->setTag('product:retailer_item_id', $product->virtuemart_product_id);

                $stockhandle          = VmConfig::get('stockhandle', 'none');
                $productAvailableDate = substr((string) $product->product_available_date, 0, 10);
                $currentDate          = date('Y-m-d');

                if ($productAvailableDate != '0000-00-00' && $currentDate < $productAvailableDate) {
                    $this->helper->setTag('product:availability', 'pending');
                } else {
                    if ($stockhandle === 'none') {
                        $this->helper->setTag('product:availability', 'instock');
                    } elseif ($stockhandle == 'disableit_children' && $product->product_parent_id == 0) {
                        $productModel = VmModel::getModel('product');
                        $children     = $productModel->getProductChilds($product->virtuemart_product_id);
                        $finalStock   = $product->product_in_stock - $product->product_ordered;

                        foreach ($children as $child) {
                            $finalStock += $child->product_in_stock - $child->product_ordered;
                        }

                        if ($finalStock > 0) {
                            $this->helper->setTag('product:availability', 'instock');
                        } else {
                            $this->helper->setTag('product:availability', 'oos');
                        }
                    } else {
                        if ($product->product_in_stock - $product->product_ordered < 1) {
                            $this->helper->setTag('product:availability', 'oos');
                        } else {
                            $this->helper->setTag('product:availability', 'instock');
                        }
                    }
                }

                $productWeight = floatval($product->product_weight);

                if (!empty($productWeight)) {
                    $this->helper->setTag('product:weight:value', $productWeight);
                    $this->helper->setTag('product:weight:units', $product->product_weight_uom);
                }

                $imageList = $this->helper->getVirtueMartImageList($product);

                foreach ($imageList as $key => $imageData) {
                    if ($imageData && !empty($imageData->url)) {
                        if ($key === 0) {
                            $this->helper->setTag('og:image', $imageData->url);
                            $this->helper->setTag('og:image:width', $imageData->width);
                            $this->helper->setTag('og:image:height', $imageData->height);
                            $this->helper->setTag('og:image:type', $imageData->type);
                        } else {
                            $this->additionalImages[] = $imageData;
                        }
                    }
                }
            } elseif ($this->helper->view === 'category' && !$this->helper->isHomePage()) { // If category view.
                $categoryId     = $this->app->input->getInt('virtuemart_category_id', 0);
                $manufacturerId = $this->app->input->getInt('virtuemart_manufacturer_id', 0);

                if ($categoryId > 0) {
                    $categoryModel = VmModel::getModel('category');
                    $category      = $categoryModel->getCategory($categoryId);

                    $categoryModel->addImages($category, 3);

                    if ($category->virtuemart_category_id > 0) {
                        $this->helper->setTag('og:type', 'product.group');

                        $this->helper->setFallbackTitle($category->category_name);
                        $this->helper->setFallbackDescription($category->category_description);

                        $imageList = $this->helper->getVirtueMartImageList($category);

                        foreach ($imageList as $key => $imageData) {
                            if ($imageData && !empty($imageData->url)) {
                                if ($key === 0) {
                                    $this->helper->setTag('og:image', $imageData->url);
                                    $this->helper->setTag('og:image:width', $imageData->width);
                                    $this->helper->setTag('og:image:height', $imageData->height);
                                    $this->helper->setTag('og:image:type', $imageData->type);
                                } else {
                                    $this->additionalImages[] = $imageData;
                                }
                            }
                        }
                    }
                } elseif ($manufacturerId > 0) {
                    $manufacturerModel = VmModel::getModel('manufacturer');
                    $manufacturer      = $manufacturerModel->getManufacturer($manufacturerId);

                    $manufacturerModel->addImages($manufacturer, 3);

                    if ($manufacturer->virtuemart_manufacturer_id > 0) {
                        $this->helper->setTag('og:type', 'product.group');

                        $this->helper->setFallbackTitle($manufacturer->mf_name);
                        $this->helper->setFallbackDescription($manufacturer->mf_desc);

                        $imageList = $this->helper->getVirtueMartImageList($manufacturer);

                        foreach ($imageList as $key => $imageData) {
                            if ($imageData && !empty($imageData->url)) {
                                if ($key === 0) {
                                    $this->helper->setTag('og:image', $imageData->url);
                                    $this->helper->setTag('og:image:width', $imageData->width);
                                    $this->helper->setTag('og:image:height', $imageData->height);
                                    $this->helper->setTag('og:image:type', $imageData->type);
                                } else {
                                    $this->additionalImages[] = $imageData;
                                }
                            }
                        }
                    }
                }
            }
        } elseif ($this->helper->option === 'com_content' && !$this->helper->isHomePage()) { // If Joomla article component.
            if ($this->helper->view === 'article') {
                $article = $this->helper->getContent('com_content.article');
                $params  = $this->helper->getContentParams('com_content.article');

                if ($article) {
                    $this->helper->setTag('og:type', 'article');

                    $this->helper->setFallbackTitle($article->title);
                    $this->helper->setFallbackDescription($article->introtext);

                    if ($params->get('show_author', 1)) {
                        $this->helper->setTag('article:author', $article->author);
                    }

                    if ($params->get('show_category', 1)) {
                        $this->helper->setTag('article:section', $article->category_title);
                    }

                    if ($params->get('show_publish_date', 1)) {
                        $this->helper->setTag('article:published_time', $article->publish_up);
                    }

                    if ($params->get('show_modify_date', 1)) {
                        $this->helper->setTag('article:modified_time', $article->modified);
                    }

                    if ($params->get('fb_publisher_id', '')) {
                        $this->helper->setTag('article:publisher', $params->get('fb_publisher_id', ''));
                    }

                    if (!empty($article->images) && is_string($article->images)) {
                        $images = new JRegistry();

                        $images->loadString($article->images);

                        $imageData = null;
                        $imageAlt  = null;

                        if ($images->get('image_fulltext', '')) {
                            $imageData = $this->helper->getImageData($images->get('image_fulltext'));

                            if ($images->get('image_fulltext_alt')) {
                                $imageAlt = $images->get('image_fulltext_alt');
                            }
                        } elseif ($images->get('image_intro', '')) {
                            $imageData = $this->helper->getImageData($images->get('image_intro'));

                            if ($images->get('image_intro_alt')) {
                                $imageAlt = $images->get('image_intro_alt');
                            }
                        }

                        if ($imageData && !empty($imageData->url)) {
                            $this->helper->setTag('og:image', $imageData->url);
                            $this->helper->setTag('og:image:width', $imageData->width);
                            $this->helper->setTag('og:image:height', $imageData->height);
                            $this->helper->setTag('og:image:type', $imageData->type);

                            if ($imageAlt) {
                                $this->helper->setTag('og:image:alt', $this->helper->escape($imageAlt));
                            }
                        }
                    }
                }
            } elseif ($this->helper->view === 'category' && $this->helper->layout === 'blog') {
                $this->helper->setTag('og:type', 'blog');
            }
        } elseif ($this->helper->option == 'com_contact' && $this->helper->view == 'contact' && !$this->helper->isHomePage()) {
            $this->helper->setTag('og:type', 'business.business');
        }
    }

    private function addBusinessTags(&$tags)
    {
        $items = $this->params->toArray();

        foreach ($items as $name => $value) {
            if (!empty($value) && (strpos($name, 'business:') === 0 || strpos($name, 'place:') === 0)) {
                $tags->set($name, $this->helper->escape($value));
            }
        }
    }

    /**
     * Before head compile event
     *
     * @return void
     */
    public function onBeforeCompileHead()
    {
        if ($this->helper->isAdmin() || !$this->helper->isHTML() || $this->helper->isExcluded()) {
            return;
        }

        // Initialise tag registry object.
        $tags = new JRegistry();

        // Add default tags.
        $tags->set('og:type', $this->params->get('og:type'));
        $tags->set('og:title', $this->helper->getTitle());
        $tags->set('og:url', JUri::current());
        $tags->set('og:site_name', $this->params->get('og:site_name', $this->app->getCfg('sitename')));
        $tags->set('og:description', $this->helper->getDescription());

        if (($defaultImage = $this->params->get('og:image'))) {
            $defaultImageData = $this->helper->getImageData($defaultImage);

            if ($defaultImageData && !empty($defaultImageData->url)) {
                $tags->set('og:image', $defaultImageData->url);
                $tags->set('og:image:width', $defaultImageData->width);
                $tags->set('og:image:height', $defaultImageData->height);
                $tags->set('og:image:type', $defaultImageData->type);
            }
        }

        // Get the special tags.
        $specialTags = $this->helper->getTags();

        // Merge special tags with default tags.
        $tags->merge($specialTags);

        // If business or contact page, add all business special tags set in the plugin options.
        if ($tags->get('og:type') === 'business.business') {
            $this->addBusinessTags($tags);
        }

        if ($this->params->get('fb:app_id')) {
            $tags->set('fb:app_id', $this->params->get('fb:app_id'));
        }

        $metaTags = array();
        /** @var \Joomla\CMS\Document\HtmlDocument $document */
        $document = JFactory::getDocument();
        $tab      = $document->_getTab();
        $lineEnd  = $document->_getLineEnd();
        $tagEnd   = method_exists($document, 'isHtml5') && $document->isHtml5() ? '>' : ' />';

        foreach ($tags->toArray() as $name => $value) {
            if (!empty($value)) {
                $metaTags[] = $tab . '<meta property="' . $name . '" content="' . $value . '"' . $tagEnd;
            }
        }

        if (!empty($this->additionalImages)) {
            foreach ($this->additionalImages as $image) {
                $metaTags[] = $tab . '<meta property="og:image" content="' . $image->url . '"' . $tagEnd;

                if (!empty($image->width)) {
                    $metaTags[] = $tab . '<meta property="og:image:width" content="' . $image->width . '"' . $tagEnd;
                }

                if (!empty($image->height)) {
                    $metaTags[] = $tab . '<meta property="og:image:height" content="' . $image->height . '"' . $tagEnd;
                }

                if (!empty($image->type)) {
                    $metaTags[] = $tab . '<meta property="og:image:type" content="' . $image->type . '"' . $tagEnd;
                }
            }
        }

        $metaTagsString = implode($lineEnd, $metaTags);

        // Finally add the meta tags.
        $document->addCustomTag($metaTagsString);

        // Remember to type.
        $this->OGType = $tags->get('og:type');
    }

    /**
     * After render event
     *
     * @return void
     */
    public function onAfterRender()
    {
        if ($this->helper->isAdmin() || !$this->helper->isHTML() || $this->helper->isExcluded()) {
            return;
        }

        if (!$this->params->get('add_og_prefix', 1) || !$this->OGType) {
            return;
        }

        $type = $this->OGType;

        if (strpos($this->OGType, '.') !== false) {
            $parts = explode('.', $this->OGType);
            $type  = $parts[0];
        }

        $ogPreifx = 'og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# ' . $type . ': http://ogp.me/ns/' . $type . '#';
        $buffer   = $this->app->getBody();

        if (strpos($buffer, '<head>') !== false) {
            $buffer = preg_replace('/<head>/', '<head prefix="' . $ogPreifx . '">', $buffer, 1);
        } elseif (strpos($buffer, '<head ') !== false) {
            $buffer = preg_replace('/<head /', '<head prefix="' . $ogPreifx . '" ', $buffer, 1);
        }

        $this->app->setBody($buffer);
    }
}