Client.php
/**
* #ORM\ManyToOne(targetEntity="EnseigneNationale", inversedBy="clients")
* ...
*/
private ?EnseigneNationale $enseigneNationale;
/**
* #ORM\OneToMany(targetEntity="ClientBanque", mappedBy="client", cascade={"persist", "remove"})
* ...
*/
private ?Collection $clientBanques;
My data comes from an old database, I have to create a command that corrects some data in the database.
if (Condition) {
/** #var ClientBanque $clientBanque */
$clientBanque = $clientBanques[0];
$clientBanque->setAA($aa);
$this->manager->persist($client);
}
When I persist, I got the error saying that doctrine unable to find "EnseigneNationale", that it can be nullable and I m not using it in my persist changes.
Somthing wrong with my code ?? Help Please
PHP : 7.4
Symfony : 5.3
Doctrine : 2.4
It was me !! Sorry for disturb, I was adding $manger->clear() who breaks everything
What is happening is basically you've detached your object from entity manager. The object was removed from the identity map and is no longer managed by this entity manager.
You can attach the object back by calling $managedCopy = $em->merge($object);
Pay attention to the fact that merge returns a new object.
The state of the passed entity will be merged into a managed copy of this entity and this copy will subsequently be returned.
How Laravel is aware of where the Router class path is? I'm aware of the concept of Facade. Now for instance Route alias point to the Route facade that return the name of the class "router"... how Laravel knows that Router is in the vendor\laravel\framework\src\Illuminate\Routing path?
/**
* Get the registered name of the component.
*
* #return string
*/
protected static function getFacadeAccessor()
{
return 'router';
}
The facade is used to resolve whatever is bound to the IoC container using that name, in this case the router.
So if you go to Illuminate\Foundation\Application.php there is a method called registerCoreContainerAliases, this is where the binding is set.
I am making packages for the first time in Laravel (v5.5). Unfortunately, the Route Model Bindings are giving me trouble. At first, I was receiving the id number raw without the model, and I realized that I had to force the package routes through the 'web' middleware grouping.
When I add the 'web' middleware grouping, I can see that laravel tries to load the model, but I receive an "Illegal offset type in isset or empty" in the first line of the Container->makeAlias method.
I have tried using custom binding loaders defined in the ServiceProvider using Route::model( $class, $closure ), but the error occurs before the loader is called. I've even tried moving this declaration from the ServiceProvider->boot method to the ServiceProvider->register method, just in case it is an order of operations issue.
I have tried adding a binding to the app by calling $this->app->bind inside the ServiceProvider, but this has had no effect.
I'm going to post the relevant code below, and I appreciate any insites that you may have! Thank you in advance!
Some Facts
The route
We are loading the url: http://127.0.0.1/profiles/1/edit for this test.
Operation without bindings
When no bindings or middleware are applied, and the url above is called, I can safely load the model from within the function manually and return the view. This indicates that the package is correctly loaded into the main application container.
The model can load in Tinker
To verify the model and database connection, we use tinker and run the command \Clemence\Profiles\Profile::find(1) to which the following is returned:
=> Clemence\Profiles\Profile {#777
id: 1,
name: "Clemence, Jared",
address: """
554 Christmas Tree Lane\n
Bakersfield, CA 93306
""",
email: "jaredclemence#gmail.com",
phone: "610-360-9558",
created_at: null,
updated_at: null,
deleted_at: null,
}
The stack trace
The Route->performBinding method is called with the following arguments:
[
Closure, /* Presumably the loader */
"1", /* the index that is passed into the route URL */
Route /* A self reference back to the containing object */
]
after this, the Closure is called with
[
"1",
Route
]
from the Closure, Application->make is called, the argument named $class is passed another Closure with the following definition:
Closure {#97 ▼
class: "Clemence\Profiles\ProfilesServiceProvider"
this: ProfilesServiceProvider {#87 …}
parameters: {▶}
}
lastly we end up in Container->makeAlias where the Exception is thrown, makeAlias is called with this Closure:
Closure {#97 ▼
class: "Clemence\Profiles\ProfilesServiceProvider"
this: ProfilesServiceProvider {#87 …}
parameters: {▶}
}
The Files
packages/clemence/profiles/src/routes.php
Route::group(['middleware' => ['web']], function() {
Route::get('/profiles/{profile}/edit', '\Clemence\Profiles\ProfileController#edit');
Route::get('/profiles/create', '\Clemence\Profiles\ProfileController#create');
Route::get('/profiles', '\Clemence\Profiles\ProfileController#showAll');
Route::get('/profiles/{profile}', '\Clemence\Profiles\ProfileController#show');
Route::post('/profiles/create', '\Clemence\Profiles\ProfileController#createWithFormData')->name('profile.create');
Route::put('/profiles/{profile}', '\Clemence\Profiles\ProfileController#updateWithFormData')->name('profile.update');
Route::delete('/profoiles/{profile}', '\Clemence\Profiles\ProfileController#destroy')->name('profile.delete');
Route::get('/roles', '\Clemence\Profiles\RoleController#showAll');
Route::get('/roles/{role_id}', '\Clemence\Profiles\RoleController#show');
Route::get('/roles/create', '\Clemence\Profiles\RoleController#create');
});
packages/clemence/profiles/src/ProfilesServiceProvider.php
namespace Clemence\Profiles;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Route;
class ProfilesServiceProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot() {
$this->loadRoutesFrom( __DIR__ . '/routes.php' );
if ($this->app->runningInConsole()) {
$this->commands([
\Clemence\Profiles\Commands\InstallProfiles::class,
\Clemence\Profiles\Commands\PrepareEnvironmentForProfiles::class
]);
}
}
/**
* Register the application services.
*
* #return void
*/
public function register() {
$this->app->make(\Clemence\Profiles\ProfileController::class);
$this->app->make(\Clemence\Profiles\RoleController::class);
$this->loadMigrationsFrom(__DIR__ . '/migrations');
$this->loadViewsFrom(__DIR__ . '/views', 'profiles');
}
}
packages/clemence/profile/src/ProfileController.php
namespace Clemence\Profiles;
use App\Http\Controllers\Controller;
use Clemence\Profiles\Profile;
use Illuminate\Http\Request;
use Clemence\Profiles\FormTemplateData;
use Illuminate\Support\Facades\URL;
class ProfileController extends Controller
{
/* ... collapsed ... */
/**
* Show the form for editing the specified resource.
*
* #param \App\Profile $profile
* #return \Illuminate\Http\Response
*/
public function edit(Profile $profile )
{
return dd( $profile );
$formData = new FormTemplateData();
$profile = Profile::find( $profile_id );
$formData->setProfile( $profile );
$formData->setFormActionMethod("POST");
$formData->setDeleteButtonText("Delete Profile");
$formData->setSubmitButtonText( "Update Profile" );
$on_cancel_route_url = $formData->getNamedUrl('profile.delete');
$on_submit_route_url = $formData->getNamedUrl('profile.update');
$formData->setFormCancelUrl($on_cancel_route_url);
$formData->setFormSubmitUrl($on_submit_route_url);
return $this->editForm($formData);
}
/* ... collapsed ... */
}
packages/clemence/profile/src/Profile.php
namespace Clemence\Profiles;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
use SoftDeletes;
}
RESOLVED: SOLUTION UNKNOWN
I will post the steps that I took to find the resolution here for those who may find this post in the future. I admit: I have no idea what fixed the problem.
What I did after asking the question
First and foremost, I got some sleep. When I have been coding too long, I find that sleep solves most problems.
On waking, I realized that I have a machine with XDebug installed and I can literally step through the PHP code as it executes, so I booted up that machine and did the following:
a. I moved the project to the local machine and opened it in NetBeans.
b. I placed breakpoints at several places in the middle ware so that I could verify that the system was running.
c. I changed the project config to run "as a website" and to load the url http://localhost:8000/profiles/1/edit as the start point.
d. I clicked 'Debug Program' and stepped through the bootup, the route loading, the model binding, and watched it all happen step-by-step looking for any line of code or parameter that looked out of sorts. I watched as the model was selected. I watched as it was passed the id 1 and asked to build the query. I watched as a collection of Profiles was returned (Oh! how excited I was to see the data I wanted sitting in that array and knowing that it was there but something would eventually block it, and I would find the block and release it!), and I watched as the collection was asked to return the first value. Then I watched as the parameter was set on the route. Lastly, I watched as the command $kernal->terminate() ran....
Needlessly to say, I was very disappointed and confused. How could I be getting an error, if the Kernal is running to completion?
So, I looked at the browser window, and there in the browser window was the very information that I was looking for! The Profile had loaded. I had changed nothing, and the Profile had loaded.
I moved the code back to the original machine, maybe it is an environment setting? I ran the web query without debugging, and it loaded... no error!
So, I honestly don't know what happened. I doubt that getting sleep helped the problem.
Maybe the Netbeans Debugger ran a cleanup service that fixed or patched a bad linkage? I honestly don't know, but I do know that this problem is resolved, so I post this answer in the hopes that it helps someone in the future, and that it saves other people the time of needlessly looking for an unnecessary solution.
The Problem
I'm attempting to set up a post-update script with Composer that checks to see which package is being updated. However, I'm having trouble figuring out how to consistently get the package name from a Composer\Installer\PackageEvent.
Attempts to solve
The source code says that $packageEvent->getOperation->getReason() should return a string, but in my testing is actually returning an instance of Composer\DependencyResolver\GenericRule.
Calling Composer\DependencyResolver\Rule::getReasonData() sometimes returns a string (the package name), and sometimes returns Composer\Package\Link.
The following code mostly works to figure out the package's name:
$reasonData = $packageEvent->getOperation()->getReason()->getReasonData();
$packageName = is_string($reasonData) ? $reasonData : $reasonData->getTarget();
except sometimes $packageEvent->getOperation()->getReason() returns null.
The Question
How do you consistently get the package name from a Composer PackageEvent?
Bonus Points
How do you get the name of the package being installed/updated/etc. from all of the Composer event classes?
My mistake! Composer operations still have access to packages, just through different methods, which depend on whether the operation is an InstallOperation or an UpdateOperation. The following works:
/**
* Returns the package name associated with $event
*
* #param PackageEvent $event Package event
* #return string
*/
public static function getPackageName(PackageEvent $event)
{
/** #var InstallOperation|UpdateOperation $operation */
$operation = $event->getOperation();
$package = method_exists($operation, 'getPackage')
? $operation->getPackage()
: $operation->getInitialPackage();
return $package->getName();
}
I have been digging in the core of Laravel because I would like to understand how it works. But I come up with a method that I just cannot wrap my head around even after 3 days.
In start.php the app is binded to itself. So far so good. But when I check the $app->share method I am lost.
public function share(Closure $closure)
{
return function($container) use ($closure)
{
// We'll simply declare a static variable within the Closures and if
// it has not been set we'll execute the given Closure to resolve
// the value and return it back to the consumers of the method.
static $object;
if (is_null($object))
{
$object = $closure($container);
}
return $object;
};
}
This method returns an anonymous function which when executed returns an instance of the app. Do I see that right? Why is this? Why do you want to return a closure and not just the instance. This seems like a strange way, but I am quite sure that there is a reason ;) ??
UPDATE
The line in start.php:
$app['app'] = $app->share(function($app) { return $app; });
So I would think that $app['app'] is a closure object. However if I do get_class the class is Illuminate\Foundation\Application .
Furthermore there is also no way to execute it as $app'app' will not work obviously.
$app is no normal array, it is actually an instance of Illuminate\Foundation\Application1, an extension of Illuminate\Container\Container2, which implements ArrayAccess. But you know this already, as that's where the share() method lives.
The container binds keys to closures, when the keys are accessed the value is fetched from memory or, on first access, the bound closure is called and the resulting value is returned. When a key is set on the container it is wrapped in a closure unless it is already a closure.
This provides a consistent internal interface for the container, so that the code is not constantly type checking its contents. It will also only load the references you actually use are into memory - it is thought that the footprint of a closure is lighter than that of a fully loaded class instance. But once loaded, you get the benefit of working with the same instance for the rest of the request.
Why the app is not registered on the container using instance() I don't know though - perhaps it produces recursive references in trace and dump output.