File::load in drupal8 custom module controller - drupal-modules

i have created one custom module, in the controller file i used File::load static method. but when I'm run phpcs for check coding standards it will give an error as
File::load calls should be avoided in classes, use dependency injection instead
anyone can please tell how to create dependency injection for this.

The be achieved by using Drupal\Core\Entity\EntityTypeManagerInterface.
use Drupal\Core\Entity\EntityTypeManagerInterface;
class MyForm extends FormBase {
/**
* The storage handler class for files.
*
* #var \Drupal\file\FileStorage
*/
protected $fileStorage;
/**
* This is an example.
*
* #param \Drupal\Core\Entity\EntityTypeManagerInterface $entity
* The Entity type manager service.
*/
public function __construct(EntityTypeManagerInterface $entity) {
$this->fileStorage = $entity->getStorage('file');
}
....
}
From there you can update the File::load($fid) to $this->fileStorage->load($fid)

Related

How to read data from the specific sheet number from Maatwebsite/Laravel-Excel package?

I am working on import excel data in Laravel framework and using Maatwebsite/Laravel-Excel package.
Now I have followed the steps but not getting any idea after reading package documentation, so I need help to read data from the second(2nd) sheet as I have multiple sheets in my excel file.
BillingDataImport
<?php
namespace App\Imports;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
class BillingDataImport implements ToCollection
{
/**
* #param Collection $collection
*/
public function collection(Collection $collection)
{
return $collection;
}
}
BillingController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Imports\BillingDataImport;
use App\Http\Controllers\Controller;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\Input;
class BillingController extends Controller
{
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$import = new BillingDataImport();
$rawData = Excel::toArray($import, $request->file('company_1'));
var_dump($rawData);
}
}
When I dump the code, I am getting data from the first(1st) sheet but I want to read second(2nd) sheet so can you please guide me as I am not too good Laravel and with this package.
You need to implement WithMultipleSheets interface in your import class. It will require you to add sheets method. You will include them like these;
public function sheets(): array
{
return [
0 => new FirstSheetImport(),
1 => new SecondSheetImport(),
];
}
Then you may select them by index. More info here

JSDoc #param - reference class from another module

I have 2 Node modules. In module A I have the following definition:
/**
* HTTP Client
* #module src/http/client
*/
/**
* A HTTP Client
* #alias src/http/client
*/
class HTTPClient {
[... class def with documented methods etc]
}
module.exports = HTTPClient
And now in module B I want to say that the first constructor parameter should be of type HTTPClient. So I tried the following
class PackageFactory {
/**
* #param {module:src/http/client} httpClient - the HTTPClient instance
*/
constructor(httpClient) {
this._httpClient = httpClient
}
}
I also tried a few variations but it never worked. Within module B the httpClient is always of type "any". What do I have to change so I can see the class member of HTTPClient in module B?
The solution was easier then I thought. There is no need to include the module paths (aka longname) or anything.
const HTTPClient = require('../http/client')
class PackageFactory {
/**
* #param {HTTPClient} httpClient - the HTTPClient instance that shall be used to make requests
*/
constructor(httpClient) {
this._httpClient = httpClient
}
}
To avoid the HTTPClient is unused error that any linter will give you, you can actually import the class in the #param field itself. This makes the doc a bit less easy to read, but you get autocompletion at design time, a nice tradeoff.
Note that you can combine this with the compilerOptions.paths option of tsconfig.json to create aliases that will make those documentation-imports look better.
class PackageFactory {
/**
* #param {import('../http/client')} httpClient - the HTTPClient instance that shall be used to make requests
*/
constructor(httpClient) {
this._httpClient = httpClient
}
}

How to document ES6 class module with jsdoc3?

If I am developing a node module something-nifty which has the following directory structure:
something-nifty/
lib/
plugins/
Plugin.cs
index.js
package.json
And plugin.cs is defined as follows:
"use strict";
/**
* #module something-nifty/lib/plugins/Plugin
*/
/**
* The base class for a 'something-nifty' plugin.
*/
class Plugin {
/**
* Constructs the plugin...
*/
constructor() {
}
}
module.exports = Plugin;
In the generated documentation the class is documented as though it has the #inner tag which means that I need to repeat the class name twice whenever I refer to it:
"use strict";
/**
* #module something-nifty/lib/foo
*/
/**
* Foo...
* #param {module:something-nifty/lib/plugins/Plugin~Plugin} plugin
*/
exports.abc = function(plugin) { ... };
Surely I shouldn't need to specify the class name twice in this situation since the module is essentially the class. What is the correct way to annotate this with jsdoc3 tags such that it outputs documentation that is properly structured (module and class listings)?
Having spent some time searching the best that I have been able to find is this is to (in my opinion) "misuse" the #alias tag like shown in the following snippet:
"use strict";
/**
* #module something-nifty/lib/plugins/Plugin
*/
/**
* The base class for a 'something-nifty' plugin.
* #alias module:something-nifty/lib/plugins/Plugin
*/
class Plugin {
/**
* Constructs the plugin...
*/
constructor() {
}
}
module.exports = Plugin;
The following link refers to the article where I picked up on this #alias trick:
http://www.pagosoft.com/javascript/using-jsdoc-amd-modules/

Is there a way to make the #Builder annotation work for immutable classes?

I'm trying to develop a project in Groovy and I've been looking through my code and trying to find areas which I could replace with something more idiomatically Groovy until I find a solution for another issue I've been having.
I've started taking a more in-depth look into the use of AST transformation annotations - they've helped significantly cut down on the amount of code I have to write in some places. However, I'm having an issue using the groovy.transform.builder.Builder annotation with one of my immutable value classes. The source for this annotation is hosted here.
The issue is that the annotation seems to make the builder set the values of the buildee directly rather than storing a copy of the values and passing them to the buildee's constructor. This results in a ReadOnlyPropertyException when you try to use it with immutable classes.
There are four possible Builder strategies you can select with this annotation, and of them I've tried DefaultStrategy, ExternalStrategy and InitializerStrategy. However, all of these have caused problems.
ExternalStrategy looks like the most promising of the four, and you can find an SSCCE based on it detailing the problem here.
The source code from the example is also included below:
import groovy.transform.Immutable
import groovy.transform.builder.Builder as GBuilder
import groovy.transform.builder.ExternalStrategy
/*
* Uncommenting the below causes a failure:
* 'groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: value for class: Value'
*/
//#Immutable
class Value {
#GBuilder(forClass = Value, prefix = 'set', builderStrategy = ExternalStrategy)
static class Builder { }
int value
String toString() { "Value($value)" }
}
def builder = new Value.Builder()
println builder.setValue(1).build()
There also seems to be a relevant JIRA discussion on the matter here.
Edit
I've tried using CFrick's answer below, using InitializerStrategy rather than ExternalStrategy.
Everything now compiles, but I get the following errors at run-time when I try to execute my tests:
java.lang.IllegalAccessError: tried to access class com.github.tagc.semver.version.BaseVersion from class com.github.tagc.semver.version.BaseVersion$com.github.tagc.semver.version.BaseVersionInitializer
at java.lang.Class.getDeclaringClass(Class.java:1227)
at java.beans.MethodRef.set(MethodRef.java:46)
at java.beans.MethodDescriptor.setMethod(MethodDescriptor.java:117)
at java.beans.MethodDescriptor.<init>(MethodDescriptor.java:72)
at java.beans.MethodDescriptor.<init>(MethodDescriptor.java:56)
at java.beans.Introspector.getTargetMethodInfo(Introspector.java:1163)
at java.beans.Introspector.getBeanInfo(Introspector.java:426)
at java.beans.Introspector.getBeanInfo(Introspector.java:173)
at com.github.tagc.semver.version.VersionFactory.createBaseVersion(VersionFactory.groovy:34)
at com.github.tagc.semver.test.util.TestSetup.<clinit>(TestSetup.groovy:77)
at java.lang.Class.forName(Class.java:344)
at com.github.tagc.semver.version.SnapshotDecoratorSpec.#decoratedVersion should be considered equal to patch-bumped #releaseVersion snapshot(SnapshotDecoratorSpec.groovy:24)
Followed thereafter by a series of exceptions like the following:
java.lang.NoClassDefFoundError: Could not initialize class com.github.tagc.semver.test.util.TestSetup
at java.lang.Class.forName(Class.java:344)
at com.github.tagc.semver.version.SnapshotDecoratorSpec.#decoratedVersion should be considered equal to minor-bumped #releaseVersion snapshot(SnapshotDecoratorSpec.groovy:36)
What I have right now is a BaseVersion class like the following:
/**
* A concrete, base implementation of {#link com.github.tagc.semver.version.Version Version}.
*
* #author davidfallah
* #since v0.1.0
*/
#Immutable
#Builder(prefix = 'set', builderStrategy = InitializerStrategy)
#PackageScope
final class BaseVersion implements Version {
// ...
/**
* The major category of this version.
*/
int major = 0
/**
* The minor category of this version.
*/
int minor = 0
/**
* The patch category of this version.
*/
int patch = 0
/**
* Whether this version is a release or snapshot version.
*/
boolean release = false
// ...
}
A factory to produce instances of these:
/**
* A factory for producing base and decorated {#code Version} objects.
*
* #author davidfallah
* #since v0.5.0
*/
class VersionFactory {
// ...
/**
* Returns an instance of {#link com.github.tagc.semver.version.BaseVersion BaseVersion} constructed
* with the given parameters.
*
* #param major the major category value of the version instance
* #param minor the minor category value of the version instance
* #param patch the patch category value of the version instance
* #param release the release setting of the version instance
* #return an instance of {#code BaseVersion}
*/
static BaseVersion createBaseVersion(int major, int minor, int patch, boolean release) {
return new BaseVersion(major, minor, patch, release)
}
/**
* Returns an instance of {#link com.github.tagc.semver.version.BaseVersion BaseVersion} constructed
* with the given parameters.
*
* #param m a map of parameter names and their corresponding values corresponding to the
* construction parameters of {#code BaseVersion}.
*
* #return an instance of {#code BaseVersion}
*/
static BaseVersion createBaseVersion(Map m) {
return new BaseVersion(m)
}
/**
* Returns an instance of {#link com.github.tagc.semver.version.BaseVersion BaseVersion} constructed
* with the given parameters.
*
* #param l a list of parameter values corresponding to the construction parameters of {#code BaseVersion}.
*
* #return an instance of {#code BaseVersion}
*/
static BaseVersion createBaseVersion(List l) {
return new BaseVersion(l)
}
/**
* Returns a builder for {#link com.github.tagc.semver.version.BaseVersion BaseVersion} to specify
* the construction parameters for the {#code BaseVersion} incrementally.
*
* #return an instance of {#code BaseVersion.Builder}
*/
static Object createBaseVersionBuilder() {
return BaseVersion.builder()
}
// ...
}
A test specification class for Version objects:
/**
* Test specification for {#link com.github.tagc.semver.version.Version Version}.
*
* #author davidfallah
* #since 0.1.0
*/
#Unroll
class VersionSpec extends Specification {
static exampleVersions = [
VersionFactory.createBaseVersion(major:1, minor:2, patch:3),
VersionFactory.createBaseVersion(major:0, minor:0, patch:0),
VersionFactory.createBaseVersion(major:5, minor:4, patch:3),
VersionFactory.createBaseVersion(major:1, minor:16, patch:2),
VersionFactory.createBaseVersion(major:4, minor:5, patch:8),
]
// ...
}
And other classes that try to create instances of BaseVersion that are failing, such as TestSetup.
Your code there fails, because chosen strategy there basically does:
def v = new Value().with{ setValue(1); return it }
and this can not be done on #Immutable objects.
According to the docs, there is only InitializerStrategy, that can explicitly cope with #Immutable.
You can use the InitializerStrategy in conjunction with #Canonical and #Immutable. If your #Builder annotation doesn’t have explicit includes or excludes annotation attributes but your #Canonical annotation does, the ones from #Canonical will be re-used for #Builder.
E.g.
import groovy.transform.*
import groovy.transform.builder.*
#Immutable
#ToString
#Builder(prefix='set', builderStrategy=InitializerStrategy)
class Value {
int value
}
def builder = Value.createInitializer().setValue(1)
assert new Value(builder).toString()=='Value(1)'
Depending on what you are up to, this is rahter ugly syntax and you might be better off just using the Map-based c'tors. Even without e.g. #TypeChecked a new Value(vlaue: 666) will generate an error and leaving params (for a class with multiple properties) will leave them null.

How to add multiple outlets for generated XText DSL

By default the generated XText artifacts generate code from my DSL to the default outlet (which defaults to src-gen folder). I know that you can explicitly pass the outlet configuration name in fsa.generateFile("myfile.txt", "MY_OUTLET_NAME", "Some file content").
I it because I want to generate code with my XText DSL and want to use the generation gap pattern and generate code in a folder called "src-once".
I'am using XText 2.2.1.
My questions:
1) Where and how do I define my outlets like "MY_OUTLET_NAME"?
2) Is there a way to prevent overwriting existing files in a specific outlet?
The hint form Christian Dietrich pointed me in the right direction. Below is the code that I ended up with.
I have created a new class MyOutputConfigurationProvider that implements IOutputConfigurationProvider. The getOutputConfigurations method returns two output configurations, the default src-gen and a custom src-gen-once with the correct settings for generating sources only once.
package com.my.dsl;
import static com.google.common.collect.Sets.newHashSet;
import java.util.Set;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IOutputConfigurationProvider;
import org.eclipse.xtext.generator.OutputConfiguration;
public class MyOutputConfigurationProvider implements
IOutputConfigurationProvider {
public final static String DEFAULT_OUTPUT_ONCE = "DEFAULT_OUTPUT_ONCE";
/**
* #return a set of {#link OutputConfiguration} available for the generator
*/
public Set<OutputConfiguration> getOutputConfigurations() {
OutputConfiguration defaultOutput = new OutputConfiguration(IFileSystemAccess.DEFAULT_OUTPUT);
defaultOutput.setDescription("Output Folder");
defaultOutput.setOutputDirectory("./src-gen");
defaultOutput.setOverrideExistingResources(true);
defaultOutput.setCreateOutputDirectory(true);
defaultOutput.setCleanUpDerivedResources(true);
defaultOutput.setSetDerivedProperty(true);
OutputConfiguration onceOutput = new OutputConfiguration(DEFAULT_OUTPUT_ONCE);
onceOutput.setDescription("Output Folder (once)");
onceOutput.setOutputDirectory("./src-gen-once");
onceOutput.setOverrideExistingResources(false);
onceOutput.setCreateOutputDirectory(true);
onceOutput.setCleanUpDerivedResources(false);
onceOutput.setSetDerivedProperty(true);
return newHashSet(defaultOutput, onceOutput);
}
}
To use the MyOutputConfigurationProvider implementation add a configure method to your module class:
/**
* Use this class to register components to be used within the IDE.
*/
public class MyDslUiModule extends com.my.dsl.ui.AbstractMyDslUiModule {
public MyDslUiModule(AbstractUIPlugin plugin) {
super(plugin);
}
#Override
public void configure(Binder binder) {
super.configure(binder);
binder.bind(IOutputConfigurationProvider.class).to(MyOutputConfigurationProvider.class).in(Singleton.class);
}
}
implement a custom IOutputConfigurationProvider should do the trick

Resources