In Symfony2, I want to test a controller action with 2 subsequent requests if it behaves properly.
The first request will analyze the database and take appropriate action, the second request will also analyze the database and take a different action.
My code goes as follows:
protected function setUp() {
$this->_client = static::createClient();
$kernel = static::$kernel;
$kernel->boot();
$this->_em = $kernel->getContainer()->get('doctrine.orm.default_entity_manager');
$this->_em->beginTransaction();
}
public function testAddToCartWith2Posts() {
$this->addObjects(); // Initialize the database
$object = static::$kernel->getContainer()->get('doctrine')->getRepository('BaseBundle:Object')->findAll()[0];
$id = $object->getId();
$crawler = $this->_client->request('POST', '/cart/add/' . $id);
$crawler = $this->_client->request('POST', '/cart/add/' . $id);
$session = static::$kernel->getContainer()->get('session');
$cart = $session->get('cart');
$this->assertEquals($session->getId(), $cart->getSession());
$this->assertEquals(2, count($cart->getCartItems()));
}
The first request is able to read the list of objects. The second request is not.
The database becomes empty between requests. How could I fix this problem?
Related
Before I start, I want to let you know I'm really a noob in PHP and this is the first API I'm making.
It works pretty good if I want to echo one array of information (for example food details), but when I try to do the same with multiple items it returns empty.
I've checked the variable values in debug. It's fine in debug and I see an array which contains multiple sub arrays.
My code
$app->get('/allfoods', 'authenticate', function () use ($app) {
global $user_id;
$db = new FoodHandler();
// In here i get foods with their details via mysql
$result = $db->GetAllFoods();
$response = array();
$response["error"] = false;
$response["foods"] = array();
// looping through result and preparing food array
while ($row = $result->fetch_assoc()) {
$tmp = array();
$tmp['food_id'] = $row['food_id'];
$tmp['food_name'] = $row['food_name'];
$tmp['food_desc'] = $row['food_desc'];
$tmp['food_category'] = $row['food_category'];
$tmp['food_creationDate'] = $row['food_creationDate'];
array_push($response["foods"], $tmp);
}
echoRespnse(200, $response);});
My output function (which works great if there is no array in my array)
function echoRespnse($status_code, $response) {
$app = \Slim\Slim::getInstance();
// Http response code
$app->status($status_code);
// setting response content type to json
$app->contentType('application/json');
echo json_encode($response);
}
$app->run();?>
What is my setup?
Localhost wamp with php 7.2.4
Apache 2.4.33
Mysql 5.7.21
I'm also using Postman to send my request (I also tried it in C#, both give back empty content)
I see several issues with your code. First, there is a problem with your route definition. When defining a route, you should pass two arguments to the get method: a pattern (a string,/allfoods in your case) and an instance of Clousure (a callable, your route callback, the anonymous function in your case.) More details in official docs.
So, first thing is to remove the authenticate string from method parameters and change your route definition to this:
$app->get('/allfoods', function ($request, $response, $args) {
// Body of the function goes here
});
Please note I also removed the use ($app) as you have access to application instance uising $this keyword, so no need for that (described in official docs as well).
Second thing is about generating the response. When using Slim framework it is always a good idea to return the $response object instead of echoing response (read more in official docs). Thisgives you some advantages, for example the helper method whitJson helps you whit generating JSON output.
To refine your whole code in a more Slim-ish way:
$app->get('/allfoods', function ($request, $response, $args) {
global $user_id;
$db = new FoodHandler();
// In here i get foods with their details via mysql
$result = $db->GetAllFoods();
$data= array();
$data["error"] = false;
$data["foods"] = array();
// looping through result and preparing food array
while ($row = $result->fetch_assoc()) {
$tmp = array();
$tmp['food_id'] = $row['food_id'];
$tmp['food_name'] = $row['food_name'];
$tmp['food_desc'] = $row['food_desc'];
$tmp['food_category'] = $row['food_category'];
$tmp['food_creationDate'] = $row['food_creationDate'];
array_push($data["foods"], $tmp);
}
// Return JSON data using helper method
return $response->withJson($data);
}
And you won't need the echoResponse function anymore.
I have a function in my Laravel application that generates TwiML for a holding queue. It seems that when I try to dynamically generate the value for the waitUrl attribute, I end up getting a 500 server error during runtime. Routes are properly established and I'm able to view the correct XML at the waitURL in the browser. However, the error persists.
If I create a static XML file with the same exact content, or use a TwiML Bin, it works like a charm.
Here are the relevant functions:
public function wait() {
return $this->generateWaitTwiml();
}
public function onHold($agentId) {
return $this->generateHoldQueueTwiml($agentId, '/phone/wait');
}
private function generateHoldQueueTwiml($agentId, $waitUrl = null) {
$queue = $agentId . '_hold';
if ($waitUrl === null){
$waitUrl = 'path_to_static.xml';
}
$queue = $agentId . '_hold';
$response = new Twiml();
$response->enqueue(
$queue,
['waitUrl' => $waitUrl]
);
return response($response)->header('Content-Type', 'application/xml');
}
private function generateWaitTwiml() {
$response = new Twiml();
$response
->play('http://path_to_my.mp3');
return response($response)->header('Content-Type', 'application/xml');
}
This was resolved by excluding the URIs from the CSRF verification (in VerifyCsrfToken.php):
class VerifyCsrfToken extends Middleware {
protected $except = [
'uri/',
'uri2/*',
];
}
Is it possible get the value of a route placeholder within a Slim container? I know I can access the placeholder by adding a third parameter to the request but I'd like to have it injected so I'm not assigning it on each request.
I've tried $app->getContainer('router') but I can't seem to find a method to actually pull the placeholder value.
Example:
$app = new Slim\App;
$c = $app->getContainer();
$c['Controller'] = function() {
$userId = // how do I get the route placeholder userId?
return new Controller($userId);
};
$app->get('/user/{userId}','Controller:getUserId');
class Controller {
public function __construct($userId) {
$this->userId = $userId;
}
public function getUserId($request,$response) {
return $response->withJson($this->userId);
}
}
Without some 'hacky' things this will not work because we have no access on the request object build by slim, while the controller get constructed. So I recommend you to just use the 3rd parameter and get your userid from there.
The 'hacky' thing would be todo the same, what slim does when you execute $app->run(), but if you really want todo this, here you'll go:
$c['Controller'] = function($c) {
$routeInfo = $c['router']->dispatch($c['request']);
$args = $routeInfo[2];
$userId = $args['userId'];
return new Controller($userId);
};
Note: slim3 also urldecoded this values so may do this as well urldecode($args['userId']) Source
create a container wrapper and a maincontroller then extend all your controller from your maincontroller, then you have access to the container.
here is how i solved this problem:
https://gist.github.com/boscho87/d5834ac1ba42aa3da02e905aa346ee30
public function searchStudent($student)
{
$db = Di::getDefault()->get('db');
$sql = 'SELECT * FROM students WHERE insurance_number = "'.$student['searchInsurenceNum'].'"';
$sth = $db->prepare($sql);
$sth->execute();
When i check here die(var_dump($sth->fetchAll())), i am getting array with data from database.
return $sth->fetchAll();
}
public function searchAction()
{
$request = new Request();
$response = new Response();
if ($request->isPost()) {
(new ContactsStorage())->searchStudent($request->getPost());
}
But in controller when i call fuction die(var_dump((new ContactsStorage())->searchStudent())), i am getting empty array .
$this->view->setVar('findData', (new ContactsStorage())->searchStudent());
}
Maybe your request is not a POST ? ($request->isPost())
by using this method you're allow to find your students only on POST request. Remove condition and try again.
If you have model Student which extends \Phalcon\Mvc\Model you can use magic static methods findBy{$FeildCamelCasedName} so there is no need to create extra repositories and even methods if you want to ge tsome entity by simple criteria:
$findData = Student::findByInsuranceNumber($in);
also you can find one element by such criteria by simply using magic method findFirstBy{$Field}
I'm currently developing a payment method and things are working quite well.
Just one thing: The customer enters some information along the payment method and through debugging I can see that it gets written into the InfoInstance via Mage_Payment_Model_Method_Abstract::assignData()
Unfortunately, I can't read that data when I'm in the capture()-Method. I retrieve the InfoInstance and try to read the information, but it's not set.
assignData() method:
public function assignData($data) {
if (!($data instanceof Varien_Object)) {
$data = new Varien_Object($data);
}
$info = $this->getInfoInstance();
$info->setEtixType($data->getEtixType());
return $this;
}
capture() method:
public function capture(Varien_Object $payment, $amount) {
// ...
$info = $this->getInfoInstance();
Mage::log('etix_type: '.$info->getEtixType()); //I expect something like "etix_type: cc"
// ...
}
Any help is appreciated. I'm sure I missed something.
Found it,
Assigning veriables directly to the InfoInstance works, but it does not persist through the whole checkout process. Instead, you have to set it on the additional_data:
$info = $this->getInfoInstance();
$info->setAdditionalInformation('etix_type', $data->getEtixType());
And later you can read it via:
$info = $this->getInfoInstance();
$etix_type = $info->getAdditionalInformation('etix_type');