<?php

/**
 * @package         Google Structured Data
 * @version         6.2.1 Free
 *
 * @author          Tassos Marinos <info@tassos.gr>
 * @link            http://www.tassos.gr
 * @copyright       Copyright © 2022 Tassos Marinos All Rights Reserved
 * @license         GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
 */

namespace GSD\Schemas\Schemas;

// No direct access
defined('_JEXEC') or die;

use GSD\Helper;
use Joomla\Registry\Registry;
use Joomla\CMS\URI\URI;

class Custom_Code extends \GSD\Schemas\Base
{
    /**
     * Return all the schema properties
     *
     * @return void
     */
    protected function initProps()
    {
        parent::initProps();

        // Since v5.3.1, the SchemaCleaner supports removing structured data also from the <head> that does not have the data-type="gsd" property.
        // In order to prevent the user defined custom code from being removed, we need to add the data-type property to every custom JSON+LD script.  
        $safe_custom_code = str_replace('<script type="application', '<script data-type="gsd" type="application', $this->data->get('custom_code', ''));
        $this->data->set('custom_code', $safe_custom_code);
    }

    /**
     * Since in the Custom Code we do not have a real array but a string, the result is not passed into the cleanProps() method, thus, we may end up
     * with unescaped characters and HTML that can break the structured data. With this override, we filter all payload props before they get replaced in the snippet.
     * 
     * Consider this as a temporary workaround. In addition, it's worth consideration to filter payload props on all Schemas by default, so we don't need to do so later.
     *
     * @param   object  $payload
     * 
     * @return  void
     */
    public function onPayloadPrepare(&$payload)
    {
        $props = $payload->toArray();

        array_walk_recursive($props, function(&$prop)
        {
            if (!is_null($prop)) // Make PHP 8.1 happy.
            {
                $this->cleanProp($prop);
            }
        });

        // Return ISO 8601 dates
        $props['created'] = isset($props['created']) ? Helper::date($props['created'], true) : null;
        $props['modified'] = isset($props['modified']) ? Helper::date($props['modified'], true) : null;
        $props['publish_up'] = isset($props['publish_up']) ? Helper::date($props['publish_up'], true) : null;
        $props['publish_down'] = isset($props['publish_down']) ? Helper::date($props['publish_down'], true) : null;
        $props['startdate'] = isset($props['startdate']) ? Helper::date($props['startdate'], true) : null;
        $props['enddate'] = isset($props['enddate']) ? Helper::date($props['enddate'], true) : null;
        $props['offerstartdate'] = isset($props['offerstartdate']) ? Helper::date($props['offerstartdate'], true) : null;

        // Fix images
        $props['image'] = isset($props['image']) ? Uri::root() . explode('#', $props['image'], 2)[0] : null;
        $props['image_intro'] = isset($props['image_intro']) ? Uri::root() . explode('#', $props['image_intro'], 2)[0] : null;
        $props['image_full'] = isset($props['image_full']) ? Uri::root() . explode('#', $props['image_full'], 2)[0] : null;
        
        $payload = new Registry($props);
    }

    /**
     * Do not clean custom script
     *
     * @return void
     */
    protected function cleanProps()
    {
    }
}