I'm working in an API rest with Symfony, FOSRestBundle.
i have a route who return some informations about the user, and i don't know why the return is always null in Postman.
/**
* #Route("/api/user/{id}", name="api_user_informations")
* #ParamConverter("user", class="UserBundle:User", options={"id" = "id"})
* #Method("GET")
*/
public function indexAction(Request $request, User $user = null)
{
if (!$user):
return new JsonResponse([
"code" => Response::HTTP_NOT_FOUND,
"error" => "No user found with this id."
]);
endif;
return new JsonResponse($user);
}
What is wrong with this ?
config.yml
fos_rest:
routing_loader:
include_format: false
view:
view_response_listener: true
format_listener:
enabled: true
rules:
- { path: '^/', priorities: ['json'], fallback_format: 'json' }
Thanks boys :)
Related
We are creating an API-REST with Symfony 3.4 and using mongodb as db
All the mapping and cofiguration has been done, and it works.
buuuuuuuttt...
The softdeleteable filter is not working, I mean:
If I "delete" one document, the deletedAt works fine.
Then, if I try to get all the documents of this collection, or even just THAT document, I CAN DO IT !!! even if it's deleted.
And if I delete again that same document, it is fully deleted from the database.
This is my config.yml :
stof_doctrine_extensions:
default_locale: '%locale%'
mongodb:
default:
timestampable: true
softdeleteable: true
translatable: true
loggable: true
uploadable: true
translation_fallback: true
uploadable:
default_file_path: "%kernel.root_dir%/../web/files/"
# Doctrine Configuration
doctrine_mongodb:
default_database: "%mongodb_default_db%"
document_managers:
default:
retry_connect: 5
retry_query: 5
auto_mapping: true
filters:
softdeleteable:
class: Gedmo\SoftDeleteable\Filter\ODM\SoftDeleteableFilter
enabled: true
mappings:
#translatable
gedmo_translatable:
type: annotation
alias: GedmoTranslatable
prefix: Gedmo\Translatable\Document
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Document"
is_bundle: false
#loggable
gedmo_loggable:
type: annotation
alias: GedmoLoggable
prefix: Gedmo\Loggable\Document
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Loggable/Document"
is_bundle: false
proxy_namespace: MongoDBODMProxies
proxy_dir: "%kernel.cache_dir%/doctrine/odm/mongodb/Proxies"
auto_generate_proxy_classes: '%kernel.debug%'
An example of the mapping:
Example\ExampleBundle\Model\Example:
collection: example
gedmo:
loggable: true
translation:
locale: locale
soft_deleteable:
field_name: deletedAt
time_aware: false
fields:
id:
type: object_id
id: true
name:
type: string
nullable: false
gedmo:
- translatable
- versioned
description:
type: string
nullable: false
gedmo:
- translatable
- versioned
createdAt:
name: created_at
type: date
gedmo:
timestampable:
on: create
updatedAt:
name: updated_at
type: date
gedmo:
timestampable:
on: update
deletedAt:
name: deleted_at
type: date
nullable: true
And my model:
class Example
{
private $id;
...
private $createdAt;
private $updatedAt;
private $deletedAt;
public function getId()
{
return $this->id;
}
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
public function getCreatedAt()
{
return $this->createdAt;
}
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getUpdatedAt()
{
return $this->updatedAt;
}
public function setDeletedAt($deletedAt)
{
$this->deletedAt = $deletedAt;
return $this;
}
public function getDeletedAt()
{
return $this->deletedAt;
}
}
In the controller, for example, to get a document by its ID, I have:
/**
* Get a single entity.
*
* #ApiDoc(
* resource=true,
* description="Get a single Example.",
* output= {"class"=Example::class},
* statusCodes={
* 200="Returned when successful",
* 404="Returned when not found"
* },
* parameters={
* {"name"="id", "dataType"="integer", "required"=true, "description"="Example id"}
* }
* )
*
* #FOS\Get("/example/{id}", requirements={"id": "([a-f\d]{24})|(\d+)"})
* #FOS\View
*
* #param Example $example
*
* #return Response
*/
public function getExampleAction(Example $example)
{
return array('example' => $example);
}
please, what am I doing wrong?
I have already 2 days trying different things but nothing :(
in the documentation it's say:
"For now, it works only with the ORM"
https://github.com/stof/DoctrineExtensions/blob/master/doc/softdeleteable.md
So i think it's not totally works with ODM, sorry.
Can you complete your querys to check the deletedAt field?
Can anyone please help me I'm desperate here !!!
I am working on a symfony 3 project and I have different actions to persist data to database or to update it but none of them is working. The code is fine I'm guessing it's a problem with the routing. This one is the action to add element to database
public function newAction(Request $request)
{
...
if($request->isMethod('POST')) {
...
return $this->redirectToRoute('meeting_new', array(
'meeting' => $meeting
));
...
}
return $this->render('SocialProMeetingBundle::ajoutMeeting.html.twig', array('users'=>$users));
}
and this is the updating action
public function editAction(Request $request, Meeting $meeting)
{
...
if($request->isMethod('POST')) {
...
return $this->redirectToRoute('meeting_edit', array(
'id' => $meeting->getId()
));
}
return $this->render('meeting/edit.html.twig', array(
'meeting' => $meeting,
));
}
and this is my routing file
meeting_index:
path: /
defaults: { _controller: "SocialProMeetingBundle:Meeting:index" }
methods: GET
meeting_show:
path: /show
defaults: { _controller: "SocialProMeetingBundle:Meeting:show" }
methods: [GET, POST]
meeting_new:
path: /new
defaults: { _controller: "SocialProMeetingBundle:Meeting:new" }
methods: [GET, POST]
meeting_edit:
path: /{id}/edit
defaults: { _controller: "SocialProMeetingBundle:Meeting:edit" }
methods: [GET, POST]
meeting_delete:
path: /{id}/delete
defaults: { _controller: "SocialProMeetingBundle:Meeting:delete" }
methods: DELETE
One problem is in your function newAction where you are passing in a meeting parameter and the route doesn't handle it. This code:
return $this->redirectToRoute('meeting_new', array(
'meeting' => $meeting
));
Your route needs to handle the parameter like so:
meeting_new:
path: /new/{meeting}
defaults: { _controller: "SocialProMeetingBundle:Meeting:new" }
methods: [GET, POST]
how validate entity variable, because in my point it's valid for empty select.
/**
* #Assert\NotBlank(message = "education level cannot be empty")
* #var EducationLevel[]|ArrayCollection
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\EducationLevel")
*/
private $educationLevel;
form type
->add('educationLevel', EntityType::class, [
'class' => 'AppBundle:EducationLevel',
'multiple' => true,
'choice_label' => function ($educationLevel) {
return $educationLevel->getName();
},
])
NotBlank won't work, because it checks if value is not null or not empty string or not false
NotBlank manual
What you have to do is to write custom Constraint and a validator:
Custom validator manual
You can create a validation method in the entity which can verify if $educationLevel is null or collection of EducationLevel instances.
/**
* #Assert\IsTrue(message="Education level has to be blank or...")
*/
public function isEducationLevelValid()
{
if ($this->educationLevel->isEmpty()) {
foreach ($this->educationLevel as $edulevel) {
if (!$edulevel instanceof EducationLevel) {
return false;
}
}
return true;
} else {
return false;
}
}
The method is used automatically during entity bound form submission and of course you can use it as a normal entity's method.
I have tried this, but it does not help me: Yii2 REST API BasicAuth not working
Here is what I did:
I have BaseController and DocumentController extending it.
in BaseController I have this code:
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator'] = [
'class' => 'yii\filters\ContentNegotiator',
'formats' => [
'application/json' => Response::FORMAT_JSON,
]
];
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
'auth' => [$this, 'authenticate']
];
return $behaviors;
}
/**
* Finds user by username and password
*
* #param string $username
* #param string $password
* #return static|null
*/
public function authenticate($username, $password)
{
// username, password are mandatory fields
if(empty($username) || empty($password)) {
return null;
}
// get user using requested email
$user = User::findByUsername($username);
// if no record matching the requested user
if(empty($user)) {
return null;
}
// if password validation fails
if(!User::validatePassword($password)) {
return null;
}
// if user validates (both user_email, user_password are valid)
return $user;
}
When I try to visit my api: localhost/api/documents/5
I get this error: Getting unknown property: app\\controllers\\DocumentController::password_hash
What I am supposed to do to make this thing work ? I just do not understand what yii wants from me anymore.
EDIT: full error :
{"name":"Unknown Property","message":"Getting unknown property: app\\controllers\\DocumentController::password_hash","code":0,"type":"yii\\base\\UnknownPropertyException","file":"/var/www/html/api/_protected/vendor/yiisoft/yii2/base/Component.php","line":143,"stack-trace":["#0 /var/www/html/api/_protected/models/UserIdentity.php(129): yii\\base\\Component->__get('password_hash')","#1 /var/www/html/api/_protected/controllers/AppController.php(58): app\\models\\UserIdentity->validatePassword('wspass')","#2 [internal function]: app\\controllers\\AppController->authenticate('wsuser', 'wspass')","#3 /var/www/html/api/_protected/vendor/yiisoft/yii2/filters/auth/HttpBasicAuth.php(68): call_user_func(Array, 'wsuser', 'wspass')","#4 /var/www/html/api/_protected/vendor/yiisoft/yii2/filters/auth/AuthMethod.php(60): yii\\filters\\auth\\HttpBasicAuth->authenticate(Object(yii\\web\\User), Object(yii\\web\\Request), Object(yii\\web\\Response))","#5 /var/www/html/api/_protected/vendor/yiisoft/yii2/base/ActionFilter.php(71): yii\\filters\\auth\\AuthMethod->beforeAction(Object(yii\\rest\\IndexAction))","#6 [internal function]: yii\\base\\ActionFilter->beforeFilter(Object(yii\\base\\ActionEvent))","#7 /var/www/html/api/_protected/vendor/yiisoft/yii2/base/Component.php(541): call_user_func(Array, Object(yii\\base\\ActionEvent))","#8 /var/www/html/api/_protected/vendor/yiisoft/yii2/base/Controller.php(269): yii\\base\\Component->trigger('beforeAction', Object(yii\\base\\ActionEvent))","#9 /var/www/html/api/_protected/vendor/yiisoft/yii2/web/Controller.php(108): yii\\base\\Controller->beforeAction(Object(yii\\rest\\IndexAction))","#10 /var/www/html/api/_protected/vendor/yiisoft/yii2/base/Controller.php(152): yii\\web\\Controller->beforeAction(Object(yii\\rest\\IndexAction))","#11 /var/www/html/api/_protected/vendor/yiisoft/yii2/base/Module.php(454): yii\\base\\Controller->runAction('index', Array)","#12 /var/www/html/api/_protected/vendor/yiisoft/yii2/web/Application.php(84): yii\\base\\Module->runAction('document/index', Array)","#13 /var/www/html/api/_protected/vendor/yiisoft/yii2/base/Application.php(375): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))","#14 /var/www/html/api/index.php(12): yii\\base\\Application->run()","#15 {main}"]}
I'm struggling to figure this out, but with everything I'm doing I am unable to fetch a users information. I simply get a 401 error and cannot figure out why.
Code:
<?php
class Tumblr
{
public function connect()
{
$tumblr = new ExternalExtended_Helper_Tumblr;
$oauth = $tumblr->getOauthConsumer('https://mysite.com/register');
$requestToken = $oauth->getRequestToken();
$accessToken = $oauth->getAccessToken($this->_input->filter(array(
'oauth_token' => XenForo_Input::STRING,
'oauth_verifier' => XenForo_Input::STRING
)), $requestToken);
$user = $tumblr->retrieveUserInfo($accessToken);
}
}
<?php
class Helper_Tumblr
{
/**
* Returns a reference to the OAuth consumer, instantiating it if necessary
*
* #param string $callbackUrl URL to return to
*
* #return bool|Zend_Oauth_Consumer False if no Tumblr app configured, otherwise Oauth consumer
*/
public static function getOauthConsumer($callbackUrl = '')
{
$options = XenForo_Application::getOptions();
if (!$options->tumblrAppKey || !$options->tumblrAppSecret)
{
return false;
}
return new Zend_Oauth_Consumer(array(
'callbackUrl' => $callbackUrl,
'requestTokenUrl' => 'https://www.tumblr.com/oauth/request_token',
'authorizeUrl' => 'https://www.tumblr.com/oauth/authorize',
'accessTokenUrl' => 'https://www.tumblr.com/oauth/access_token',
'consumerKey' => $options->tumblrAppKey,
'consumerSecret' => $options->tumblrAppSecret,
));
}
/**
* Returns a reference to the OAuth client, instantiating it if necessary
*
* #param string $accessToken Tumblr access token (from code swap, or given by user); may be empty
*
* #return bool|Zend_Oauth_Client False if no Tumblr app configured, otherwise Oauth client
*/
public static function getOauthClient($accessToken)
{
$options = XenForo_Application::getOptions();
if (!$options->tumblrAppKey || !$options->tumblrAppSecret)
{
return false;
}
$access = new Zend_Oauth_Token_Access();
$access->setToken($accessToken->getToken());
$access->setTokenSecret($accessToken->getToken());
return $access->getHttpClient(array(
'consumerKey' => $options->tumblrAppKey,
'consumerSecret' => $options->tumblrAppSecret
));
}
/**
* Get a User's Information
*
* #return json
*/
public static function retrieveUserInfo($accessToken)
{
$oauthClient = self::getOauthClient($accessToken);
$oauthClient->setUri('http://api.tumblr.com/v2/user/info');
$response = $oauthClient->request(Zend_Http_Client::POST);
if ($response->isError())
{
throw new Exception("An error occurred sending request. Status code: {$response->getStatus()}");
}
return $response;
}
}
The error occurs in the function 'retrieveUserInfo' and a dump of the object looks like this:
object(Zend_Http_Response)#280 (5) {
["version":protected] => string(3) "1.1"
["code":protected] => int(401)
["message":protected] => string(14) "Not Authorized"
["headers":protected] => array(7) {
["Server"] => string(5) "nginx"
["Date"] => string(29) "Mon, 17 Feb 2014 02:53:08 GMT"
["Content-type"] => string(31) "application/json; charset=utf-8"
["Transfer-encoding"] => string(7) "chunked"
["Connection"] => string(5) "close"
["Set-cookie"] => string(89) "tmgioct=53017993ddbda801421421421421; expires=Thu, 15-Feb-2024 02:53:07 GMT; path=/; httponly"
["P3p"] => string(46) "CP="ALL ADM DEV PSAi COM OUR OTRo STP IND ONL""
}
["body":protected] => string(71) "3c
{"meta":{"status":401,"msg":"Not Authorized"},"response":[]}
0
"
Why is it saying I'm not authorized and what haven't I done to become authorized?
Thanks!
Alright it's all fine, just a simple typo...
$access->setToken($accessToken->getToken());
$access->setTokenSecret($accessToken->getToken());
Should be:
$access->setToken($accessToken->getToken());
$access->setTokenSecret($accessToken->getTokenSecret());