hey there I'm trying to do crud operation using Symfony and elastic search, crud is working fine but when I insert or delete data then elastic search data is not updating by self I need to run populate command every time. can you help with this?
here is my fos_elastica.yml file.
fos_elastica:
clients:
default: { url: '%env(ELASTICSEARCH_URL)%' }
indexes:
reply:
properties:
category:
type: object
properties:
title: ~
persistence:
driver: orm
model: App\Entity\Reply
and here is my controller.
<?php
namespace App\Controller\CP\Support\Replies;
use App\Controller\CP\AbstractCPController;
use App\Entity\Reply;
use App\Form\Filter\ReplyFilterType;
use App\Form\ReplyType;
use App\Repository\ReplyRepository;
use App\Security\Enum\AdminPermission;
use App\Security\Routing\DenyAccessUnlessGranted;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use FOS\ElasticaBundle\Finder\TransformedFinder;
use Elastica\Util;
use Throwable;
#[Route('/support/pre-defined-replies/reply')]
#[DenyAccessUnlessGranted(permission: AdminPermission::MANAGE_PRE_DEFINED_REPLIES_REPLY)]
class ReplyController extends AbstractCPController
{
private ReplyRepository $replyRepository;
public function __construct(ReplyRepository $replyRepository)
{
$this->replyRepository = $replyRepository;
}
#[Route('/', name: 'cp_support_pre_defined_replies_reply_index', methods: ['GET'])]
public function index(TransformedFinder $replyFinder, Request $request): Response
{
$searchTerm = '';
$filterForm = $this->createForm(ReplyFilterType::class);
$filterForm->handleRequest($request);
if ($filterForm->isSubmitted()) {
$category = $filterForm->get('category')->getData();
$searchTerm = $category->getName();
}
$search = Util::escapeTerm($searchTerm);
$results = $replyFinder->find($search);
return $this->render('support/pre_defined_replies/reply/index.html.twig', [
'replies' => $results,
'form' => $filterForm->createView(),
]);
}
#[Route('/new', name: 'cp_support_pre_defined_replies_reply_new', methods: ['GET', 'POST'])]
public function new(Request $request): Response
{
$reply = new Reply();
$form = $this->createForm(ReplyType::class, $reply);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$this->replyRepository->add($reply, true);
$this->addFlash('success', 'successfully created new reply.');
} catch (Throwable $throwable) {
$this->addFlash('danger', 'fail create new reply.');
}
return $this->redirectToRoute('cp_support_pre_defined_replies_reply_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('support/pre_defined_replies/reply/new.html.twig', [
'reply' => $reply,
'form' => $form,
]);
}
#[Route('/{id}/edit', name: 'cp_support_pre_defined_replies_reply_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Reply $reply): Response
{
$form = $this->createForm(ReplyType::class, $reply);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$this->replyRepository->add($reply, true);
$this->addFlash('success', 'successfully updated reply');
} catch (Throwable $throwable) {
$this->addFlash('danger', 'failed to update reply');
}
return $this->redirectToRoute('cp_support_pre_defined_replies_reply_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('support/pre_defined_replies/reply/edit.html.twig', [
'reply' => $reply,
'form' => $form,
]);
}
#[Route('/{id}/delete', name: 'cp_support_pre_defined_replies_reply_delete', methods: ['POST'])]
public function delete(Request $request, Reply $reply): Response
{
$csrfTokenReply = (string) $request->request->get('csrf');
$status = false;
$errorMessage = null;
if ($this->isCsrfTokenValid('reply', $csrfTokenReply)) {
try {
$this->replyRepository->remove($reply);
$status = true;
$this->addFlash('danger', 'category successfully deleted');
} catch (\Throwable $e) {
$errorMessage = 'An error occurred when deleting category from DB.';
}
} else {
$errorMessage = 'Invalid CSRF token';
}
return new JsonResponse(['status' => $status, 'errorMessage' => $errorMessage]);
}
}
we can use refresh indexes in elastic search for update data
first we need to bind new parameter in service.yaml file
App\Controller\CP\Support\Replies\ReplyController:
tags: [ controller.service_arguments ]
bind:
FOS\ElasticaBundle\Finder\TransformedFinder $replyFinder: '#fos_elastica.finder.reply'
FOS\ElasticaBundle\Elastica\Index: '#fos_elastica.index.reply'
then we can use simply like this in controller to refresh indexes
#[Route('/new', name: 'cp_support_pre_defined_replies_reply_new', methods: ['GET', 'POST'])]
public function new(Request $request, Index $replyIndex): Response
{
$reply = new Reply();
$form = $this->createForm(ReplyType::class, $reply);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$this->replyRepository->add($reply, true);
$this->addFlash('success', 'successfully created new reply.');
$replyIndex->refresh();
} catch (Throwable $throwable) {
$this->addFlash('danger', 'fail create new reply.');
}
return $this->redirectToRoute('cp_support_pre_defined_replies_reply_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('support/pre_defined_replies/reply/new.html.twig', [
'reply' => $reply,
'form' => $form,
]);
}
Related
I created a new project in Laravel that consumes all data from an API. For private data like a user profile, I need an access token to get the data.
Once I have an access token, how do I set the token as Auth::id() in Laravel? Or perhaps I can store the user profile as Auth::user() so that I can use #auth in a frontend blade file?
class CustomAuthController extends Controller
{
public function index()
{
return view('login');
}
public function store(Request $request)
{
$request->validate([
'phone' => 'required|numeric'
]);
$data = [
'phone' => $request->phone
];
$codeSent = GeneralFunction::WebRequestPublicApi('first-login', $data, null, null, null, true);
if($codeSent->status == "success")
{
return redirect('verify');
} else {
$errors = new MessageBag();
$errors->add("phone", "Invalid phone number");
return view('login')->withErrors($errors);
}
}
public function showVerify()
{
return view('verify');
}
public function verify(Request $request)
{
try {
$request->validate([
'verify' => 'required|size:6'
]);
$data = [
'token_code' => $request->verify,
'source' => 'web'
];
$token = GeneralFunction::WebRequestPublicApi('verify-login', $data, null, null, null, true);
if($token->status === "success")
{
$userData = GeneralFunction::WebRequestPublicApi('membership', null, 'GET', null, null, true, $token->results->access_token);
if($userData->status !== "error")
{
$user = (array) $userData->results[0];
$request->session()->put('token', $token->results->access_token);
Auth::attempt($user, false, false);
return redirect('/');
}
} else {
$errors = new MessageBag();
$errors->add("verify", "Invalid Token");
return view('verify')->withErrors($errors);
}
} catch (Exception $e) {
$errors = new MessageBag();
$errors->add("verify", $e->getMessage());
return view('verify')->withErrors($errors);
}
}
}
I tried using Auth::attempt, Auth::login(), and the other method, but all of these required a user table. My project does not have a database.
You can do something like following.
In the controller
if($auth_ok)
{
session(['user' => ['key' => 'value', 'key2' => 'value2'] ]); // set session data
return view('frontend');
}
In the view
$user = session('user', false);
#if(!$user) // if not logged in
do something
#else // logged in successfully
Welcome my user
#endif
Hope this helps.
i guess the best thing you need to do is to use sqlite and once you got login from your api create a new user from it or find if there is existing already and Auth::login($newUser);
I use post man to test my api , So when I send the token in header I get token not provided , but when i pass it in body raw in json format I get a succes result, So I want to get succes result when I pass my token in header
How I can make this change ??
This my Postcompanies controller
class CompaniesController extends Controller
{
public function index(Request $request)
{
# code...
// $Ads = ads::all();
// return $this->sendResponse($Ads->toArray(), 'Ads read succesfully');
// This is the name of the column you wish to search
$input = $request->all();
$validator = Validator::make($input, [
'user_id'=> 'required'
] );
$Companies = Companies::where('user_id','=', $request->user_id)->first();
return response()->json(['Companies'=>$Companies]);
}
public function stockcompanies (Request $request){
$input = $request->all();
$validator = Validator::make($input, [
'title'=> 'required',
'description'=> 'required',
'logo_path'=> 'image|nullable|max:1999'
] );
$user_id = Auth::id();
if($request->hasFile('logo_path')){
// Get filename with the extension
$filenameWithExt = $request->file('logo_path')->getClientOriginalName();
// Get just filename
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
// Get just ext
$extension = $request->file('logo_path')->getClientOriginalExtension();
// Filename to store
$fileNameToStore= $filename.'_'.time().'.'.$extension;
// Upload Image
$path = $request->file('logo_path')->storeAs('public/cover_images', $fileNameToStore);
} else {
$fileNameToStore = 'noimage.jpg';
}
if ($validator -> fails()) {
# code...
return response()->json($validator->errors());
}
//$Cards = CreditCards::create($input,$user_id);
$companies = Companies::create([
'title' => $request->get('title'),
'description' => $request->get('description'),
'logo_path' => $fileNameToStore,
'user_id' => $user_id
]);
return response()->json(['Companies'=>$companies]);
}
}
and this is my api :
Route::group(['middleware' => ['jwt.auth']], function() {
Route::post('postmycompanies', 'CompaniesController#stockcompanies');
Route::get('test', function(){
return response()->json(['foo'=>'bar']);
});
I resolve my probleme :
I use a custom middelware
namespace App\Http\Middleware;
use Closure;
use JWTAuth;
use Exception;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class JwtMiddleware extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
try {
$user = JWTAuth::parseToken()->authenticate();
} catch (Exception $e) {
if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
return response()->json(['status' => 'Token is Invalid']);
}else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
return response()->json(['status' => 'Token is Expired']);
}else{
return response()->json(['status' => 'Authorization Token not found']);
}
}
return $next($request);
}
}
Next, we need to register our middleware. Open app/http/Kernel.php and add the following:
[...]
protected $routeMiddleware = [
[...]
'jwt.verify' => \App\Http\Middleware\JwtMiddleware::class,
];
[...]
Next, Open routes/api.php and add the content with the following:
Route::group(['middleware' => ['jwt.verify']], function() {
Route::post('postmycompanies', 'CompaniesController#stockcompanies');
});
I'm still trying to add a recaptcha to my website, I want try the recaptcha from Google but I can't use it properly. Checked or not, my email is still sent.
I tried to understand the code of How to validate Google reCaptcha v2 using phalcon/volt forms?.
But i don't understand where are my problems and more over how can you create an element like
$recaptcha = new Check('recaptcha');
My controller implementation :
<?php
/**
* ContactController
*
* Allows to contact the staff using a contact form
*/
class ContactController extends ControllerBase
{
public function initialize()
{
$this->tag->setTitle('Contact');
parent::initialize();
}
public function indexAction()
{
$this->view->form = new ContactForm;
}
/**
* Saves the contact information in the database
*/
public function sendAction()
{
if ($this->request->isPost() != true) {
return $this->forward('contact/index');
}
$form = new ContactForm;
$contact = new Contact();
// Validate the form
$data = $this->request->getPost();
if (!$form->isValid($data, $contact)) {
foreach ($form->getMessages() as $message) {
$this->flash->error($message);
}
return $this->forward('contact/index');
}
if ($contact->save() == false) {
foreach ($contact->getMessages() as $message) {
$this->flash->error($message);
}
return $this->forward('contact/index');
}
$this->flash->success('Merci, nous vous contacterons très rapidement');
return $this->forward('index/index');
}
}
In my view i added :
<div class="g-recaptcha" data-sitekey="mypublickey0123456789"></div>
{{ form.messages('recaptcha') }}
But my problem is after : i create a new validator for the recaptcha like in How to validate Google reCaptcha v2 using phalcon/volt forms? :
use \Phalcon\Validation\Validator;
use \Phalcon\Validation\ValidatorInterface;
use \Phalcon\Validation\Message;
class RecaptchaValidator extends Validator implements ValidatorInterface
{
public function validate(\Phalcon\Validation $validation, $attribute)
{
if (!$this->isValid($validation)) {
$message = $this->getOption('message');
if ($message) {
$validation->appendMessage(new Message($message, $attribute, 'Recaptcha'));
}
return false;
}
return true;
}
public function isValid($validation)
{
try {
$value = $validation->getValue('g-recaptcha-response');
$ip = $validation->request->getClientAddress();
$url = $config->'https://www.google.com/recaptcha/api/siteverify'
$data = ['secret' => $config->mysecretkey123456789
'response' => $value,
'remoteip' => $ip,
];
// Prepare POST request
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
],
];
// Make POST request and evaluate the response
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return json_decode($result)->success;
}
catch (Exception $e) {
return null;
}
}
}
So i don't know if tjis code is correct anyway, i have a problem too after that : how to create an object "recaptcha" in my form add
$recaptcha = new ?????('recaptcha');
$recaptcha->addValidator(new RecaptchaValidator([
'message' => 'Please confirm that you are human'
]));
$this->add($recaptcha);
PS: I apologize because i'm a noob here and my mother tongue is not english, so if you don't understand me or want give me some advices to create a proper question, don't hesitate ^^
I've made a custom form element for recaptcha. Used it for many projects so far.
The form element class:
class Recaptcha extends \Phalcon\Forms\Element
{
public function render($attributes = null)
{
$html = '<script src="https://www.google.com/recaptcha/api.js?hl=en"></script>';
$html.= '<div class="g-recaptcha" data-sitekey="YOUR_PUBLIC_KEY"></div>';
return $html;
}
}
The recaptcha validator class:
use Phalcon\Validation\Validator;
use Phalcon\Validation\ValidatorInterface;
use Phalcon\Validation\Message;
class RecaptchaValidator extends Validator implements ValidatorInterface
{
public function validate(\Phalcon\Validation $validation, $attribute)
{
$value = $validation->getValue('g-recaptcha-response');
$ip = $validation->request->getClientAddress();
if (!$this->verify($value, $ip)) {
$validation->appendMessage(new Message($this->getOption('message'), $attribute, 'Recaptcha'));
return false;
}
return true;
}
protected function verify($value, $ip)
{
$params = [
'secret' => 'YOUR_PRIVATE_KEY',
'response' => $value,
'remoteip' => $ip
];
$response = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?' . http_build_query($params)));
return (bool)$response->success;
}
}
Using in your form class:
$recaptcha = new Recaptcha($name);
$recaptcha->addValidator(new RecaptchaValidator([
'message' => 'YOUR_RECAPTCHA_ERROR_MESSAGE'
]));
Note 1: You were almost there, you just missed to create custom form element (the first and last code piece from my example);
Note 2: Also there is a library in Github: https://github.com/fizzka/phalcon-recaptcha I have not used it, but few peeps at phalcon forum recommended it.
Ok i got stuck and no info in documentation about this (correct me if i am wrong)
Example: i have update metod in controller, some form and if forim is valid i use flush method to make changes. How can i check if changes were made in DB so i can send flash message if changes were made "Success" or if query is not executed if there is some error i send flash message "Failed to make changes to DB"
Here is example of my code but i think that flush returns void or null so this is not the way to go, maybe it returns some exceptions on failure i dont know..
/**
* #Route("createpost", name="createpost")
*/
public function createPostAction(Request $request) {
if (!$this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) {
throw $this->createAccessDeniedException();
}
$post = new Post();
$form = $this->createForm(new PostForm(), $post);
$form->handleRequest($request);
if($form->isValid()) {
$user = $this->getUser();
$author = $user->getUsername();
//$post->setPublishDate(new \DateTime);
$post->setAuthor($author);
$em = $this->getDoctrine()->getManager();
$em->persist($post);
$pom = $em->flush();
return $this->render('success/success.html.twig', array(
'test' => var_dump($pom)
));
if($pom) {
$this->addFlash(
'notice',
'You have successfully created post'
);
}
return $this->redirectToRoute('home', array(), 301);
}
return $this->render(
'create/post.html.twig', array(
'form' => $form->createView()
));
}
You can do it like this:
...
if($form->isValid()) {
$user = $this->getUser();
$author = $user->getUsername();
//$post->setPublishDate(new \DateTime);
$post->setAuthor($author);
$em = $this->getDoctrine()->getManager();
$em->persist($post);
$em->flush();
if(null != $post->getId()) {
$this->addFlash(
'notice',
'You have successfully created post'
);
return $this->render('success/success.html.twig', array(
'test' => var_dump($pom)
));
}
// This line never be called
return $this->redirectToRoute('home', array(), 301);
}
...
However, you don't need to check if flush worked properly or not, it throws an exception if something goes wrong..
Update for the comment:
if($form->isValid()) {
try {
$user = $this->getUser();
$author = $user->getUsername();
//$post->setPublishDate(new \DateTime);
$post->setAuthor($author);
$em = $this->getDoctrine()->getManager();
$em->persist($post);
$em->flush();
if(null != $post->getId()) {
$this->addFlash(
'notice',
'You have successfully created post'
);
return $this->render('success/success.html.twig', array(
'test' => var_dump($pom)
));
}
} catch (SOMEEXCEPTION $e) {
return $this->redirectToRoute('home', array(), 301);
}
}
Change
return $this->render('success/success.html.twig', array(
'test' => var_dump($pom)
));
if($pom) {
$this->addFlash(
'notice',
'You have successfully created post'
);
}
To
if($pom) {
$this->addFlash(
'notice',
'You have successfully created post'
);
}
return $this->render('success/success.html.twig', array(
'test' => var_dump($pom)
));
You need to add flash before returning the response
I'm new to Payum. A lot thing quite confuse to me. I'm try to build up a simple paypal express checkout like the example show on the Payum document.However, when I tried to process the payment, it shows up an exception:
"Payum payment named my_paypal_express_checkout does not exist.
500 Internal Server Error - InvalidArgumentException"
Here is the config:
payum:
security:
token_storage:
Acme\PaymentBundle\Entity\PayumSecurityToken:
doctrine:
driver: orm
storages:
Acme\PaymentBundle\Entity\PaymentDetails:
doctrine:
driver: orm
contexts:
Ibase_paypal_express:
paypal_express_checkout_nvp:
...codes...
Here are the code of prepare and done action in controller:
public function preparePaypalAction(Request $request)
{
$paymentName = 'ibase_paypal_express_checkout';
$form = $this->createPurchaseForm();
$form->handleRequest($request);
if ($form->isValid()) {
$data = $form->getData();
$storage = $this->get('payum')->getStorage('Ibase\PaymentBundle\Entity\PaymentDetails');
/** #var \Ibase\CartBundle\Entity\PaymentDetails $paymentDetails */
$paymentDetails = $storage->createModel();
$paymentDetails['PAYMENTREQUEST_0_CURRENCYCODE'] = $data['currency'];
$paymentDetails['PAYMENTREQUEST_0_AMT'] = $data['amount'];//total amount ??
$storage->updateModel($paymentDetails);
$captureToken = $this->get('payum.security.token_factory')->createCaptureToken(
$paymentName,
$paymentDetails,
'payment_done' // the route to redirect after capture;
);
$paymentDetails['INVNUM'] = $paymentDetails->getId();
$paymentDetails['RETURNURL'] = $captureToken->getTargetUrl();
$paymentDetails['CANCELURL'] = $captureToken->getTargetUrl();
$storage->updateModel($paymentDetails);
return $this->redirect($captureToken->getTargetUrl());
}
return $this->render('PaymentBundle:PaypalExpress:paypalPrepare.html.twig', array(
'form' => $form->createView(),
'paymentName' => $paymentName
));
}
public function doneAction(Request $request)
{
$token = $this->get('payum.security.http_request_verifier')->verify($request);
$payment = $this->get('payum')->getPayment($token->getPaymentName());
$status = new BinaryMaskStatusRequest($token);
$payment->execute($status);
if ($status->isSuccess()) {
$this->getUser()->addCredits(100);
$this->get('session')->getFlashBag()->set(
'notice',
'Payment success. Credits were added'
);
} else if ($status->isPending()) {
$this->get('session')->getFlashBag()->set(
'notice',
'Payment is still pending. Credits were not added'
);
} else {
$this->get('session')->getFlashBag()->set('error', 'Payment failed');
}
return $this->redirect('home');
}
/**
* #return \Symfony\Component\Form\Form
*/
protected function createPurchaseForm()
{
return $this->createFormBuilder()
->add('amount', null, array(
'data' => 1,
'constraints' => array(new Range(array('max' => 2)))
))
->add('currency', null, array('data' => 'AUD'))
->getForm()
;
}
Anyone can help will be appreciate!
Look at your YML file
contexts:
Ibase_paypal_express:
and your code :
$paymentName = 'ibase_paypal_express_checkout';
Notice the capital 'I' and string name? Those two names/values should be the same.
So either
$paymentName = 'Ibase_paypal_express';
or
contexts:
ibase_paypal_express_checkout: