Is the includeFile() Method necessary? - composer-php

I'm just curious that why don`t official team use include $file; directly in ClassLoader.php ?
Thanks in advance!

The code docs are pretty clear about that:
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}
It isolates the loading code so it can't access $this or $self.

Related

How to override the resourcePath() function defined in Illuminate/Foundation/Application.php

I am modularizing laravel. I have decided to move all the default routes, controllers, resources, etc.. to /app/Modules/Pub. For the most part this has worked well. However I would like to change the default resources path of the application. Unfortunately this doesn't seem to be (easily) configurable.
So... using grep I was able to track down the resource_path() function to /var/www/sigma/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
I think it's possible to override this function somewhere but this seems like a subpar hack as this function consists simply of:
app()->resourcePath($path)
Again using grep I found out that this function is to be found in /var/www/sigma/vendor/laravel/framework/src/Illuminate/Foundation/Application.php
This seems to be the thing to change since it does not reference any configuration value, rather the value is hard coded:
return $this->basePath.DIRECTORY_SEPARATOR.'resources'.($path ? DIRECTORY_SEPARATOR.$path : $path);
But I think it's safe to assume it's pretty foolish to change anything under the vendor folder manually. Obviously I need to override this function somewhere. I am unclear where and how to do this
Create a new Application class which extends the \Illuminate\Foundation\Application:
<?php
namespace <YOUR NAMESPACE HERE>;
class ApplicationCustom extends \Illuminate\Foundation\Application
{
public function __construct()
{
parent::__construct();
}
/**
* Get the path to the resources directory.
*
* #param string $path
* #return string
*/
public function resourcePath($path = '')
{
// Implement the custom method
}
}
Now, just change your bootstrap/app.php file to use the custom class:
$app = new YOUR_NAMESPACE\ApplicationCustom(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
Hope it helps.
You could create a class somewhere in your project and extend the default \Illuminate\Foundation\Application class. Then override the methods you need and switch the class instantiated in bootstrap/app.php with your custom one.

What causes an illegal offset in the makeAlias function of laravel 5.5 within this package implementation?

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.

REST_Controller.php is not working in codeigniter

I am going to use REST_Controller.php to make rest api's. (using codeigniter v3 on ubnatu 15)
from link https://github.com/chriskacerguis/codeigniter-restserver
on calling
localhost/rest_api_ci/api/example/user/1
Showing me error
Fatal error: Class 'REST_Controller' not found in /var/www/html/rest_api_ci/application/controllers/api/Example.php on line 21
A look of Example.php file
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
// This can be removed if you use __autoload() in config.php OR use Modular Extensions
/** #noinspection PhpIncludeInspection */
require(APPPATH.'libraries/REST_Controller.php');
/**
* This is an example of a few basic user interaction methods you could use
* all done with a hardcoded array
*
* #package CodeIgniter
* #subpackage Rest Server
* #category Controller
* #author Phil Sturgeon, Chris Kacerguis
* #license MIT
* #link https://github.com/chriskacerguis/codeigniter-restserver
*/
class Example extends REST_Controller {
function __construct()
{
change your url from
localhost/rest_api_ci/api/example/user/1
to
http://localhost/rest_api_ci/index.php/api/Example/users
Removing Unnecessary Namespaces in REST_Server.php and Format.php helped me.
After
require(APPPATH.'libraries/REST_Controller.php');
you need to add the namespace:
// use namespace
use Restserver\Libraries\REST_Controller;
... I ran into this issue few minutes ago and it worked with me
I think its the path issue, same answer is given here Hope it will help you or someone else.
Thanks

Styleci fixes phpdoc comments at file level

I specify phpdoc for $factory variable in ModelFactory for completion in PhpStorm.
/**
* #var Illuminate\Database\Eloquent\Factory $factory
*/
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
However, when I push commit to github, styleci send me such pull request
-/**
+/*
* #var Illuminate\Database\Eloquent\Factory $factory
*/
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
But PhpStorm doesn't recognize such comments and there is no completion. Is it possible to tell styleci not to fix phpdoc comments at file level?
My .styleci looks like this
preset: recommended
risky: true
linting: true
disabled:
- align_double_arrow
I do not have experience with StyleCI, and this is not tested, but a quick glance at the documentation shows this fixer:
phpdoc_to_comment
Docblocks should only be used on structural elements.
To me, it sounds like this fixer is responsible for changing your PHPDoc comment to a plain comment, since it is not describing a structural element. I would try adding this fixer to your disabled list.

Is there a way to specify the installation location for composer? (PSR-4)

I'm using composer to install my package and I'm trying to install my bundle in a very specific location.
In short, I have my packages with the following namespace prefixes:
TeamXyz/AbcBundle
TeamXyz/AbcComponent
Now, since we have tons of components and bundles, we want to separate them into 2 folders like this:
vendor/TeamXyz/Component/AbcComponent
vendor/TeamXyz/Bundle/AbcBundle
It used to work very well but with PSR-4 I cannot seem to be able to control the location where my package should be installed. I wonder if I have to write custom package installer for composer to be able to do this?
Ok, I found out a way to do that, simply wrote my own custom package installer and voila.
<?php
/**
* Created by myTeam.
* Date: 6/11/14
* Time: 1:43 PM
* Question? Come to our website at http://my.com
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace My\PackageInstaller;
use Composer\Package\PackageInterface;
use Composer\Installer\LibraryInstaller;
class BundleInstaller extends LibraryInstaller
{
/**
* {#inheritDoc}
*/
public function getPackageBasePath(PackageInterface $package)
{
$prefix = substr($package->getPrettyName(), 0, 3);
if ('my/' !== $prefix) {
throw new \InvalidArgumentException(
'Unable to install package, my package '
. 'should always start their package name with '
. '"my/"'
);
}
$packageName = str_replace('my/', '', $package->getPrettyName());
return $this->vendorDir . '/my/Bundle/' . $packageName;
}
/**
* {#inheritDoc}
*/
public function supports($packageType)
{
return 'my-bundle' === $packageType;
}
}
And yes I understand everything you guys complain about, but a tool is a tool and one person can use it the best way that fits his need. At least that's what I believe :). Maybe I'm doing something stupid here for not using Composer the exact way it was meant to be used. But hey, if we are using all the tools the exact ways they were meant to be used, lots of innovation would have happened in the first place :)

Resources