I am trying to get static PHP code analysis to work on my OXID 6 eshop.
I am, however, hitting a brick wall when it comes to this:
When I run vendor/bin/phpstan analyse --configuration phpstan.neon source/modules/myvendor/mymodule I always get errors like Class mynamespace\Article_parent not found.
This is probably because in Oxid, the eshop classes are not directly overwritten, but instead declared like this
<?php
namespace mynamespace;
class Article extends Article_parent
{
...
and in a metadata.php the overwritten class is defined:
'extend' => [
\OxidEsales\Eshop\Application\Model\Article::class => \mynamespace\Article::class,
],
Phpstan does not seem to be able to resolve this, I've tried many different configuration files, like this one
parameters:
level: max
inferPrivatePropertyTypeFromConstructor: true
autoload_files:
- vendor/oxid-esales/oxideshop-ce/source/oxfunctions.php
- vendor/oxid-esales/oxideshop-ce/source/overridablefunctions.php
or this one
parameters:
level: 7
autoload_files:
- vendor/oxid-esales/testing-library/base.php
- vendor/oxid-esales/oxideshop-ce/source/oxfunctions.php
- vendor/autoload.php
but to no avail.
How can I get phpstan to work?
Please upgrade to the latest PHPStan version 0.12.33.
In version 0.12.26 a lot has been reworked that's described in this article. The main takeaway is that you should no longer get "class not found" for classes that clearly exist without any need for additional configuration.
Also, autoload_files has been deprecated. Please follow Discovering Symbols guide to see what to do instead (you can most likely just delete this section from your configuration).
The \mynamespace\Article_parent class does not exist and will be created at runtime as an alias. This is because it depends on your configuration / other modules installed where this alias points to.
My colleague Alfred Bez created the oxid-dump-autoload tool, what will dump out the module chain based on your current configuration and setup, so that PHPStan / Psalm can find the classes:
https://github.com/alfredbez/oxid-dump-autoload
Hope I could help
Related
Hello :) On start: I use PrestaShop 1.7.6.2 and MySQL 5.6 and PHP 7.2
I want to create a module on new way with Symfony Controller and Entites without ObjectModel (beacouse like say one of develoeper of PrestaShop: Pablo Borowicz - ObjectModel is deprecated)
So on start I create simple module available at the link
https://github.com/DarkSidePro/testmodule
Controller and routing works perfect the problem is when I try use enity manager
$entityManager = $this->container->get('doctrine.orm.entity_manager');
$testRepository = $entityManager->getRepository(TestmoduleTest::class);
$test = $testRepository->findAll();
And I have error like that:
The class 'DarkSide\Testmodule\Entity\TestmoduleTest' was not found in the chain configured namespaces PrestaShopBundle\Entity
Maybe I doing something wrong? But doc of prestashop of coures is suck about new way of creating a PrestaShop modules
Looking 4 help :)
Thx all :)
The PrestaShop documentation is a completely mess concerning the handling of the Symfony repositories.
Doctrine is looking (by the auto_mapping orm configuration attribute) for the presence of your entity under the Prestashop Entity namespace, so given that your TestmoduleTest entity isn't there, it cannot be found and therefore loaded.
You may have to register your entity under the following namespace : namespace PrestaShop\Module\Testmodule\Entity;
You'll be able to find more about how to create your own repository class inside the official productcomments module here.
Ok the problem is on other way :)
In this case i have problem with my Repository class (probably with constructor of this class)
when I deleted them module start work
Problem solved :)
Please point out any naivete or incorrect assumptions I'm making about Laravel, Composer, PHPUnit, etc.
I had a class called SpeechToTextHelper that was inside a Laravel project, and it used facades like this:
use Cache;
use Log;
use Storage;
Then, since I wanted to share it between multiple Laravel projects, I moved it into a separate repo and required it (into the first project) as a dependency via Composer.
The code all seems to run fine.
My question is different from Using Laravel Facades outside Laravel
What I want to know is:
Now that I also want to write PHPUnit tests for SpeechToTextHelper in my new tools repo, I see errors like RuntimeException: A facade root has not been set. and Error: Class 'Log' not found, presumably because this tools repo has no awareness of Laravel. I guess this means my production code has been working just by side-effect.
In my new tools repo (where my SpeechToTextHelper now is), how am I supposed to indicate (maybe somewhere in composer.json?) that the code will only work if Laravel's facades exist and are initiated properly?
How can I fix my separate repo's code so that its tests can run and also so that it ensures that it can only be "required" by a Laravel project?
P.S. https://laravel.com/docs/5.7/facades says "When building a third-party package that interacts with Laravel, it's better to inject Laravel contracts (https://laravel.com/docs/5.7/contracts) [which live in their own GitHub repository] instead of using facades." "If you are building a package, you should strongly consider using contracts since they will be easier to test in a package context."
But I do not see contracts for Log or Storage at all.
I think you are looking for Laravel component repositories
Cache - This component shows how to use Laravel's Cache features in non-Laravel applications.
Log - This component shows how to use Laravel's Log features in non-Laravel applications.
This video shows, how you can use eloquent outside laravel, I think that will give you better idea.
I'm not positive that this is the best approach, so I'd love if others
would provide better answers.
For production code
My composer.json still has this in the "require" section: "laravel/framework": "5.7.*",.
I plan to only ever require this tools library from within a Laravel app. I'm not sure that this is the right way to make that a rule, but my production code at least seems to be working.
For tests
As for tests, what seems to have been necessary was to add these files from https://github.com/laravel/laravel/tree/2a1f3761e89df690190e9f50a6b4ac5ebb8b35a3:
app/Console/Kernel.php
app/Providers/AppServiceProvider.php
app/Providers/AuthServiceProvider.php
app/Providers/EventServiceProvider.php
app/Providers/RouteServiceProvider.php
bootstrap/cache/.gitignore
bootstrap/app.php
bootstrap/autoload.php
config/app.php
config/database.php
config/logging.php
config/view.php
storage/logs/laravel.log
tests/CreatesApplication.php
tests/TestCase.php
Perhaps those are the minimum set of barebones Laravel files without which tests can't run.
Then I made sure that each test class extended tests/TestCase.php. And I adjusted the namespaces.
I am able to successfully record changes to classes, and return what has been changed (not including many-to-many). However, I am unable to revert back any change using the built-in new transitionTo() method.
I get the following error on all classes:
Expected Auditable type App\XYZ, got XYZ instead
I have all of my morphable classes (which are all I am using for tracking audits) attached correctly within AppServiceProvider in a morphmap like so:
\Illuminate\Database\Eloquent\Relations\Relation::morphMap([
'Employee' => \App\Employee::class,
];
All classes work correctly with all other Laravel morphTo methods.
The auditable code looks like it is tripping the error in line 467 of the Auditable class:
if (!$this instanceof $audit->auditable_type) {}
It doesn't appear to be looking to the map for any of the morphed classes. Or, I could be totally missing something of course!
Any help on how to get this to work using the auditing method -- has anyone gotten this to work with standard morph classes? (It will of course revert the class manually by looping on the old fields and saving the object).
Using Laravel 5.5 and the latest version (5.0) of Laravel-Auditing.
Sent a note to the developer - this was in fact a bug. Vendor code was needed to include morphMapped objects.
Developer at Laravel Auditing responded within an hour and had a fix a few hours later. I can confirm this is now functioning as expected. Outstanding support.
I'm currently building a new CakePHP app with version 3.0.0-RC1, and trying to install and use the jasig/phpCAS plugin. Using this guide, I've run the following command from the command prompt: composer require jasig/phpcas
This correctly copies the jasig/phpcas files into the vendor directory of my app, but one of the other files that the guide says should be updated (vendor/cakephp-plugins.php) doesn't even exist.
I've had a tough time accessing the plugin. I want to be able to call its static methods, and I keep getting errors of the form: Error: Class 'App\Controller\phpCAS' not found. (The exact directory in the error changes depending on where I'm calling the method from.)
I don't know if this is due to not having the cakephp-plugins.php file, or if I'm not calling the plugin correctly. It's my understanding that if the plugin is loaded I should just be able to call static methods on it like this: phpCAS::methodName()
First of all jasig/phpcas is not a CakePHP plugin. And the vendor/cakephp-plugins.php file is created by the CakePHP plugin installer, so if you don't see such a file, you seem to have either not installed any plugins yet, or you are not using a recent version of the installer, as the creation of this file has been introduced just recently.
Regarding the error about the class not being found, you are missing the leading namespace separator (\phpCAS::methodName()) to access the class in the global namespace, respectively you are missing a proper import (use phpCAS;) that would make the class available in the current namespace.
In case you are not familiar with namespaces, you may want to start with: http://php.net/namespaces
I just downloaded Laravel 5 and started migrating to it. However, I find the required use of namespaces really annoying.
I don't feel like I am getting much from it, other than cluttering my code.
How can I disable the namespacing requirement?
I don't think you should disable or remove namespaces. The main reason for namespacing is to avoid conflicts with classes that have the same name. As soon as an application gets larger you will have classes that have the same name. Example from the Framework source:
Illuminate\Console\Application and Illuminate\Foundation\Application
Both are called the same. Only because of the namespacing you can import the right class. Of course you could also name them:
ConsoleApplication and FoundationApplication
But while the namespace normally is only used when importing a class at the top of a file:
use `Illuminate\Console\Application`
The name itself is used everywhere in the code. That's something that really clutters up your code, too long class names.
Besides the naming thing, namespaces also encourage better structure and help with knowing where your files are. That's because Laravel's default structure is PSR-4 compliant. That means if you have a controller App\Http\Controllers\HomeController you can be certain that you will find a HomeController.php under app/Http/Controllers.
I am aware of that, but it's not needed in the project I am working on.
Maybe it doesn't make sense for the current project but getting used to namespaces will help you tackle bigger projects in the future
And being a Sublime Text user, which doesn't have autoimport, it really gets to be a pain
I don't know Sublime Text that well, but CodeIntel might have auto import. Otherwise consider switching to another editor / IDE. I can highly recommend JetBrains PhpStorm
In the end, if you still don't want to use namespaces, keep using Laravel 4 or search for another framework that follows less good practices...
Removing namespaces from your app classes
While a totally don't recommend this, it is possible to at least remove some of the namespacing in your application.
For example the default controller namespace App\Http\Controllers can be changed to no namespace at all in RouteServiceProvider:
protected $namespace = '';
And for your models you can just remove the namespace in the file and your good. But keep in mind that without namespaces PSR-4 autoloading won't work anymore. You will have to autoload your files using classmap in composer.json
You can avoid using namespaces for own classes by defining them in the global namespace in your composer.json file. Like this:
"autoload": {
"psr-0": {
"": ["app/Http/Controllers/",
"app/models/",
"app/helpers"
]
},
You will also have to change your app/Providers/RouteServiceProvider.php to:
protected $namespace = '';
for routing to work.