<?php
/** 
 * @package     VikRestaurants
 * @subpackage  core
 * @author      E4J s.r.l.
 * @copyright   Copyright (C) 2023 E4J s.r.l. All Rights Reserved.
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
 * @link        https://vikwp.com
 */

namespace E4J\VikRestaurants\Cron\Traits;

// No direct access
defined('ABSPATH') or die('No script kiddies please!');

/**
 * Helper trait used to implement common installation methods.
 * 
 * @since 1.10
 */
trait ReminderInstallation
{ 
    /**
     * @inheritDoc
     * 
     * @see E4J\VikRestaurants\Cron\Installable
     */
    public function install(int $id)
    {
        $db = \JFactory::getDbo();

        // install a new column to track all the notified records
        $db->setQuery("ALTER TABLE `{$this->getDatabaseTable()}` ADD COLUMN `cron_reminder_notified_{$id}` tinyint(1) DEFAULT 0");
        $db->execute();

        // mark all the existing records as notified to prevent unwanted behaviors
        $query = $db->getQuery(true)
            ->update($db->qn($this->getDatabaseTable()))
            ->set($db->qn('cron_reminder_notified_' . $id) . ' = 1');

        $db->setQuery($query);
        $db->execute();
    }

    /**
     * @inheritDoc
     * 
     * @see E4J\VikRestaurants\Cron\Installable
     */
    public function uninstall(int $id)
    {
        $db = \JFactory::getDbo();

        // uninstall the column used to track whether a record was notified
        $db->setQuery("ALTER TABLE `{$this->getDatabaseTable()}` DROP COLUMN `cron_reminder_notified_{$id}`");
        $db->execute();
    }

    /**
     * Sets the given record as notified.
     * 
     * @param   int     $cronId  The unique identifier of the cron job.
     * @param   int     $id      The record primary key.
     * @param   string  $pk      The name of the primary key column (id by default).
     * 
     * @return  void
     */
    protected function setNotified(int $cronId, int $id, string $pk = 'id')
    {
        // store cron notification
        $data = new \stdClass;
        $data->{$pk} = $id;
        $data->{'cron_reminder_notified_' . $cronId} = 1;

        \JFactory::getDbo()->updateObject($this->getDatabaseTable(), $data, $pk);
    }

    /**
     * Extends the provided query to exclude all the records that have been already notified.
     * 
     * @param   int          $cronId  The unique identifier of the cron job.
     * @param   object       $query   The query builder instance.
     * @param   object|null  $db      The database instance. If null, the default one will be used.   
     */
    protected function filterQuery(int $cronId, $query, $db = null)
    {
        if (!$db)
        {
            $db = \JFactory::getDbo();
        }

        // filter the query to exclude all the records that have been already notified
        $query->where($db->qn('cron_reminder_notified_' . $cronId) . ' = 0');
    }

    /**
     * Returns the database table affected by the installation changes.
     * 
     * @return  string  The database table.
     */
    abstract protected function getDatabaseTable();
}
