Problems with Doctrine 2.0 - zend-framework

1-) In old version i use syncronizeWithArray method of Doctrine_Record, it's save a lote of time.
Version 2.0 does not provide it?
2-) In code below flush command generate 3 records on database, its a bug of 2.0?
public function indexAction()
{
$em = $this->getInvokeArg('bootstrap')->em
$obj = new Entity\Obj();
$obj->name = "teste";
$obj->last_name = "teste";
$em->persist($obj);
$em->flush();
}
Obs: The indexAction is called onlyOneTime.
Problem 2 Solved. its my fault!!

In version 2 doctrine entities don't extend from a base class anymore. Therefore the functionaly synchronizeWithArray isn't in the model anymore.
You could however implement ArrayAcces to work with Entities as if with arrays.
See implementing array access in the reference.

Related

Shopware 6 Forms

Newbie question. How to handle Storefront Form Submit in Shopware 6? How to save the data from form to database? I have an entity, form shown in storefront and a controller but i have no idea how to save the data to entity. Thanks in advance.
you would have to be more specific with the description, of what exactly you are trying to achieve.
But in general, if you already have a controller, that receives the data, then you can get them from the request like this:
$data = $request->request->all();
By this, you have all the values from your form saved in an array $data. You have written, that you already have an entity, so from that I assume, that your entity is already mapped to your database table. So the only thing you have to do, is to use the repository to save the data. For thta, you just need to inject it into your class and get a context. The context depends on where you currently are, so for the purpose of the example, I have just created the default context.
It should look like this:
class MyClass
{
protected $myEntityRepository;
public function __construct(
MyEntityRepository $myEntityRepository
)
{
$this->myEntityRepository = $myEntityRepository;
$this->context = \Shopware\Core\Framework\Context::createDefaultContext();
}
public function myMethod ($data)
{
$this->myEntityRepository->upsert($data, $this->context);
}
}
Hope this helps. I have actually written an article on repositories in Shopware 6, so if you want to get some more information and examples, you can check it here: https://shopwarian.com/repositories-in-shopware-6/.

Ability to tell if a model for CRUD controller has been updated using Backpack for Laravel

I'm using a Backpack for Laravel CRUD controller and I'm trying to figure out if there's an efficient way to tell if a Model has been updated without loading both the current model and the updated model and then comparing attribute values.
I ended up following the suggestion in the comment and overrode the save() method on my model as such.
public function save(array $options = [])
{
// Update the mode accordingly and perform any
// other actions you need to prior to saving here.
$saved = parent::save($options);
return $saved;
}

Eloquent error: A facade root has not been set

I have been using Eloquent as a standalone package in Slim Framework 2 successfully.
But now that I want to make use of Illuminate\Support\Facades\DB since I need to show some statistics by getting the info from 2 tables and using a Left Join and a Counter from the database like this:
use Illuminate\Support\Facades\DB;
$projectsbyarea = DB::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id');
I get the following error:
Type: RuntimeException
Message: A facade root has not been set.
File: ...\vendor\illuminate\support\Facades\Facade.php
Line: 206
How can I solve it?
So far I have found out, in this link that I need to create a new app container and then bind it to the Facade. But I haven't found out how to make it work.
This is how I started the rest of my Eloquent and working fine:
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule();
$capsule->addConnection([
'my' => $app->config->get('settings'),
/* more settings ...*/
]);
/*booting Eloquent*/
$capsule->bootEloquent();
How do I fix this?
Fixed
As #user5972059 said, I had to add $capsule->setAsGlobal();//This is important to make work the DB (Capsule) just above $capsule->bootEloquent();
Then, the query is executed like this:
use Illuminate\Database\Capsule\Manager as Capsule;
$projectsbyarea = Capsule::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id')
->get();
You have to change your code to:
$Capsule = new Capsule;
$Capsule->addConnection(config::get('database'));
$Capsule->setAsGlobal(); //this is important
$Capsule->bootEloquent();
And at the beginning of your class file you have to import:
use Illuminate\Database\Capsule\Manager as DB;
I have just solved this problem by uncommenting $app->withFacades(); in bootstrap/app.php
Had the same issue with laravel 8. I replaced
use PHPUnit\Framework\TestCase;
with:
use Tests\TestCase;
Try uncommenting in app.php $app->withFacades();
Do not forget to call parent::setUp(); before.
fails
public function setUp(): void {
Config::set('something', true);
}
works
public function setUp(): void {
parent::setUp();
Config::set('something', true);
}
One random problem using phpUnit tests for laravel is that the laravel facades have not been initialized when testing.
Instead of using the standard PHPUnit TestCase class
class MyTestClass extends PHPUnit\Framework\TestCase
one can use
class UserTest extends Illuminate\Foundation\Testing\TestCase
and this problem is solved.
I got this error after running:
$ php artisan config:cache
The solution for me was to delete the /bootstrap/cache/config.php file. I'm running Laravel 5.5.
The seems to arise in multiple situation, and not just about facades.
I received the following message while running tests using PHPUnit v.9.5.4, PHP v.8.0.3 and Lumen v. 8.2.2:
PHP Fatal error: Uncaught RuntimeException: A facade root has not
been set. in path_to_project/vendor/illuminate/support/Facades/Facade.php:258
And that happened although I had apparently already configured my app.php to enable facades ($app->withFacades();), still I received this error message whenever I tried to run tests using Illuminate\Support\Facades\DB. Unfortunately, none of the other answers helped me.
This error was actually been thrown due to my configs in phpunit.xml, which didn't point to my app.php file, where I actually enabled facades.
I just had to change
<phpunit (...OTHER_PARAMS_HERE) bootstrap="vendor/autoload.php">
to
<phpunit (...OTHER_PARAMS_HERE) bootstrap="bootstrap/app.php">
Hope it helps.
wrong way
public function register()
{
$this->app->bind('Activity', function($app)
{
new Activity;
});
}
right way 👍
public function register()
{
$this->app->bind('Activity', function($app)
{
return new Activity;
});
}
---------------------------------- don't forget return
Upgrade version for php, I encountered this error while calling the interface.
$ php artisan config:cache
Deleting the /bootstrap/cache/config.php file is a very effective way.
In my project, I managed to fix this issue by using Laravel Dependency Injection when instantiating the object. Previously I had it like this:
$class = new MyClass(
new Client(),
env('client_id', 'test'),
Config::get('myapp.client_secret')
);
The same error message happened when I used Laravel env() and Config().
I introduced the Client and env in the AppServiceProvider like this:
$this->app->bind(
MyClass::class,
function () {
return new MyClass(
new Client(),
env('client_id', 'test')),
Config::get('myapp.client_secret')
);
}
and then instantiated the class like this:
$class = app(MyClass::class);
See more from https://laravel.com/docs/5.8/container .
In my case, for a while a ran a PHP project in PHP version 8, and that time I used some PHP 8 features like param definition and method's multiple return type declarations supported by only PHP 8 and above. When I downgraded from PHP 8 to PHP 7.4 I faced this issue. After removing the return types and param hinting the problems are gone.
Tested on Laravel 8.78
tests/bootstrap.php
<?php
use Illuminate\Foundation\Bootstrap\RegisterFacades;
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
require_once __DIR__ . '/../vendor/autoload.php';
$app = require_once __DIR__ . '/../bootstrap/app.php';
(new LoadConfiguration())->bootstrap($app);// <------- Required for next line
(new RegisterFacades())->bootstrap($app);// <------- Add this line
Here is yet another instance of this error, happened to me after upgrading Laravel 8 to 9.
I had feature tests with a #dataProvider to supply data to those tests. Some of the data supplied by the data provider methods came from an application service. It was being initialised like this:
/**
* #dataProvider myDataProvider
*/
public function testSomeStuff(...)
{
...
}
public function myDataProvider()
{
$myService = app(Service::class); // This is trouble
return [
['test1_data' => $myService::SOME_CONSTANT],
[...],
...
];
}
This worked under Laravel 8, but not in Laravel 9. All other solutions listed in this SO thread were checked and were correctly set up.
The problem is that the application is not being inititialised until after the data provider method is run. It was presumably initialised before this stage in the Laravel 8 install. So app(Service::class) was failing due to it using facades internally.
One workaround could be to force the application to initialise earlier, in the data provider function: $this->createApplication(). I would not recommend this due to potential side effects of the test parts running in the wrong order, though it does appear to work when I tried it.
Best solution is to avoid accessing any part of the application functionality in the data provider methods. In my case it was easy to replace $myService::SOME_CONSTANT with MyService::SOME_CONSTANT after making sure those constants were public.
Hopefully this will help somebody suddenly hitting this problem running feature tests after a Laravel 9 upgrade.
If you recently upgrade Laravel on Homestead & VirtualBox environment or do not find any reason that causing please be sure your Vagrant is up to date.
Referance
I had Taylor lock this thread. The past several replies have restated the solution, which is to Upgrade to Virtualbox 6.x, the thread is locked to prevent other issues that are not related from being dogpiled on here.
#melvin's answer above works correctly.
In case someone is wondering about it, the mistake people do is to choose Yes when VSCode asks them if they are making a Unit Test. Remember, Unit Tests should really be unit tests, independent of other application features (models, factories, routes; basically anything that would require the Laravel app to be fired up). In most scenarios, people really actually want to make Feature Tests and therefore should answer No to the above question. A feature test inherits from Tests\TestCase class (which takes care of firing up Laravel app before running the test) unlike unit tests that inherit from the class PHPUnit\Framework\TestCase which use just PHPUnit and are therefore much faster.
credit with thanks to #Aken Roberts's answer here.
From Laravel Documentation: Generally, most of your tests should be feature tests. These types of tests provide the most confidence that your system as a whole is functioning as intended.

FuelPHP - pre_save() on model not working

Does anyone knows how to get pre_save() or pre_validate() to work in my model?
I have the code below in the model, but it is never called.
protected function pre_validate($data)
{
//die("asefeg");
$data->idRegistrant = Session::get('idRegistrant', null);
return $data;
}
The ORM does not have a pre_save() method like the CRUD model does. For this functionality you want to look into implementing an observer. Plenty of info can be found about this in the fuelphp docs

Zend Framework 1.11, Doctrine2 - How to test controllers without flushing to the database

I have doctrine2 setup with ZF 1.11, I am having difficulty learning the best way to unit test controllers. I would like to be able to test actions in controllers without writing to the database within my unit tests however I am finding it impossible to actually do so.
For example say I have the following hypothetical action within my controller.
public function redirectUserAction() {
$registry = Zend_Registry::getInstance();
$em = $registry->entitymanager;
$user = $em->getRepository('Application_Model_User')
->findOneBy(array('email' => 'test#test.com'));
if(is_object($user)) {
$this->_redirect('/');
}
}
I want to test that if there is a user available with the email address test#test.com it will redirect to / so at the moment I have the following test.
public function testUserAvaliableShouldRedirectIndex() {
$registry = Zend_Registry::getInstance();
$em = $registry->entitymanager;
$user = new Application_Model_User();
$user->setEmail('test#test.com');
$em->persist($user);
$em->flush();
$this->dispatch('/index/redirect-user');
$this->assertRedirectTo('/');
$em->remove($user);
$em->flush();
}
This seems to me like a very messy way of writing tests. I was under the impression that with doctrine I wouldn't need to actually flush to the database because my objects would be stored in the persistence layer but at the moment my tests fail without flushing.
If anyone knows a better way I could write tests or can help me see where I am going wrong I would be very grateful.
Thanks
Instead of creating and deleting the user in testUserAvaliableShouldRedirectIndex() you could use setUp() and tearDown() to create and delete the user. This way you can use that user throughout all actions that expect an existing user, like your redirectUserAction(), loginAction(), etc. instead of having to do what you currently do for each of these actions.