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();
}
Related
When I click on my first record to delete from my application, I get method not found error but when I click on another record apart from first one it easily gets deleted.
What is the issue?
Below is the code for Delete:
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
$video = Video::findOrFail($id);
$delete = $video->delete();
if ($delete){
return redirect()->back()->with('trueDelete','Data Not Deleted');
}else{
return redirect()->back()->with('falseDelete','Data Deleted Successfully');
}
}
While clicking on first record from list shows below error,
Route::get('delete-video/{id}','VideoController#destroy');
First of all, that is too much work you are putting into deleting the record. Check out the link below on the official docs to see how to delete in a single line.
https://laravel.com/docs/5.6/eloquent#deleting-models
As for the image, you have a
Method not allowed exception.
This means that, on the place you are deleting from link one, you are using a different route variable than the one specified in the web.php file. Check that you aren't confusing a GET and POST and/or PUT.
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.
Out of curiosity, I'd like to know why Http/Kernel->sendRequestThroughRouter($request) sets an instance of request and immediately right after wipes it out.
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
...
What is the purpose of doing that?
Seems that I finally got the point:
Facades just hold references to the actual service instances located in the Container
If the instance is replaced by a new instance via $app->instance() or by other means, then the Facade reference becomes obsolete since it is still pointing to the previous deleted instance
By clearing the facade instance reference with clearResolvedInstance, it forces the facade to store a new reference the next time the facade is invoked via resolveFacadeInstance($name)
Did I get it right?
This leads to another question:
What's the point of managing and returning these resolvedInstances:
if (isset(static::$resolvedInstance[$name])) {
return static::$resolvedInstance[$name];
}
return static::$resolvedInstance[$name] = static::$app[$name];
Instead of just always return the instance directly from Container like this:
return static::$app[$name];
because it is registerd app wide
/**
* Register an existing instance as shared in the container.
*
* #param string $abstract
* #param mixed $instance
* #return void
*/
public function instance($abstract, $instance);
after it is registered in the container then unresolved version is wiped as far as I am understanding
I created a module (extends Mage_Core_Model_Abstract) and an admin controller.
When I run this module online translations are going right.
When I run this module as cronjob, everything goes allright but translations are not done, I specified translation file in config.xml in as well frontend as adminhtml.
What I am doing wrong?
I see this is a very old question. I've posted here to future reference and others.
Quick and dirty solution
// Fix unitialized translator
Mage::app()->getTranslator()->init('frontend', true);
just after
$initialEnvironmentInfo = $appEmulation>startEnvironmentEmulation($storeId);
for instance. Or in a foreach loop of your own, which is called via cron/admin. Since you're talking about crons, I assume that you know what you are doing.
The real problem
In Magento 1.9 in Mage_Core_Model_App_Emulation (in app/code/core/Mage/Core/Model/App/Emulation.php), there's this function:
/**
* Apply locale of the specified store
*
* #param integer $storeId
* #param string $area
*
* #return string initial locale code
*/
protected function _emulateLocale($storeId, $area = Mage_Core_Model_App_Area::AREA_FRONTEND)
{
$initialLocaleCode = $this->_app->getLocale()->getLocaleCode();
$newLocaleCode = $this->_getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE, $storeId);
if ($initialLocaleCode != $newLocaleCode) {
$this->_app->getLocale()->setLocaleCode($newLocaleCode);
$this->_factory->getSingleton('core/translate')->setLocale($newLocaleCode)->init($area, true);
}
return $initialLocaleCode;
}
The $initialLocaleCode != $newLocaleCode seems to be the issue here. When iteration orders/customers/subscribers/*, the locale could stay the same, which then prevents executing the code in the statement. And the locale is thus not set in the Translator (Mage::app()->getTranslator()).
We've yet to fix the issue, but you could change if ($initialLocaleCode != $newLocaleCode) { to if (true) { straight in the core source. Off course, this is ugly. I suggest something like extending the class and then :
/**
* Apply locale of the specified store. Extended
* to fix Magento's uninitialized translator.
*
* #see http://stackoverflow.com/questions/19940733/magento-translations-ok-in-online-program-but-not-run-as-cronjob#
* #param integer $storeId
* #param string $area
*
* #return string initial locale code
*/
protected function _emulateLocale($storeId, $area = Mage_Core_Model_App_Area::AREA_FRONTEND)
{
$initialLocaleCode = $this->_app->getLocale()->getLocaleCode();
$newLocaleCode = $this->_getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE, $storeId);
$this->_app
->getLocale()
->setLocaleCode($newLocaleCode);
$this->_factory
->getSingleton('core/translate')
->setLocale($newLocaleCode)
->init($area, true);
return $initialLocaleCode;
}
Magento 2
I guess the developers became aware it was borked and they changed the code in Magento 2. The _emulateLocale() function is gone all together and they added this line to the startEnvironmentEmulation() function, without any conditional around it:
$this->_localeResolver->setLocale($newLocaleCode);
It's a bug even with CE 1.9.0.1!
See what I've done about it:
https://magento.stackexchange.com/questions/25612/cron-job-template-block-not-being-translated-but-testobserver-is/25920#25920
I just started to play with AngularJS and I got error below.
Error: Argument '?' is not a function, got Object
at assertArg (http://localhost/angular/project/scripts/vendor/angular.js:1039:11)
at assertArgFn (http://localhost/angular/project/scripts/vendor/angular.js:1049:3)
at http://localhost/angular/project/scripts/vendor/angular.js:4802:9
at http://localhost/angular/project/scripts/vendor/angular.js:4384:17
at forEach (http://localhost/angular/project/scripts/vendor/angular.js:137:20)
at nodeLinkFn (http://localhost/angular/project/scripts/vendor/angular.js:4369:11)
at compositeLinkFn (http://localhost/angular/project/scripts/vendor/angular.js:4015:15)
at compositeLinkFn (http://localhost/angular/project/scripts/vendor/angular.js:4018:13)
at publicLinkFn (http://localhost/angular/project/scripts/vendor/angular.js:3920:30)
at update (http://localhost/angular/project/scripts/vendor/angular.js:14202:11)
Now, my question is: Is there a way I can find line in .js file where error occurred?
I get line number in angular.js file on raised exception but there is too many files where
error can occur.
I tried with AngularJS Batarang, but this is more for debugging semantic not syntax errors.
Thanks.
It'll be easier if you link to the js files that would have caused this error.
From the angular.js source, https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js
it looks like a problem with instantiating the controller.
Here's the line that's causing assertion failure:
/**
* #ngdoc function
* #name ng.$controller
* #requires $injector
*
* #param {Function|string} constructor If called with a function then it's considered to be the
* controller constructor function. Otherwise it's considered to be a string which is used
* to retrieve the controller constructor using the following steps:
*
* * check if a controller with given name is registered via `$controllerProvider`
* * check if evaluating the string on the current scope returns a constructor
* * check `window[constructor]` on the global `window` object
*
* #param {Object} locals Injection locals for Controller.
* #return {Object} Instance of given controller.
*
* #description
* `$controller` service is responsible for instantiating controllers.
*
* It's just a simple call to {#link AUTO.$injector $injector}, but extracted into
* a service, so that one can override this service with {#link https://gist.github.com/1649788
* BC version}.
*/
return function(constructor, locals) {
if(isString(constructor)) {
var name = constructor;
constructor = controllers.hasOwnProperty(name)
? controllers[name]
: getter(locals.$scope, name, true) || getter($window, name, true);
======> assertArgFn(constructor, name, true);
}
return $injector.instantiate(constructor, locals);
};
It's unable to find the constructor for the controller.