smarty phpunit empty fetch - phpunit

I need help please.
I'm using Smarty with PHPUnit, and I have troubles.
For example:
In some checks, I call fetch function many times, and I only receive right the first call, the others only return empty. Why???
I let some code here as an example:
/**
* #dataProvider provider_test
*/
public function test_field($field) {
// with this I instance smarty
$front = $this->get_template();
$front->assign('function', 'fb_user_field');
$front->assign('field', $field);
// this fetch only return right widh the first value of field
$result = $front->fetch('tests/generic.tpl');
$this->assertNotNull($result);
}
public function provider_test() {
return array(
array('field' => 'subdomain'),
array('field' => 'login')
);
}
I check $field and in every iteration receive the correct value, but after the first one, fetch return only empty.
Why???? Thanks!!!

My suggestion is to use the MakeGood or similar to step by step debug your php code. Otherwise it is guess and check till you die!
Here's some links
http://blog.loftdigital.com/running-phpunit-tests-in-eclipse-pdt
http://www.youtube.com/watch?v=1qnWL52wt58
I used to spend hours guess and check with phpunit until I discovered MakeGood. Hope it helps!

Related

Convert old silverstripe form to SS 3

I have an old SS2.4 site which I have updated to SS3.1.13. The only part of the old site I can't get working is a search form that filters DataObjects. The old code is:
public function doCollectionSearch($data, $form)
{
$filters = array();
...
//setup some filters based on user selections
...
$where = implode(" AND ", $filters);
if(!isset($_REQUEST['start'])) $_REQUEST['start'] = 0;
$limit = $_REQUEST['start'].",50";
return $this->customise(array(
'Collections' => DataObject::get("Collection", $where, "Genus, Species ASC", null, $limit)
))->renderWith(array('Collection_results','Page'));
}
I have updated the last part to:
return $this->customise(array(
'Collections' => Collection::get()->where($where)->sort("Genus, Species ASC")->limit($limit)
))->renderWith(array('Collection_results','Page'));
But I get a "the method 'fortemplate' does not exist on 'CollectionPage_Controller'".
I know the $where is not right yet, but if I strip that out I still get an error..
I know I am missing something obvious...can anyone suggest a fix?
You'll get that error if your template accesses a method or database field that returns an object that can't be reduced to a string. This often happens when you have a related object (say a parent page) and you do something like the following:
<p>My parent is: $Parent</p>
Instead of
<p>My parent is: $Parent.Title</p>
The same thing existed in 2.4 so this doesn't totally explain your problem, but I'd look for something like the above scenario in your templates.

Send a message to an updated number in Silverstripe

I have a SendSMS() function in customer.php file, and I am updating the MobileTelephone field in the database. When the mobile number is updated a message should go to the new number. In my case, database updates and message goes to the previous number. I want to make them go to the new number. Any suggestions?
Below is my function:
Below function is in MyAccountPage.php
function changeMyContactDetails($data,$form){
$member = Customer::CurrentUser();
//debug::show($member);
if($member){
if($data['MobileTelephone']!=$member-> MobileTelephone){
//sleep(10);
$verified = array(
'IsMobileVerified' => 'N',
//'MobileVeryDate' => date(MYSQL_DATETIME, strtotime(SS_Datetime::now()))
);
//sleep(10);
$member->update($verified);
$member->write();
//sleep(10);
$member = Customer::CurrentUser();
$member->SendSMS();
}
$form->saveInto($member);
$member->write();
}
return $this->redirectBack();
}
You have not altered member before sending the message.
use Form::saveInto first, not after sending.
This could also be done directly from member, in onAfterWrite(), using $this->isChanged('MobileTelephone').
That way it is centralised so it doesn't matter which form/process updates the number.
It is best to achieve this through an Extension: http://docs.silverstripe.org/en/developer_guides/model/extending_dataobjects/

foreign key not persisted symfony2 after a clone

I'm using symfony + Doctrine and I'm stuck with a problem:
I cloned an existing object and I would like to change a FK on the clone. It should be like that:
$dafCloned = clone $daf;
$dafState = $dafStateRepository->findOneBy(
array(
'name' => 'saved',
'dafType' => 'invoice',
'company' => $daf->getSeller(),
));
$dafCloned->setDafState($dafState);
var_dump($dafState->getId());
var_dump($dafCloned->getDafState()->getId());
$this->em->persist($dafCloned);
$this->em->flush();
As you may have noticed, I got 2 var_dump here. Here are the print of the Custom Command calling this code :
int(5500)
int(5499)
5500 is the id I should have in db for $dafCloned, 5499 is the id I have for $daf.
I'd like to know WHY I got different id...My dafState should be the same. I'm probably missing something really stupid but I'm stuck on it since 9am...I even tried to delete all caches we have, moving flush() and persist() but cant help :s
EDIT : added the setDafState() method if needed, but this is basic :
public function setDafState(DafState $dafState) {
$this->dafState = $dafState;
return $this;
}
EDIT2 :
Here getDafState() :
/**
* Get dafState
*
* #return MyPath\Entity\DafState
*/
public function getDafState() {
return $this->dafState;
}
If you need more code sample, just ask for it, I'll edit ;)
For the object, both are huge (Doctrine Object) and i can't find any way to get what could be useful :s. I cant grep dafState on $daf Object, output is still huge.
EDIT 3 :
if ($daf->getId() == 8902) // daf test which should be duplicated
var_dump($dafCloned->getDafState() === $dafState);
output
bool(true)
$dafCloned = clone $daf; // Here your clone is the same object as the old one
$dafState = $dafStateRepository->findOneBy( // Here you get some fresh object
array(
'name' => 'saved',
'dafType' => 'invoice',
'company' => $daf->getSeller(),
));
$dafCloned->setDafState($dafState); // Because this object is still managed by the entity manager it will set the $dafState on the old object (tracked by Id most likely)
var_dump($dafState->getId()); // Show the Id on the fresh object
var_dump($dafCloned->getDafState()->getId()); // Show the Id on the old object
$this->em->persist($dafCloned); // overwrite the old object
$this->em->flush();
This Post will be helpful to you: How to re-save the entity as another row in Doctrine 2
I will update my answer if this doesn't solve your issue
Here we go.
Thanks to #cheesemacfly i find out i have a prePersistListener which was resetting my dafState !
So, next time you have something weird looking like the above problem, check your listener !

How to remove all items in a magento product collection?

Seems doesn't works:
<?php
$collection = Mage::getModel('catalog/product')->getCollection();
foreach($collection->getItems() as $key => $_product){
//product
$collection->removeItemByKey($key);
}
?>
$collection is still populated
If you'd like to work with an empty collection, the best approach would be to load it with a filter that would always produce an empty set. Here's an example:
$collection = Mage::getModel('catalog/product')->getCollection()
->addFieldToFilter('entity_id', 0);
Because Magento product ids start at 1, this collection would remain empty, until you add items to it with the addItem() method.
clear() and removeItemByKey(), on the other hand, will only trigger a second run to the database to refetch the data you don't want in there.
You question doesn't make sense. Running the following code
$c = Mage::getModel('catalog/product')->getCollection();
foreach($c->getItems() as $key=>$item)
{
$c->removeItemByKey($key);
}
foreach($c->getItems() as $key=>$item)
{
var_dump($key);
}
var_dump( "Done" );
results in only the word "done" being output (Magento 1.6.1).
My guess it something about your installation of Magento is making the call to $c->getItems(); trigger a reload of the collection. So, you remove all the items, but then when you call your second getItems, the collection is refetched.
There's clear() method in Varien_Data_Collection class which clears the collection.
I'm not sure if the method exists in the time the question was asked, but it exists in Magento 1.7
There's also a possibility to remove all the items without "fake loading" (in opposite to Shay Acrich's answer):
class MyCollection extends SomeCollection {
// ...
public function setEmpty()
{
$this->clear();
$this->_totalRecords = 0;
$this->_setIsLoaded(true);
return $this;
}
// ...
}
Setting _totalRecords to 0 is required in order not to allow getSize() method to reload the collection.
Nevertheless, one needs to extend / modify a collection's code, because both the field _totalRecords and the method _setIsLoaded() are protected.
There should be noted, that if a particular collection ignores flags like _totalRecords and _isCollectionLoaded the above solution may not work as expected.
$collection->clear()
should do the work.

How do I create a functional test which includes a POST to a page with parameters?

I've read the documentation from Symfony2 but it doesn't seem to work. Here's my functional test:
public function testSearch()
{
$client = static::createClient();
$crawler = $client->request('POST', '/search/results', array('term' => 'Carteron'));
$this->assertTrue($crawler->filter('html:contains("Carteron")')->count() > 0);
$this->assertTrue($crawler->filter('html:contains("Auctions")')->count() > 0);
}
In my controller the "term" parameter is null when this request comes in. However, search works just fine when I perform it on the site, so I know its a problem with setting up the test.
I had the same problem, neither $request->query nor $request->request worked. Both did the same for me: it returned $default, not the given $parameters (Symfony 2.3).
Same behaviour as chris, in normal web browsers it works. I fixed this by replacing:
public function searchResultsAction($name)
{
$request = Request::createFromGlobals();
$term = trim($request->request->get('term'));
return $this->searchResultsWithTermAction($term);
}
With:
public function searchResultsAction(Request $request, $name)
{
// do NOT overwrite $request, we got it as parameter
//$request = Request::createFromGlobals();
$term = trim($request->request->get('term'));
return $this->searchResultsWithTermAction($term);
}
So createFromGlobals() does only work if $_GET and $_POST are set. Shich is not the case if you use the symfony test client. you have to add the $request parameter to the action.
(I used $name as a GET parameter in my routing)
I've never gotten an answer to this, but have implemented a work around that seems to work for my testing purposes. I'd love to hear feedback or get a real answers to this questions.
What I've done is create a 2nd route for the purposes of testing.
In real usage the uri would be /search/results?term=searchtermhere
For the purposes of testing, this didn't work. I could never get access to the term value when invoked via the automated test.
So what I've done is create a 2nd route just for testing which has a uri of /search/results/{searchtermhere}.
Then my action class used for a real search would call down to another function and pass the term to the function:
public function searchResultsAction()
{
$request = Request::createFromGlobals();
$term = trim($request->request->get('term'));
return $this->searchResultsWithTermAction($term);
}
So my functional tests would excersize searchResultsWithTermAction(), so the only code coverage I'm missing from this workaround is the extraction of the term from the request.
I don't know if anyone is still searching for an answer to this, but basically the problem is that you are looking in the wrong place for the parameter.
For your example you would need:
$term = trim($request->query->get('term'));
Hope this helps!

Resources