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

Cron/deferred problem: Cannot modify header information - headers already sent

Discussion in 'XenForo Development Discussions' started by Teapot, Nov 27, 2013.

  1. Teapot

    Teapot Well-Known Member

    I'm having some trouble with a cron job that is working, but produces an error in the error log every time it runs. For the life of me, I can't work out why:

    Code:
    ErrorException: Cannot modify header information - headers already sent by (output started at /home/pcharms/public_html/library/CreativeCorner/Model/Works.php:1) - deferred.php:21
    
    array(3) {
      ["url"] => string(34) "http://pokecharms.com/deferred.php"
      ["_GET"] => array(0) {
      }
      ["_POST"] => array(4) {
        ["_xfRequestUri"] => string(106) "/admin.php?cron/CCorner_UpdateViews/run&_xfToken=1%2C1385546511%2Cb5031f692efcb2484c1938be253b33308cbe40f1"
        ["_xfNoRedirect"] => string(1) "1"
        ["_xfToken"] => string(8) "********"
        ["_xfResponseType"] => string(4) "json"
      }
    }
    The code that's run by this cron is this:

    CreativeCorner_CronEntry_Views
    Code:
    <?php
    class CreativeCorner_CronEntry_Views
    {
        public static function runViewUpdate()
        {
            XenForo_Model::create('CreativeCorner_Model_Works')->updateWorkViews();
        }
    }
    CreativeCorner_Model_Works
    Code:
    <?php
    class CreativeCorner_Model_Works extends XenForo_Model
    {
    
    // [unrelated/unexecuted code removed...]
    
        public function updateWorkViews()
        {
            $db = $this->_getDb();
    
            $db->query('
                UPDATE cc_work
                INNER JOIN (
                    SELECT work_id, COUNT(*) AS total
                    FROM cc_work_view
                    GROUP BY work_id
                ) AS new_count ON (new_count.work_id = cc_work.work_id)
                SET cc_work.view_count = cc_work.view_count + new_count.total
            ');
    
            $db->query('TRUNCATE TABLE cc_work_view');
        }
    
    // [...]
    
    }
    Anyone have any ideas as to what could be causing this issue?

    As always, thanks very much for your time. :)
     
  2. tyteen4a03

    tyteen4a03 Well-Known Member

    In this case, it looks like the constructor is sending out the header.

    Full code to the model please?
     
  3. Teapot

    Teapot Well-Known Member

    I actually fixed it in the end - it's a massive PHP quirk. There was some whitespace before the opening <?php in the model, which PHP was trying to output before setting the headers in deferred.php - because it was outputting whitespace, it was outputting headers, hence the error. Anyway, I removed the offending whitespace and the problem went away.

    Thanks for your help @tyteen4a03. :)
     
  4. shawn

    shawn Well-Known Member

    What else could be causing this? I have the same problem. Couple of cleanup scripts based loosely on this tutorial to move old/deleted/etc threads. They worked fine under 1.1x, but now under 1.2, the header lines in deferred.php (26-29ish?) trip the cannot-modify-header php error and they fault out. PITA to troubleshoot, too, since manually running the scripts doesn't pipe them through deferred.php.
     
  5. tyteen4a03

    tyteen4a03 Well-Known Member

    Code please?
     
  6. shawn

    shawn Well-Known Member

    PHP:
    <?php
    class RSC_MoveThreadCron_CronEntry
    {
        public static function 
    runMoveOldThreads()
        {
            
    $options XenForo_Application::get('options');

            
    $threadModel XenForo_Model::create('XenForo_Model_Thread');
            
    $nodes XenForo_Model::create('XenForo_Model_Node')->getViewableNodeList();
           
            
    $sourceNodes = array();
           
            if (empty(
    $options->xefModeratedForums[0]))
            {
                return;
            }
            else
            {
                
    $sourceNodes $options->xefModeratedForums;
            }

            
    $fetchOptions = array(
                
    'join' => XenForo_Model_Thread::FETCH_FORUM XenForo_Model_Thread::FETCH_USER,
                
    'order' => 'last_post_date',
                
    'orderDirection' => 'desc',
            );

            
    $conditions = array(
                    
    'last_post_date' => array('<'XenForo_Application::$time 86400 $options->xefExpirationInterval),
                    
    'node_id'    => $sourceNodes,
                    
    'sticky'    => $options->xefStickyThread,
            );
               
            
    $threads $threadModel->getThreads($conditions$fetchOptions);

            if (
    $threads)
            {
                foreach (
    $threads as $thread)
                {
                    
    $dw XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
                    
    $dw->setExistingData($thread);
                    
    $dw->set('node_id'$options->xefRecycleForum);
                    
    $dw->save();
                }
            }
           
        }
        public static function 
    runMoveDeletedThreads()
        {
            
    $options XenForo_Application::get('options');

        if (
    $options->xefDeletedThread === '1')
        {
            if (empty(
    $options->xefModeratedForums[0]))
            {
            return;
            }
            else
            {
            
    $sourceNodes = array($options->xefModeratedForums);
            }

            
    $db XenForo_Application::getDb();
           
             
    $threads $db->fetchAll('
                    SELECT thread_id
                    FROM xf_thread
                    WHERE discussion_state = \'deleted\'
                    AND node_id IN (' 
    $db->quote($sourceNodes) . ')
            '
    ); 
           
                if (
    $threads)
            {
                 foreach (
    $threads AS $thread)
                 {
                        
    $dw XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
                        
    $dw->setExistingData($thread);
                        
    $dw->set('node_id'$options->xefRecycleForum);
                        
    $dw->save();
                    }           
                } 
        }
        }
    }
     
  7. tyteen4a03

    tyteen4a03 Well-Known Member

    Hm, nothing obvious. I'll let somebody else pass by :p

    (Being a PITA: The database fetching and writing bit is probably more suited to be in a Model)
     
  8. shawn

    shawn Well-Known Member

    Right, and the thing that gets me is that the script isn't creating any headers -- it's really a bug related to the new(er) deferred.php way of processing cron jobs.... which, unfortunately, I don't know much about.
     
  9. Teapot

    Teapot Well-Known Member

    It's a PHP quirk, basically. I ended up using an automated CLI-based cleaner of some sort, whose name I unfortunately forget, and it fixed the whitespace issue for me.
     
  10. shawn

    shawn Well-Known Member

    No, white space will cause the error, but that's not the problem in my case. I have a <?php at the very beginning of the script and no closing tags.
     
  11. shawn

    shawn Well-Known Member

    TTT... Bueller?
     

Share This Page