Upload photo without form (API) - symfony

I'm making an app mobile and I need to upload a photo from my camera via my API. But when doctrine try to INSERT INTO, he isn't happy because my name field is null. So the name generate by my entity is missing.
I don't understand where the code block. My web app uses already the same entity photo and everything works fine.
My Api controller:
<?php
/**
* #throws AccessDeniedException
* #return array
* #FOSRest\View()
*/
public function apiUploadAction()
{
$photo = new Photo;
$photo->setUser($this->getUser());
$photo->setFile = new UploadedFile(
$_FILES["file"]["tmp_name"],
$_FILES["file"]["name"],
$_FILES["file"]["type"],
$_FILES["file"]["size"],
$_FILES["file"]["error"],
$test = false
);
$em = $this->getDoctrine()->getManager();
$em->persist($photo);
$em->flush();
$apiResponse = array(
"code" => true,
"style" => "success",
/*********** SCREENSHOT COMES FROM HERE ***********/
"message" => $_FILES["file"]["tmp_name"]." ".$_FILES["file"]["name"]." ".$_FILES["file"]["type"]." ".$_FILES["file"]["size"]." ".$_FILES["file"]["error"],
);
$view = View::create();
$view->setFormat('json');
$view->setData($apiResponse);
return $this->get('fos_rest.view_handler')->handle($view);
}
The $apiResponse.message (screenshot):
As you can see symfony has the image so the problem don't come from my app mobile. new UploadedFile(); is the right way ? To upload without form.

Here is the solution :
Replace :
$photo->setFile = new UploadedFile(
$_FILES["file"]["tmp_name"],
$_FILES["file"]["name"],
$_FILES["file"]["type"],
$_FILES["file"]["size"],
$_FILES["file"]["error"],
$test = false
);
by
$photo->setFile($this->getRequest()->files->get('file'));

Related

What I am doing wrong with twitter API?

I am making a widget using https://github.com/j7mbo/twitter-api-php.
My widget is working fine there is no problem in my widget.
So what's the problem:
Inside my TwitterWidget Class whichi is extending WP_Widget inside the widget( $args, $instance ). I have make a function inside :
Here is it:
function get_Connection_With_Twitter_API( $scr_name, $cons_key, $cons_secret, $acce_token_key, $acce_token_secret ) {
$settings = array(
'oauth_access_token' => $acce_token_key,
'oauth_access_token_secret' => $acce_token_secret,
'consumer_key' => $cons_key,
'consumer_secret' => $cons_secret
);
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name='.$scr_name;
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($settings);
echo $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
// $twitter = new TwitterAPIExchange($settings);
// return $twitter->buildOauth($url, $requestMethod)
// ->setPostfields($postfields)
// ->performRequest();
}
$connection = get_Connection_With_Twitter_API( $instance['twitter_username'], $instance['twitter_consumerkey'], $instance['twitter_consumersecret'], $instance['twitter_accesstoken'], $instance['twitter_accesstokensecret'] );
I am getting this message:
{"errors":[{"code":89,"message":"Invalid or expired token."}]}
What I am doing wrong.
I assume you have your access tokens and you are being careful not displaying them here, and you have created a new app on the twitter account. On that light, I strongly suggest you change the permission of your app to "Read, Write and Direct Message".
For the perfect and most simple and well documented api, I suggest Twit.

why Update and insert in same method is not working in symfony?

I am using symfony3 with window 7:
This method should work for both action update and add.But its behavior only insertion. while i am setting $id also.
/**
* #Route("entity/entity/{id}", name="entity_entity",defaults={"id" = 0})
*/
public function entityAction(Request $request,$id){
$action = false;
$arr_XYZ_data = array();
$arr_XYZ_prepare_data = array();
$form_title = 'Add New XYZ';
$obj_XYZ = new XYZ();
$form = $this->createForm(XYZType::class, $obj_XYZ);
if($id!=0){
$obj_repo = $this->getDoctrine()->getRepository('AppBundle:XYZ');
$arr_XYZ_data = $obj_repo->find($id);
if($arr_XYZ_data){
$action = true;
$form_title = 'Update XYZ';
$arr_XYZ_data = $obj_repo->findXYZById($id);
$arr_XYZ_prepare_data = $this->_prepareData($arr_XYZ_data);
}
}
$form->handleRequest($request);
if (($form->isSubmitted())) {
$obj_XYZ->setXYZId($id);
$str_hiddenfield_result = $form->get('extraformfield')->getData();
$arr_hiddenfield_result = explode('&',$str_hiddenfield_result);
$obj_XYZ->setDef($obj_XYZ->getDef()->getDefId());
$obj_XYZ->setAbc($arr_hiddenfield_result[3]);
$obj_XYZ->setAuthor(1); //ldap session value
$em = $this->getDoctrine()->getManager();
$em->persist($obj_XYZ);
$em->flush();
$this->addFlash('success', 'Your record has been added successfully!');
return $this->redirectToRoute('XYZ_index', array(), 301);
}
}
anyone can suggest me how can i achieve this ?
Some remarks:
Are you calling the right URL (with $id != 0)?
Check if the form that is submitted is valid before doing anything.
Why are you calling setId() on the entity? Doctrine will set the ID of a new and persisted entity.
Finally, you are using a 301 redirect, which is a Permanent Redirect. This means that the browser will redirect any request to entity/entity/{id} to whichever URL is generated by XYZ_index.
I would recommend the following things:
Use isValid instead of isSubmitted for the form (it might not be valid but you are persisting its data!).
Use the built-in Forms, which you can load with an entity (so that you do not have to process data fields yourself).
Return a $this -> redirectToRoute('...', array(...)) instead of a 301.
After a lot of R&D i got the solution:
use:
$em->merge($obj_XYZ) instead of $em->persist($obj_XYZ);
before
$em->flush();

Delete test entity after testing with phpunit symfony

When I test an entity it creates it in the database but I can't manage to delete it. I think I have the default code to delete the entity but it does not work, is there another way? am I missing something?
Here is the code. I'm using symfony 2.7.8 and Php unit 4.8.0
public function testCreateCurso()
{
// Create a new client to browse the application
$client = static::createAuthorizedClient();
// Create a new entry in the database
$crawler = $client->request('GET', '/admin/curso/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(), 'Unexpected HTTP status code for GET /curso/');
$crawler = $client->click($crawler->selectLink('Crear Nuevo Curso')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Create')->form(array(
'appbundle_curso[nombreCurso]' => 'Test',
'appbundle_curso[codigoCurso]' => 'Test4',
// ... other fields to fill
));
$client->submit($form);
$this->assertTrue($client->getResponse()->isRedirect());
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test")')->count(), 'Missing element td:contains("Test")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Editar')->link());
$form = $crawler->selectButton('Update')->form(array(
'appbundle_curso[nombreCurso]' => 'Foo',
'appbundle_curso[codigoCurso]' => 'Foo1',
// ... other fields to fill
));
$client->submit($form);
//
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
// Delete the entity
$client->submit($crawler->selectButton('Delete')->form());
$crawler = $client->followRedirect();
// Check the entity has been delete on the list
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
var_dump($client->getResponse()->getContent());
}
This code is actually showing us how you test the UI, but the real code that is actually deleting the entity...
So, you should first of all check that both scenarios (adding an entity and deleting it) are actually working properly with unit tests (maybe when deleting the entity you're not flushing changes, for example...).
Then, when you have demonstrated yourself that you can actually add and delete the entity, and the controllers are working, then you should test your user interface, and that's what you're showing us.
So, if you've already done this, the issue is on your UI (for example, your button can't be followed).
Maybe a little bit more of information?
I was missing this method to delete the entity from the database
/**
* Close doctrine connections to avoid having a 'too many connections'
* message when running many tests
*/
public function tearDown(){
parent::tearDown();
}

PhpUnit test very long

I'm doing some functional testing with PHPUnit in Symfony2 .
I use PHPUnit version 4.4.1 ,tests were created with the controller generation (doctrine:generate:crud)
So , I only tests the CRUD on an User, and it takes me more than 30 seconds (This varies between 30 and 40s ) . Is this comes from the code? Tests themselves ? The fact that I worked on a remote server?
Here is the test class :
class UserControllerTest extends WebTestCase
{
/**
* Test CRUD functions (Create, read, update, delete)
*/
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient();
// Create a new entry in the database
$crawler = $client->request('GET', '/user/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /user/");
$crawler = $client->click($crawler->selectLink('Create a new entry')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Create')->form(array(
's_dosfabbundle_user[login]' => 'test.test',
's_dosfabbundle_user[trigram]' => 'tet',
's_dosfabbundle_user[email]' => 'test#test.com',
's_dosfabbundle_user[productionUnits]' => '11',
's_dosfabbundle_user[roles]' => '55',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("test.test")')->count(), 'Missing element td:contains("test.test")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
$form = $crawler->selectButton('Update')->form(array(
's_dosfabbundle_user[login]' => 'test.testUpdate',
's_dosfabbundle_user[trigram]' => 'tetU',
's_dosfabbundle_user[email]' => 'test_update#test.com',
's_dosfabbundle_user[productionUnits]' => '11',
's_dosfabbundle_user[roles]' => '57',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="tetU"]')->count(), 'Missing element [value="tetU"]');
// Delete the entity
$client->submit($crawler->selectButton('Delete')->form());
$crawler = $client->followRedirect();
// Check the entity has been delete on the list
$this->assertNotRegExp('/tetU/', $client->getResponse()->getContent());
}
}
Just a shot in the dark, as more info is needed, but I had the same issue. If you've got xdebug enabled, you could try disabling it, see disabling xdebug. This is of course only relevant if you're not using it for things like code coverage (which always takes quite a while).

Elastic Search : How to get most researched terms

i m implemeting elasticsearch in a symfony2 project with fos_elastica.
everythings works fine ( indexing data, updating, etc.)
i m currently looking for user behavior analysis : i would like to get the 10 most user searches or keywords in order to re-query it .
for example :
if 45% of searches are about yellow balloons and 45% are about red balloons, i would like to suggest on my homepage some yellow or red balloons
firstly, i was thinking about creating a symfony2 entity to save user search with a timestamp then compute last 1000 searches to get the most famous keywords. although it would surely work , that would be resource killer.
i was wondering if elasticsearch is able to provide these and how to implement it .
i ve read that i could create an index to store my user queries ( and that would be awsome, cause i could use facets to compute them really easily ) , but i don t know how to do save it directly in elastic search from symfony2 without an dedicated entity.
Okay, i finally got it !
here are the different steps :
1) create a new index in config.yml with a specific mapping for your keywords search
in config.yml
indexes:
your_index:
types:
search:
mappings:
value: {type:string}
date : {type:date}
provider: acme\AppBundle\Service\SearchProvider
2) create a new class SearchProvider in Service directory
in acme\Appbundle\Service\SearchProvider
<?php
namespace acme\AppBundle\Service;
use FOS\ElasticaBundle\Provider\ProviderInterface;
use Elastica\Type;
use Elastica\Document;
class SearchProvider implements ProviderInterface
{
protected $searchType;
private $search;
public function __construct(Type $searchType)
{
$this->searchType = $searchType;
}
// the function you will call from your service
public function add( $search )
{
$this->search = $search;
$this->populate();
}
/**
* Insert the repository objects in the type index
*
* #param \Closure $loggerClosure
* #param array $options
*/
public function populate(\Closure $loggerClosure = null, array $options = array())
{
if ($loggerClosure) {
$loggerClosure('Indexing users');
}
$date = time();
$document = new Document();
$document->setData(array('value' => $this->search, 'date' => $date ) );
$this->userType->addDocuments(array($document));
$this->userType->getIndex()->refresh();
}
}
3) create a new service declaration in your service.yml
services:
acme.search_provider:
class: acme\AppBundle\Service\SearchProvider
arguments:
- #fos_elastica.index.recetas.search
tags:
- { name: fos_elastica.provider, index: your_index, type: search }
4) call your service to store new searches like this
$this->get("acme.search_provider")->add("kapoue");
kapoue will be added to the searches.
5) get all the search keywords and rank it with aggregation
$es = $this->get('fos_elastica.index.acme.search');
$query = new \Elastica\Query();
$aggregation = new \Elastica\Aggregation\Terms("top_hits");
$aggregation->setField('value');
$aggregation->setSize( 3 );
$query->addAggregation($aggregation);
$result = $es->search($query);
$mostResearched = $result->getAggregation("top_hits");
print_r ( $mostResearched ); die();

Resources