<commit_before><?php
/**
 * Phergie 
 *
 * PHP version 5
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.
 * It is also available through the world-wide-web at this URL:
 * http://phergie.org/license
 *
 * @category  Phergie 
 * @package   Phergie_Plugin_TerryChay
 * @author    Phergie Development Team <<EMAIL>>
 * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
 * @license   http://phergie.org/license New BSD License
 * @link      http://pear.phergie.org/package/Phergie_Plugin_TerryChay
 */

/**
 * Parses and logs messages that should be relayed to other users the next time
 * the recipient is active on the same channel.
 *
 * @category Phergie
 * @package  Phergie_Plugin_Remind
 * @author   Phergie Development Team <<EMAIL>>
 * @license  http://phergie.org/license New BSD License
 * @link     http://pear.phergie.org/package/Phergie_Plugin_Drink
 * @uses     Phergie_Plugin_Command
 * @uses     Phergie_Plugin_Helper_Time pear.phergie.org
 */
class Phergie_Plugin_Remind extends Phergie_Plugin_Abstract
{
    /**
     * Number of reminders to show in public.
     */
    const PUBLIC_REMINDERS = 3;

    /**
     * PDO resource for a SQLite database containing the reminders.
     *
     * @var resource
     */
    protected $db;

    /**
     * Flag that indicates whether or not to use an in-memory reminder list.
     *
     * @var bool
     */
    protected $keepListInMemory = true;

    /**
     * In-memory store for pending reminders.
     */
    protected $msgStorage = array();

    /**
     * Check for dependencies.
     *
     * @return void
     */
    public function onLoad()
    {
        $this->getPluginHandler()->getPlugin('Command');
        $path = dirname(__FILE__) . '/reminder.db';

        if (isset($this->config['remind.use_memory'])) {
            $this->keepListInMemory = (bool)$this->config['remind.use_memory'];
        }

        try {
            $this->db = new PDO('sqlite:' . $path);
            $this->createTables();
        } catch (PDO_Exception $e) {
            throw new Phergie_Plugin_Exception($e->getMessage());
        }
    }

    /**
     * Intercepts a message and processes any contained recognized commands.
     *
     * @return void
     */
    public function onPrivmsg()
    {
        $source = $this->getEvent()->getSource();
        $nick = $this->getEvent()->getNick();

        $this->deliverReminders($source, $nick);
    }

    /**
     * Handle reminder requests
     *
     * @param string $recipient
     * @param string $message
     * @return void
     * @see handleRemind()
     */
    public function onCommandTell($recipient, $message)
    {
        $this->handleRemind($recipient, $message);
    }

    /**
     * Handle reminder requests
     *
     * @param string $recipient
     * @param string $message
     * @return void
     * @see handleRemind()
     */
    public function onCommandAsk($recipient, $message)
    {
        $this->handleRemind($recipient, $message);
    }

    /**
     * Handle reminder requests
     *
     * @param string $recipient
     * @param string $message
     * @return void
     * @see handleRemind()
     */
    public function onCommandRemind($recipient, $message)
    {
        $this->handleRemind($recipient, $message);
    }

    /**
     * Handles the tell/remind command (stores the message)
     *
     * @param string $recipient name of the recipient
     * @param string $message   message to store
     * @return void
     */
    protected function handleRemind($recipient, $message)
    {
        $source = $this->getEvent()->getSource();
        $nick = $this->getEvent()->getNick();

        if (!$this->getEvent()->isInChannel()) {
            $this->doPrivmsg($source, 'Reminders must be requested in-channel.');
            return;
        }

        $q = $this->db->prepare('
            INSERT INTO remind
                (
                    time,
                    channel,
                    recipient,
                    sender,
                    message
                )
            VALUES
                (
                    :time,
                    :channel,
                    :recipient,
                    :sender,
                    :message
                )
        ');
        try {
            $q->execute(array(
                'time' => date(DATE_RFC822),
                'channel' => $source,
                'recipient' => strtolower($recipient),
                'sender' => strtolower($nick),
                'message' => $message
            ));
        } catch (PDOException $e) { }

        $this->doPrivmsg($source, 'Will tell ' . $recipient . ': ' . $message);

        if ($this->keepListInMemory) {
            $this->msgStorage[$source][$recipient] = $message;
        }
    }

    /**
     * Determines if the user has pending reminders, and if so, delivers them.
     *
     * @param string $channel channel to check
     * @param string $nick    nick to check
     * @return void
     */
    protected function deliverReminders($channel, $nick)
    {
        if ($channel[0] != '#') {
            // private message, not a channel, so don't check
            return;
        }

        // short circuit if there's no message in memory (if allowed)
        if ($this->keepListInMemory
            && !isset($this->msgStorage[$channel][strtolower($nick)])) {
            return;
        }

        // fetch and deliver messages
        $reminders = $this->fetchMessages($channel, $nick);
        if (count($reminders) > self::PUBLIC_REMINDERS) {
            $msgs = array_slice($reminders, 0, self::PUBLIC_REMINDERS);
            $privmsgs = array_slice($reminders, self::PUBLIC_REMINDERS);
        } else {
            $msgs = $reminders;
            $privmsgs = false;
        }

        foreach ($msgs as $msg) {
            $ts = new Phergie_Plugin_Helper_Time($msg['time']);
            $this->doPrivmsg($channel, sprintf('%s: (from %s, %s ago) %s',
                $nick, $msg['sender'], $ts->getCountdown(), $msg['message']));
            $this->deleteMessage($msg['rowid'], $channel, $nick);
        }

        if ($privmsgs) {
            foreach ($privmsgs as $msg) {
                $ts = new Phergie_Plugin_Helper_Time($msg['time']);
                $this->doPrivmsg($nick, sprintf('from %s, %s ago: %s',
                    $msg['sender'], $ts->getCountdown(), $msg['message']));
                $this->deleteMessage($msg['rowid'], $channel, $nick);
            }
            $this->doPrivmsg($channel, sprintf('%s: (%d more messages sent in private.)',
                $nick, count($privmsgs)));
        }
    }

    /**
     * Get pending messages (for a specific channel/recipient)
     *
     * @param string $channel   channel on which to check for pending messages
     * @param string $recipient user for which to check pending messages
     * @return array of records
     */
    protected function fetchMessages($channel = null, $recipient = null)
    {
        if ($channel) {
            $qClause = 'WHERE channel = :channel AND recipient LIKE :recipient';
            $params = compact('channel', 'recipient');
        } else {
            $qClause = '';
            $params = array();
        }
        $q = $this->db->prepare(
            'SELECT rowid, channel, sender, recipient, time, message
            FROM remind ' . $qClause
        );
        $q->execute($params);
        return $q->fetchAll();
    }

    /**
     * Deletes a delivered message
     *
     * @param int    $rowid   ID of the message to delete
     * @param string $channel message's channel
     * @param string $nick    message's recipient
     * @return void
     */
    protected function deleteMessage($rowid, $channel, $nick)
    {
        $q = $this->db->prepare('DELETE FROM remind WHERE rowid = :rowid');
        $q->execute(array('rowid' => $rowid));

        if ($this->keepListInMemory) {
            if (isset($this->msgStorage[$channel][$nick])
                && $this->msgStorage[$channel][$nick] == $rowid) {
                unset($this->msgStorage[$channel][$nick]);
            }
        }
    }

    /**
     * Determines if a table exists
     *
     * @param string $name Table name
     * @return bool
     */
    protected function haveTable($name)
    {
        return (bool) $this->db->query(
            'SELECT COUNT(*) FROM sqlite_master WHERE name = ' . $this->db->quote($name)
            )->fetchColumn();
    }

    /**
     * Creates the database table(s) (if they don't exist)
     *
     * @return void
     */
    protected function createTables()
    {
        if (!$this->haveTable('remind')) {
            $this->db->exec('
                CREATE TABLE
                    remind
                    (
                        time INTEGER,
                        channel TEXT,
                        recipient TEXT,
                        sender TEXT,
                        message TEXT
                    )
            ');
        }
    }

    /**
     * Populates the in-memory cache of pending reminders
     *
     * @return void
     */
    protected function populateMemory()
    {
        if (!$this->keepListInMemory) {
            return;
        }
        foreach ($this->fetchMessages() as $msg) {
            $this->msgStorage[$msg['channel']][$msg['recipient']] = $msg['rowid'];
        }
    }
}
<commit_msg>Fixed Remind plugin so the $rowid is stored in memory and the response alerts the user if the save fails.<commit_after><?php
/**
 * Phergie 
 *
 * PHP version 5
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.
 * It is also available through the world-wide-web at this URL:
 * http://phergie.org/license
 *
 * @category  Phergie 
 * @package   Phergie_Plugin_TerryChay
 * @author    Phergie Development Team <<EMAIL>>
 * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
 * @license   http://phergie.org/license New BSD License
 * @link      http://pear.phergie.org/package/Phergie_Plugin_TerryChay
 */

/**
 * Parses and logs messages that should be relayed to other users the next time
 * the recipient is active on the same channel.
 *
 * @category Phergie
 * @package  Phergie_Plugin_Remind
 * @author   Phergie Development Team <<EMAIL>>
 * @license  http://phergie.org/license New BSD License
 * @link     http://pear.phergie.org/package/Phergie_Plugin_Drink
 * @uses     Phergie_Plugin_Command
 * @uses     Phergie_Plugin_Helper_Time pear.phergie.org
 */
class Phergie_Plugin_Remind extends Phergie_Plugin_Abstract
{
    /**
     * Number of reminders to show in public.
     */
    const PUBLIC_REMINDERS = 3;

    /**
     * PDO resource for a SQLite database containing the reminders.
     *
     * @var resource
     */
    protected $db;

    /**
     * Flag that indicates whether or not to use an in-memory reminder list.
     *
     * @var bool
     */
    protected $keepListInMemory = true;

    /**
     * In-memory store for pending reminders.
     */
    protected $msgStorage = array();

    /**
     * Check for dependencies.
     *
     * @return void
     */
    public function onLoad()
    {
        $this->getPluginHandler()->getPlugin('Command');
        $path = dirname(__FILE__) . '/reminder.db';

        if (isset($this->config['remind.use_memory'])) {
            $this->keepListInMemory = (bool)$this->config['remind.use_memory'];
        }

        try {
            $this->db = new PDO('sqlite:' . $path);
            $this->createTables();
        } catch (PDO_Exception $e) {
            throw new Phergie_Plugin_Exception($e->getMessage());
        }
    }

    /**
     * Intercepts a message and processes any contained recognized commands.
     *
     * @return void
     */
    public function onPrivmsg()
    {
        $source = $this->getEvent()->getSource();
        $nick = $this->getEvent()->getNick();

        $this->deliverReminders($source, $nick);
    }

    /**
     * Handle reminder requests
     *
     * @param string $recipient
     * @param string $message
     * @return void
     * @see handleRemind()
     */
    public function onCommandTell($recipient, $message)
    {
        $this->handleRemind($recipient, $message);
    }

    /**
     * Handle reminder requests
     *
     * @param string $recipient
     * @param string $message
     * @return void
     * @see handleRemind()
     */
    public function onCommandAsk($recipient, $message)
    {
        $this->handleRemind($recipient, $message);
    }

    /**
     * Handle reminder requests
     *
     * @param string $recipient
     * @param string $message
     * @return void
     * @see handleRemind()
     */
    public function onCommandRemind($recipient, $message)
    {
        $this->handleRemind($recipient, $message);
    }

    /**
     * Handles the tell/remind command (stores the message)
     *
     * @param string $recipient name of the recipient
     * @param string $message   message to store
     * @return void
     */
    protected function handleRemind($recipient, $message)
    {
        $source = $this->getEvent()->getSource();
        $nick = $this->getEvent()->getNick();

        if (!$this->getEvent()->isInChannel()) {
            $this->doPrivmsg($source, 'Reminders must be requested in-channel.');
            return;
        }

        $q = $this->db->prepare('
            INSERT INTO remind
                (
                    time,
                    channel,
                    recipient,
                    sender,
                    message
                )
            VALUES
                (
                    :time,
                    :channel,
                    :recipient,
                    :sender,
                    :message
                )
        ');
        try {
            $q->execute(array(
                'time' => date(DATE_RFC822),
                'channel' => $source,
                'recipient' => strtolower($recipient),
                'sender' => strtolower($nick),
                'message' => $message
            ));
        } catch (PDOException $e) { }

        if ($rowid = $this->db->lastInsertId()) {
            $this->doPrivmsg($source, 'ok, ' . $nick . ', message stored');
        } else {
            $this->doPrivmsg($source, $nick . ': bad things happened. Message not saved.');
            return;
        }

        if ($this->keepListInMemory) {
            $this->msgStorage[$source][strtolower($recipient)] = $rowid;
        }
    }

    /**
     * Determines if the user has pending reminders, and if so, delivers them.
     *
     * @param string $channel channel to check
     * @param string $nick    nick to check
     * @return void
     */
    protected function deliverReminders($channel, $nick)
    {
        if ($channel[0] != '#') {
            // private message, not a channel, so don't check
            return;
        }

        // short circuit if there's no message in memory (if allowed)
        if ($this->keepListInMemory
            && !isset($this->msgStorage[$channel][strtolower($nick)])) {
            return;
        }

        // fetch and deliver messages
        $reminders = $this->fetchMessages($channel, $nick);
        if (count($reminders) > self::PUBLIC_REMINDERS) {
            $msgs = array_slice($reminders, 0, self::PUBLIC_REMINDERS);
            $privmsgs = array_slice($reminders, self::PUBLIC_REMINDERS);
        } else {
            $msgs = $reminders;
            $privmsgs = false;
        }

        foreach ($msgs as $msg) {
            $ts = new Phergie_Plugin_Helper_Time($msg['time']);
            $this->doPrivmsg($channel, sprintf('%s: (from %s, %s ago) %s',
                $nick, $msg['sender'], $ts->getCountdown(), $msg['message']));
            $this->deleteMessage($msg['rowid'], $channel, $nick);
        }

        if ($privmsgs) {
            foreach ($privmsgs as $msg) {
                $ts = new Phergie_Plugin_Helper_Time($msg['time']);
                $this->doPrivmsg($nick, sprintf('from %s, %s ago: %s',
                    $msg['sender'], $ts->getCountdown(), $msg['message']));
                $this->deleteMessage($msg['rowid'], $channel, $nick);
            }
            $this->doPrivmsg($channel, sprintf('%s: (%d more messages sent in private.)',
                $nick, count($privmsgs)));
        }
    }

    /**
     * Get pending messages (for a specific channel/recipient)
     *
     * @param string $channel   channel on which to check for pending messages
     * @param string $recipient user for which to check pending messages
     * @return array of records
     */
    protected function fetchMessages($channel = null, $recipient = null)
    {
        if ($channel) {
            $qClause = 'WHERE channel = :channel AND recipient LIKE :recipient';
            $params = compact('channel', 'recipient');
        } else {
            $qClause = '';
            $params = array();
        }
        $q = $this->db->prepare(
            'SELECT rowid, channel, sender, recipient, time, message
            FROM remind ' . $qClause
        );
        $q->execute($params);
        return $q->fetchAll();
    }

    /**
     * Deletes a delivered message
     *
     * @param int    $rowid   ID of the message to delete
     * @param string $channel message's channel
     * @param string $nick    message's recipient
     * @return void
     */
    protected function deleteMessage($rowid, $channel, $nick)
    {
        $q = $this->db->prepare('DELETE FROM remind WHERE rowid = :rowid');
        $q->execute(array('rowid' => $rowid));

        if ($this->keepListInMemory) {
            if (isset($this->msgStorage[$channel][$nick])
                && $this->msgStorage[$channel][$nick] == $rowid) {
                unset($this->msgStorage[$channel][$nick]);
            }
        }
    }

    /**
     * Determines if a table exists
     *
     * @param string $name Table name
     * @return bool
     */
    protected function haveTable($name)
    {
        return (bool) $this->db->query(
            'SELECT COUNT(*) FROM sqlite_master WHERE name = ' . $this->db->quote($name)
            )->fetchColumn();
    }

    /**
     * Creates the database table(s) (if they don't exist)
     *
     * @return void
     */
    protected function createTables()
    {
        if (!$this->haveTable('remind')) {
            $this->db->exec('
                CREATE TABLE
                    remind
                    (
                        time INTEGER,
                        channel TEXT,
                        recipient TEXT,
                        sender TEXT,
                        message TEXT
                    )
            ');
        }
    }

    /**
     * Populates the in-memory cache of pending reminders
     *
     * @return void
     */
    protected function populateMemory()
    {
        if (!$this->keepListInMemory) {
            return;
        }
        foreach ($this->fetchMessages() as $msg) {
            $this->msgStorage[$msg['channel']][$msg['recipient']] = $msg['rowid'];
        }
    }
}

{'fraction_non_alphanumeric': 0.13020155200249986, 'fraction_numerical': 0.0015624186240299983, 'mean_word_length': 1.7885564914318908, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 150, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4479090', 'n_tokens_mistral': 5582, 'n_tokens_neox': 5344, 'n_words': 1350}