jsdoc self executing anonymous function - module

How can i document a module like this with jsdoc? I tried many version, but can't get it work. Funciton test doesn't appear in the documentation.
/**
* Description of module, defines module for whole file
*
* #module constructors
* #exports app
*/
var app = (function() {
/**
* Description of function test
*/
function test() {
return '';
}
return {
test: test
}
}());

As of version 3.2.2, jsdoc is easily tripped by modules, the solution is to use module: with the module name to specify where the entity you are documenting resides:
/**
* Description of module, defines module for whole file
*
* #module constructors
*/
var app = (/** #lends module:constructors */ function() {
/**
* Description of function test
*/
function test() {
return '';
}
return {
test: test
}
}());

For me, using JSDoc 3.4.0 helped this solution:
/**
* #module array-cop
*/
/**
* #function
* #name Anonymous self-invoked function
* #description Call main module
* #param {Object} this Window for the browser
*/
(function(_) {
var array_ = {
/**
* #function
* #name check
* #description Method for checking type of the source data.
* #param {Array} arr Source data.
* #returns {Boolean} Returns true if Array.isArray, otherwise throw error.
* #throws Will throw an error "Not an array" if the argument isn't array.
*/
check: function(arr) {
return Array.isArray(arr) || (function() {
throw new Error("Not an array!");
}());
},
// Some code stuff
/**
* npm / <script> compatibility
*/
if (typeof module !== "undefined" && module.exports) {
module.exports = array_;
} else {
_.array_ = array_;
}
}(this));
and also I created gulp task for generate JSDoc documentation:
var gulp = require('gulp'),
child_exec = require('child_process').exec;
// Task for generationg JSDoc
gulp.task('docs', function(done) {
var settings = {
docGenerator: "./node_modules/jsdoc/jsdoc.js",
srcFile: "./src/array-cop.js",
jsDocConfPath: "./jsdoc.json",
docsOutputPath: "./docs"
}
child_exec('node '
+ settings.docGenerator
+ ' ' + settings.srcFile
+ ' -c ' + settings.jsDocConfPath
+ ' -d ' + settings.docsOutputPath, undefined, done);
});
after running gulp docs
documentation will be placed to the ./docs folder

Related

Empty result with findAll in FlexForm UserFunc in TYPO3 7.6.15

I get an empty result with findAll in FlexForm UserFunc in TYPO3 7.6.15.
The storagePid is set and in Frontend I get all results with findAll.
Here is my UserFunc-Method:
public function getBuldingOptions(&$config)
{
/** #var ObjectManager $om */
$om = GeneralUtility::makeInstance(ObjectManager::class);
/** #var BuildingRepository $repo */
$repo = $om->get(BuildingRepository::class);
$building = $repo->findAll();
DebuggerUtility::var_dump($building, '$building'); // Output: TYPO3\CMS\Extbase\Persistence\Generic\QueryResultprototypeobject (empty)
// add empty value option
$config['items'][] = [LocalizationUtility::translate('BuildingUserFunc.building.emtpyValue', $this->extName), 0];
/** #var Building $entity */
foreach ($building as $entity) {
$config['items'][] = [$entity->getName(), $entity->getUid()];
}
return $config;
}
What can by still wrong? Anybody an idea?
I've found the problem and a suitable solution.
The problem is, that the configured storagePid does not work in plugin configuration scope. You have to solve the storagePid manually.
I have wrote a service for that and added to EXT:xm_tools:
https://github.com/xima-media/xm_tools/blob/rc-1.0.0/Classes/Extensionmanager/ExtensionUtility.php
And my repository have a initializeObject method:
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
use TYPO3\CMS\Extbase\Persistence\Repository;
use Xima\XmTools\Extensionmanager\ExtensionUtility;
class BaseRepository extends Repository
{
private $extName = 'my_extension_key';
public function initializeObject()
{
$pluginSetup = ExtensionUtility::getTypoScriptPluginSetup($this->extName);
/** #var Typo3QuerySettings $querySettings */
$querySettings = $this->objectManager->get(Typo3QuerySettings::class);
$querySettings->setStoragePageIds(array_merge($querySettings->getStoragePageIds(), explode(',', $pluginSetup['persistence']['storagePid'])));
$this->setDefaultQuerySettings($querySettings);
}
}

Adding version info to jar file name using IntelliJ

I'm used to Android Studio and developing Android projects.
In Android Studio I put this in the build.gradle file:
defaultConfig {
applicationId "com.domain.myapp"
minSdkVersion 19
targetSdkVersion 19
versionCode 1
versionName "1.0"
setProperty("archivesBaseName", "myapp.$versionName.$versionCode")
signingConfig signingConfigs.config
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationVariants.all { variant ->
variant.outputs.each { output ->
def newName = output.outputFile.name
newName = newName.replace("-release", "")
output.outputFile = new File(output.outputFile.parent, newName)
}
}
signingConfig signingConfigs.config
}
debug {
signingConfig signingConfigs.config
}
}
When I build I get myapp.1.0.1.apk, works wonderfully.
Now I am developing a java project .jar using IntelliJ, NOT Android Studio.
How can I accomplish the same thing? I'm finding sparse information ...
Android does this by adding a task that build the R.java file. As simple as Android makes it look replicating the behavior takes a little effort. You can create your own gradle task to accomplish the same. You will need a gradle plugin that creates and extension and a task. The extension will be used to track values added in the build.gradle
Plugin should create extensions and tasks
// create DSL model
target.extensions.create('buildConfig', BuildConfigModel)
// create task to generate file
def buildConfigTask = target.tasks.create('generateBuildConfig', BuildConfigTask)
target.tasks.findByName('clean').configure {
delete new File("$project.projectDir/src/main", "generated-sources")
}
// this task must always run... it's never `upToDate`
buildConfigTask.outputs.upToDateWhen { false }
// java compiler depends on this task... allows us to reference generated code from
// human written code
target.tasks.getByName('compileJava').dependsOn buildConfigTask
Here is how you can use your task to add a generated sources file
project.configure(project, { Project configuredProject ->
// compilerJava task {#link JavaCompile}
def compileJava = configuredProject.compileJava
// add the created java file to source path so it gets compiled
compileJava.source(project.buildConfig.createBuildConfig(project, compileJava))
})
Then our extension would looks something like this
package com.jbirdvegas.q41680813;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.tasks.compile.JavaCompile;
import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Handles creating the BuildConfig.java from a module project
* <p>
* Warning... Keep this in java, gradle doesn't have the streams api we are using
*/
public class BuildConfigModel {
/**
* Final java file output path pattern for {#link String#format(String, Object...) String#format} formatting of
* the file's path. Directory structure will be created if needed
*/
private static final String OUTPUT_PATH_FORMAT = "%s/src/main/generated-sources/%s/%s/BuildConfig.java";
/**
* List of DSL supplied {#link BuildValue buildConfig#add}
*/
private List<BuildValue> mBuildValues = new ArrayList<>();
/**
* Required... do not remove
*/
public BuildConfigModel() {
}
/**
* Create a new field to the project's generated `BuildConfig.java`'s inner class for each type
*
* #param clazz Type of value to be written (will be grouped by clazz)
* #param name field name to be created
* #param value value to be assigned to field's name
*/
#SuppressWarnings({"unused", "WeakerAccess"})
public void add(Class clazz, String name, Object value) {
mBuildValues.add(new BuildValue(clazz, name, value));
}
/**
* Create `BuildConfig.java` and add it to the {#link JavaCompile#source(Object...)} compileJava#source(Object...)}
*
* #param project module to generate BuildConfig for
* #param javaCompile project's `compileJava` task
* #return generated `BuildConfig.java` file
*/
public File createBuildConfig(Project project, JavaCompile javaCompile) {
File buildConfigFile = getBuildConfigFile(project);
createJavaClass(project, buildConfigFile);
javaCompile.source(buildConfigFile);
return buildConfigFile;
}
/**
* Destination file for given project's `BuildConfig.java`
*
* #param project module to generate BuildConfig for
* #return File representing the destination of the created `BuildConfig.java`
*/
#SuppressWarnings("WeakerAccess")
public File getBuildConfigFile(Project project) {
return project.file(String.format(OUTPUT_PATH_FORMAT,
project.getProjectDir().getAbsolutePath(),
project.getGroup().toString().replaceAll("\\.", "/"),
project.getName()));
}
/**
* Create `BuildConfig.java` with a few default values and any values supplied
* to the `buildConfig`'s {#link #add(Class, String, Object) add} method.
* <p>
* Default BuildConfig fields will be generated by {#link #getDefaultFields}
* <p>
* Fields added via {#link #add(Class, String, Object) add} method will be grouped into inner classes
* named <pre>{#code Class#getSimpleName().toLowerCase() + "s"}</pre>
*
* #param project module to generate BuildConfig for
* #param buildConfigFile File representing the destination of the BuildConfig.java output
*/
#SuppressWarnings("WeakerAccess")
public void createJavaClass(Project project, File buildConfigFile) {
//noinspection unchecked
Collections.sort(mBuildValues);
// group our configs by their types into a map of groups
Map<Class, List<BuildValue>> groupedConfigs = mBuildValues.stream()
// put the values in groups based on the simple name of the class in lowercase
.collect(Collectors.groupingBy(BuildValue::getValueType));
// create the fully qualified class that will contain our build settings
TypeSpec.Builder buildConfigJavaBuilder = TypeSpec.classBuilder("BuildConfig")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
// note for javadoc
.addJavadoc("$S\n", "DO NOT MODIFY; this class is written automatically by the compiler")
// replace public constructor with private
.addMethod(createPrivateConstructor());
// add any fields that will be in all BuildConfig classes
buildConfigJavaBuilder.addFields(getDefaultFields(project));
groupedConfigs.forEach((aClass, buildValues) -> {
// create the inner class
String safeInnerClassName = aClass.getSimpleName().toLowerCase() + 's';
TypeSpec.Builder innerClass = TypeSpec.classBuilder(safeInnerClassName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
// make a constructor that's private since all the members of this class are public static final
.addMethod(createPrivateConstructor());
// for each inner class type create a field
// each object type gets it's own inner class
//noinspection SimplifyStreamApiCallChains
buildValues.stream().forEachOrdered(buildValue -> {
// create the requested field in the class
FieldSpec fieldSpec = FieldSpec.builder(buildValue.clazz, buildValue.name)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer(CodeBlock.of(getStringFormatter(buildValue.clazz), buildValue.value))
.build();
// add the field to the inner class
innerClass.addField(fieldSpec);
});
// add the inner class to the fully qualified class
buildConfigJavaBuilder.addType(innerClass.build());
});
// determine the package name from project.group + '.' + project.name
String packageName = project.getGroup() + "." + project.getName();
// create a java file writer
JavaFile.Builder builder = JavaFile.builder(packageName, buildConfigJavaBuilder.build());
// don't import java.lang.* it's redundant
builder.skipJavaLangImports(true);
// use four spaces for indent instead of default two spaces
builder.indent(" ");
// create the file in memory
JavaFile javaFile = builder.build();
// ensure file structure
if (!buildConfigFile.getParentFile().exists() && !buildConfigFile.getParentFile().mkdirs()) {
throw new GradleException("Failed to create directory structure for " + buildConfigFile.getAbsolutePath());
}
// write BuildConfig.java to location
try (FileWriter writer = new FileWriter(buildConfigFile)) {
javaFile.writeTo(writer);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Strings require being treated specially in order to be encapsulated in quotes correctly
* All other classes are treated as literals... We may want to handle more {#link java.lang.reflect.Type Type}
*
* #param clazz Class formatter is needed for
* #return "$S" if the class is a {#link String} else a literal formatter is returned "$L"
*/
private String getStringFormatter(Class clazz) {
switch (clazz.getSimpleName().toLowerCase()) {
case "string":
// causes the formatter used to wrap the value in quotes correctly
case "date":
// date objects are serialized to a string
return "$S";
case "long":
return "$LL";
case "double":
return "$LD";
case "float":
return "$LF";
default:
// for the reset use literal
return "$L";
}
}
/**
* get project added build values
*
* #return List of build values added by project's `buildConfig` closure
*/
#SuppressWarnings("unused")
public List<BuildValue> collectBuildValues() {
return mBuildValues;
}
/**
* Make a private constructor for the class. Default is public but our classes only contain
* <pre>{#code public static final {#link Object}}</pre> so public constructors are redundant
*
* #return private constructor method
*/
private MethodSpec createPrivateConstructor() {
return MethodSpec.constructorBuilder().addModifiers(Modifier.PRIVATE).build();
}
/**
* Create default field references
*
* #param project module to generate BuildConfig for
* #return List of fields to write to generated BuildConfig
*/
private List<FieldSpec> getDefaultFields(Project project) {
List<FieldSpec> fields = new ArrayList<>();
// set current version
fields.add(FieldSpec.builder(String.class, "version")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer(CodeBlock.of(getStringFormatter(String.class), project.getVersion()))
.build());
return fields;
}
class BuildValue implements Comparable {
/**
* Type of field's value
*/
/* package */ Class clazz;
/**
* Field name
*/
/* package */ String name;
/**
* Field's value Value must be able to be serialized as a string
*/
/* package */ Object value;
/* package */ BuildValue(Class clazz, String name, Object value) {
this.clazz = clazz;
this.name = name;
this.value = value;
}
/* package */ Class getValueType() {
return clazz;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BuildValue)) return false;
BuildValue that = (BuildValue) o;
if (clazz != null ? !clazz.equals(that.clazz) : that.clazz != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
return value != null ? value.equals(that.value) : that.value == null;
}
#Override
public int hashCode() {
int result = clazz != null ? clazz.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (value != null ? value.hashCode() : 0);
return result;
}
#Override
public int compareTo(Object o) {
return (name != null && o != null) ? name.compareTo(o.toString()) : -1;
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("BuildValue{");
sb.append("class=").append(clazz.getCanonicalName());
sb.append(", name='").append(name).append('\'');
sb.append(", value=").append(value);
sb.append('}');
return sb.toString();
}
}
}
Here by default the plugin will create the BuildConfig.java with the default field of version but you could add your own values also
buildConfig {
add Boolean, 'myKey', false
}
Then at runtime you could get the reference's value with BuildConfig.value and for the example above you would also have the field BuildConfig.myKey available as a Boolean type.
Edit: my example uses groovy for the plugin class and the task class, however the extension, BuildConfigModel, is written in java. All my sources are located in src/main/groovy

Symfony 2: How to use the ParamConverter with a PUT method to get or create an entity object

I need to implement an API with a PUT method and I would like to use the ParamConverter in my Controller to find an existing entity object, or if the entity object doesn't exist, to create a new one.
However the standard Symfony ParamConverter returns an exception if it doesn't find the entity object in the repository.
Do you have any ideas to do that in a nice and clean way ? Thx.
Here is an example of what I would like to do (I use FOS REST Bundle to handle the PUT request):
/**
* #param Request $request
* #return View
*
* #ParamConverter("video")
*
*/
public function putVideosAction(Request $request, Video $video)
{
try {
return $this->getHandlerVideos()->put($video, $request->request->all());
} catch (InvalidFormException $e) {
return $e->getForm();
}
}
Here's a solution. Please give me your thoughts on it.
In your controller, I would do that:
/**
* #param Request $request
* #return View
*
* #Rest\Put()
* #Rest\View()
*
* #ParamConverter("video", converter="app_get_or_create_entity_converter", options={"repository_method" = "findOneById"})
*/
public function putVideosAction(Request $request, Video $video)
{
try {
$video = $this->getHandlerVideos()->put($video, $request->request->all());
return $video;
} catch (InvalidFormException $e) {
return $e->getForm();
}
}
I would write a dynamic param converter that way:
class GetOrCreateEntityConverter implements \Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface
{
/**
* #var EntityManagerInterface
*/
protected $entityManager;
/**
* #var ManagerRegistry $registry Manager registry
*/
private $registry;
/**
* #param ManagerRegistry $registry
* #param EntityManagerInterface $entityManager
*/
public function __construct(ManagerRegistry $registry, EntityManagerInterface $entityManager)
{
$this->registry = $registry;
$this->entityManager = $entityManager;
}
public function supports(ParamConverter $configuration)
{
if ('app_get_or_create_entity_converter' !== $configuration->getConverter()) {
return false;
}
return true;
}
/**
* {#inheritdoc}
*
* Applies converting
*
* #throws \InvalidArgumentException When route attributes are missing
* #throws NotFoundHttpException When object not found
*/
public function apply(Request $request, ParamConverter $configuration)
{
$name = $configuration->getName();
$options = $configuration->getOptions();
$class = $configuration->getClass();
$repository = $this->entityManager->getRepository($class);
$repositoryMethod = $options['repository_method'];
if (!is_callable([$repository, $repositoryMethod])) {
throw new \BadMethodCallException($repositoryMethod . ' function does not exist.', 405);
}
$entity = $repository->$repositoryMethod($id);
if (null === $entity) {
$entity = new $class;
}
$request->attributes->set($name, $entity);
}
}
If you ask why I return a form in the catch, please go and see https://github.com/liuggio/symfony2-rest-api-the-best-2013-way/blob/master/src/Acme/BlogBundle/Controller/PageController.php
You'll have to create your own custom paramConverter.
First, here is what you want to write in your controller:
/**
* #ParamConverter("video", class = "MyBundle:Video", converter = "my_param_converter")
* #param Request $request
* #param Video $video
* #return \Symfony\Component\HttpFoundation\Response
*/
public function putVideosAction(Request $request, Video $video)
{
// your code..
}
Now let's write the my_param_converter!
use Doctrine\Common\Persistence\ManagerRegistry;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface;
// ...
class MyParamConverter implements ParamConverterInterface
{
private $registry;
/**
* #param ManagerRegistry $registry
*/
public function __construct(ManagerRegistry $registry = null)
{
$this->registry = $registry;
}
/**
* Check if object supported by our paramConverter
*
* #param ParamConverter $configuration
*/
public function supports(ParamConverter $configuration)
{
// In this case we can do nothing and just return
if (null === $this->registry || !count($this->registry->getManagers())) {
return false;
}
// Check if the class is set in configuration
if(null === $configuration->getClass()) {
return false;
}
// Get actual entity manager for class
$em = $this->registry->getManagerForClass($configuration->getClass());
// Check what you need to check...
return true;
}
public function apply(Request $request, ParamConverter $configuration)
{
$videoId = $request->attributes->get('video');
if(null === videoId) {
throw new \InvalidArgumentException('Route attribute is missing');
}
// Get actual entity manager for class
$em = $this->registry->getManagerForClass($configuration->getClass());
$repository = $em->getRepository($configuration->getClass());
// Try to find the video
$video = $$repository->findOneById($videoId);
if($video === null || !($video instanceof Video)) {
// Here you can create your new video object
}
// Map video to the route's parameter
$request->attributes->set($configuration->getName(), $video);
}
}
Once your new paramConverter wrote, declare it as a service:
services:
app.param_converter.my_param_converter:
class: YourBundle\Path\To\MyParamConverter
tags:
- { name: request.param_converter, converter: my_param_converter }
arguments:
- #?doctrine
Here you're done!
My answer is largely inspired by this article and hope is helpful.

Laravel with Linkedin API error - ServiceFactory::createService() must be an instance of OAuth\Common\Storage\TokenStorageInterface

I'm using Laravel to develop my website, and I integrated the linkedin login to it, it works fine for like a few months. then suddenly, last week i received an error. I didn't change any code that has something to do with Linkedin API. I'm suspecting whether it has something to do with Linkedin itself.
here's what the error looks like:
If you are using this library to integrate Linkedin to your laravel project, there might be an issue right now with the update. you can simply fix the error in OAuth.php by replacing it with this code:
<?php namespace Artdarek\OAuth;
/**
* #author Dariusz Prząda <artdarek#gmail.com>
* #copyright Copyright (c) 2013
* #license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use \Config;
use \URL;
use \OAuth\ServiceFactory;
use \OAuth\Common\Consumer\Credentials;
class OAuth {
/**
* #var ServiceFactory
*/
private $_serviceFactory;
/**
* Storege name from config
*
* #var string
*/
private $_storage_name = 'Session';
/**
* Client ID from config
*
* #var string
*/
private $_client_id;
/**
* Client secret from config
*
* #var string
*/
private $_client_secret;
/**
* Scope from config
*
* #var array
*/
private $_scope = [];
/**
* Constructor
*
* #param ServiceFactory $serviceFactory - (Dependency injection) If not provided, a ServiceFactory instance will be constructed.
*/
public function __construct(ServiceFactory $serviceFactory = null)
{
if (null === $serviceFactory)
{
// Create the service factory
$serviceFactory = new ServiceFactory();
}
$this->_serviceFactory = $serviceFactory;
}
/**
* Detect config and set data from it
*
* #param string $service
*/
public function setConfig($service)
{
// if config/oauth-4-laravel.php exists use this one
if (Config::get('oauth-5-laravel.consumers') != null)
{
$this->_storage_name = Config::get('oauth-5-laravel.storage', 'Session');
$this->_client_id = Config::get("oauth-5-laravel.consumers.$service.client_id");
$this->_client_secret = Config::get("oauth-5-laravel.consumers.$service.client_secret");
$this->_scope = Config::get("oauth-5-laravel.consumers.$service.scope", []);
// esle try to find config in packages configs
}
else
{
$this->_storage_name = Config::get('oauth-5-laravel::storage', 'Session');
$this->_client_id = Config::get("oauth-5-laravel::consumers.$service.client_id");
$this->_client_secret = Config::get("oauth-5-laravel::consumers.$service.client_secret");
$this->_scope = Config::get("oauth-5-laravel::consumers.$service.scope", []);
}
}
/**
* Create storage instance
*
* #param string $storageName
*
* #return OAuth\Common\\Storage
*/
public function createStorageInstance($storageName)
{
$storageClass = "\\OAuth\\Common\\Storage\\$storageName";
$storage = new $storageClass();
return $storage;
}
/**
* Set the http client object
*
* #param string $httpClientName
*
* #return void
*/
public function setHttpClient($httpClientName)
{
$httpClientClass = "\\OAuth\\Common\\Http\\Client\\$httpClientName";
$this->_serviceFactory->setHttpClient(new $httpClientClass());
}
/**
* #param string $service
* #param string $url
* #param array $scope
*
* #return \OAuth\Common\Service\AbstractService
*/
public function consumer($service, $url = null, $scope = null)
{
// get config
$this->setConfig($service);
// get storage object
$storage = $this->createStorageInstance($this->_storage_name);
// create credentials object
$credentials = new Credentials(
$this->_client_id,
$this->_client_secret,
$url ? : URL::current()
);
// check if scopes were provided
if (is_null($scope))
{
// get scope from config (default to empty array)
$scope = $this->_scope;
}
// return the service consumer object
return $this->_serviceFactory->createService($service, $credentials, $storage, $scope);
}
}

Laravel Auth Custom Driver Error

FYI : I'm very new to Laravel and doing my best to learn it properly.
Working on an auth driver that uses a soap service to authenticate.
Error I get when trying to test with Auth::attempt()
Symfony \ Component \ Debug \ Exception \ FatalErrorException (E_COMPILE_ERROR)
Declaration of Project\Providers\AuthUserProvider::retrieveByToken() must be compatible with Illuminate\Auth\UserProviderInterface::retrieveByToken($identifier, $token)
Here is the driver...
<?php namespace Project\Providers;
use Illuminate\Auth\UserProviderInterface;
use Illuminate\Auth\GenericUser;
use Illuminate\Auth\UserInterface;
class AuthUserProvider implements UserProviderInterface {
/**
* External webservice for authentication
*/
private $webservice;
/**
* The user object.
*/
private $user;
/**
* Constructor
*
* #return void
*/
public function __construct(\Project\Webservice\AuthCheckApi $webservice)
{
$this->webservice = $webservice;
$this->user = null;
}
/**
* Retrieves a user by id
*
* #param int $identifier
* #return mixed null|array
*/
public function retrieveByID($identifier)
{
$this->user = is_null($this->user) ? $this->webservice->find($identifier) : $this->user;
return $this->user;
}
/**
* Tries to find a user based on the credentials passed.
*
* #param array $crendtials username|password
* #return mixed bool|UserInterface
*/
public function retrieveByCredentials(array $credentials)
{
if(!$user = $this->webservice->byusername($credentials['username'],$credentials['password'])) return false;
return new GenericUser($user);
}
/**
* Validates the credentials passed to the ones in webservice.
*
* #param UserInterface $user
* #param array $credentials
* #return bool
*/
public function validateCredentials(\Illuminate\Auth\UserInterface $user, array $credentials)
{
$validated = $this->webservice->validateCredentials($user,$credentials['username']);
return true;
}
/**
* Needed by Laravel 4.1.26 and above
*/
public function retrieveByToken()
{
return true;
}
/**
* Needed by Laravel 4.1.26 and above
*/
public function updateRememberToken()
{
return false;
}
}
Thanks for any help.
You are implementing the UserProviderInterface so you need to add the complete definition of all functions of the interface, here you are forgetting the arguments for the last two function
public function retrieveByToken($identifier, $token)
{
}
public function updateRememberToken($user, $token)
{
}