Cakephp 3.x Crud plugin beforeFind event not available - rest

I have a Cakephp 3.x API using CRUD plugin.
This is my crud configuration:
$this->loadComponent('Crud.Crud', [
'actions' => [
'Crud.Index',
'Crud.View',
'Crud.Add',
'Crud.Edit',
'Crud.Delete'
],
'listeners' => [
'Crud.Api',
'Crud.ApiPagination',
'Crud.ApiQueryLog'
]
]);
In my controller when I call this->Crud->implementedEvents() it returns beforeFilter startuperxot beforePaginate only
public function index(){
$this->Crud->implementedEvents(); //returns beforeFilter startuperxot beforePaginate
$this->Crud->on('beforeFind', function(\Cake\Event\Event $event) {
if(isset($this->request->query['state'])){
$event->getSubject()->query->where(['state =' => $this->request->query['state']]);
}
});
return $this->Crud->execute();
}
How can I enable beforeFind listener? Thanks in advance.

You should use beforePaginate on index
https://crud.readthedocs.io/en/latest/actions/index.html#crud-beforepaginate

Related

Using Symfony Form component standalone with security-csrf - error on submission

I have a question regarding symfony/form using as a standalone component and security-csrf running with PHP build-in server. I hardly remember having such issue with the Symfony framework.
When setting symfony/form as a standalone component I tried this code for both v4.2 and v5.1 https://github.com/xmgcoyi/standalone-forms/tree/4.2+twig. A rewrite of webmozart's example mentioned here https://symfony.com/doc/current/components/form.html
The csrf token is generated with twig-bridge, but when submitting the form - on calling$form->isValid() - invalid csrf error appears.
By default csrf protection is enabled, setting to false - the form submits.
Tried CSRF component with both setups with NativeSessionTokenStorage and SessionTokenStorage + Session of HttpFoundation.
Could you give any hint on what I'm doing wrong and where to look at?
P.S.
Code samples with csrf error on submission:
https://github.com/xmgcoyi/standalone-forms/tree/4.2+twig
https://github.com/liorchamla/pratique-symfony-form/tree/06-protection-csrf
UPD
The apps above work well, the problem was in browser storage filled with garbage.
Setting to false in $formFactory->createBuilder(FormType::class, null, ['csrf_protection' => false]) submits the form
This is a bit of a guess but the 4.2 linked repo has:
$csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage);
$csrfTokenManager = new CsrfTokenManager();
Two token managers. One is used in the twig form engine and one is used in the form factory extension. Does not seem like a reasonable thing to do.
Here is an updated 5.1 working example. I stripped it down even more from your linked repo. But the only thing that I really changed was the token manager.
# index.php
require_once '../vendor/autoload.php';
$app = new App();
$app->run();
final class App
{
public function run()
{
$csrfGenerator = new UriSafeTokenGenerator();
$csrfStorage = new NativeSessionTokenStorage();
$csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage);
$twig = new Environment(new FilesystemLoader([
'../templates',
'../vendor/symfony/twig-bridge/Resources/views/Form',
]));
$formEngine = new TwigRendererEngine(['form_div_layout.html.twig'], $twig);
$twig->addRuntimeLoader(new FactoryRuntimeLoader([
FormRenderer::class => function () use ($formEngine,$csrfManager) {
return new FormRenderer($formEngine, $csrfManager);
},
]));
$twig->addExtension(new TranslationExtension());
$twig->addExtension(new FormExtension());
$formFactory = Forms::createFormFactoryBuilder()
->addExtension(new CsrfExtension($csrfManager))
//->addExtension(new ValidatorExtension($validator))
->getFormFactory();
$form = $formFactory->createBuilder()
->add('firstName', TextType::class)
->getForm();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$form->submit($_POST[$form->getName()]); // form
if ($form->isValid()) {
dump('form is valid');
}
}
echo $twig->render('index.html.twig', [
'form' => $form->createView(),
]);
}
}
The composer.json is simply:
{
"require": {
"symfony/form": "^5.1",
"symfony/twig-bridge": "^5.1",
"symfony/translation": "^5.1",
"symfony/security-csrf": "^5.1"
},
"require-dev": {
"symfony/var-dumper": "^5.1"
}
}
If you still have trouble then I would suggest tracking down where the sessions are stored and then verifying the that csrf token is being properly stored. It should look something like:
_csrf|a:1:{s:4:"form";s:43:"9v1tUNe3J3eYVOmEPwVdz5_iISfzBg8Qa9pLMV8tSN4";}
This was actually kind of an interesting exercise in using the twig system for standalone forms. Thanks.

signup to Laravel from a different server

I want to show a signup form on a website but then when user hits submit, the form data will be posted to a Laravel app (on a different server) for registration.
So far, laravel stops it throwing the CSRF not found exception. Any idea how to work around it ?
If both applications are yours?
You can create a new middleware group:
protected $middlewareGroups = [
'web' => [
...
],
'remote-login' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Commenting/removing/disabling the VerifyCsrfToken middleware. Then map it to a new file:
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
Route::middleware('remote-login')
->namespace($this->namespace)
->group(base_path('routes/remote-login.php'));
}
Then in your routes/remote-login.php, you better create a non-trivial login route:
Route::group(['prefix' => 'remote-login'], function () {
Route::get('/auth/8g7h6jk5l4oA/', function () {
dd('do you authentication');
});
});
Antonio's approach will work, but it's easier to just add the routes you don't want protected by the CSRF middleware to the $except array in app/Http/Middleware/VerifyCsrfToken.php.

Laravel 5.4 Locale restores to default when using redirect()

I'm struggling with the Laravel's locale on Fresh new Project. I googled many times, but they didn't solve my problem.
Then I followed locale in laravel 5.4 returns to the pervious locale after refresh source, but it works only when I call pages by view
return view('home');
And it does not work when I use routes
return redirect()->route('home');
Here are my files:
web.php
Route::get('/lang/{locale}', function ($locale) {
App::setLocale($locale);
Session::put('locale', $locale);
//return view('home'); ###### This one works
return redirect()->route('home'); ###### Where as this does NOT work
});
Route::get('/', function () {
return view('welcome');
});
Route::get('/home', 'HomeController#index')->name('home');
home.blade.php
<div class="panel-body">
You are logged in!
{{__('auth.success')}}
<br>
Rus
<br>
Kgz
</div>
ChangeLocale.php Middleware (I call it for every request of pages)
public function handle($request, Closure $next)
{
if(Session::has('locale')) {
app()->setLocale(Session::get('locale'));
}
return $next($request);
}
Thanks in advance ;)
Ok, after I changed
Route::get('/home', 'HomeController#index')->name('home');
to
Route::get('/home', 'HomeController#index')->name('home')->middleware('changeLocale');
It started to work.
So, why my Middleware, is not working?
Should I assign middleware seperately to all my routes?
You may add your changeLocale middleware to web group in app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
...
\Your\ChangeLocateMiddleware::class
],
...
]
As you may see in app/Providers/RouteServiceProvider.php, this middleware group applies to all your web routes.

Zend framework: how to pass creation options to services

When registering a service in module.config.php like
'service_manager' => [
'factories' => [
\Path\To\Your\Service\AService => \Path\To\Your\Service\Factory\AServiceFactory,
]
]
I can't pass in creation options when calling the service factory neither in ZF2 (when the factory implements MutableCreationOptionsInterface) nor in ZF3 (via $container->get(\Path\To\Your\Service\AService::class, $options).
Could anyone tell me how to pass the creation options to the services?
MutableOptions is currently only available on plugin manager instances; the service manager does not implement it. This is why you see the discrepancy.
Références : https://github.com/zendframework/zend-servicemanager/issues/7
Sample : https://samsonasik.wordpress.com/2014/08/14/zend-framework-2-using-creationoptions-in-pluginmanager/
COMPLEMENT
My solution is to add a method with a fluent pattern to the AService class :
class AService
{
public function __construct(...)
{
//your code, you can inject variables from $container by AServiceFactory
}
public function setOptions($options)
{
// your setting from $options
...
// fluent pattern
return $this;
}
}
To use your service :
$container->get(\Path\To\Your\Service\Aservice::class)->setOptions($options);

Including and using Zend Service ReCaptcha in ZF2 (v2.3.3)

how to include Recaptcha service in zend framework 2?
I tried to do like this:
public function contactAction()
{
$formContact = new ContactForm();
$pubKey = 'mypubkey';
$privKey = 'myprivkey';
$recaptcha = new ZendService\ReCaptcha\ReCaptcha($pubKey, $privKey);
return array ('formContact' => $formContact, 'recaptcha' => $recaptcha);
}
but I discovered that ZendService\ReCaptcha is not present by default when you download the framework.
So, I downloaded it from here
https://github.com/zendframework/ZendService_ReCaptcha
and I placed it into vendor\zendframework\zendframework\library\zend together with the other parts of the library.
I tried to refresh the page but doesn't work again because it can't find the zend service recaptcha.
Fatal error: Class 'Application\Controller\ZendService\ReCaptcha\ReCaptcha' not found in C:\Program Files (x86)\xampp\htdocs\Zf-tutorial\module\Application\src\Application\Controller\IndexController.php on line 79
can someone help me? I thought it was simple to implement recaptcha, but it is not so ! thanks!
Add the zendservice-recaptcha module to your composer.json file and run an update:
{
...
"repositories": [
{
"type": "composer",
"url": "http://packages.zendframework.com/"
}
],
...
"require": {
...
"zendframework/zendservice-recaptcha": "*",
...
}
...
}
update composer :
php composer.phar update
This will install the module and configure the relevant class mapping and you will be able to access the classes by adding the use statements as with any other classes you use.
Even i tried recaptcha but with no success so implemented something different to refresh captcha and worked very well, try this once
resetCaptcha function:
$form = $this->getServiceLocator()->get('zfcuser_register_form');
$captcha = $form->get('captcha')->getCaptcha();
$data = array();
$data['id'] = $captcha->generate();
$data['src'] = $captcha->getImgUrl() .
$captcha->getId() .
$captcha->getSuffix();
return $data;
ajax request :
$(document).ready(function() {
$('#refreshcaptcha').click(function() {
var data = [];
var form = <?php $this->registerForm; ?>
data.push({name: "action", value: 'resetCaptcha'});
data.push({name: "params[form]", value: form});
$.post("<?php echo BASE_URL ?>/user/iajax", data,
function(data) {
$('#form_reg img').attr('src', data.src);
$('#captcha-id-hidden').attr('value', data.id);
}, 'json');
});
});
Html call :
<p class="refresh_captcha"><?php echo $this->formCaptcha($form->get('captcha')); ?>
<input type="button" id="refreshcaptcha" value="refresh">
</p>
You do not properly install the library ZendService\ReCaptcha.
your system write:
Class 'Application\Controller\ZendService\ReCaptcha\ReCaptcha' not found
You must:
placed it into vendor\zendframework\zendframework\library
In the file vendor/ZF2/library/Zend/Loader/StandardAutoloader.php insert string
$this->registerNamespace('ZendService', dirname(dirname((__DIR__)))
. '/ZendService');
in case self::AUTOREGISTER_ZF:
in the file init_autoloader.php insert string
$loader->add('ZendService', $zf2Path);.