Symfony3, Doctrine2, custom fixtures loader - doctrine-orm

I am trying to make a custom fixture that will take data from a csv file, parse it in a specific way, create the objects, insert the data and flush it to the database.
My problem is that my file lives in AppBundle/Command and I do not know how to access the manager in order to persist and flush my file.
So my question is: How do i access doctrine's manager?
<?php
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\Common\Persistence\ObjectManager;
use AppBundle\Entity\Country;
class LoadFixturesCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('app:load-fixtures'));
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// file path
$csvfile = '/home/amarui/Documents/studyin/country.csv';
// if opened
if (($handle = fopen($csvfile, 'r')) !== false) {
// read line and breakes at semicolon(;)
while (($line = fgetcsv($handle, 1000, ';', '"')) !== false) {
$counter = 0;
$i = 0; // counter for the array elements
$city{$counter} = new Country();
// read elements from breakpoint(;)
foreach ($line as $value) {
// if the element has a comma(,)
if (strstr($line[$i], ',')) {
// breaks at comma(,)
$line[$i] = explode(',', $line[$i]);
// reads elements from the breakpoint(,)
foreach ($line[$i] as $multiple) {
// echo '<br /> count'.$i.' '.$multiple;
// TODO:
}
} else {
// echo '<br /> count'.$i.' '.$value;
if ($i = 0) {
$city{$counter}->setName($value);
}
}
$i += 1; // next element in the array
$counter += 1; // updates the variable name
$this->getDoctrine()->getManager()->persist($city{$counter});
}
}
}
$this->getDoctrine()->getManager()->flush();
}
}
Here is the error that it outputs
[Symfony\Component\Debug\Exception\FatalThrowableError]
Fatal error: Call to undefined method AppBundle\Comm
and\LoadFixturesCommand::getDoctrine()
Stack trace
[2016-02-29 11:55:44] php.CRITICAL: Fatal error: Call to undefined method AppBundle\Command\LoadFixturesCommand::getDoctrine() {"type":1,"file":"/home/amarui/Dev/student360/src/AppBundle/Command/LoadFixturesCommand.php","line":60,"level":32767,"stack":[{"file":"/home/amarui/Dev/student360/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php","line":256,"function":"execute","class":"AppBundle\\Command\\LoadFixturesCommand","type":"->","args":["[object] (Symfony\\Component\\Console\\Input\\ArgvInput: 'app:load-fixtures')","[object] (Symfony\\Component\\Console\\Output\\ConsoleOutput: {})"]},{"file":"/home/amarui/Dev/student360/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php","line":803,"function":"run","class":"Symfony\\Component\\Console\\Command\\Command","type":"->","args":["[object] (Symfony\\Component\\Console\\Input\\ArgvInput: 'app:load-fixtures')","[object] (Symfony\\Component\\Console\\Output\\ConsoleOutput: {})"]},{"file":"/home/amarui/Dev/student360/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php","line":186,"function":"doRunCommand","class":"Symfony\\Component\\Console\\Application","type":"->","args":["[object] (AppBundle\\Command\\LoadFixturesCommand: {})","[object] (Symfony\\Component\\Console\\Input\\ArgvInput: 'app:load-fixtures')","[object] (Symfony\\Component\\Console\\Output\\ConsoleOutput: {})"]},{"file":"/home/amarui/Dev/student360/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php","line":86,"function":"doRun","class":"Symfony\\Component\\Console\\Application","type":"->","args":["[object] (Symfony\\Component\\Console\\Input\\ArgvInput: 'app:load-fixtures')","[object] (Symfony\\Component\\Console\\Output\\ConsoleOutput: {})"]},{"file":"/home/amarui/Dev/student360/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php","line":117,"function":"doRun","class":"Symfony\\Bundle\\FrameworkBundle\\Console\\Application","type":"->","args":["[object] (Symfony\\Component\\Console\\Input\\ArgvInput: 'app:load-fixtures')","[object] (Symfony\\Component\\Console\\Output\\ConsoleOutput: {})"]},{"file":"/home/amarui/Dev/student360/bin/console","line":29,"function":"run","class":"Symfony\\Component\\Console\\Application","type":"->","args":["[object] (Symfony\\Component\\Console\\Input\\ArgvInput: 'app:load-fixtures')"]}]}

You haven't the helper method getDoctrine() in a command (instead this exists in a controller if inhered from Symfony\Bundle\FrameworkBundle\Controller\Controller).
try with
$this->getContainer()->get('doctrine')
instead of
$this->getDoctrine()
Hope this help

Related

How to write PHPunit test code with external object (having DAO)?

I'm trying to write test code for monosilic code like below.
Q1. How to write test code which has access to DB?
Q2. How to refactor these code testable?
Q3. Is there any way to write test code with fewer change to production code?
I need your help!
Thanks!!
Example Production Code)
<?
class Sample_Model_Service_A
{
private $_result
private $_options
private $_someValue
public function __construct($params, $ids, $data) {
$this->_options = Sample_Model_Service_B::getOption($data);
}
private function setSomeValue() {
// some code shaping $_params to $someValue with $this->_options
$this->_someValue= $someValue;
}
// want to write test for this function
// changed this function's logic
private function setResult() {
// some code shaping $_someValue to $result
$this->_result = $result;
}
public function getter() {
retrn $this->_result;
}
}
?>
<?
class Sample_Model_Service_B
{
// get option from DB
public static function getOption($data) {
$dao = new Model_Dao_Option();
$option = $dao->getOption($data['id']);
return $option;
}
}
?>
My Test Code so far)
public function testsetResult()
{
// just make sure these variables are defined
$params = $ids = $data = [];
// try to make test for private function
$sample = new Sample_Model_Service_A($params, $ids, $data);
$reflection = new ReflectionClass($sample);
// get Method
$method = $reflection->getMethod('setresult');
$method->setAccessible(true);
// wondering how to get $result
$result = $method->invoke($sample);
// assert
$this->assertSame($result);
}
Mockery solved my issue.
Sample Code)
/**
* #dataProvider sampleProvider
*/
public function testsetResult($sampleData)
{
// mock Sample_Model_Service_B
$mockSample_Model_Service_B = Mockery::mock('alias:' . Sample_Model_Service_B::class);
$mockSample_Model_Service_B->shouldReceive('getOption')->andReturn($sampleData['option']);
$sample = new Sample_Model_Service_A($sampleData['params'], $sampleData['ids'], $sampleData['data']);
$sample->setResult();
$result = $sample->getter();
// assert
$this->assertSame($result, $sampleData['result']);
}

How set console argument in symfony 3 console command testing

I am unable to set Argument while creating Unit test case in Symfony 3.4 console command application
My Console command
php bin\console identification-requests:process input.csv
My Console code
protected function execute(InputInterface $input, OutputInterface $output)
{
// Retrieve the argument value using getArgument()
$csv_name = $input->getArgument('file');
// Check file name
if ($csv_name == 'input.csv') {
// Get input file from filesystem
$csvData = array_map('str_getcsv', file($this->base_path.$csv_name));
$formatData = Helpers::formatInputData($csvData);
// Start session
$session = new Session();
$session->start();
foreach ($csvData as $key => $data) {
if (!empty($data[0])) {
$validation = Validator::getInformationData($data, $formatData[$data[1]]);
if (!empty($validation)) {
$output->writeln($validation);
} else {
$output->writeln('valid');
}
}
}
} else {
$output->writeln('Invalid file!');
}
}
I tried the following test code
$kernel = static::createKernel();
$kernel->boot();
$application = new Application($kernel);
$application->add(new DocumentCommand());
$command = $application->find('identification-requests:process')
->addArgument('file', InputArgument::REQUIRED, "input.csv");
$commandTester = new CommandTester($command);
$commandTester->execute(array(
'command' => $command->getName()
));
$output = $commandTester->getOutput();
$this->assertContains('valid',$output);
When I run unit test it showing the following error message
There was 1 error:
1) Tests\AppBundle\Command\DocumentCommandTest::testExecute
Symfony\Component\Console\Exception\LogicException: An argument with name "file" already exists.
I think you should put your input in the command tester and not in the command finder, in this case you are trying to create another parameter for that command, and that's why it's telling you that it is existing already.
try this
$command = $application->find('identification-requests:process');
$commandTester = new CommandTester($command);
$commandTester->execute(array(
'command' => $command->getName(),
'file' => 'input.csv'
));

Doctrine: how to curb circular references

I have devices being parts of brands and repairs being part of devices. Now I'm trying to get a simple AJAX call which will allow me to search for a device by either brand name or device name. Unfortunately, I get circular references. Even when I've written a handler for circular references to limit it to one, I still get too much information in my objects.
Consider the following return from serialize on my DQL query:
[{"0":{"id":1,"name":"iPhone
1","logo":"iPhone1","brand":{"id":2,"name":"Apple","logo":"apple","devices":["iPhone
1",{"id":2,"name":"iPhone","logo":"iphone","brand":"Apple","deletedAt":null,"repairs":[]}],"deletedAt":null},"deletedAt":null,"repairs":[]},"name":"Apple"},{"0":{"id":2,"name":"iPhone","logo":"iphone","brand":{"id":2,"name":"Apple","logo":"apple","devices":[{"id":1,"name":"iPhone
1","logo":"iPhone1","brand":"Apple","deletedAt":null,"repairs":[]},"iPhone"],"deletedAt":null},"deletedAt":null,"repairs":[]},"name":"Apple"}]
Here I don't even need repairs at all. However, since it is referenced in the PartEntity, I still get a bunch of unnecessary repair info. How can I limit the data I get out of an object?
my Controller code:
public function ajaxShowDevicesAction(Request $request) {
//if ($request->isXmlHttpRequest()) {
$data = $request->query->get('data');
$result = "";
if ($data) {
$result = $this->getDoctrine()->getManager()->getRepository('AppBundle:Device')->findAllByBrandOrName($data);
}
if ($result) {
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new GetSetMethodNormalizer());
$normalizers[0]->setCircularReferenceHandler(function ($object) {
return $object->getName();
});
$serializer = new Serializer($normalizers, $encoders);
$jsoncontent = $serializer->serialize($result, 'json');
$response = new Response($jsoncontent);
return $response;
}
// else { # unsure how to give a "no results" response
// $response = new Response(json_encode(array()));
// $response->headers->set('Content-Type', 'application/json');
// return $response;
// }
// } else {
// throw new HttpException(403, "Ajax access only");
// }
}
You can use
setCircularReferenceLimit()
method for normalizers.
Handling Circular References

Joomla 2.5 - component fatal error [duplicate]

This question already exists:
imade a simple component aboutus with table contactus when i click on publish/unpublish get this errore
Closed 7 years ago.
When I make component in Joomla 2.5 I had this error:
Fatal error: Call to a member function reset() on a non-object in
/var/www/html/joomla/libraries/joomla/application/component/modeladmin.php
on line 850
I found‌ :when click on publish or unpublish first run this controller quite in my project this name is :
notic:run first this file
com_contactus/controllers/categories.php
<?php
defined( '_JEXEC' ) or die();
jimport ('joomla.application.component.controlleradmin');
echo "run first this file ";
class contactusControllerCategories extends JControllerAdmin
{
public function getModel($name='Category',$prefix='contactusModel',$config=array('ignore_request'=>true))
{
$model = parent::getModel($name,$prefix,$config);
return $model;
}
}
after run that Top file rund this file Of course gettable method
com_contactus/models/category.php
<?php
defined( '_JEXEC' ) or die();
jimport ('joomla.application.component.modeladmin');
class contactusModelCategory extends JModelAdmin
{
public function getTable($type='Category',$prefix='contactusTable',$config=array())
{
echo "second ";
return JTable::getInstance ($type,$prefix,$config);
}
protected function loadFormData()
{
$data = JFactory::getApplication()->getUserState('com_contactus.edit.category.data',array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
function getForm($data=array(),$loadData=true)
{
$form = $this->loadForm('com_contactus.category','Category',array('control'=>'jform' , 'load_data'=>$loadData));
return $form;
}
}
after that run towice files rund this file for run
com_contactus/tables/category.php
<?php
defined( '_JEXEC' ) or die();
jimport ('joomla.database.table');
echo "three ";
die();
class contactusTableCategory extends JTable
{
public function __construct (&$db)
{
parent::__construct('#__contactus','id',$db);
}
}
one of my wrong:
. I put the wrong tabels instead tables name in project

SimpleTester on CodeIgniter fails with "Class 'GroupTest' not found"

I'm trying to do a clean install SimpleTester on a new CodeIgniter application, following the instructions here: http://codeigniter.com/wiki/SimpleTester_-_Unit_testing_library
Everything's fine until step 6, when I add "simpletester" to the list of libraries that are autoloaded. As soon as I do that, visiting any page simply results in:
Fatal error: Class 'GroupTest' not found in
/path/to/app/application/libraries/simpletester.php on line 84
Grepping through the code for GroupTest I only see it referenced in comments, and in a readme file which states the following:
The GroupTest has been renamed TestSuite (see below).
It was removed completely in 1.1 in favour of this
name.
I tried modifying line 84 to replace GroupTest with TestSuite, but then I get the following error:
Fatal error: Call to undefined method TestSuite::addTestFile() in
/home/path/to/app/application/libraries/simpletester.php
on line 96
Is this a bug on their end? Has anyone seen this before?
I have run into the same issue. The GroupTest class can be found in test_case.php of version 1.0.1 of SimpleTest:
http://sourceforge.net/projects/simpletest/files/simpletest/simpletest_1.0.1/
Unfortunately, simply inserting v1.0.1 into the libraries folder doesn’t solve all the world’s problems. I no longer get the “Fatal error: Class ‘GroupTest’ not found ...” error, but I do get a segmentation fault and my site no longer works.
I have briefly tried to track down the issue but to no avail.
Note: I also responded on the CodeIgniter Wiki page containing the same question.
I had the same problem with a current project and found that the problem is that GroupTest was replaced with TestSuite which works a little differently.
This is the library code I use:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
$libraryDir = APPPATH . 'libraries/simpletest';
if(!is_dir($libraryDir))
exit("Simpletest must be located in \"$libraryDir\"");
require_once $libraryDir . '/unit_tester.php';
require_once $libraryDir . '/mock_objects.php';
require_once $libraryDir . '/collector.php';
class SimpleTester
{
/**
* What reporter should be used for display.
* Could be either HtmlReporter, SmallReporter, MinimalReporter or ShowPasses.
*/
public $Reporter = 'MinimalReporter';
private $testDir;
private $testTitle;
private $fileExtension;
public function __construct($params = false)
{
$ci =& get_instance();
$ci->config->load('simpletester');
if($params == false) {
$params['runFromIPs'] = $ci->config->item('runFromIPs');
$params['testDir'] = $ci->config->item('testDir');
$params['fileExtension'] = $ci->config->item('fileExtension');
$params['autorun'] = $ci->config->item('autorun');
$params['reporter'] = $ci->config->item('reporter');
$params['testTitle'] = $ci->config->item('testTitle');
}
if(isset($params['runFromIPs']) && strpos($params['runFromIPs'], $ci->input->server('SERVER_ADDR') === FALSE))
{
// Tests won't be run automatically from this IP.
$params['autorun'] = FALSE;
}
// Check if call was an AJAX call. No point in running test
// if not seen and may break the call.
$header = 'CONTENT_TYPE';
if(!empty($_SERVER[$header])) {
// #todo Content types could be placed in config.
$ajaxContentTypes = array('application/x-www-form-urlencoded', 'multipart/form-data');
foreach ($ajaxContentTypes as $ajaxContentType) {
if(false !== stripos($_SERVER[$header], $ajaxContentType))
{
$params['autorun'] = FALSE;
break;
}
}
}
$this->testDir = $params['testDir'];
$this->testTitle = $params['testTitle'];
$this->fileExtension = $params['fileExtension'];
if(isset($params['reporter']))
$this->Reporter = $params['reporter'];
if($params['autorun'] == TRUE)
echo $this->Run();
}
/**
* Run the tests, returning the reporter output.
*/
public function Run()
{
// Save superglobals that might be tested.
if(isset($_SESSION)) $oldsession = $_SESSION;
$oldrequest = $_REQUEST;
$oldpost = $_POST;
$oldget = $_GET;
$oldfiles = $_FILES;
$oldcookie = $_COOKIE;
$test_suite = new TestSuite($this->testTitle);
// Add files in tests_dir
if(is_dir($this->testDir))
{
if($dh = opendir($this->testDir))
{
while(($file = readdir($dh)) !== FALSE)
{
// Test if file ends with php, then include it.
if(substr($file, -(strlen($this->fileExtension)+1)) == '.' . $this->fileExtension)
{
$test_suite->addFile($this->testDir . "/$file");
}
}
closedir($dh);
}
}
// Start the tests
ob_start();
$test_suite->run(new $this->Reporter);
$output_buffer = ob_get_clean();
// Restore superglobals
if(isset($oldsession)) $_SESSION = $oldsession;
$_REQUEST = $oldrequest;
$_POST = $oldpost;
$_GET = $oldget;
$_FILES = $oldfiles;
$_COOKIE = $oldcookie;
return $output_buffer;
}
}
// Html output reporter classes //////////////////////////////////////
/**
* Display passes
*/
class ShowPasses extends HtmlReporter
{
function ShowPasses()
{
$this->HtmlReporter();
}
function paintPass($message)
{
parent::paintPass($message);
print "<span class=\"pass\">Pass</span>: ";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
print implode("->", $breadcrumb);
print "->$message<br />\n";
}
function _getCss()
{
return parent::_getCss() . ' .pass {color:green;}';
}
}
/**
* Displays a tiny div in upper right corner when ok
*/
class SmallReporter extends HtmlReporter
{
var $test_name;
function ShowPasses()
{
$this->HtmlReporter();
}
function paintHeader($test_name)
{
$this->test_name = $test_name;
}
function paintFooter($test_name)
{
if($this->getFailCount() + $this->getExceptionCount() == 0)
{
$text = $this->getPassCount() . " tests ok";
print "<div style=\"background-color:#F5FFA8; text-align:center; right:10px; top:30px; border:2px solid green; z-index:10; position:absolute;\">$text</div>";
}
else
{
parent::paintFooter($test_name);
print "</div>";
}
}
function paintFail($message)
{
static $header = FALSE;
if(!$header)
{
$this->newPaintHeader();
$header = TRUE;
}
parent::paintFail($message);
}
function newPaintHeader()
{
$this->sendNoCacheHeaders();
print "<style type=\"text/css\">\n";
print $this->_getCss() . "\n";
print "</style>\n";
print "<h1 style=\"background-color:red; color:white;\">$this->test_name</h1>\n";
print "<div style=\"background-color:#FBFBF0;\">";
flush();
}
}
/**
* Minimal only displays on error
*/
class MinimalReporter extends SmallReporter
{
function paintFooter($test_name)
{
if($this->getFailCount() + $this->getExceptionCount() != 0)
{
parent::paintFooter($test_name);
print "</div>";
}
}
}
Works fine for me I haven't tested all the different reporters yet though. But the default one works fine.
And this is how I use it:
$this->load->library('simpletester');
echo $this->simpletester->Run();
And my config file is:
$config['testDir'] = APPPATH . 'tests';
$config['runFromIPs'] = '127.0.0.1';
$config['reporter'] = 'HtmlReporter';
$config['autorun'] = false;
$config['fileExtension'] = 'php';
$config['testTitle'] = 'My Unit Tests';