• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

The existing data required by the data writer could not be found.

silence

Well-known member
#1
PHP:
        // Current goal? Just add the donation and return
        if ($donation['donation_date'] >= $goal['start_date'] AND (empty($goal['end_date']) OR $donation['donation_date'] <= $goal['end_date']))
        {
            $dw = XenForo_DataWriter::create('xf_DonationManager_DataWriter_Goal');
            // THIS RHODO!!!
            $dw->setExistingData($goal['goal_id']);
            $dw->setExistingData($goal['callback_class']);
            $dw->setExistingData($goal['callback_method']);
            $dw->set('donated', $dw->get('donated') + $donation['amount']);
            $dw->save();

            return;
        }
It's telling me that for the callback_class and for the callback_method. I print_r'd $goal and it does contain that key, the datawriter has those 2 keys as well (print_r'd it to be sure!) and I have no idea what else would be causing this.

This guy: http://xenforo.com/community/thread...-by-the-data-writer-could-not-be-found.16847/
Is having the exact same issue I'm having, so I'd thought I'd throw it in for clarification!
 

silence

Well-known member
#3
You can't set existing data multiple times. You give the id of the record you wish to modify.
What can be a potential workaround for this then? Could I setexistingdata to the entire array or make an array with the stuff I want and set it to that?
EDIT
I did that, but it doesn't seem to work. It acts like callback_class/method don't exist D:
 

tyteen4a03

Well-known member
#4
What can be a potential workaround for this then? Could I setexistingdata to the entire array or make an array with the stuff I want and set it to that?
EDIT
I did that, but it doesn't seem to work. It acts like callback_class/method don't exist D:
$dw->set(callback), $dw->set(otherthings)?
 

silence

Well-known member
#5
No, but if I try to set existing data with the callback, it doesn't work (btw, when I say, it doesn't work, I traced this function down that was overwriting my custom tables.)
I'm trying this:

PHP:
            $dw = XenForo_DataWriter::create('xf_DonationManager_DataWriter_Goal');
            // THIS RHODO!!!
            $dw->setExistingData($goal['goal_id']);
            $existing = array(
                        'donated' => $dw->get('donated') + $donation['amount'],
                        'callback_class' => $goal['callback_class'],
                        'callback_method' => $goal['callback_method']
            );
            //$dw->set('donated', $dw->get('donated') + $donation['amount']);
            $dw->bulkSet($existing);
            $dw->save();

            return;
But that doesn't work either. I've spent a few hours tracing the function down to whatever was erasing my callback row, and after much commenting it lead to this. I'm just perplexed as to why it would even be doing that to begin with (the array is the same as the table, yet it's overwriting my callbacks after executing!)
 

tyteen4a03

Well-known member
#6
No, but if I try to set existing data with the callback, it doesn't work (btw, when I say, it doesn't work, I traced this function down that was overwriting my custom tables.)
I'm trying this:

PHP:
            $dw = XenForo_DataWriter::create('xf_DonationManager_DataWriter_Goal');
            // THIS RHODO!!!
            $dw->setExistingData($goal['goal_id']);
            $existing = array(
                        'donated' => $dw->get('donated') + $donation['amount'],
                        'callback_class' => $goal['callback_class'],
                        'callback_method' => $goal['callback_method']
            );
            //$dw->set('donated', $dw->get('donated') + $donation['amount']);
            $dw->bulkSet($existing);
            $dw->save();

            return;
But that doesn't work either. I've spent a few hours tracing the function down to whatever was erasing my callback row, and after much commenting it lead to this. I'm just perplexed as to why it would even be doing that to begin with (the array is the same as the table, yet it's overwriting my callbacks after executing!)
Can you paste your DataWriter fields?
 

silence

Well-known member
#7
Can you paste your DataWriter fields?
Here is the original:
PHP:
<?php

class Xf_DonationManager_DataWriter_Goal extends XenForo_DataWriter
{
    protected function _getFields()
    {
        return array(
            'xf_goal' => array(
                'goal_id' => array('type' => self::TYPE_UINT, 'autoIncrement' => true),
                'title' => array('type' => self::TYPE_STRING, 'required' => true),
                'description' => array('type' => self::TYPE_STRING, 'required' => true),
                'donated' => array('type' => self::TYPE_FLOAT, 'default' => 0),
                'goal' => array('type' => self::TYPE_FLOAT, 'required' => true, 'verification' => array('$this', '_verifyGoal')),
                'goal_reached' => array('type' => self::TYPE_STRING, 'default' => '', 'allowedValues' => array('', 'restart', 'archive')),
                'start_date' => array('type' => self::TYPE_UINT, 'default' => XenForo_Application::$time),
                'end_date' => array('type' => self::TYPE_UINT, 'default' => 0),
                'recurring' => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                'archived' => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                'feature' => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                'display_order' => array('type' => self::TYPE_UINT, 'default' => 0)
            )
        );
    }
    protected function _getExistingData($data)
    {
        if (!$id = $this->_getExistingPrimaryKey($data))
        {
            return false;
        }
        return array('xf_goal' => $this->_getGoalModel()->getGoalById($id));
    }
    protected function _getUpdateCondition($tableName)
    {
        return 'goal_id = ' . $this->_db->quote($this->getExisting('goal_id'));
    }
    public function addDonation($amount, $donationDate)
    {
        if ($donationDate >= $this->get('start_date') AND $donationDate <= $this->get('end_date'))
        {
            $this->set('donated', max(0, $this->get('donated') + $amount));
            return true;
        }
        // TODO: move this query to a model?
        $logs = $this->_db->fetchAll('
            SELECT *
            FROM xf_goal_log
            WHERE goal_id = ?
        ', $this->get('goal_id'));
        $validLog = false;
        foreach ($logs AS $log)
        {
            if ($donationDate >= $log['start_date'] AND $donationDate <= $log['end_date'])
            {
                $validLog = $log;
                break;
            }
        }
        if ($validLog)
        {
            $this->_db->query('
                UPDATE xf_goal_log
                SET donated = ?
                WHERE goal_log_id = ?
            ', array(max(0, $log['donated'] + $amount), $log['goal_log_id']));
            return false;
        }
        $this->error('specified_goal_wasnt_active_at_the_set_time');
        return false;
    }
    protected function _postSave()
    {
        if ($this->get('goal_reached') != '' AND $this->get('donated') >= $this->get('goal'))
        {
            if ($this->get('goal_reached') == 'restart')
            {
                $this->_getGoalModel()->logAndRestartGoal($this->get('goal_id'));
            }
            else if ($this->get('goal_reached') == 'archive' AND !$this->get('archived'))
            {
                $this->_getGoalModel()->archiveGoal($this->get('goal_id'));
            }
        }
    }
    protected function _verifyGoal($goal)
    {
        $goal = (int) $goal;
        if (!$goal)
        {
            $this->error('goal_can_not_be_zero', 'goal');
            return false;
        }
        return true;
    }
    protected function _getGoalModel()
    {
        return $this->getModelFromCache('Xf_DonationManager_Model_Goal');
    }
}
Here is my extension:
PHP:
<?php

class XenoGamers_DataWriter_Goal extends Xf_DonationManager_DataWriter_Goal
{
    protected function _getFields()
    {
        return array(
            'xf_goal' => array(
                'goal_id' => array('type' => self::TYPE_UINT, 'autoIncrement' => true),
                'title' => array('type' => self::TYPE_STRING, 'required' => true),
                'description' => array('type' => self::TYPE_STRING, 'required' => true),
                'donated' => array('type' => self::TYPE_FLOAT, 'default' => 0),
                'goal' => array('type' => self::TYPE_FLOAT, 'required' => true, 'verification' => array('$this', '_verifyGoal')),
                'goal_reached' => array('type' => self::TYPE_STRING, 'default' => '', 'allowedValues' => array('', 'restart', 'archive')),
                'start_date' => array('type' => self::TYPE_UINT, 'default' => XenForo_Application::$time),
                'end_date' => array('type' => self::TYPE_UINT, 'default' => 0),
                'recurring' => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                'archived' => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                'feature' => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                'display_order' => array('type' => self::TYPE_UINT, 'default' => 0),
                'callback_class' => array('type' => self::TYPE_STRING, 'default' => 0, 'maxLength' => 250, 'requiredError' => 'please_enter_valid_callback_class'),
                'callback_method' => array('type' => self::TYPE_STRING, 'default' => 0, 'maxLength' => 250, 'requiredError' => 'please_enter_valid_callback_method')
            )
        );
    }
    protected function _verifyCallback($class, $method)
    {
        if (!XenForo_Application::autoload($class) || !method_exists($class, $method))
        {
            $this->error(new XenForo_Phrase('please_enter_valid_callback_method'), 'callback_method');
        }
    }
    protected function _preSave()
    {
        $_input = new XenForo_Input($_REQUEST);
        $extraData = $_input->filter(array(
            'callback_class' => XenForo_Input::STRING,
            'callback_method' => XenForo_Input::STRING,
        ));
        $this->bulkSet($extraData);
        if($this->get('callback_class'))
        {
            $this->_verifyCallback($this->get('callback_class'), $this->get('callback_method'));
        }
        return parent::_preSave();
    }
}
 

tyteen4a03

Well-known member
#8
You need to proxy the extension, otherwise your changes and methods won't go in.

class XenoGamers_DataWriter_Goal extends XFCP_XenoGamers_DataWriter_Goal, then add a listener.

(Also, can I point out that your DW init code is $dw = XenForo_DataWriter::create('xf_DonationManager_DataWriter_Goal'))
 

silence

Well-known member
#9
You need to proxy the extension, otherwise your changes and methods won't go in.

class XenoGamers_DataWriter_Goal extends XFCP_XenoGamers_DataWriter_Goal, then add a listener.

(Also, can I point out that your DW init code is $dw = XenForo_DataWriter::create('xf_DonationManager_DataWriter_Goal'))
Wow that was silly... It seemed to fix it.