Styleci fixes phpdoc comments at file level - laravel

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.

Related

Intellisense (autocompletion) for model in Laravel for Visual Studio Code or another IDE

I am looking for sth similiar to Intellisense in .NET in Laravel. So far I've been using .NET and autocompletion for models is awesome and makes my work way more easy.
Now I need to create Laravel application, I've been following this tutorial to prepare my environment but the only autocompletion I get is for default PHP functions and some predefined methods (ex. SaveSessionListener from Symfony\Component\HttpKernel\EventListener - I am not even using Symfony anywhere).
What I'd like to achieve is get autocompletion from models, for example there is a class called Model in Laravel, I have class Page which extends Model.
use App/Page
$home = new Page();
$home->content = "lorem ipsum";
$home->save();
I don't have any completion when I write $home->, no content, no save(), only some random functions. I can understand why there might be no content autocompletion - its not written directly into code, but its written on database and object-database engine is parsing that one, I didn't figure out how yet, but I don't understand why even save() doesn't get autocompletion.
I tried to google the issue, but without any good result.
I figured it out how to get it work with Visual Studio Code.
First and most important is the link morph provided me in comment:
laravel-ide-helper
I just followed docs and generated basic helper + model helper. I guess later I'll automate those generation commands, its also explained how to do it in docs.
Second thing is that it works only with:
PHP Intelephense plugin
Note that you need to reset VSC before it actually works.
Third thing I did - VSC have build-in php autocompletion, it was pretty annoying cause it started to show me model fields in suggestions, but it was between dozens of other suggestions. To disable build-in autocompletion I added line to user settings:
"php.suggest.basic": false,
Last thing I did - I have moved snippets to bottom of suggestions box to clear autocompletion results a little bit more:
"editor.snippetSuggestions": "bottom"
And that works really decent as Laravel programming environment.
I use PHP Doc for fields definition like following example:
namespace App\Models;
use App\Enums\MediaType;
use App\Models\Commons\BaseModel;
use DateTime;
/**
* Famous Media.
*
* #property int $id
* #property int $famous_id
* #property MediaType $type
* #property string $url
* #property int $position
* #property DateTime $created_at
* #property DateTime $updated_at
*/
class FamousMedia extends BaseModel
{
const TABLE = 'famous_medias';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'type',
'url',
'position',
'famous_id',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'famous_id',
'deleted_at',
'created_at',
'updated_at',
];
public function famous()
{
return $this->hasOne(Famous::class, 'famous_id');
}
}
Update:
You can now use Laravel Extra Intellisense is now supporting Model Attributes.
Still in Beta but it works fine.

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.

Is the includeFile() Method necessary?

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.

Check line existence in laravel's trans()

Lets say in my lang/en/general.php there are multiple translation lines for example:
"token" => "This password reset token is invalid.",
"sent" => "Password reminder sent!",
"reset" => "Password has been reset!",
But in my lang/de/general.php these lines are missing.
So later, when I use the Lang::get('general.token') or simply trans('general.token')
The english version will return
This password reset token is invalid.
And the german (de) version will return
general.token
Is there any way I can handle a 'translation not found' function, like a filter but not creating a special class for it? For example, when a line has no translation, I want to throw an Exception.
Thanks in advance!
In Laravel 4 only, you can use Lang::has() as below, here is the doc
if (\Lang::has('general.token')) {
// line exists.
} else {
// line not exist.
}
In current Laravel versions you can just use trans helper like so:
#if (trans()->has('general.token'))
{{ trans('general.token') }}
#endif
This question is getting a little bit old but as per version 5.8 you can simply check as this :
array_key_exists('your-word-key', trans('your-file'))
or
array_key_exists('your-word-key', trans('your-file.array_key'))
for nested translations
You might want to write a helper similar to the one below to help with fallbacks:
/**
* Makes translation fall back to specified value if definition does not exist
*
* #param string $key
* #param null|string $fallback
* #param null|string $locale
* #param array|null $replace
*
* #return array|\Illuminate\Contracts\Translation\Translator|null|string
*/
function trans_fb(string $key, ?string $fallback = null, ?string $locale = null, ?array $replace = [])
{
if (\Illuminate\Support\Facades\Lang::has($key, $locale)) {
return trans($key, $replace, $locale);
}
return $fallback;
}
Note: The helper only works on PHP 7.1 (which has support nullable types). Adjust it to your PHP version if it's lower than 7.1.
You can create your own TranslationServiceProvider and Translator and override the get() method in translator to throw an exception when the parent::get() returns a translation string that is equal to the translation key that was passed in. Both #lang() and trans() functions call the get() method of the translator.
Seems like a whole lot of trouble only to get another reason for a "Whoops! something went wrong!" on your site. You will only get the exception when the translation is encountered.
Another solution: you can use the barryvdh/laravel-translation-manager package, it has a translation service provider that logs missing translation keys and a web interface for managing translations. It will log missing translation keys per locale and let you edit them through a web interface.
It is simple to setup and easy to modify. So you can replace the logging with throwing an exception.

code asistant comment style

I try to make use of code assistant in Aptana.
It seems that it is not working with js self written code, or I'm using it the wrong way.
I'm working with Aptana Studio 3, build: 3.2.2.201208201020
I comment my javascript like so:
/**
Simple utilities like alert/info/error windows etc.
#constructor
#param object params - set of key:value properties
*/
function SomeClass(params)
{
/**
* #var some description
*/
this.messages = [];
/**
* My function
*
* #param string some_param - some description
*/
this.somefunction = function(some_param)
{
//some code
}
}
Now when I type this. in SomeClass block a popup shows and i can find messages and somefunction but it say that both have no description.
When I'm in this.somefunction section I get proposals for global variables like window.location but no help for this. nor for SomeClass
I'm using this comment style in php and it works like a charm.
What am I doing wrong? This JS comment style was working in my previous eclipse - helios.

Resources