问:
Testing ES2015 class with Intern v4
How do I import my class and write unit tests using Intern v4. I keep running into an error SyntaxError: Unexpected token import

Unit test file demo.js:

```<code>import Demo from '../../app/demo.js';

const { suite, test } = intern.getInterface('tdd');
const { assert } = intern.getPlugin('chai');
const { expect } = intern.getPlugin('chai');
</code>```

Demo.js class:

```<code>class Demo{
  constructor(){

  }

  print(){
    console.log(`hello world`);
  }

}

export default {Demo};
</code>```

答:
Like @jason0x43 says you must use a loader to load your ESModule to test.
For exemple with babel-register, in your intern.json file you need :

```<code>"plugins": [
    "node_modules/babel-register/lib/node.js"
]
</code>```

But this doesn't load your test files. So if your test files are also ESModules you can use babel-plugin-transform-es2015-modules-commonjs in combination with babel-register.

babel-register is already loaded by intern so just add a .babelrc file with :

```<code>{
    "plugins": [
        "transform-es2015-modules-commonjs"
    ]
}
</code>```

Title: Testing ES2015 class with Intern v4

Body:
How do I import my class and write unit tests using Intern v4. I keep running into an error SyntaxError: Unexpected token import

Unit test file demo.js:

import Demo from '../../app/demo.js';

const { suite, test } = intern.getInterface('tdd');
const { assert } = intern.getPlugin('chai');
const { expect } = intern.getPlugin('chai');

Demo.js class:

class Demo{
  constructor(){

  }

  print(){
    console.log(`hello world`);
  }

}

export default {Demo};

Body:
Like @jason0x43 says you must use a loader to load your ESModule to test.
For exemple with babel-register, in your intern.json file you need :

"plugins": [
    "node_modules/babel-register/lib/node.js"
]

But this doesn't load your test files. So if your test files are also ESModules you can use babel-plugin-transform-es2015-modules-commonjs in combination with babel-register.

babel-register is already loaded by intern so just add a .babelrc file with :

{
    "plugins": [
        "transform-es2015-modules-commonjs"
    ]
}


来源: stackexchange

问:
Nesting reducers in redux
Say, I have a store like that:

```<code>{
  modules: {
    myModule: {
      aFlag: true,
      anotherFlag: false,
      nestedItem: {...}
    },
    ...
  },
  entities: {...},
  ...
}
</code>```

and modules reducer is combineReducers({myModule: myModuleReducer})
Inside myModuleReducer I wanna delegate handling of the nestedItem to another reducer, so myModuleReducer would handle actions for aFlag and anotherFlag, while nestedItem would be handled by nestedReducer.

How can I do that?
It's pretty easy with combineReducers if I create a nested namespace for those flags, i.e. if I have

```<code>myModule: {flags: {aFlag: true, anotherFlag: false}, nestedItem: {...}}
</code>```

I can just do myModuleReducer = combineReducers({flags: flagReducer, nestedItem: nestedReducer})
But what if I don't want to create a namespace for those flags and want myModuleReducer to handle those, while I want nestedReducer to handle nestedItem?

I've come up with a "pattern" like this, using reduce-reducers package:

```<code>const nestedReducers = combineReducers({
  // defaults for slices of state not handled by nested reducers
  aFlag: (state = initialState.aFlag) => state,
  anotherFlag: (state = initialState.anotherFlag) => state,
  // nested reducers for particular slices of state
  nestedItems: nestedReducer
});
</code>```

and then

```<code>const finalReducer = reduceReducers(nestedReducers, myModuleReducer);
</code>```

This ways it seems to make the nestedReducer handle nestedItems slice and myModuleReducer handles top-level parts of state (i.e. aFlag and anotherFlag fields).

But I don't like that I need to pass those default functions for everything which is not handled by the nested reducer. Can it be avoided? (Ofcourse I can abstract this away to some kind of nestReducers helper, but still). In general, what are problems with my approach?

答:
You could always just do that manually in your myModuleReducer function, like this:

```<code>function myModuleReducer(state = someInitialState, action) {

    // Call nestedReducer here
    const reducedNestedItem = nestedReducer(state, action)

    switch (action.type) {
    case 'MY_ACTION_TYPE':
        return Object.assign({}, state, {
            aFlag: // aFlag logic
            anotherFlag: // anotherFlag logic
            nestedItem: reducedNestedItem
        })
    default:
        return state
    }
}
</code>```

You just need to make sure if you do it like that that you follow Redux's purity philosophy.

ContentLicense: CC BY-SA 3.0

Title: Nesting reducers in redux

Body:
Say, I have a store like that:

{
  modules: {
    myModule: {
      aFlag: true,
      anotherFlag: false,
      nestedItem: {...}
    },
    ...
  },
  entities: {...},
  ...
}

and modules reducer is combineReducers({myModule: myModuleReducer})
Inside myModuleReducer I wanna delegate handling of the nestedItem to another reducer, so myModuleReducer would handle actions for aFlag and anotherFlag, while nestedItem would be handled by nestedReducer.

How can I do that?
It's pretty easy with combineReducers if I create a nested namespace for those flags, i.e. if I have

myModule: {flags: {aFlag: true, anotherFlag: false}, nestedItem: {...}}

I can just do myModuleReducer = combineReducers({flags: flagReducer, nestedItem: nestedReducer})
But what if I don't want to create a namespace for those flags and want myModuleReducer to handle those, while I want nestedReducer to handle nestedItem?

I've come up with a "pattern" like this, using reduce-reducers package:

const nestedReducers = combineReducers({
  // defaults for slices of state not handled by nested reducers
  aFlag: (state = initialState.aFlag) => state,
  anotherFlag: (state = initialState.anotherFlag) => state,
  // nested reducers for particular slices of state
  nestedItems: nestedReducer
});

and then

const finalReducer = reduceReducers(nestedReducers, myModuleReducer);

This ways it seems to make the nestedReducer handle nestedItems slice and myModuleReducer handles top-level parts of state (i.e. aFlag and anotherFlag fields).

But I don't like that I need to pass those default functions for everything which is not handled by the nested reducer. Can it be avoided? (Ofcourse I can abstract this away to some kind of nestReducers helper, but still). In general, what are problems with my approach?

Body:
You could always just do that manually in your myModuleReducer function, like this:

function myModuleReducer(state = someInitialState, action) {

    // Call nestedReducer here
    const reducedNestedItem = nestedReducer(state, action)

    switch (action.type) {
    case 'MY_ACTION_TYPE':
        return Object.assign({}, state, {
            aFlag: // aFlag logic
            anotherFlag: // anotherFlag logic
            nestedItem: reducedNestedItem
        })
    default:
        return state
    }
}

You just need to make sure if you do it like that that you follow Redux's purity philosophy.


问:
Python: smart way to lowercase transformation of key values from an array of JSON
I am trying to do lowercase data transformation. My input data are in the following format

```<code>ret = { "users":[
             {"EMAIL":"jogn@doe.com","Name":"John Doe"},
             {"EMail":"james@black.com","nAme":"James Black"}
             ]
}
</code>```

and the output should be something like

```<code>ret = { "users":[
                 {"email":"jogn@doe.com","name":"John Doe"},
                 {"email":"james@black.com","name":"James Black"}
                 ]
    }
</code>```

What I did is :

```<code>users = ret['users']
new_array = []
for item in users:
    for key in item:
        k = key.lower()
        new_array.append({k:item[key]})
</code>```

and the result is what I expected but I was wondering if there is a smart and better way to achieve this task. Is there a way to avoid the double loop?

Thanks.

答:
Even though your original solution is already very readable, you could also try using list comprehensions:

```<code>ret = { "users":[
                 {"EMAIL":"jogn@doe.com","Name":"John Doe"},
                 {"EMail":"james@black.com","nAme":"James Black"}
                ]
      }

ret['users'] = [dict((k.lower(), v) for k, v in d.items()) for d in ret['users']]

>>> print(ret)
{'users': [{'email': 'jogn@doe.com', 'name': 'John Doe'}, {'email': 'james@black.com', 'name': 'James Black'}]}
</code>```

Additionally, It's probably safer to just rebuild a new dictionary with all values updated, than to overwrite the original data. This can be demonstrated below:

```<code>result = {}

# Can be a another one-liner, but then it becomes unreadable
for key, value in ret.items():
    result[key] = [dict((k.lower(), v) for k, v in d.items()) for d in value]

>>> print(result)
{'users': [{'name': 'John Doe', 'email': 'jogn@doe.com'}, {'name': 'James Black', 'email': 'james@black.com'}]}
</code>```

If you really want the one liner to the second part:

```<code>result = dict((key, [dict((k.lower(), v) for k, v in d.items()) for d in value]) for key, value in ret.items())
</code>```

Body:
I am trying to do lowercase data transformation. My input data are in the following format

ret = { "users":[
             {"EMAIL":"jogn@doe.com","Name":"John Doe"},
             {"EMail":"james@black.com","nAme":"James Black"}
             ]
}

and the output should be something like

ret = { "users":[
                 {"email":"jogn@doe.com","name":"John Doe"},
                 {"email":"james@black.com","name":"James Black"}
                 ]
    }

What I did is :

users = ret['users']
new_array = []
for item in users:
    for key in item:
        k = key.lower()
        new_array.append({k:item[key]})

and the result is what I expected but I was wondering if there is a smart and better way to achieve this task. Is there a way to avoid the double loop?

Thanks.

Body:
Even though your original solution is already very readable, you could also try using list comprehensions:

ret = { "users":[
                 {"EMAIL":"jogn@doe.com","Name":"John Doe"},
                 {"EMail":"james@black.com","nAme":"James Black"}
                ]
      }

ret['users'] = [dict((k.lower(), v) for k, v in d.items()) for d in ret['users']]

>>> print(ret)
{'users': [{'email': 'jogn@doe.com', 'name': 'John Doe'}, {'email': 'james@black.com', 'name': 'James Black'}]}

Additionally, It's probably safer to just rebuild a new dictionary with all values updated, than to overwrite the original data. This can be demonstrated below:

result = {}

# Can be a another one-liner, but then it becomes unreadable
for key, value in ret.items():
    result[key] = [dict((k.lower(), v) for k, v in d.items()) for d in value]

>>> print(result)
{'users': [{'name': 'John Doe', 'email': 'jogn@doe.com'}, {'name': 'James Black', 'email': 'james@black.com'}]}

If you really want the one liner to the second part:

result = dict((key, [dict((k.lower(), v) for k, v in d.items()) for d in value]) for key, value in ret.items())


问:
Import column with multiple values in data.frame r
I would like to create a data.frame in R with some columns with more than one value. The dataframe is originated by importing a csv containing several columns with multiple values. Here is an example of the dataframe:

```<code>name fruit

john    banana, orange, apple
isaac    apple
</code>```

I want to know if there is any way to separate the data in csv so when they are imported they will not be treated as a single string. And also after being differentiated and applied a factor (), if they would stay in that format:

```<code>> levels(fruit)
 [1] "banana"
 [2] "orange"
 [3] "apple"
</code>```

答:
What you want to do is store a list in a data.frame cell. To build your list use strsplit

```<code>df$fruits = sapply(df$fruit, function(s)strsplit(s, ", "))
</code>```

Regarding your levels, I think you are asking a bit too much

Body:
I would like to create a data.frame in R with some columns with more than one value. The dataframe is originated by importing a csv containing several columns with multiple values. Here is an example of the dataframe:

name fruit

john    banana, orange, apple
isaac    apple

I want to know if there is any way to separate the data in csv so when they are imported they will not be treated as a single string. And also after being differentiated and applied a factor (), if they would stay in that format:

> levels(fruit)
 [1] "banana"
 [2] "orange"
 [3] "apple"

Body:
What you want to do is store a list in a data.frame cell. To build your list use strsplit

df$fruits = sapply(df$fruit, function(s)strsplit(s, ", "))

Regarding your levels, I think you are asking a bit too much


问:
Uploading a file to Facebook using Koala on Ruby on Rails
I followed the following blogpost to figure out how to create Facebook events remotely using my app.  I've been having problems loading the images from my app, however, because I do not have images stored locally on my app, they are stored in AWS.

```<code>    @graph = Koala::Facebook::GraphAPI.new(@token)
    picture = Koala::UploadableIO.new(@event.photo.url(:small))
    params = {
        :picture => picture,
        :name => 'Event name',
        :description => 'Event descriptio
        :start_time => datetime,
       }
</code>```

is the following code I am currently using to send pictures to Facebook when Facebook events are created on my app.  The problem is, however, that Rails is throwing the error: No such file or directory - http://s3.amazonaws.com/ColumbiaEventsApp/photos/21/small.jpeg?1312521889.

Does anybody who's more experienced with Rails development know if there is a way for me to treat a URL like a path to a file?  The UploadableIO class expects a path to a file, and I'm struggling to figure out if there's a way in Ruby to treat URL's like filepaths.  The way that photos stored on the app can be loaded to Facebook is as follows:

picture = Koala::UploadableIO.new(File.open("PATH TO YOUR EVENT IMAGE"))

if that helps.

I appreciate any new insights into this issue.

答:
For Facebook Ad Images, you unfortunately currently cannot do it by URL, thus:</p>

```<code>require 'open-uri'
img_data = open(my_post.image.url :medium).read
img = graph.put_connections('act_X', 'adimages', bytes: Base64.encode64(img_data))
</code>```

Body:
I followed the following blogpost to figure out how to create Facebook events remotely using my app.  I've been having problems loading the images from my app, however, because I do not have images stored locally on my app, they are stored in AWS.

    @graph = Koala::Facebook::GraphAPI.new(@token)
    picture = Koala::UploadableIO.new(@event.photo.url(:small))
    params = {
        :picture => picture,
        :name => 'Event name',
        :description => 'Event descriptio
        :start_time => datetime,
       }

is the following code I am currently using to send pictures to Facebook when Facebook events are created on my app.  The problem is, however, that Rails is throwing the error: No such file or directory - http://s3.amazonaws.com/ColumbiaEventsApp/photos/21/small.jpeg?1312521889.

Does anybody who's more experienced with Rails development know if there is a way for me to treat a URL like a path to a file?  The UploadableIO class expects a path to a file, and I'm struggling to figure out if there's a way in Ruby to treat URL's like filepaths.  The way that photos stored on the app can be loaded to Facebook is as follows:

picture = Koala::UploadableIO.new(File.open("PATH TO YOUR EVENT IMAGE"))

if that helps.

I appreciate any new insights into this issue.

Body:
For Facebook Ad Images, you unfortunately currently cannot do it by URL, thus:

require 'open-uri'
img_data = open(my_post.image.url :medium).read
img = graph.put_connections('act_X', 'adimages', bytes: Base64.encode64(img_data))


问:
Excel Function checking street name in full addresses
I have two sheets in excel, on containing full addresses and one containing street names. I need to create a lookup function that checks each full address to see if it contains one of the street names in the other sheet.

Normally i would use this =VLOOKUP or =Countif function to return a value if the cell exist in the lookup matrix, but they both check the whole content of the cell. while i only need to see if it contains a specific part.

Example cells would be.

Full Adresse Sheet1 A1:

Alpha street 34, fictional city Zip230

Lookup Sheet2 columns A:

Alpha Street

Beta Street

...

trying to create a function that check if any string in Column A Sheet2 exisit inside the string in Sheet1 A1. Even better if the function is not case sensitive.

答:
You can use wildcards in countif formulas as well:

=COUNTIF(rng,"*txt*")

This will count all cells that contain the string txt anywhere in the desired range.


问:
Is there a way to execute JavaScript in Perl?
I've worked some years now in Perl building Web scrapers, and given the problem that spam represents, and how scraping Web pages would turn out to be much more easier to those folks if, for example, Perl's LWP::UserAgent could handle its cup of JavaScript, I'm amazed no one has built a JS engine for it yet.

What am I missing here?

Thanks in advance. Regards.

PS: I'm not a spammer. Just curious.

ContentLicense: CC BY-SA 2.5

Body: WWW::Selenium?


问:
Performance issue in Websphere8.5
We migrated web application from jsf1.0 to 1.2 and deployed in Websphere 8.5. EArlier application was deployed in Websphere6.0. We are facing performance issue during SOAK testing. Got some thread hung message in sysout logs also i observe lot of blocking thread in thread dump file and its released on time.
Application performance degrades on time. i can see the performance issue remains same even the application is idle for 1 day .

Main issue is with the High CPU usage and high JVM memory even the application is idle for 1 day.  Application is fast after the restart of server. Does the GC will not clear the JVM memory for 1 day or why this CPU is high ?

答:
High cpu with low/declining app throughput is typical of java heap exhaust, when the JVM spends most of its time running GC trying to clear space in the heap to do real work. You should enable verbose GC logging, the GC log will show the heap state and GC activity. If the heap is below 10% tenure/OldGen free (assuming using default gencon collector) after a global/full GC, you are in heap exhaust state.

You could try increasing the heap size, maybe it just needs more space than currently provided. If the heap use (used tenure after global) continues to climb over time, when the workload offered is steady/constant, then the app probably has a memory leak. The objects accumulating in the heap can be seen by taking a core/system dump when the server is near heap exhaust state, and examining the dump with e.g. Eclipse Memory Analyzer.

Title: Performance issue in Websphere8.5


问:
User defined concatenate
I am trying to expand my annual planning document to give me more information. Currently however I am stuck.

My current Sheet is laid out as follows:

I need to create a second sheet that concatenates the client name with each column heading there is a "yes" value in, as its own separate line.

Example 1 in the new sheet would become:

```<code>Example 1 - Annuals
Example 1 - Xero Fee
</code>```

I had tried a copy and paste Macro, based on a quantity column counting the rows that include text. This gave the desired amount of client names in a new sheet but I was unable to work out how to include the "concatenate" part of this problem to it.

```<code>Public Sub CopyData()

    ' This routing will copy rows based on the quantity to a new sheet.
    Dim rngSinglecell As Range
    Dim rngQuantityCells As Range
    Dim intCount As Integer

    ' Set this for the range where the Quantity column exists. This works only if there are no empty cells
    Set rngQuantityCells = Range("G1", Range("G1").End(xlDown))

    For Each rngSinglecell In rngQuantityCells
        ' Check if this cell actually contains a number
        If IsNumeric(rngSinglecell.Value) Then
            ' Check if the number is greater than 0
            If rngSinglecell.Value > 0 Then
                ' Copy this row as many times as .value
                For intCount = 1 To rngSinglecell.Value
                    ' Copy the row into the next emtpy row in sheet2
                    Range(rngSinglecell.Address).EntireRow.Copy Destination:=Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1)
                    ' The above line finds the next empty row.

                Next
            End If
        End If
    Next
End Sub
</code>```

答:
If your goal is to get from this:

...to this (or that):

...then what you want to do is called an Unpivot.

How to Unpivot "crosstab-style" data:

You can find the steps written out on a question I answered a week ago, and there's a more detailed explanation and steps over here.

Let me know if you have any questions!

Yeah, maybe I used this as an excuse to practice using Screen2Gif, but it sure helps demo a point!  :-)

Title: User defined concatenate

Body:
I am trying to expand my annual planning document to give me more information. Currently however I am stuck.

My current Sheet is laid out as follows:

I need to create a second sheet that concatenates the client name with each column heading there is a "yes" value in, as its own separate line.

Example 1 in the new sheet would become:

Example 1 - Annuals
Example 1 - Xero Fee

I had tried a copy and paste Macro, based on a quantity column counting the rows that include text. This gave the desired amount of client names in a new sheet but I was unable to work out how to include the "concatenate" part of this problem to it.

Public Sub CopyData()

    ' This routing will copy rows based on the quantity to a new sheet.
    Dim rngSinglecell As Range
    Dim rngQuantityCells As Range
    Dim intCount As Integer

    ' Set this for the range where the Quantity column exists. This works only if there are no empty cells
    Set rngQuantityCells = Range("G1", Range("G1").End(xlDown))

    For Each rngSinglecell In rngQuantityCells
        ' Check if this cell actually contains a number
        If IsNumeric(rngSinglecell.Value) Then
            ' Check if the number is greater than 0
            If rngSinglecell.Value > 0 Then
                ' Copy this row as many times as .value
                For intCount = 1 To rngSinglecell.Value
                    ' Copy the row into the next emtpy row in sheet2
                    Range(rngSinglecell.Address).EntireRow.Copy Destination:=Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1)
                    ' The above line finds the next empty row.

                Next
            End If
        End If
    Next
End Sub

ContentLicense: CC BY-SA 4.0


问:
Converting a JsonDocument to its mapped entity
I use CouchbaseRepository in my project but sometimes I use lower level couchbase sdk methods to retrieve JsonDocument. Is there a way I can use spring-data-couchbase to convert a JsonDocument to lets say a User?

This is all done internally in CouchbaseTemplate in the method private <T> T mapToEntity(String id, Document<String> data, Class<T> entityClass)

But as you can see it's private so I can't call it myself.

答:
You can create a wrapper which uses Jackson to convert the JsonDocument to any object you want.

mapper.readValue(doc.content().toString(), SomeClass.class);

The first argument is the JsonDocument, the content method is what contains the actual Json.


问:
Why cherrypy server logs error messages even though it seems to work?
I'm using cherrypy to start a server, that its computation engine is Apache Spark. It logs this weird result:

```<code>[06/Dec/2017:13:25:42] ENGINE Bus STARTING
INFO:cherrypy.error:[06/Dec/2017:13:25:42] ENGINE Bus STARTING
[06/Dec/2017:13:25:42] ENGINE Started monitor thread 'Autoreloader'.
INFO:cherrypy.error:[06/Dec/2017:13:25:42] ENGINE Started monitor thread 'Autoreloader'.
[06/Dec/2017:13:25:42] ENGINE Serving on http://0.0.0.0:5432
INFO:cherrypy.error:[06/Dec/2017:13:25:42] ENGINE Serving on http://0.0.0.0:5432
[06/Dec/2017:13:25:42] ENGINE Bus STARTED
INFO:cherrypy.error:[06/Dec/2017:13:25:42] ENGINE Bus STARTED
</code>```

My question is, what is this INFO:cherrypy.error: it logs?

This is how I run the server:

```<code>def run_server(app):
    # Enable WSGI access logging via Paste
    app_logged = TransLogger(app)

    # Mount the WSGI callable object (app) on the root directory
    cherrypy.tree.graft(app_logged, '/')

    # Set the configuration of the web server
    cherrypy.config.update({
        'engine.autoreload.on': True,
        'log.screen': True,
        'server.socket_port': 5432,
        'server.socket_host': '0.0.0.0'
    })

    # Start the CherryPy WSGI web server
    cherrypy.engine.start()
    cherrypy.engine.block()
</code>```

答: There's absolutely nothing wrong with what you're seeing in the log file. I see the same bus and serving statements when I run Cherrypy. I guess Cherrypy haven't really used the term 'error' too effectively there, like some people call the HTTP status codes 'error codes', when in fact code 200 means everything is all good. </p>

Body:
I'm using cherrypy to start a server, that its computation engine is Apache Spark. It logs this weird result:

[06/Dec/2017:13:25:42] ENGINE Bus STARTING
INFO:cherrypy.error:[06/Dec/2017:13:25:42] ENGINE Bus STARTING
[06/Dec/2017:13:25:42] ENGINE Started monitor thread 'Autoreloader'.
INFO:cherrypy.error:[06/Dec/2017:13:25:42] ENGINE Started monitor thread 'Autoreloader'.
[06/Dec/2017:13:25:42] ENGINE Serving on http://0.0.0.0:5432
INFO:cherrypy.error:[06/Dec/2017:13:25:42] ENGINE Serving on http://0.0.0.0:5432
[06/Dec/2017:13:25:42] ENGINE Bus STARTED
INFO:cherrypy.error:[06/Dec/2017:13:25:42] ENGINE Bus STARTED

My question is, what is this INFO:cherrypy.error: it logs?

This is how I run the server:

def run_server(app):
    # Enable WSGI access logging via Paste
    app_logged = TransLogger(app)

    # Mount the WSGI callable object (app) on the root directory
    cherrypy.tree.graft(app_logged, '/')

    # Set the configuration of the web server
    cherrypy.config.update({
        'engine.autoreload.on': True,
        'log.screen': True,
        'server.socket_port': 5432,
        'server.socket_host': '0.0.0.0'
    })

    # Start the CherryPy WSGI web server
    cherrypy.engine.start()
    cherrypy.engine.block()


问:
Google Sheets OnEdit() - You do not have permission to call a service
```<code>function onEdit(e){
    var html = HtmlService.createTemplateFromFile( 'MyHtmlFile' )
          .evaluate()
          .setWidth( 800 )
          .setHeight( 400 );
    SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
          .showModalDialog( html, 'My page title' );
}
</code>```

When I edit a Spreadsheet's cell NO pop up is shown but I got this error in the console:

Google Apps Script: You do not have permission to call showModalDialog

答:
The onEdit() will have to be an Installable Trigger because it is using a service that requires authorization.

note: rename onEdit() when using it as an installable trigger to avoid possible issues

Like simple triggers, installable triggers let Apps Script run a function automatically when a certain event, such as opening a document, occurs. Installable triggers, however, offer more flexibility than simple triggers: they can call services that require authorization, ...

Managing triggers manually:

To manually create an installable trigger through a dialog in the script editor, follow these steps:

From the script editor, choose Edit > Current project's triggers.

Click the link that says: No triggers set up. Click here to add one now.

Under Run, select the name of function you want to trigger.

Under Events, select either Time-driven or the Google App that the script is bound to (for example, From spreadsheet).

Select and configure the type of trigger you want to create (for example, an Hour timer that runs Every hour or an On open trigger).

Optionally, click Notifications to configure how and when you will be contacted by email if your triggered function fails.

Click Save.

Body:
function onEdit(e){
    var html = HtmlService.createTemplateFromFile( 'MyHtmlFile' )
          .evaluate()
          .setWidth( 800 )
          .setHeight( 400 );
    SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
          .showModalDialog( html, 'My page title' );
}

When I edit a Spreadsheet's cell NO pop up is shown but I got this error in the console:

Google Apps Script: You do not have permission to call showModalDialog


问:
How to generate a bill in pdf format using python 2.7
My need is to generate a bill in pdf format using python. That bill will change its data like no of passengers or travel details, date, time etc. But i need to generate a template like format for that. Which one i need to use? give me some example? I'm new to python, So please help me.

I tried to use reportlab module to generate pdf, But may i need to give exact x and y points of characters in this reportlab? Is there any other option? If my passenger details increase into more than one how can i automate or generate dynamic pdf?

I tried this one as sample two line:

```<code>import os
import sys
import unittest

from reportlab.pdfgen import canvas

canvas = canvas.Canvas("form.pdf")
canvas.setLineWidth(.3)

def titleOfTicket():
    canvas.setFont('Helvetica', 12)
    canvas.drawString(30,750,'Bus Ticket')
    canvas.drawString(550,750,"Mr.X")

def header():
    canvas.line(30,740,580,740)
    canvas.drawString(30,723,"Bangalore to Chennai")
    canvas.drawString(250,723,"thu, 19 june 2017")
    canvas.drawString(450,723,"Trip ID 12345678901245")
    canvas.line(30,715,580,715)

titleOfTicket()
header()

canvas.save()
</code>```

Is there any other module or option to generate the template for a ticket easily? my sample format ticket is need to be like this

答:
Just starting to use reportlab, so I don't know much yet. But I think the platypus submodule would make this much easier. It's described in the ReportLab User Guide. And I just found a blog post that might help, even if it's quite old:
simple step by step reportlab tutorial.

And what about the commercial version? That might be still easier to use, as far as I can tell from the website.

Body:
My need is to generate a bill in pdf format using python. That bill will change its data like no of passengers or travel details, date, time etc. But i need to generate a template like format for that. Which one i need to use? give me some example? I'm new to python, So please help me.

I tried to use reportlab module to generate pdf, But may i need to give exact x and y points of characters in this reportlab? Is there any other option? If my passenger details increase into more than one how can i automate or generate dynamic pdf?

I tried this one as sample two line:

import os
import sys
import unittest

from reportlab.pdfgen import canvas

canvas = canvas.Canvas("form.pdf")
canvas.setLineWidth(.3)

def titleOfTicket():
    canvas.setFont('Helvetica', 12)
    canvas.drawString(30,750,'Bus Ticket')
    canvas.drawString(550,750,"Mr.X")

def header():
    canvas.line(30,740,580,740)
    canvas.drawString(30,723,"Bangalore to Chennai")
    canvas.drawString(250,723,"thu, 19 june 2017")
    canvas.drawString(450,723,"Trip ID 12345678901245")
    canvas.line(30,715,580,715)

titleOfTicket()
header()

canvas.save()

Is there any other module or option to generate the template for a ticket easily? my sample format ticket is need to be like this


问:
SpringBoot + Jackson + Kotlin data class : Field annotations ignored
I'm using Spring Boot with Kotlin and Java8 time. Somehow the Jackson annotations on the data class fields are ignored.

```<code>import com.fasterxml.jackson.annotation.JsonProperty
import java.time.MonthDay

data class DataView(val id: String,
                    @get:JsonProperty("dayOfMonth") val monthDay: MonthDay) {}
</code>```

Why would these annotations be ignored? The response still contains the field name "monthDay".

I know the annotation is correct, according to this discussion on discuss.kotlinlang.org.

I don't have any configurations that should affect this, as far as I know.

pom contains:

```<code>...
<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>1.5.6.RELEASE</version>
    <relativePath/>
</parent>
...
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-kotlin</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-hibernate5</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-hppc</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-json-org</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-afterburner</artifactId>
    </dependency>
...
</code>```

答:
Very strange. I check this code local, and all looks fine

```<code>data class DataView(val id: String,
                     @get:JsonProperty("dayOfMonth") val monthDay: MonthDay)

data class MonthDay(val day: Int)

fun main(args: Array<String>) {
    val objectMapper = ObjectMapper()
            .registerKotlinModule()

    val dataView = DataView("someId", MonthDay(1))

    //{"id":"someId","dayOfMonth":{"day":1}}
    println(objectMapper.writeValueAsString(dataView))
}
</code>```

It works same even if I remove registerKotlinModule and change from @get to @field.

Body:
I'm using Spring Boot with Kotlin and Java8 time. Somehow the Jackson annotations on the data class fields are ignored.

import com.fasterxml.jackson.annotation.JsonProperty
import java.time.MonthDay

data class DataView(val id: String,
                    @get:JsonProperty("dayOfMonth") val monthDay: MonthDay) {}

Why would these annotations be ignored? The response still contains the field name "monthDay".

I know the annotation is correct, according to this discussion on discuss.kotlinlang.org.

I don't have any configurations that should affect this, as far as I know.

pom contains:

...
<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>1.5.6.RELEASE</version>
    <relativePath/>
</parent>
...
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-kotlin</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-hibernate5</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-hppc</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-json-org</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-afterburner</artifactId>
    </dependency>
...

Body:
Very strange. I check this code local, and all looks fine

data class DataView(val id: String,
                     @get:JsonProperty("dayOfMonth") val monthDay: MonthDay)

data class MonthDay(val day: Int)

fun main(args: Array<String>) {
    val objectMapper = ObjectMapper()
            .registerKotlinModule()

    val dataView = DataView("someId", MonthDay(1))

    //{"id":"someId","dayOfMonth":{"day":1}}
    println(objectMapper.writeValueAsString(dataView))
}

It works same even if I remove registerKotlinModule and change from @get to @field.


问:
How to cast two flow types with a maybe attribute
I want to cast the RedisGetHashJob to RedisKey type but I've an error...

My types:

```<code>export type RedisKey = {
  source: string,
  destination: string,
  type: string,
  id: string,
  groupId: string,
  pid?: string,
};

export type RedisGetHashJob = {
  source: string,
  destination: string,
  type: string,
  id: string,
  groupId: string,
  pid: string,
};
</code>```

I've two functions:

1 - function createKey(obj: RedisKey): string

2 - function getHashJob(obj: RedisGetHashJob): Promise

In my second function, the pid attribute has to be set. But when I try to call it like:

```<code>function getHashJob(obj: RedisGetHashJob): Promise<string> {
  const key = createKey(obj);
  ....
}
</code>```

I have the bellow error:

```<code>Error: src/common/lib/redis.js:60
 60:   const key = createKey(obj);
                             ^^^ object type. This type is incompatible with the expected param type of
 15: export function createKey(obj: RedisKey): string {
                                    ^^^^^^^^ object type
  Property `pid` is incompatible:
      8:   pid?: string,
                 ^^^^^^ undefined. This type is incompatible with. See: src/types/redis.js:8
     26:   pid: string,
                ^^^^^^ string. See: src/types/redis.js:26
</code>```

Do you know a pretty way to make this job ?

Regards,

答:
It happens because you can delete pid property in RedisKey object and it will be still RedisKey object but not RedisGetHashJob anymore.
What if your createKey looks like

```<code>function createKey(obj: RedisKey): string {
  delete obj.pid
  return 'a';
}
</code>```

To solve this you can copy obj before pass it to createKey:

```<code>function getHashJob(obj: RedisGetHashJob): Promise<string> {
  const objCopy = {...obj}
  const key = createKey(objCopy);
  ...
}
</code>```

Try it out

Body:
I want to cast the RedisGetHashJob to RedisKey type but I've an error...

My types:

export type RedisKey = {
  source: string,
  destination: string,
  type: string,
  id: string,
  groupId: string,
  pid?: string,
};

export type RedisGetHashJob = {
  source: string,
  destination: string,
  type: string,
  id: string,
  groupId: string,
  pid: string,
};

I've two functions:

1 - function createKey(obj: RedisKey): string

2 - function getHashJob(obj: RedisGetHashJob): Promise

In my second function, the pid attribute has to be set. But when I try to call it like:

function getHashJob(obj: RedisGetHashJob): Promise<string> {
  const key = createKey(obj);
  ....
}

I have the bellow error:

Error: src/common/lib/redis.js:60
 60:   const key = createKey(obj);
                             ^^^ object type. This type is incompatible with the expected param type of
 15: export function createKey(obj: RedisKey): string {
                                    ^^^^^^^^ object type
  Property `pid` is incompatible:
      8:   pid?: string,
                 ^^^^^^ undefined. This type is incompatible with. See: src/types/redis.js:8
     26:   pid: string,
                ^^^^^^ string. See: src/types/redis.js:26

Do you know a pretty way to make this job ?

Regards,

Body:
It happens because you can delete pid property in RedisKey object and it will be still RedisKey object but not RedisGetHashJob anymore.
What if your createKey looks like

function createKey(obj: RedisKey): string {
  delete obj.pid
  return 'a';
}

To solve this you can copy obj before pass it to createKey:

function getHashJob(obj: RedisGetHashJob): Promise<string> {
  const objCopy = {...obj}
  const key = createKey(objCopy);
  ...
}

Try it out


问:
How to use nelmio/api-doc-bundle standalone (without symfony app)?
My web application is not based on Symfony or any other open-source framework.

How can I still use the package nelmio/api-doc-bundle to generate my API documentation from class annotations?

答:
nelmio-api-doc bundle  is made symfony platform only so you can not use it without symfony.

if you want to use only API documentation then https://swagger.io/swagger-ui/ may help you. swagger provides ymal and json (annotations is also part of symfony) based documentation and its implement most of popular work platform.

actually nelmio-api-doc bundle is using swagger-ui as API documentation provider (in config setting https://github.com/nelmio/NelmioApiDocBundle)


问:
Merging cells in JTable
Is it possible to merge some cells of a JTable object?

(source: codeguru.com)

If it's not possible through JTable what is the best approach. Thanks.

答: Not out-of-the-box. Here is an example that supports merging arbitrarty cells. This page has several examples of tables with spanning cells. Of course it's old and you get what you pay for. If paid software is an option, JIDE Grids has some really nice Swing table support including custom cell spans.</p>

OwnerDisplayName: kvphxga

Title: Merging cells in JTable

LastEditorDisplayName: kvphxga

OwnerDisplayName: Dave Ray


问:
Adding Error Handlers In VB
```<code>  ' Button which allows the user to enter in there own password
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

        Try
            If TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text > 0 And TextBox4.Text <> "" Then
                'input in these textboxes must be numerical
                ' It adds the passwords which is made by the user himself
                ListBox1.Items.Add("Application : " & TextBox4.Text & " Password : " & TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text & " Time : " & TimeString & " Date : " & DateTime.Today)

            End If
        Catch ex As Exception
            MessageBox.Show("Please provide correct input")

        End Try
</code>```

I'm currently making a password generator on visual basic , i have displayed the code in the part where the user can make there own password , however i wish to have some error handlers , currently i have got it working so a error message is displayed if non numeric information is entered into textbox3,6,7,8 . this works , however i wish to add two things
1. An error message if textboxes3,6,7,8 are empty
2. An error message if textbox4 is empty , curently nothing is printed in the listbox but no error message is displayed.

P.S
A beginner to vb

答:
You don't really need exception handling for validation. You can use the built in methods to do this.

For example the following checks if a texbox called ExampleTextBox has input and the input is a valid integer.

```<code> If String.IsNullOrEmpty(ExampleTextBox.Text) Then
   'no input
 Else
   'has input, check if number
    Dim enteredNumber As Integer

    If Integer.TryParse(ExampleTextBox.Text, enteredNumber) Then
       'input is a valid integer
    Else
       'input is not a valid integer
    End If

End If
</code>```

Title: Adding Error Handlers In VB

Body:
  ' Button which allows the user to enter in there own password
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

        Try
            If TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text > 0 And TextBox4.Text <> "" Then
                'input in these textboxes must be numerical
                ' It adds the passwords which is made by the user himself
                ListBox1.Items.Add("Application : " & TextBox4.Text & " Password : " & TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text & " Time : " & TimeString & " Date : " & DateTime.Today)

            End If
        Catch ex As Exception
            MessageBox.Show("Please provide correct input")

        End Try

I'm currently making a password generator on visual basic , i have displayed the code in the part where the user can make there own password , however i wish to have some error handlers , currently i have got it working so a error message is displayed if non numeric information is entered into textbox3,6,7,8 . this works , however i wish to add two things
1. An error message if textboxes3,6,7,8 are empty
2. An error message if textbox4 is empty , curently nothing is printed in the listbox but no error message is displayed.

P.S
A beginner to vb

Body:
You don't really need exception handling for validation. You can use the built in methods to do this.

For example the following checks if a texbox called ExampleTextBox has input and the input is a valid integer.

 If String.IsNullOrEmpty(ExampleTextBox.Text) Then
   'no input
 Else
   'has input, check if number
    Dim enteredNumber As Integer

    If Integer.TryParse(ExampleTextBox.Text, enteredNumber) Then
       'input is a valid integer
    Else
       'input is not a valid integer
    End If

End If


问:
Token was deauthenticated after trying to refresh it
I updated my Symfony environment form 3.3 to 4.0. After the update I have problems with the login (user provided by database). When I submit the login form, I just got right back to the login form without any error message. When I use invalid credentials, I got the corresponding error message. Here is the log after trying to login. The login with the "in_memory" user provider is working. Do you need more information?

```<code>[2017-12-06 13:57:05] security.INFO: User has been authenticated successfully. {"username":"***"} []
[2017-12-06 14:22:39] doctrine.DEBUG: "START TRANSACTION" [] []
[2017-12-06 13:57:05] security.DEBUG: Read existing security token from the session. {"key":"_security_secured_area","token_class":"Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken"} []
[2017-12-06 13:57:05] doctrine.DEBUG: SELECT t0.username AS username_1, t0.password AS password_2, t0.email AS email_3, t0.email_new AS email_new_4, t0.first_name AS first_name_5, t0.last_name AS last_name_6, t0.is_active AS is_active_7, t0.email_confirmed AS email_confirmed_8, t0.shibboleth_state AS shibboleth_state_9, t0.shibboleth_hash AS shibboleth_hash_10, t0.shibboleth_persistent_id AS shibboleth_persistent_id_11, t0.confirmation_email_send AS confirmation_email_send_12, t0.last_login AS last_login_13, t0.expires AS expires_14, t0.session_id AS session_id_15, t0.id AS id_16, t0.hidden AS hidden_17, t0.deleted AS deleted_18, t0.created AS created_19, t0.modified AS modified_20, t0.sorting AS sorting_21, t0.salutation_id AS salutation_id_22, t0.creator_id AS creator_id_23, t0.modifier_id AS modifier_id_24 FROM User t0 WHERE t0.id = ? AND ((t0.deleted = 0)) [2] []
[2017-12-06 13:57:05] security.DEBUG: Token was deauthenticated after trying to refresh it. {"username":"user","provider":"Symfony\\Component\\Security\\Core\\User\\ChainUserProvider"} []
[2017-12-06 13:57:05] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2017-12-06 13:57:05] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:68)"} []
[2017-12-06 13:57:05] security.DEBUG: Calling Authentication entry point. [] []
</code>```

Entity\User:

```<code>class User extends EntitySuperclass implements AdvancedUserInterface, \Serializable
{
    /**
     * @ORM\Column(type="string")
     */
    private $username;

    /**
     *
     * @Assert\Length(max=4096,groups={"account_complete","account_password","user"})
     * @Assert\Length(min = 8,groups={"account_complete","account_password","user"}, minMessage="user.password_length")
     */
    private $plainPassword;

    /**
     * The below length depends on the "algorithm" you use for encoding
     * the password, but this works well with bcrypt.
     *
     * @ORM\Column(type="string", length=64)
     */
    private $password;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank(groups={"account_register","user"})
     * @Assert\Email(
     *      groups = {"account_register", "account","user"},
     *      strict = true,
     *      checkMX = true
     * )
     */
    private $email;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $emailNew = '';

    /**
     * @ORM\ManyToOne(targetEntity="Salutation")
     *
     */
    private $salutation;

    /**
     * @ORM\Column(type="string")
     * @Assert\NotBlank(groups={"account_complete","user"})
     * @Assert\Regex(pattern = "/^[a-zA-ZäöüÄÖÜß0-9 ]+$/",groups={"account_complete","user"}, message="user.first_name.regex")
     */
    private $firstName;

    /**
     * @ORM\Column(type="string")
     * @Assert\NotBlank(groups={"account_complete","user"})
     * @Assert\Regex(pattern = "/^[a-zA-ZäöüÄÖÜß0-9 ]+$/",groups={"account_complete","user"}, message="user.last_name.regex")
     */
    private $lastName;

    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive = false;

    /**
     * @ORM\Column(name="email_confirmed", type="boolean")
     */
    private $emailConfirmed = false;

    /**
     * @ORM\Column(type="integer")
     */
    private $shibbolethState = 0;

    /**
     * @ORM\Column(type="string")
     */
    private $shibbolethHash = '';

    /**
     * @ORM\Column(type="string")
     */
    private $shibbolethPersistentId = '';

    /**
     * @ORM\ManyToMany(targetEntity="UserGroup")
     * @ORM\JoinTable(name="User_UserGroup",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     *      )
     */
    private $userGroups;

    /**
     * @ORM\Column(type="integer")
     */
    private $confirmationEmailSend;

    /**
     * @ORM\Column(type="integer")
     */
    private $lastLogin = 0;

    /**
     * @ORM\Column(type="integer")
     */
    protected $expires = 0;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $sessionId = '';

    /**
     * @ORM\ManyToMany(targetEntity="BankDetails", cascade={"persist"})
     * @ORM\JoinTable(name="User_BankDetails",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="bank_details_id", referencedColumnName="id")}
     * )
     * @Assert\Valid
     */
    private $bankDetails;

    /**
     * @ORM\ManyToMany(targetEntity="Address", cascade={"persist"})
     * @ORM\JoinTable(name="User_BillingAddress",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="billing_address_id", referencedColumnName="id")}
     * )
     * @Assert\Count(
     *      min = 1,
     *      minMessage = "user.billing_addresses.min",
     * )
     * @Assert\Valid
     */
    private $billingAddresses;

    public function __construct()
    {
        parent::__construct();
        $this->isActive = true;
        $this->confirmationEmailSend = 0;
        $this->userGroups = new ArrayCollection();
        $this->bankDetails = new ArrayCollection();
        $this->billingAddresses = new ArrayCollection();
        // may not be needed, see section on salt below
        // $this->salt = md5(uniqid(null, true));
    }

    /**
     * @ORM\PrePersist
     */
    public function prePersist()
    {
        $currentTimestamp = time();

        if($this->getConfirmationEmailSend() == NULL)
            $this->setConfirmationEmailSend(0);

   }

    public function getUsername()
    {
        //return $this->username;
        return $this->email;
    }

    public function getSalt()
    {
        // The bcrypt algorithm doesn't require a separate salt.
        return null;
    }

    public function getPassword()
    {
        return $this->password;
    }

    public function getRoles()
    {
        $roles = array();
        $userGroups = $this->getUserGroups();
        if(!empty($userGroups)) {
            foreach($userGroups as $userGroup) {
                $role = $userGroup->getRole();
                $roles[] = 'ROLE_'.strtoupper($role);
            }
        }
        return $roles;
    }

    public function isGranted($role)
    {
        return in_array($role, $this->getRoles());
    }

    public function eraseCredentials()
    {
    }

    public function isAccountNonExpired()
    {
        return true;
    }

    public function isAccountNonLocked()
    {
        return true;
    }

    public function isCredentialsNonExpired()
    {
        return true;
    }

    public function isEnabled()
    {
        return $this->isActive;
    }

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            // see section on salt below
            // $this->salt,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            // see section on salt below
            // $this->salt
        ) = unserialize($serialized);
    }

    /**
     * Set username
     *
     * @param string $username
     *
     * @return User
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    public function getPlainPassword()
    {
        return $this->plainPassword;
    }

    public function setPlainPassword($password)
    {
        $this->plainPassword = $password;
    }

    /**
     * Set password
     *
     * @param string $password
     *
     * @return User
     */
    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }

    /**
     * Set email
     *
     * @param string $email
     *
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;
        $this->setUsername($email);

        return $this;
    }

    /**
     * Get email
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set isActive
     *
     * @param boolean $isActive
     *
     * @return User
     */
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;

        return $this;
    }

    /**
     * Get isActive
     *
     * @return boolean
     */
    public function getIsActive()
    {
        return $this->isActive;
    }

    /**
     * Add userGroup
     *
     * @param \AppBundle\Entity\UserGroup $userGroup
     *
     * @return User
     */
    public function addUserGroup(\AppBundle\Entity\UserGroup $userGroup)
    {
        $this->userGroups[] = $userGroup;

        return $this;
    }

    /**
     * Remove userGroup
     *
     * @param \AppBundle\Entity\UserGroup $userGroup
     */
    public function removeUserGroup(\AppBundle\Entity\UserGroup $userGroup)
    {
        $this->userGroups->removeElement($userGroup);
    }

    /**
     * Get userGroups
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getUserGroups()
    {
        return $this->userGroups;
    }

    /**
     * Set shibbolethPersistentId
     *
     * @param string $shibbolethPersistentId
     *
     * @return User
     */
    public function setShibbolethPersistentId($shibbolethPersistentId)
    {
        $this->shibbolethPersistentId = $shibbolethPersistentId;

        return $this;
    }

    /**
     * Get shibbolethPersistentId
     *
     * @return string
     */
    public function getShibbolethPersistentId()
    {
        return $this->shibbolethPersistentId;
    }

    /**
     * Set firstName
     *
     * @param string $firstName
     *
     * @return User
     */
    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;

        return $this;
    }

    /**
     * Get firstName
     *
     * @return string
     */
    public function getFirstName()
    {
        return $this->firstName;
    }

    /**
     * Set lastName
     *
     * @param string $lastName
     *
     * @return User
     */
    public function setLastName($lastName)
    {
        $this->lastName = $lastName;

        return $this;
    }

    /**
     * Get lastName
     *
     * @return string
     */
    public function getLastName()
    {
        return $this->lastName;
    }

    /**
     * Set emailConfirmed
     *
     * @param boolean $emailConfirmed
     *
     * @return User
     */
    public function setEmailConfirmed($emailConfirmed)
    {
        $this->emailConfirmed = $emailConfirmed;

        return $this;
    }

    /**
     * Get emailConfirmed
     *
     * @return boolean
     */
    public function getEmailConfirmed()
    {
        return $this->emailConfirmed;
    }

    public function removeAllUserGroups() {
        $userGroups = $this->getUserGroups();
        foreach($userGroups as $userGroup) {
           $this->removeUserGroup($userGroup);
        }
    }

    public function hasUserGroup($userGroupId) {
        foreach($this->getUserGroups() as $userGroup) {
            if($userGroup->getId() == $userGroupId)
                return true;
        }
        return false;
    }

    /**
     * Set lastLogin
     *
     * @param integer $lastLogin
     *
     * @return User
     */
    public function setLastLogin($lastLogin)
    {
        $this->lastLogin = $lastLogin;

        return $this;
    }

    /**
     * Get lastLogin
     *
     * @return integer
     */
    public function getLastLogin()
    {
        return $this->lastLogin;
    }

    /**
     * Set confirmationEmailSend
     *
     * @param integer $confirmationEmailSend
     *
     * @return User
     */
    public function setConfirmationEmailSend($confirmationEmailSend)
    {
        $this->confirmationEmailSend = $confirmationEmailSend;

        return $this;
    }

    /**
     * Get confirmationEmailSend
     *
     * @return integer
     */
    public function getConfirmationEmailSend()
    {
        return $this->confirmationEmailSend;
    }

    /**
     * Set validTill
     *
     * @param integer $validTill
     *
     * @return User
     */
    public function setValidTill($validTill)
    {
        $this->validTill = $validTill;

        return $this;
    }

    /**
     * Get validTill
     *
     * @return integer
     */
    public function getValidTill()
    {
        return $this->validTill;
    }

    /**
     * Set shibbolethValid
     *
     * @param integer $shibbolethValid
     *
     * @return User
     */
    public function setShibbolethValid($shibbolethValid)
    {
        $this->shibbolethValid = $shibbolethValid;

        return $this;
    }

    /**
     * Get shibbolethValid
     *
     * @return integer
     */
    public function getShibbolethValid()
    {
        return $this->shibbolethValid;
    }

    /**
     * Set shibbolethHash
     *
     * @param string $shibbolethHash
     *
     * @return User
     */
    public function setShibbolethHash($shibbolethHash)
    {
        $this->shibbolethHash = $shibbolethHash;

        return $this;
    }

    /**
     * Get shibbolethHash
     *
     * @return string
     */
    public function getShibbolethHash()
    {
        return $this->shibbolethHash;
    }

    /**
     * Set shibbolethState
     *
     * @param integer $shibbolethState
     *
     * @return User
     */
    public function setShibbolethState($shibbolethState)
    {
        $this->shibbolethState = $shibbolethState;

        return $this;
    }

    /**
     * Get shibbolethState
     *
     * @return integer
     */
    public function getShibbolethState()
    {
        return $this->shibbolethState;
    }

    /**
     * Set expires
     *
     * @param integer $expires
     *
     * @return User
     */
    public function setExpires($expires)
    {
        $this->expires = $expires;

        return $this;
    }

    /**
     * Get expires
     *
     * @return integer
     */
    public function getExpires()
    {
        return $this->expires;
    }

    /**
     * Set emailNew
     *
     * @param string $emailNew
     *
     * @return User
     */
    public function setEmailNew($emailNew)
    {
        $this->emailNew = $emailNew;

        return $this;
    }

    /**
     * Get emailNew
     *
     * @return string
     */
    public function getEmailNew()
    {
        return $this->emailNew;
    }

    /**
     * Set passwordHash
     *
     * @param string $passwordHash
     *
     * @return User
     */
    public function setPasswordHash($passwordHash)
    {
        $this->passwordHash = $passwordHash;

        return $this;
    }

    /**
     * Get passwordHash
     *
     * @return string
     */
    public function getPasswordHash()
    {
        return $this->passwordHash;
    }

    /**
     * Set sessionId
     *
     * @param string $sessionId
     *
     * @return User
     */
    public function setSessionId($sessionId)
    {
        $this->sessionId = $sessionId;

        return $this;
    }

    /**
     * Get sessionId
     *
     * @return string
     */
    public function getSessionId()
    {
        return $this->sessionId;
    }

    /**
     * Set salutation
     *
     * @param \AppBundle\Entity\Salutation $salutation
     *
     * @return User
     */
    public function setSalutation(\AppBundle\Entity\Salutation $salutation = null)
    {
        $this->salutation = $salutation;

        return $this;
    }

    /**
     * Get salutation
     *
     * @return \AppBundle\Entity\Salutation
     */
    public function getSalutation()
    {
        return $this->salutation;
    }

    /**
     * Add bankDetail
     *
     * @param \AppBundle\Entity\BankDetails $bankDetail
     *
     * @return User
     */
    public function addBankDetail(\AppBundle\Entity\BankDetails $bankDetail)
    {
        $this->bankDetails[] = $bankDetail;

        return $this;
    }

    /**
     * Remove bankDetail
     *
     * @param \AppBundle\Entity\BankDetails $bankDetail
     */
    public function removeBankDetail(\AppBundle\Entity\BankDetails $bankDetail)
    {
        $this->bankDetails->removeElement($bankDetail);
    }

    /**
     * Get bankDetails
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBankDetails()
    {
        return $this->bankDetails;
    }

    /**
     * Add billingAddress
     *
     * @param \AppBundle\Entity\Address $billingAddress
     *
     * @return User
     */
    public function addBillingAddress(\AppBundle\Entity\Address $billingAddress)
    {
        $this->billingAddresses[] = $billingAddress;

        return $this;
    }

    /**
     * Remove billingAddress
     *
     * @param \AppBundle\Entity\Address $billingAddress
     */
    public function removeBillingAddress(\AppBundle\Entity\Address $billingAddress)
    {
        $this->billingAddresses->removeElement($billingAddress);
    }

    /**
     * Set billingAddresses
     *
     * @param \AppBundle\Entity\Address $billingAddress
     *
     * @return User
     *
     */
    public function setBillingAddresses(\AppBundle\Entity\Address $billingAddress)
    {
        if($this->billingAddresses !== NULL and $this->billingAddresses->contains($billingAddress)){
            return false;
        }
        $this->addBillingAddress($billingAddress);
        return $this;
    }

    /**
     * Set one billingAddresses
     *
     * @param \AppBundle\Entity\Address $billingAddress
     *
     * @return User
     *
     */
    public function setOneBillingAddresses(\AppBundle\Entity\Address $billingAddress)
    {
        $this->billingAddresses = $billingAddress;

        return $this;
    }

    /**
     * Set one billingAddresses
     *
     * @param \AppBundle\Entity\Address $billingAddress
     *
     * @return User
     *
     */
    public function unsetBillingAddresses()
    {
        $this->billingAddresses = new ArrayCollection();

        return $this;
    }

    /**
     * Get billingAddresses
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBillingAddresses()
    {
        return $this->billingAddresses;
    }
}
</code>```

config/security.yml

```<code>providers:
        chain_provider:
            chain:
                providers: [in_memory, database_user]
        in_memory:
            memory:
                users:
                    admin:
                        password: ***
                        roles: 'ROLE_ADMIN'
        database_user:
            entity:
                class: AppBundle:User

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        secured_area:
            # pattern: match to pages
            anonymous: ~
            pattern:    ^/
            access_denied_handler: AppBundle\Security\AccessDeniedHandler
            provider: chain_provider
            form_login:
                login_path: /login
                check_path: /login_check
                default_target_path: account
                # Configuring CSRF protection
                csrf_parameter: _csrf_security_token
                csrf_token_id: a_private_string
                success_handler: AppBundle\Handler\LoginSuccessHandler
            logout:
                path: /logout
                target: /login

    access_control:
        ...

    role_hierarchy:
        ...

    encoders:
        AppBundle\Entity\User:
            algorithm: bcrypt
        Symfony\Component\Security\Core\User\User:
            plaintext
</code>```

答:
As of Symfony 4.0, logout_on_user_change is set to true. That means a user will be logged out if it has been changed.

You should implement Symfony\Component\Security\Core\User\EquatableInterface and add the isEqualTo method:

```<code>class User implements EquatableInterface
{
    public function isEqualTo(UserInterface $user)
    {
        if ($this->password !== $user->getPassword()) {
            return false;
        }

        if ($this->salt !== $user->getSalt()) {
            return false;
        }

        if ($this->username !== $user->getUsername()) {
            return false;
        }

        return true;
    }
}
</code>```

Changelog

https://github.com/symfony/security-bundle/blob/master/CHANGELOG.md

4.1.0

The logout_on_user_change firewall option is deprecated and will be removed in 5.0.

4.0.0

the firewall option logout_on_user_change is now always true, which will trigger a logout if the user changes between requests

3.4.0

Added logout_on_user_change to the firewall options. This config item will trigger a logout when the user has changed. Should be set to true to avoid deprecations in the configuration.

The option wasn't documented by the time of writing this answer: https://github.com/symfony/symfony-docs/issues/8428, but it now is: https://symfony.com/doc/4.4/reference/configuration/security.html#logout-on-user-change

Side note on updating to a new major release

If you want to upgrade to a new major version, always update to the latest minor version first. That means update to 2.8 before updating to 3.0 and updating to 3.4 before going to 4.0. See Symfony 4: Compose your Applications by Fabien Potencier.

Symfony 3.0 = Symfony 2.8 - deprecated features

(..)

Symfony 4.0 = Symfony 3.4 - deprecated features + a new way to develop
applications

Updating to a new major release is much easier if you're already on the latest minor release, because you can see all deprecation notices.

Body:
I updated my Symfony environment form 3.3 to 4.0. After the update I have problems with the login (user provided by database). When I submit the login form, I just got right back to the login form without any error message. When I use invalid credentials, I got the corresponding error message. Here is the log after trying to login. The login with the "in_memory" user provider is working. Do you need more information?

[2017-12-06 13:57:05] security.INFO: User has been authenticated successfully. {"username":"***"} []
[2017-12-06 14:22:39] doctrine.DEBUG: "START TRANSACTION" [] []
[2017-12-06 13:57:05] security.DEBUG: Read existing security token from the session. {"key":"_security_secured_area","token_class":"Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken"} []
[2017-12-06 13:57:05] doctrine.DEBUG: SELECT t0.username AS username_1, t0.password AS password_2, t0.email AS email_3, t0.email_new AS email_new_4, t0.first_name AS first_name_5, t0.last_name AS last_name_6, t0.is_active AS is_active_7, t0.email_confirmed AS email_confirmed_8, t0.shibboleth_state AS shibboleth_state_9, t0.shibboleth_hash AS shibboleth_hash_10, t0.shibboleth_persistent_id AS shibboleth_persistent_id_11, t0.confirmation_email_send AS confirmation_email_send_12, t0.last_login AS last_login_13, t0.expires AS expires_14, t0.session_id AS session_id_15, t0.id AS id_16, t0.hidden AS hidden_17, t0.deleted AS deleted_18, t0.created AS created_19, t0.modified AS modified_20, t0.sorting AS sorting_21, t0.salutation_id AS salutation_id_22, t0.creator_id AS creator_id_23, t0.modifier_id AS modifier_id_24 FROM User t0 WHERE t0.id = ? AND ((t0.deleted = 0)) [2] []
[2017-12-06 13:57:05] security.DEBUG: Token was deauthenticated after trying to refresh it. {"username":"user","provider":"Symfony\\Component\\Security\\Core\\User\\ChainUserProvider"} []
[2017-12-06 13:57:05] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2017-12-06 13:57:05] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:68)"} []
[2017-12-06 13:57:05] security.DEBUG: Calling Authentication entry point. [] []

Entity\User:

class User extends EntitySuperclass implements AdvancedUserInterface, \Serializable
{
    /**
     * @ORM\Column(type="string")
     */
    private $username;

    /**
     *
     * @Assert\Length(max=4096,groups={"account_complete","account_password","user"})
     * @Assert\Length(min = 8,groups={"account_complete","account_password","user"}, minMessage="user.password_length")
     */
    private $plainPassword;

    /**
     * The below length depends on the "algorithm" you use for encoding
     * the password, but this works well with bcrypt.
     *
     * @ORM\Column(type="string", length=64)
     */
    private $password;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank(groups={"account_register","user"})
     * @Assert\Email(
     *      groups = {"account_register", "account","user"},
     *      strict = true,
     *      checkMX = true
     * )
     */
    private $email;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $emailNew = '';

    /**
     * @ORM\ManyToOne(targetEntity="Salutation")
     *
     */
    private $salutation;

    /**
     * @ORM\Column(type="string")
     * @Assert\NotBlank(groups={"account_complete","user"})
     * @Assert\Regex(pattern = "/^[a-zA-ZäöüÄÖÜß0-9 ]+$/",groups={"account_complete","user"}, message="user.first_name.regex")
     */
    private $firstName;

    /**
     * @ORM\Column(type="string")
     * @Assert\NotBlank(groups={"account_complete","user"})
     * @Assert\Regex(pattern = "/^[a-zA-ZäöüÄÖÜß0-9 ]+$/",groups={"account_complete","user"}, message="user.last_name.regex")
     */
    private $lastName;

    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive = false;

    /**
     * @ORM\Column(name="email_confirmed", type="boolean")
     */
    private $emailConfirmed = false;

    /**
     * @ORM\Column(type="integer")
     */
    private $shibbolethState = 0;

    /**
     * @ORM\Column(type="string")
     */
    private $shibbolethHash = '';

    /**
     * @ORM\Column(type="string")
     */
    private $shibbolethPersistentId = '';

    /**
     * @ORM\ManyToMany(targetEntity="UserGroup")
     * @ORM\JoinTable(name="User_UserGroup",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     *      )
     */
    private $userGroups;

    /**
     * @ORM\Column(type="integer")
     */
    private $confirmationEmailSend;

    /**
     * @ORM\Column(type="integer")
     */
    private $lastLogin = 0;

    /**
     * @ORM\Column(type="integer")
     */
    protected $expires = 0;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $sessionId = '';

    /**
     * @ORM\ManyToMany(targetEntity="BankDetails", cascade={"persist"})
     * @ORM\JoinTable(name="User_BankDetails",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="bank_details_id", referencedColumnName="id")}
     * )
     * @Assert\Valid
     */
    private $bankDetails;

    /**
     * @ORM\ManyToMany(targetEntity="Address", cascade={"persist"})
     * @ORM\JoinTable(name="User_BillingAddress",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="billing_address_id", referencedColumnName="id")}
     * )
     * @Assert\Count(
     *      min = 1,
     *      minMessage = "user.billing_addresses.min",
     * )
     * @Assert\Valid
     */
    private $billingAddresses;

    public function __construct()
    {
        parent::__construct();
        $this->isActive = true;
        $this->confirmationEmailSend = 0;
        $this->userGroups = new ArrayCollection();
        $this->bankDetails = new ArrayCollection();
        $this->billingAddresses = new ArrayCollection();
        // may not be needed, see section on salt below
        // $this->salt = md5(uniqid(null, true));
    }

    /**
     * @ORM\PrePersist
     */
    public function prePersist()
    {
        $currentTimestamp = time();

        if($this->getConfirmationEmailSend() == NULL)
            $this->setConfirmationEmailSend(0);

   }

    public function getUsername()
    {
        //return $this->username;
        return $this->email;
    }

    public function getSalt()
    {
        // The bcrypt algorithm doesn't require a separate salt.
        return null;
    }

    public function getPassword()
    {
        return $this->password;
    }

    public function getRoles()
    {
        $roles = array();
        $userGroups = $this->getUserGroups();
        if(!empty($userGroups)) {
            foreach($userGroups as $userGroup) {
                $role = $userGroup->getRole();
                $roles[] = 'ROLE_'.strtoupper($role);
            }
        }
        return $roles;
    }

    public function isGranted($role)
    {
        return in_array($role, $this->getRoles());
    }

    public function eraseCredentials()
    {
    }

    public function isAccountNonExpired()
    {
        return true;
    }

    public function isAccountNonLocked()
    {
        return true;
    }

    public function isCredentialsNonExpired()
    {
        return true;
    }

    public function isEnabled()
    {
        return $this->isActive;
    }

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            // see section on salt below
            // $this->salt,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            // see section on salt below
            // $this->salt
        ) = unserialize($serialized);
    }

    /**
     * Set username
     *
     * @param string $username
     *
     * @return User
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    public function getPlainPassword()
    {
        return $this->plainPassword;
    }

    public function setPlainPassword($password)
    {
        $this->plainPassword = $password;
    }

    /**
     * Set password
     *
     * @param string $password
     *
     * @return User
     */
    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }

    /**
     * Set email
     *
     * @param string $email
     *
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;
        $this->setUsername($email);

        return $this;
    }

    /**
     * Get email
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set isActive
     *
     * @param boolean $isActive
     *
     * @return User
     */
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;

        return $this;
    }

    /**
     * Get isActive
     *
     * @return boolean
     */
    public function getIsActive()
    {
        return $this->isActive;
    }

    /**
     * Add userGroup
     *
     * @param \AppBundle\Entity\UserGroup $userGroup
     *
     * @return User
     */
    public function addUserGroup(\AppBundle\Entity\UserGroup $userGroup)
    {
        $this->userGroups[] = $userGroup;

        return $this;
    }

    /**
     * Remove userGroup
     *
     * @param \AppBundle\Entity\UserGroup $userGroup
     */
    public function removeUserGroup(\AppBundle\Entity\UserGroup $userGroup)
    {
        $this->userGroups->removeElement($userGroup);
    }

    /**
     * Get userGroups
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getUserGroups()
    {
        return $this->userGroups;
    }

    /**
     * Set shibbolethPersistentId
     *
     * @param string $shibbolethPersistentId
     *
     * @return User
     */
    public function setShibbolethPersistentId($shibbolethPersistentId)
    {
        $this->shibbolethPersistentId = $shibbolethPersistentId;

        return $this;
    }

    /**
     * Get shibbolethPersistentId
     *
     * @return string
     */
    public function getShibbolethPersistentId()
    {
        return $this->shibbolethPersistentId;
    }

    /**
     * Set firstName
     *
     * @param string $firstName
     *
     * @return User
     */
    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;

        return $this;
    }

    /**
     * Get firstName
     *
     * @return string
     */
    public function getFirstName()
    {
        return $this->firstName;
    }

    /**
     * Set lastName
     *
     * @param string $lastName
     *
     * @return User
     */
    public function setLastName($lastName)
    {
        $this->lastName = $lastName;

        return $this;
    }

    /**
     * Get lastName
     *
     * @return string
     */
    public function getLastName()
    {
        return $this->lastName;
    }

    /**
     * Set emailConfirmed
     *
     * @param boolean $emailConfirmed
     *
     * @return User
     */
    public function setEmailConfirmed($emailConfirmed)
    {
        $this->emailConfirmed = $emailConfirmed;

        return $this;
    }

    /**
     * Get emailConfirmed
     *
     * @return boolean
     */
    public function getEmailConfirmed()
    {
        return $this->emailConfirmed;
    }

    public function removeAllUserGroups() {
        $userGroups = $this->getUserGroups();
        foreach($userGroups as $userGroup) {
           $this->removeUserGroup($userGroup);
        }
    }

    public function hasUserGroup($userGroupId) {
        foreach($this->getUserGroups() as $userGroup) {
            if($userGroup->getId() == $userGroupId)
                return true;
        }
        return false;
    }

    /**
     * Set lastLogin
     *
     * @param integer $lastLogin
     *
     * @return User
     */
    public function setLastLogin($lastLogin)
    {
        $this->lastLogin = $lastLogin;

        return $this;
    }

    /**
     * Get lastLogin
     *
     * @return integer
     */
    public function getLastLogin()
    {
        return $this->lastLogin;
    }

    /**
     * Set confirmationEmailSend
     *
     * @param integer $confirmationEmailSend
     *
     * @return User
     */
    public function setConfirmationEmailSend($confirmationEmailSend)
    {
        $this->confirmationEmailSend = $confirmationEmailSend;

        return $this;
    }

    /**
     * Get confirmationEmailSend
     *
     * @return integer
     */
    public function getConfirmationEmailSend()
    {
        return $this->confirmationEmailSend;
    }

    /**
     * Set validTill
     *
     * @param integer $validTill
     *
     * @return User
     */
    public function setValidTill($validTill)
    {
        $this->validTill = $validTill;

        return $this;
    }

    /**
     * Get validTill
     *
     * @return integer
     */
    public function getValidTill()
    {
        return $this->validTill;
    }

    /**
     * Set shibbolethValid
     *
     * @param integer $shibbolethValid
     *
     * @return User
     */
    public function setShibbolethValid($shibbolethValid)
    {
        $this->shibbolethValid = $shibbolethValid;

        return $this;
    }

    /**
     * Get shibbolethValid
     *
     * @return integer
     */
    public function getShibbolethValid()
    {
        return $this->shibbolethValid;
    }

    /**
     * Set shibbolethHash
     *
     * @param string $shibbolethHash
     *
     * @return User
     */
    public function setShibbolethHash($shibbolethHash)
    {
        $this->shibbolethHash = $shibbolethHash;

        return $this;
    }

    /**
     * Get shibbolethHash
     *
     * @return string
     */
    public function getShibbolethHash()
    {
        return $this->shibbolethHash;
    }

    /**
     * Set shibbolethState
     *
     * @param integer $shibbolethState
     *
     * @return User
     */
    public function setShibbolethState($shibbolethState)
    {
        $this->shibbolethState = $shibbolethState;

        return $this;
    }

    /**
     * Get shibbolethState
     *
     * @return integer
     */
    public function getShibbolethState()
    {
        return $this->shibbolethState;
    }

    /**
     * Set expires
     *
     * @param integer $expires
     *
     * @return User
     */
    public function setExpires($expires)
    {
        $this->expires = $expires;

        return $this;
    }

    /**
     * Get expires
     *
     * @return integer
     */
    public function getExpires()
    {
        return $this->expires;
    }

    /**
     * Set emailNew
     *
     * @param string $emailNew
     *
     * @return User
     */
    public function setEmailNew($emailNew)
    {
        $this->emailNew = $emailNew;

        return $this;
    }

    /**
     * Get emailNew
     *
     * @return string
     */
    public function getEmailNew()
    {
        return $this->emailNew;
    }

    /**
     * Set passwordHash
     *
     * @param string $passwordHash
     *
     * @return User
     */
    public function setPasswordHash($passwordHash)
    {
        $this->passwordHash = $passwordHash;

        return $this;
    }

    /**
     * Get passwordHash
     *
     * @return string
     */
    public function getPasswordHash()
    {
        return $this->passwordHash;
    }

    /**
     * Set sessionId
     *
     * @param string $sessionId
     *
     * @return User
     */
    public function setSessionId($sessionId)
    {
        $this->sessionId = $sessionId;

        return $this;
    }

    /**
     * Get sessionId
     *
     * @return string
     */
    public function getSessionId()
    {
        return $this->sessionId;
    }

    /**
     * Set salutation
     *
     * @param \AppBundle\Entity\Salutation $salutation
     *
     * @return User
     */
    public function setSalutation(\AppBundle\Entity\Salutation $salutation = null)
    {
        $this->salutation = $salutation;

        return $this;
    }

    /**
     * Get salutation
     *
     * @return \AppBundle\Entity\Salutation
     */
    public function getSalutation()
    {
        return $this->salutation;
    }

    /**
     * Add bankDetail
     *
     * @param \AppBundle\Entity\BankDetails $bankDetail
     *
     * @return User
     */
    public function addBankDetail(\AppBundle\Entity\BankDetails $bankDetail)
    {
        $this->bankDetails[] = $bankDetail;

        return $this;
    }

    /**
     * Remove bankDetail
     *
     * @param \AppBundle\Entity\BankDetails $bankDetail
     */
    public function removeBankDetail(\AppBundle\Entity\BankDetails $bankDetail)
    {
        $this->bankDetails->removeElement($bankDetail);
    }

    /**
     * Get bankDetails
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBankDetails()
    {
        return $this->bankDetails;
    }

    /**
     * Add billingAddress
     *
     * @param \AppBundle\Entity\Address $billingAddress
     *
     * @return User
     */
    public function addBillingAddress(\AppBundle\Entity\Address $billingAddress)
    {
        $this->billingAddresses[] = $billingAddress;

        return $this;
    }

    /**
     * Remove billingAddress
     *
     * @param \AppBundle\Entity\Address $billingAddress
     */
    public function removeBillingAddress(\AppBundle\Entity\Address $billingAddress)
    {
        $this->billingAddresses->removeElement($billingAddress);
    }

    /**
     * Set billingAddresses
     *
     * @param \AppBundle\Entity\Address $billingAddress
     *
     * @return User
     *
     */
    public function setBillingAddresses(\AppBundle\Entity\Address $billingAddress)
    {
        if($this->billingAddresses !== NULL and $this->billingAddresses->contains($billingAddress)){
            return false;
        }
        $this->addBillingAddress($billingAddress);
        return $this;
    }

    /**
     * Set one billingAddresses
     *
     * @param \AppBundle\Entity\Address $billingAddress
     *
     * @return User
     *
     */
    public function setOneBillingAddresses(\AppBundle\Entity\Address $billingAddress)
    {
        $this->billingAddresses = $billingAddress;

        return $this;
    }

    /**
     * Set one billingAddresses
     *
     * @param \AppBundle\Entity\Address $billingAddress
     *
     * @return User
     *
     */
    public function unsetBillingAddresses()
    {
        $this->billingAddresses = new ArrayCollection();

        return $this;
    }

    /**
     * Get billingAddresses
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getBillingAddresses()
    {
        return $this->billingAddresses;
    }
}

config/security.yml

providers:
        chain_provider:
            chain:
                providers: [in_memory, database_user]
        in_memory:
            memory:
                users:
                    admin:
                        password: ***
                        roles: 'ROLE_ADMIN'
        database_user:
            entity:
                class: AppBundle:User

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        secured_area:
            # pattern: match to pages
            anonymous: ~
            pattern:    ^/
            access_denied_handler: AppBundle\Security\AccessDeniedHandler
            provider: chain_provider
            form_login:
                login_path: /login
                check_path: /login_check
                default_target_path: account
                # Configuring CSRF protection
                csrf_parameter: _csrf_security_token
                csrf_token_id: a_private_string
                success_handler: AppBundle\Handler\LoginSuccessHandler
            logout:
                path: /logout
                target: /login

    access_control:
        ...

    role_hierarchy:
        ...

    encoders:
        AppBundle\Entity\User:
            algorithm: bcrypt
        Symfony\Component\Security\Core\User\User:
            plaintext

Body:
As of Symfony 4.0, logout_on_user_change is set to true. That means a user will be logged out if it has been changed.

You should implement Symfony\Component\Security\Core\User\EquatableInterface and add the isEqualTo method:

class User implements EquatableInterface
{
    public function isEqualTo(UserInterface $user)
    {
        if ($this->password !== $user->getPassword()) {
            return false;
        }

        if ($this->salt !== $user->getSalt()) {
            return false;
        }

        if ($this->username !== $user->getUsername()) {
            return false;
        }

        return true;
    }
}

Changelog

https://github.com/symfony/security-bundle/blob/master/CHANGELOG.md

4.1.0

The logout_on_user_change firewall option is deprecated and will be removed in 5.0.

4.0.0

the firewall option logout_on_user_change is now always true, which will trigger a logout if the user changes between requests

3.4.0

Added logout_on_user_change to the firewall options. This config item will trigger a logout when the user has changed. Should be set to true to avoid deprecations in the configuration.

The option wasn't documented by the time of writing this answer: https://github.com/symfony/symfony-docs/issues/8428, but it now is: https://symfony.com/doc/4.4/reference/configuration/security.html#logout-on-user-change

Side note on updating to a new major release

If you want to upgrade to a new major version, always update to the latest minor version first. That means update to 2.8 before updating to 3.0 and updating to 3.4 before going to 4.0. See Symfony 4: Compose your Applications by Fabien Potencier.

Symfony 3.0 = Symfony 2.8 - deprecated features

(..)

Symfony 4.0 = Symfony 3.4 - deprecated features + a new way to develop
applications

Updating to a new major release is much easier if you're already on the latest minor release, because you can see all deprecation notices.


问:
Running FuncAnimation multiple times with different parameters in a for loop
I'm trying to run FuncAnimation multiple times with different parameters but every time it gets through the first run of the simulation, the entire program stops. It won't even run the functions that I call after the initial run of FuncAnimation.

```<code>    T = [1,2,4,8]
    N = [20,40,60,80]
    for j in N:
        for k in T:
            anim = animation.FuncAnimation(fig,drawNext,interval = 10, frames = 300, repeat = False)
            plt.show()
            idealgas()
            count += 1
</code>```

Does FuncAnimation stop the entire program once the run is through? I set repeat to false as I want it to quit after a certain amount of time so that the other functions will be called and then it will iterate through the forloop. But as of right now, it animates until the time I have specified and then nothing else happens. I have a print statement in the idealgas() function to check it and it never prints so I'm assuming it never gets there. I can provide more context if need be, but the jist of this program is finding the ideal gas constant of a box with a varying number of balls and temperature. Thanks in advance for the help, I'm  new to StackOverflow so go easy on me.

答:
Closing figure at the end of animation

You could in principle create a new figure inside the loop. Then closing one figure will allow the program to continue and create the next figure and show it. The figure can be closed automatically at the end of the animation.

```<code>import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def createanimatedfig(omega):
    fig, ax = plt.subplots()
    ax.axis([0,2*np.pi,-1,1])
    ax.set_title(u"animated sin(${:g}\cdot t$)".format(omega))
    t = np.linspace(0,2*np.pi)
    x = np.sin(omega*t)
    line, = ax.plot([],[], lw=3)
    ani = FuncAnimation(fig,animate, len(t), repeat=False,
                        fargs=(t,x,line, len(t)), interval=20)
    plt.show()

def animate(i, t,x, line, maxsteps):
    line.set_data(t[:i],x[:i])
    if i >= maxsteps-1:
        plt.close(line.axes.figure)

omegas= [1,2,4,5]
for omega in omegas:
    createanimatedfig(omega)
</code>```

Note that the above will produce an error when run with the TkAgg backend. In this case you need to postpone the figure closing to after the animation has truely stopped. To this end a timer may be used.

```<code>def animate(i, t,x, line, maxsteps):
    line.set_data(t[:i],x[:i])
    if i >= maxsteps-1:
        timer = line.axes.figure.canvas.new_timer(interval=10)
        timer.single_shot = True
        timer.add_callback(lambda : plt.close(line.axes.figure))
        timer.start()
</code>```

Run animations within single figure

Alternatively you may use a single figure to show all animations one after the other. This would require to have some control over when which animation stops and so the use of a class to handle the steps is useful.

```<code>import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

class Ani():
    def __init__(self,omegas, nsteps, line):
        self.nsteps = nsteps
        self.omegas = omegas
        self.line=line
        self.step = 0
        self.i = 0

    def getdata(self,j):
        t = np.arange(0,j)/float(self.nsteps)*2*np.pi
        x = np.sin(self.omegas[self.step]*t)
        return t,x

    def gen(self):
        for i in range(len(self.omegas)):
            tit = u"animated sin(${:g}\cdot t$)".format(self.omegas[self.step])
            self.line.axes.set_title(tit)
            for j in range(self.nsteps):
                yield j
            self.step += 1

    def animate(self,j):
        x,y = self.getdata(j)
        self.line.set_data(x,y)

fig, ax = plt.subplots()
ax.axis([0,2*np.pi,-1,1])
title = ax.set_title(u"")
line, = ax.plot([],[], lw=3)

omegas= [1,2,4,5]
a = Ani(omegas,50,line)
ani = FuncAnimation(fig,a.animate, a.gen, repeat=False, interval=60)
plt.show()
</code>```

Body:
I'm trying to run FuncAnimation multiple times with different parameters but every time it gets through the first run of the simulation, the entire program stops. It won't even run the functions that I call after the initial run of FuncAnimation.

    T = [1,2,4,8]
    N = [20,40,60,80]
    for j in N:
        for k in T:
            anim = animation.FuncAnimation(fig,drawNext,interval = 10, frames = 300, repeat = False)
            plt.show()
            idealgas()
            count += 1

Does FuncAnimation stop the entire program once the run is through? I set repeat to false as I want it to quit after a certain amount of time so that the other functions will be called and then it will iterate through the forloop. But as of right now, it animates until the time I have specified and then nothing else happens. I have a print statement in the idealgas() function to check it and it never prints so I'm assuming it never gets there. I can provide more context if need be, but the jist of this program is finding the ideal gas constant of a box with a varying number of balls and temperature. Thanks in advance for the help, I'm  new to StackOverflow so go easy on me.

Body:
Closing figure at the end of animation

You could in principle create a new figure inside the loop. Then closing one figure will allow the program to continue and create the next figure and show it. The figure can be closed automatically at the end of the animation.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def createanimatedfig(omega):
    fig, ax = plt.subplots()
    ax.axis([0,2*np.pi,-1,1])
    ax.set_title(u"animated sin(${:g}\cdot t$)".format(omega))
    t = np.linspace(0,2*np.pi)
    x = np.sin(omega*t)
    line, = ax.plot([],[], lw=3)
    ani = FuncAnimation(fig,animate, len(t), repeat=False,
                        fargs=(t,x,line, len(t)), interval=20)
    plt.show()

def animate(i, t,x, line, maxsteps):
    line.set_data(t[:i],x[:i])
    if i >= maxsteps-1:
        plt.close(line.axes.figure)

omegas= [1,2,4,5]
for omega in omegas:
    createanimatedfig(omega)

Note that the above will produce an error when run with the TkAgg backend. In this case you need to postpone the figure closing to after the animation has truely stopped. To this end a timer may be used.

def animate(i, t,x, line, maxsteps):
    line.set_data(t[:i],x[:i])
    if i >= maxsteps-1:
        timer = line.axes.figure.canvas.new_timer(interval=10)
        timer.single_shot = True
        timer.add_callback(lambda : plt.close(line.axes.figure))
        timer.start()

Run animations within single figure

Alternatively you may use a single figure to show all animations one after the other. This would require to have some control over when which animation stops and so the use of a class to handle the steps is useful.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

class Ani():
    def __init__(self,omegas, nsteps, line):
        self.nsteps = nsteps
        self.omegas = omegas
        self.line=line
        self.step = 0
        self.i = 0

    def getdata(self,j):
        t = np.arange(0,j)/float(self.nsteps)*2*np.pi
        x = np.sin(self.omegas[self.step]*t)
        return t,x

    def gen(self):
        for i in range(len(self.omegas)):
            tit = u"animated sin(${:g}\cdot t$)".format(self.omegas[self.step])
            self.line.axes.set_title(tit)
            for j in range(self.nsteps):
                yield j
            self.step += 1

    def animate(self,j):
        x,y = self.getdata(j)
        self.line.set_data(x,y)

fig, ax = plt.subplots()
ax.axis([0,2*np.pi,-1,1])
title = ax.set_title(u"")
line, = ax.plot([],[], lw=3)

omegas= [1,2,4,5]
a = Ani(omegas,50,line)
ani = FuncAnimation(fig,a.animate, a.gen, repeat=False, interval=60)
plt.show()