1. 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.

Discussion in 'XenForo Development Discussions' started by silence, Jul 4, 2013.

  1. silence

    silence Well-Known Member

    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!
     
  2. tyteen4a03

    tyteen4a03 Well-Known Member

    You can't set existing data multiple times. You give the id of the record you wish to modify.
     
    silence likes this.
  3. silence

    silence Well-Known Member

    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:
     
  4. tyteen4a03

    tyteen4a03 Well-Known Member

    $dw->set(callback), $dw->set(otherthings)?
     
    silence likes this.
  5. silence

    silence Well-Known Member

    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!)
     
  6. tyteen4a03

    tyteen4a03 Well-Known Member

    Can you paste your DataWriter fields?
     
    silence likes this.
  7. silence

    silence Well-Known Member

    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();
        }
    }
     
  8. tyteen4a03

    tyteen4a03 Well-Known Member

    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 likes this.
  9. silence

    silence Well-Known Member

    Wow that was silly... It seemed to fix it.
     

Share This Page