1

SOLVED I solved this issue with Jonathan Hussey help I changed this line:

$mModel->getCollection()->load($mId)->getData();

for this:

$mModel->getCollection()->addFieldToFilter('met_id',$Id)->getSelect();

Problem
I created custom module which added tab to admin product page with additional text field. When I try save this product I get this error:

a:5:{i:0;s:140:"Cannot send headers; headers already sent in /home/nano/domains/mydomain/public_html/gw/lib/Varien/Data/Collection/Db.php, line 693";i:1;s:1630:"#0 /home/nano/domains/mydomain/public_html/gw/lib/Zend/Controller/Response/Abstract.php(148): Zend_Controller_Response_Abstract->canSendHeaders(true)...

I saw that this error created in Observer.php:

$mId = $collection['m_id'];         
$mModel->getCollection()->load($mId)->getData(); <-- this line give an error

$data['met_id'] = $mId;
$data['product_id'] = $product->getId();
$data['metf1'] = $this->_getRequest()->getPost('f1');
$mModel->setData($data);
$mModel->save();

Do you have any ideas how fix this ?

EDIT content of admin template tab file:

<?php
$product = Mage::registry('current_product');
$mItem = Mage::getModel('mmodel/mmodel')->getCollection()->
addFilter('product_id',$product->getId())->getFirstItem();

echo '<div class="input-field">
 <label for="f1">File</label>
 <input type="text" class="input-text" name="f1" id="f1" value='.$mItem['f1'].' />
</div>';


Debug backtrace after line $mModel->getCollection()->load($mId)->getData(); from Observer.php

SELECT `main_table`.* FROM `mmodel` AS `main_table`
    Debug Backtrace:
    File    Line    Function
    /home/nano/domains/mydomain/public_html/gw/app/code/local/GW/MModel/Model/Observer.php  42  printDebugBacktrace
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/App.php    1338    saveProductTabData
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/App.php    1317    _callObserverMethod
    /home/nano/domains/mydomain/public_html/gw/app/Mage.php 468 dispatchEvent
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/Abstract.php   466 dispatchEvent
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Catalog/Model/Product.php 548 _afterSave
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/Abstract.php   319 _afterSave
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php   714 save
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Controller/Varien/Action.php 419 saveAction
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php    250 dispatch
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Controller/Varien/Front.php  176 match
    /home/nano/domains/mydomain/public_html/gw/app/code/core/Mage/Core/Model/App.php    354 dispatch
    /home/nano/domains/mydomain/public_html/gw/app/Mage.php 704 run
    /home/nano/domains/mydomain/public_html/gw/index.php    87  run
That1Guy
  • 7,075
  • 4
  • 47
  • 59
Krzysztof
  • 355
  • 6
  • 15
  • 3
    Probably, you have left some whitespace in the end of source file after `?>` tag, or you have started output using `echo` command before headers were sent. – Mikhail Chernykh Mar 27 '13 at 22:06
  • Thanks for your advice. But I checked all module files for whitespace few times and I didn't find any whitespace. Maybe admin template is responsible for this issue. Pleas see, I edit post. – Krzysztof Mar 27 '13 at 22:14
  • 1
    This is a weird one to get considering Magento's MVC architecture. Are you able to get a complete stack trace? – Steve Robbins Mar 27 '13 at 22:25
  • 1
    What's possibly happening is you are trying to run some code after the headers are sent. What this error is telling you is that the headers have already been returned from the called page, and that it is in fact too late to modify them. Make sure your code doesn't have echo or print before the call to header() in your function. (A stack trace helps find this) .. That's all I got unfortunately .. Good Luck. – Zak Mar 27 '13 at 22:31
  • 2
    @netme - I think this is the most probable solution, I've had it several times so far. You can either remove `?>` from all your class/function files and make sure that there is no whitespace before the opening ` – ducin Mar 27 '13 at 23:00
  • cannnot sent header happens when some html owa already generated.This happens when some white space was laft before or after ?> end of php file.Apart from this if your code has resulted in some echo(html output) so you need to check.Also check if warning/errors if generated are not displayed on site as they are also a candidate for generating some output and from your line headers already sent in /home/nano/domains/mydomain/public_html/gw/lib/Varien/Data/Collection/Db.php, line 693 it looks like either some code there or some warning generated as output. – Oscprofessionals Mar 28 '13 at 04:18
  • This general topic is answered here: http://stackoverflow.com/questions/8028957/headers-already-sent-by-php – KelAt Jun 21 '13 at 11:34

1 Answers1

4

When working with collections you should only pass arguments to ->load() if you want the SQL for that collection to be logged or output. If you don't want the collection to return all items you can pull the select object from the collection with ->getSelect() and filter with standard Zend methods this way.

If you trace back your collection command you will see because you pass an argument it echo's out the collection SQL.

$mModel->getCollection()->load($mId)->getData();

Have a look at lib/Varien/Data/Collection/Db.php as per the error message and find the load() method. You will see that it accepts two aguments, $printQuery and $logQuery, you have passed an argument to $printQuery. A few lines down in the method you see:

$this->printLogQuery($printQuery, $logQuery);

Looking at the printLogQuery() method you will see that anything passed as the $printQuery argument which evaluates to true triggers the echo on line 693 as per the error message:

echo is_null($sql) ? $this->getSelect()->__toString() : $sql;

This is what is sending headers in your case. Remove the argument from ->load() or pass false and it should fix your problem.

Jonathan Hussey
  • 1,044
  • 6
  • 9