问:
Spark : Read Nested Array from Elasticsearch
I have data in Elasticsearch that I want to use with Spark. The problem is that my Elasticsearch document contains array type.

Here is a sample of my Elasticsearch data :

```<code>{
   "took":4,
   "timed_out":false,
   "_shards":{
      "total":36,
      "successful":36,
      "skipped":0,
      "failed":0
   },
   "hits":{
      "total":2586638,
      "max_score":1,
      "hits":[
         {
            "_index":"Index_Name",
            "_type":"Type_Name",
            "_id":"l-hplmIBgpUzwNjPutjY",
            "_score":1,
            "_source":{
               "currentTime":1518339120000,
               "location":{
                  "lat":25.13,
                  "lon":55.18
               },
               "radius":65.935,
               "myArray":[
                  {
                     "id":"1154",
                     "field2":8,
                     "field3":16.39,
                     "myInnerArray":[
                        [
                           55.18,
                           25.13
                        ],
                        [
                           55.18,
                           25.13
                        ],
                        ...
                     ]
                  }
               ],
               "field4":0.512,
               "field5":123.47,
               "time":"2018-02-11T08:52:00+0000"
            }
         },
         {
            "_index":"Index_Name",
            "_type":"Type_Name",
            "_id":"4OhplmIBgpUzwNjPutjY",
            "_score":1,
            "_source":{
               "currentTime":1518491400000,
               "location":{
                  "lat":25.16,
                  "lon":55.22
               },
               "radius":6.02,
               "myArray":[
                  {
                     "id":"1158",
                     "field2":14,
                     "field3":32.455,
                     "myInnerArray":[
                        [
                           55.227,
                           25.169
                        ],
                        [
                           55.2277,
                           25.169
                        ],
                       ...
                     ]
                  }
               ],
               "field4":0.5686,
               "field5":11.681,
               "time":"2018-02-13T03:10:00+0000"
            }
         },
         ...
      ]
   }
}
</code>```

I managed to query Elasticsearch with the following code :

```<code>val df= spark.read.format("org.elasticsearch.spark.sql")
             // Some options
             .option("es.read.field.exclude","myArray")
             .option("es.query", DSL_QUERY)
             .load("Index_Name/Type_Name")
</code>```

That return me a Dataframe with all my datas except my array.
I now want to get a Dataframe with all my datas including the array.
I tried this :

```<code>val df= spark.read.format("org.elasticsearch.spark.sql")
        // Some options
        .option("es.read.field.as.array.include","myArray")
        .option("es.query", DSL_QUERY)
        .load("Index_Name/Type_Name")
</code>```

But I get the following error :

```<code>org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 2.0 failed 4 times, most recent failure: Lost task 0.3 in stage 2.0 (TID 1389, 10.139.64.5, executor 0): java.lang.ClassCastException: scala.collection.convert.Wrappers$JListWrapper cannot be cast to java.lang.Float
    at scala.runtime.BoxesRunTime.unboxToFloat(BoxesRunTime.java:109)
    at org.apache.spark.sql.catalyst.expressions.BaseGenericInternalRow$class.getFloat(rows.scala:43)
    at org.apache.spark.sql.catalyst.expressions.GenericInternalRow.getFloat(rows.scala:194)
    at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIterator.processNext(Unknown Source)
    at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
    at org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8$$anon$1.hasNext(WholeStageCodegenExec.scala:423)
    at org.apache.spark.sql.execution.collect.UnsafeRowBatchUtils$.encodeUnsafeRows(UnsafeRowBatchUtils.scala:49)
    at org.apache.spark.sql.execution.collect.Collector$$anonfun$2.apply(Collector.scala:126)
    at org.apache.spark.sql.execution.collect.Collector$$anonfun$2.apply(Collector.scala:125)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)
    at org.apache.spark.scheduler.Task.run(Task.scala:110)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:349)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
</code>```

What am I missing ?

EDIT :

The problem seem to come from the nested array.
If I add the option

```<code>.option("es.read.field.as.array.include","myArray")
</code>```

The field myArray is recognized as an array, but not 'myInnerArray'
So I added

```<code>.option("es.read.field.as.array.include","myArray.myInnerArray")
</code>```

This time, 'myInnerArray' is recognized as an array, but not 'myArray'.

答:
It seems that the second option overwrite the first option because you make them into two separate lines.

Try to combine them into one line like below,

```<code>.option("es.read.field.as.array.include","myArray,myArray.myInnerArray")
</code>```

Body:
I have data in Elasticsearch that I want to use with Spark. The problem is that my Elasticsearch document contains array type.

Here is a sample of my Elasticsearch data :

{
   "took":4,
   "timed_out":false,
   "_shards":{
      "total":36,
      "successful":36,
      "skipped":0,
      "failed":0
   },
   "hits":{
      "total":2586638,
      "max_score":1,
      "hits":[
         {
            "_index":"Index_Name",
            "_type":"Type_Name",
            "_id":"l-hplmIBgpUzwNjPutjY",
            "_score":1,
            "_source":{
               "currentTime":1518339120000,
               "location":{
                  "lat":25.13,
                  "lon":55.18
               },
               "radius":65.935,
               "myArray":[
                  {
                     "id":"1154",
                     "field2":8,
                     "field3":16.39,
                     "myInnerArray":[
                        [
                           55.18,
                           25.13
                        ],
                        [
                           55.18,
                           25.13
                        ],
                        ...
                     ]
                  }
               ],
               "field4":0.512,
               "field5":123.47,
               "time":"2018-02-11T08:52:00+0000"
            }
         },
         {
            "_index":"Index_Name",
            "_type":"Type_Name",
            "_id":"4OhplmIBgpUzwNjPutjY",
            "_score":1,
            "_source":{
               "currentTime":1518491400000,
               "location":{
                  "lat":25.16,
                  "lon":55.22
               },
               "radius":6.02,
               "myArray":[
                  {
                     "id":"1158",
                     "field2":14,
                     "field3":32.455,
                     "myInnerArray":[
                        [
                           55.227,
                           25.169
                        ],
                        [
                           55.2277,
                           25.169
                        ],
                       ...
                     ]
                  }
               ],
               "field4":0.5686,
               "field5":11.681,
               "time":"2018-02-13T03:10:00+0000"
            }
         },
         ...
      ]
   }
}

I managed to query Elasticsearch with the following code :

val df= spark.read.format("org.elasticsearch.spark.sql")
             // Some options
             .option("es.read.field.exclude","myArray")
             .option("es.query", DSL_QUERY)
             .load("Index_Name/Type_Name")

That return me a Dataframe with all my datas except my array.
I now want to get a Dataframe with all my datas including the array.
I tried this :

val df= spark.read.format("org.elasticsearch.spark.sql")
        // Some options
        .option("es.read.field.as.array.include","myArray")
        .option("es.query", DSL_QUERY)
        .load("Index_Name/Type_Name")

But I get the following error :

org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 2.0 failed 4 times, most recent failure: Lost task 0.3 in stage 2.0 (TID 1389, 10.139.64.5, executor 0): java.lang.ClassCastException: scala.collection.convert.Wrappers$JListWrapper cannot be cast to java.lang.Float
    at scala.runtime.BoxesRunTime.unboxToFloat(BoxesRunTime.java:109)
    at org.apache.spark.sql.catalyst.expressions.BaseGenericInternalRow$class.getFloat(rows.scala:43)
    at org.apache.spark.sql.catalyst.expressions.GenericInternalRow.getFloat(rows.scala:194)
    at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIterator.processNext(Unknown Source)
    at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
    at org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8$$anon$1.hasNext(WholeStageCodegenExec.scala:423)
    at org.apache.spark.sql.execution.collect.UnsafeRowBatchUtils$.encodeUnsafeRows(UnsafeRowBatchUtils.scala:49)
    at org.apache.spark.sql.execution.collect.Collector$$anonfun$2.apply(Collector.scala:126)
    at org.apache.spark.sql.execution.collect.Collector$$anonfun$2.apply(Collector.scala:125)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)
    at org.apache.spark.scheduler.Task.run(Task.scala:110)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:349)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

What am I missing ?

EDIT :

The problem seem to come from the nested array.
If I add the option

.option("es.read.field.as.array.include","myArray")

The field myArray is recognized as an array, but not 'myInnerArray'
So I added

.option("es.read.field.as.array.include","myArray.myInnerArray")

This time, 'myInnerArray' is recognized as an array, but not 'myArray'.

Body:
It seems that the second option overwrite the first option because you make them into two separate lines.

Try to combine them into one line like below,

.option("es.read.field.as.array.include","myArray,myArray.myInnerArray")


来源: stackexchange

问:
How to install libcurl with nss backend in aws ec2? (Python 3.6 64bit Amazon Linux)
I have an ec2 instance in AWS running Python3.6 (Amazon Linux/2.8.3) where I need to install pycurl with NSS ssl backend.

First I tried it by adding pycurl==7.43.0 --global-option="--with-nss" to my requirement.txt file but I was getting errors installation errors. So I ended up doing it by adding a .config file in .ebextensions (that runs during deployment):

```<code>container_commands:
  09_pycurl_reinstall:
    # the upgrade option is because it will run after PIP installs the requirements.txt file.
    # and it needs to be done with the virtual-env activated
    command: 'source /opt/python/run/venv/bin/activate && PYCURL_SSL_LIBRARY=nss pip3 install pycurl --global-option="--with-nss" --upgrade --no-cache-dir --compile --ignore-installed'
</code>```

Pycurl seems to be correctly installed, but the celery worker is not running. The celery worker logs show:

```<code>__main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory
</code>```

If I ssh connect to the instance and run python 3.6 -c 'import pycurl' I get a more detailed error:

```<code>ImportError: pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (nss)
</code>```

So I guess that my problem is that I had previously installed libcurl with openSSL instead of NSS, and hence the mismatch between libcurl and pycurl.

According to another stackoverflow question, for libcurl to be installed with NSS backend I should have installed it with:

```<code>sudo apt libcurl4-nss-dev
</code>```

But since the server is running Amazon Linux I can't use the apt command. So I did instead:

```<code>yum install libcurl-devel
</code>```

And I guess this is the problem: this installs libcurl with OpenSSL support when I need it with NSS support.

How can I install libcurl with NSS in Amazon Linux?? (I need NSS because I'm running a Django app with celery using SQS as the broker, and SQS requires NSS).

Thank you very much!

答:
I just ran into the same issue and did manage to fix it :)

Retrieve Amazon Linux configure options for libcurl:

```<code>curl-config --configure
</code>```

All options referring to paths can be ignored, but other must be kept if you want the same features than system libcurl. Of course, --with-ssl will be replaced with --without-ssl --with-nss.

1.1 Install prerequisites:

```<code>sudo yum install libssh2-devel nss-devel
</code>```

(of course you should rather add then to the packages > yum section of your ebextensions)

Compile libcurl from source (i chose 7.61.1 to match the one used by Amazon Linux 2018.03):

```<code>wget https://curl.haxx.se/download/curl-7.61.1.tar.gz
tar xf curl-7.61.1.tar.gz
cd curl-7.61.1
./configure '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-amazon-linux-gnu' '--program-prefix=' '--cache-file=../config.cache' '--disable-static' '--enable-symbol-hiding' '--enable-ipv6' '--enable-threaded-resolver' '--with-gssapi' '--with-nghttp2' '--without-ssl' '--with-nss' '--with-ca-bundle=/etc/pki/tls/certs/ca-bundle.crt' '--enable-ldap' '--enable-ldaps' '--enable-manual' '--with-libidn2' '--with-libpsl' '--with-libssh2' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'target_alias=x86_64-amazon-linux-gnu' 'CFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
make
sudo make install
</code>```

(of course this should be deployed properly as a Shell script through the files section of your ebextensions).

Now you should see libcurl.so.4 created in /usr/local/lib.

Define the following envvars for pycurl to be compiled using your custom libcurl:

```<code>LD_LIBRARY_PATH=/usr/local/lib
PYCURL_CURL_CONFIG=/usr/local/bin/curl-config
PYCURL_SSL_LIBRARY=nss
</code>```

Run your pip install

You can check pycurl linked to the right libcurl:

```<code>ldd /opt/python/run/venv/local/lib64/python3.6/site-packages/pycurl.cpython-36m-x86_64-linux-gnu.so
</code>```

should show you libcurl.so.4 => /usr/local/lib64/libcurl.so.4

And of course python 3.6 -c 'import pycurl' should work.

That's it! You should be able to run Celery with SQS.

ContentLicense: CC BY-SA 4.0

Body:
I have an ec2 instance in AWS running Python3.6 (Amazon Linux/2.8.3) where I need to install pycurl with NSS ssl backend.

First I tried it by adding pycurl==7.43.0 --global-option="--with-nss" to my requirement.txt file but I was getting errors installation errors. So I ended up doing it by adding a .config file in .ebextensions (that runs during deployment):

container_commands:
  09_pycurl_reinstall:
    # the upgrade option is because it will run after PIP installs the requirements.txt file.
    # and it needs to be done with the virtual-env activated
    command: 'source /opt/python/run/venv/bin/activate && PYCURL_SSL_LIBRARY=nss pip3 install pycurl --global-option="--with-nss" --upgrade --no-cache-dir --compile --ignore-installed'

Pycurl seems to be correctly installed, but the celery worker is not running. The celery worker logs show:

__main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory

If I ssh connect to the instance and run python 3.6 -c 'import pycurl' I get a more detailed error:

ImportError: pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (nss)

So I guess that my problem is that I had previously installed libcurl with openSSL instead of NSS, and hence the mismatch between libcurl and pycurl.

According to another stackoverflow question, for libcurl to be installed with NSS backend I should have installed it with:

sudo apt libcurl4-nss-dev

But since the server is running Amazon Linux I can't use the apt command. So I did instead:

yum install libcurl-devel

And I guess this is the problem: this installs libcurl with OpenSSL support when I need it with NSS support.

How can I install libcurl with NSS in Amazon Linux?? (I need NSS because I'm running a Django app with celery using SQS as the broker, and SQS requires NSS).

Thank you very much!

Body:
I just ran into the same issue and did manage to fix it :)

Retrieve Amazon Linux configure options for libcurl:

curl-config --configure

All options referring to paths can be ignored, but other must be kept if you want the same features than system libcurl. Of course, --with-ssl will be replaced with --without-ssl --with-nss.

1.1 Install prerequisites:

sudo yum install libssh2-devel nss-devel

(of course you should rather add then to the packages > yum section of your ebextensions)

Compile libcurl from source (i chose 7.61.1 to match the one used by Amazon Linux 2018.03):

wget https://curl.haxx.se/download/curl-7.61.1.tar.gz
tar xf curl-7.61.1.tar.gz
cd curl-7.61.1
./configure '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-amazon-linux-gnu' '--program-prefix=' '--cache-file=../config.cache' '--disable-static' '--enable-symbol-hiding' '--enable-ipv6' '--enable-threaded-resolver' '--with-gssapi' '--with-nghttp2' '--without-ssl' '--with-nss' '--with-ca-bundle=/etc/pki/tls/certs/ca-bundle.crt' '--enable-ldap' '--enable-ldaps' '--enable-manual' '--with-libidn2' '--with-libpsl' '--with-libssh2' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'target_alias=x86_64-amazon-linux-gnu' 'CFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
make
sudo make install

(of course this should be deployed properly as a Shell script through the files section of your ebextensions).

Now you should see libcurl.so.4 created in /usr/local/lib.

Define the following envvars for pycurl to be compiled using your custom libcurl:

LD_LIBRARY_PATH=/usr/local/lib
PYCURL_CURL_CONFIG=/usr/local/bin/curl-config
PYCURL_SSL_LIBRARY=nss

Run your pip install

You can check pycurl linked to the right libcurl:

ldd /opt/python/run/venv/local/lib64/python3.6/site-packages/pycurl.cpython-36m-x86_64-linux-gnu.so

should show you libcurl.so.4 => /usr/local/lib64/libcurl.so.4

And of course python 3.6 -c 'import pycurl' should work.

That's it! You should be able to run Celery with SQS.


问:
How to reload/refresh jQuery dataTable?
I am trying to implement functionality whereby clicking a button on the screen will cause my jQuery dataTable to refresh (as the server-side data source may have changed since the dataTable was created).

Here's what I have:

```<code>$(document).ready(function() {
    $("#my-button").click(function() {
        $("#my-datatable").dataTable().fnReloadAjax();
    });
});
</code>```

But when I run this, it does nothing. What's the proper way to refresh the dataTable when the button is clicked?

答:
Use this code ,when you want to refresh your datatable: </p>

```<code> $("#my-button").click(function() {
    $('#my-datatable').DataTable().clear().draw();
 });
</code>```

Title: How to reload/refresh jQuery dataTable?

Body:
I am trying to implement functionality whereby clicking a button on the screen will cause my jQuery dataTable to refresh (as the server-side data source may have changed since the dataTable was created).

Here's what I have:

$(document).ready(function() {
    $("#my-button").click(function() {
        $("#my-datatable").dataTable().fnReloadAjax();
    });
});

But when I run this, it does nothing. What's the proper way to refresh the dataTable when the button is clicked?

Body:
Use this code ,when you want to refresh your datatable:

 $("#my-button").click(function() {
    $('#my-datatable').DataTable().clear().draw();
 });


问:
How do I extract the text content from a word document with PHP?
I want to extract the text content from the word document with PHP.

I have created a new word document in Microsoft Word for Mac 2011.
Edit: have also tested by creating the same document in Microsoft Word under Windows 7.

The contents of the document is

```<code>The quick brown fox jumps over the lazy dog
</code>```

I have saved it to disk as a Word 97-2004 Document (.doc).

I'm using phpoffice/phpword and this code to extract the text:

```<code><?php

$source = "word.doc";

$phpWord = \PhpOffice\PhpWord\IOFactory::load($source, 'MsDoc');

$text = '';

$sections = $phpWord->getSections();

foreach ($sections as $s) {
    $els = $s->getElements();
    foreach ($els as $e) {
        if (get_class($e) === 'PhpOffice\PhpWord\Element\Text') {
            $text .= $e->getText();
        } elseif (get_class($e) === 'PhpOffice\PhpWord\Section\TextBreak') {
            $text .= " \n";
        } else {
            throw new Exception('Unknown class type ' . get_class($e));
        }
    }
}

print $text;
</code>```

The output of this code is only parts of the text:

```<code>The quick brown fox j
</code>```

Is there a problem with the code, or is it some kind of compatibility issue?

Edit:

If I add a var_dump($els); before foreach ($els as $e) { the output is this:

```<code>array(1) {
  [0]=>
  object(PhpOffice\PhpWord\Element\Text)#1265 (14) {
    ["text":protected]=>
    string(21) "The quick brown fox j"
    ["fontStyle":protected]=>
    object(PhpOffice\PhpWord\Style\Font)#1267 (25) {
      ["aliases":protected]=>
      array(1) {
        ["line-height"]=>
        string(10) "lineHeight"
      }
      ["type":"PhpOffice\PhpWord\Style\Font":private]=>
      string(4) "text"
      ["name":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["hint":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["size":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["color":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["bold":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["italic":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["underline":"PhpOffice\PhpWord\Style\Font":private]=>
      string(4) "none"
      ["superScript":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["subScript":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["strikethrough":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["doubleStrikethrough":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["smallCaps":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["allCaps":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["fgColor":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["scale":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["spacing":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["kerning":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["paragraph":"PhpOffice\PhpWord\Style\Font":private]=>
      object(PhpOffice\PhpWord\Style\Paragraph)#1266 (26) {
        ["aliases":protected]=>
        array(1) {
          ["line-height"]=>
          string(10) "lineHeight"
        }
        ["basedOn":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        string(6) "Normal"
        ["next":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["alignment":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        string(0) ""
        ["indentation":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["spacing":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["lineHeight":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["widowControl":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        bool(true)
        ["keepNext":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        bool(false)
        ["keepLines":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        bool(false)
        ["pageBreakBefore":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        bool(false)
        ["numStyle":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["numLevel":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        int(0)
        ["tabs":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        array(0) {
        }
        ["shading":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["borderTopSize":protected]=>
        NULL
        ["borderTopColor":protected]=>
        NULL
        ["borderLeftSize":protected]=>
        NULL
        ["borderLeftColor":protected]=>
        NULL
        ["borderRightSize":protected]=>
        NULL
        ["borderRightColor":protected]=>
        NULL
        ["borderBottomSize":protected]=>
        NULL
        ["borderBottomColor":protected]=>
        NULL
        ["styleName":protected]=>
        NULL
        ["index":protected]=>
        NULL
        ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
        bool(false)
      }
      ["shading":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["rtl":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["styleName":protected]=>
      NULL
      ["index":protected]=>
      NULL
      ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
      bool(false)
    }
    ["paragraphStyle":protected]=>
    object(PhpOffice\PhpWord\Style\Paragraph)#1266 (26) {
      ["aliases":protected]=>
      array(1) {
        ["line-height"]=>
        string(10) "lineHeight"
      }
      ["basedOn":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      string(6) "Normal"
      ["next":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["alignment":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      string(0) ""
      ["indentation":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["spacing":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["lineHeight":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["widowControl":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      bool(true)
      ["keepNext":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      bool(false)
      ["keepLines":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      bool(false)
      ["pageBreakBefore":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      bool(false)
      ["numStyle":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["numLevel":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      int(0)
      ["tabs":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      array(0) {
      }
      ["shading":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["borderTopSize":protected]=>
      NULL
      ["borderTopColor":protected]=>
      NULL
      ["borderLeftSize":protected]=>
      NULL
      ["borderLeftColor":protected]=>
      NULL
      ["borderRightSize":protected]=>
      NULL
      ["borderRightColor":protected]=>
      NULL
      ["borderBottomSize":protected]=>
      NULL
      ["borderBottomColor":protected]=>
      NULL
      ["styleName":protected]=>
      NULL
      ["index":protected]=>
      NULL
      ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
      bool(false)
    }
    ["phpWord":protected]=>
    object(PhpOffice\PhpWord\PhpWord)#1247 (3) {
      ["sections":"PhpOffice\PhpWord\PhpWord":private]=>
      array(1) {
        [0]=>
        object(PhpOffice\PhpWord\Element\Section)#1261 (16) {
          ["container":protected]=>
          string(7) "Section"
          ["style":"PhpOffice\PhpWord\Element\Section":private]=>
          object(PhpOffice\PhpWord\Style\Section)#1262 (28) {
            ["orientation":"PhpOffice\PhpWord\Style\Section":private]=>
            string(8) "portrait"
            ["paper":"PhpOffice\PhpWord\Style\Section":private]=>
            object(PhpOffice\PhpWord\Style\Paper)#1263 (8) {
              ["sizes":"PhpOffice\PhpWord\Style\Paper":private]=>
              array(6) {
                ["A3"]=>
                array(3) {
                  [0]=>
                  int(297)
                  [1]=>
                  int(420)
                  [2]=>
                  string(2) "mm"
                }
                ["A4"]=>
                array(3) {
                  [0]=>
                  int(210)
                  [1]=>
                  int(297)
                  [2]=>
                  string(2) "mm"
                }
                ["A5"]=>
                array(3) {
                  [0]=>
                  int(148)
                  [1]=>
                  int(210)
                  [2]=>
                  string(2) "mm"
                }
                ["Folio"]=>
                array(3) {
                  [0]=>
                  float(8.5)
                  [1]=>
                  int(13)
                  [2]=>
                  string(2) "in"
                }
                ["Legal"]=>
                array(3) {
                  [0]=>
                  float(8.5)
                  [1]=>
                  int(14)
                  [2]=>
                  string(2) "in"
                }
                ["Letter"]=>
                array(3) {
                  [0]=>
                  float(8.5)
                  [1]=>
                  int(11)
                  [2]=>
                  string(2) "in"
                }
              }
              ["size":"PhpOffice\PhpWord\Style\Paper":private]=>
              string(2) "A4"
              ["width":"PhpOffice\PhpWord\Style\Paper":private]=>
              int(11870)
              ["height":"PhpOffice\PhpWord\Style\Paper":private]=>
              int(16787)
              ["styleName":protected]=>
              NULL
              ["index":protected]=>
              NULL
              ["aliases":protected]=>
              array(0) {
              }
              ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
              bool(false)
            }
            ["pageSizeW":"PhpOffice\PhpWord\Style\Section":private]=>
            int(11906)
            ["pageSizeH":"PhpOffice\PhpWord\Style\Section":private]=>
            int(16838)
            ["marginTop":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1417)
            ["marginLeft":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1417)
            ["marginRight":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1417)
            ["marginBottom":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1417)
            ["gutter":"PhpOffice\PhpWord\Style\Section":private]=>
            int(0)
            ["headerHeight":"PhpOffice\PhpWord\Style\Section":private]=>
            int(720)
            ["footerHeight":"PhpOffice\PhpWord\Style\Section":private]=>
            int(720)
            ["pageNumberingStart":"PhpOffice\PhpWord\Style\Section":private]=>
            NULL
            ["colsNum":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1)
            ["colsSpace":"PhpOffice\PhpWord\Style\Section":private]=>
            int(720)
            ["breakType":"PhpOffice\PhpWord\Style\Section":private]=>
            NULL
            ["lineNumbering":"PhpOffice\PhpWord\Style\Section":private]=>
            NULL
            ["borderTopSize":protected]=>
            NULL
            ["borderTopColor":protected]=>
            NULL
            ["borderLeftSize":protected]=>
            NULL
            ["borderLeftColor":protected]=>
            NULL
            ["borderRightSize":protected]=>
            NULL
            ["borderRightColor":protected]=>
            NULL
            ["borderBottomSize":protected]=>
            NULL
            ["borderBottomColor":protected]=>
            NULL
            ["styleName":protected]=>
            NULL
            ["index":protected]=>
            NULL
            ["aliases":protected]=>
            array(0) {
            }
            ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
            bool(false)
          }
          ["headers":"PhpOffice\PhpWord\Element\Section":private]=>
          array(0) {
          }
          ["footers":"PhpOffice\PhpWord\Element\Section":private]=>
          array(0) {
          }
          ["elements":protected]=>
          array(1) {
            [0]=>
            *RECURSION*
          }
          ["phpWord":protected]=>
          *RECURSION*
          ["sectionId":protected]=>
          int(1)
          ["docPart":protected]=>
          string(7) "Section"
          ["docPartId":protected]=>
          int(1)
          ["elementIndex":protected]=>
          int(1)
          ["elementId":protected]=>
          NULL
          ["relationId":protected]=>
          NULL
          ["nestedLevel":"PhpOffice\PhpWord\Element\AbstractElement":private]=>
          int(0)
          ["parentContainer":"PhpOffice\PhpWord\Element\AbstractElement":private]=>
          NULL
          ["mediaRelation":protected]=>
          bool(false)
          ["collectionRelation":protected]=>
          bool(false)
        }
      }
      ["collections":"PhpOffice\PhpWord\PhpWord":private]=>
      array(5) {
        ["Bookmarks"]=>
        object(PhpOffice\PhpWord\Collection\Bookmarks)#1248 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
        ["Titles"]=>
        object(PhpOffice\PhpWord\Collection\Titles)#1249 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
        ["Footnotes"]=>
        object(PhpOffice\PhpWord\Collection\Footnotes)#1250 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
        ["Endnotes"]=>
        object(PhpOffice\PhpWord\Collection\Endnotes)#1251 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
        ["Charts"]=>
        object(PhpOffice\PhpWord\Collection\Charts)#1252 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
      }
      ["metadata":"PhpOffice\PhpWord\PhpWord":private]=>
      array(3) {
        ["DocInfo"]=>
        object(PhpOffice\PhpWord\Metadata\DocInfo)#1253 (12) {
          ["creator":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["lastModifiedBy":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["created":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          int(1483515248)
          ["modified":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          int(1483515248)
          ["title":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["description":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["subject":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["keywords":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["category":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["company":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["manager":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["customProperties":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          array(0) {
          }
        }
        ["Protection"]=>
        object(PhpOffice\PhpWord\Metadata\Protection)#1254 (1) {
          ["editing":"PhpOffice\PhpWord\Metadata\Protection":private]=>
          NULL
        }
        ["Compatibility"]=>
        object(PhpOffice\PhpWord\Metadata\Compatibility)#1255 (1) {
          ["ooxmlVersion":"PhpOffice\PhpWord\Metadata\Compatibility":private]=>
          int(12)
        }
      }
    }
    ["sectionId":protected]=>
    NULL
    ["docPart":protected]=>
    string(7) "Section"
    ["docPartId":protected]=>
    int(1)
    ["elementIndex":protected]=>
    int(1)
    ["elementId":protected]=>
    string(6) "5d531b"
    ["relationId":protected]=>
    NULL
    ["nestedLevel":"PhpOffice\PhpWord\Element\AbstractElement":private]=>
    int(0)
    ["parentContainer":"PhpOffice\PhpWord\Element\AbstractElement":private]=>
    string(7) "Section"
    ["mediaRelation":protected]=>
    bool(false)
    ["collectionRelation":protected]=>
    bool(false)
  }
}
</code>```

答:
Rather than check each class for text, you can use

                    $sections = $phpWord->getSections();

                    foreach ($sections as $s) {
                        $els = $s->getElements();
                        /** @var ElementTest $e */
                        foreach ($els as $e) {
                            $class = get_class($e);
                            if (method_exists($class, 'getText')) {
                                $text .= $e->getText();
                            } else {
                                $text .= "\n";
                            }
                        }
                    }

```

ContentLicense: CC BY-SA 3.0

Body:
I want to extract the text content from the word document with PHP.

I have created a new word document in Microsoft Word for Mac 2011.
Edit: have also tested by creating the same document in Microsoft Word under Windows 7.

The contents of the document is

The quick brown fox jumps over the lazy dog

I have saved it to disk as a Word 97-2004 Document (.doc).

I'm using phpoffice/phpword and this code to extract the text:

<?php

$source = "word.doc";

$phpWord = \PhpOffice\PhpWord\IOFactory::load($source, 'MsDoc');

$text = '';

$sections = $phpWord->getSections();

foreach ($sections as $s) {
    $els = $s->getElements();
    foreach ($els as $e) {
        if (get_class($e) === 'PhpOffice\PhpWord\Element\Text') {
            $text .= $e->getText();
        } elseif (get_class($e) === 'PhpOffice\PhpWord\Section\TextBreak') {
            $text .= " \n";
        } else {
            throw new Exception('Unknown class type ' . get_class($e));
        }
    }
}

print $text;

The output of this code is only parts of the text:

The quick brown fox j

Is there a problem with the code, or is it some kind of compatibility issue?

Edit:

If I add a var_dump($els); before foreach ($els as $e) { the output is this:

array(1) {
  [0]=>
  object(PhpOffice\PhpWord\Element\Text)#1265 (14) {
    ["text":protected]=>
    string(21) "The quick brown fox j"
    ["fontStyle":protected]=>
    object(PhpOffice\PhpWord\Style\Font)#1267 (25) {
      ["aliases":protected]=>
      array(1) {
        ["line-height"]=>
        string(10) "lineHeight"
      }
      ["type":"PhpOffice\PhpWord\Style\Font":private]=>
      string(4) "text"
      ["name":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["hint":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["size":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["color":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["bold":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["italic":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["underline":"PhpOffice\PhpWord\Style\Font":private]=>
      string(4) "none"
      ["superScript":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["subScript":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["strikethrough":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["doubleStrikethrough":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["smallCaps":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["allCaps":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["fgColor":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["scale":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["spacing":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["kerning":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["paragraph":"PhpOffice\PhpWord\Style\Font":private]=>
      object(PhpOffice\PhpWord\Style\Paragraph)#1266 (26) {
        ["aliases":protected]=>
        array(1) {
          ["line-height"]=>
          string(10) "lineHeight"
        }
        ["basedOn":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        string(6) "Normal"
        ["next":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["alignment":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        string(0) ""
        ["indentation":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["spacing":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["lineHeight":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["widowControl":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        bool(true)
        ["keepNext":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        bool(false)
        ["keepLines":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        bool(false)
        ["pageBreakBefore":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        bool(false)
        ["numStyle":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["numLevel":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        int(0)
        ["tabs":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        array(0) {
        }
        ["shading":"PhpOffice\PhpWord\Style\Paragraph":private]=>
        NULL
        ["borderTopSize":protected]=>
        NULL
        ["borderTopColor":protected]=>
        NULL
        ["borderLeftSize":protected]=>
        NULL
        ["borderLeftColor":protected]=>
        NULL
        ["borderRightSize":protected]=>
        NULL
        ["borderRightColor":protected]=>
        NULL
        ["borderBottomSize":protected]=>
        NULL
        ["borderBottomColor":protected]=>
        NULL
        ["styleName":protected]=>
        NULL
        ["index":protected]=>
        NULL
        ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
        bool(false)
      }
      ["shading":"PhpOffice\PhpWord\Style\Font":private]=>
      NULL
      ["rtl":"PhpOffice\PhpWord\Style\Font":private]=>
      bool(false)
      ["styleName":protected]=>
      NULL
      ["index":protected]=>
      NULL
      ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
      bool(false)
    }
    ["paragraphStyle":protected]=>
    object(PhpOffice\PhpWord\Style\Paragraph)#1266 (26) {
      ["aliases":protected]=>
      array(1) {
        ["line-height"]=>
        string(10) "lineHeight"
      }
      ["basedOn":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      string(6) "Normal"
      ["next":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["alignment":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      string(0) ""
      ["indentation":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["spacing":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["lineHeight":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["widowControl":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      bool(true)
      ["keepNext":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      bool(false)
      ["keepLines":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      bool(false)
      ["pageBreakBefore":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      bool(false)
      ["numStyle":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["numLevel":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      int(0)
      ["tabs":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      array(0) {
      }
      ["shading":"PhpOffice\PhpWord\Style\Paragraph":private]=>
      NULL
      ["borderTopSize":protected]=>
      NULL
      ["borderTopColor":protected]=>
      NULL
      ["borderLeftSize":protected]=>
      NULL
      ["borderLeftColor":protected]=>
      NULL
      ["borderRightSize":protected]=>
      NULL
      ["borderRightColor":protected]=>
      NULL
      ["borderBottomSize":protected]=>
      NULL
      ["borderBottomColor":protected]=>
      NULL
      ["styleName":protected]=>
      NULL
      ["index":protected]=>
      NULL
      ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
      bool(false)
    }
    ["phpWord":protected]=>
    object(PhpOffice\PhpWord\PhpWord)#1247 (3) {
      ["sections":"PhpOffice\PhpWord\PhpWord":private]=>
      array(1) {
        [0]=>
        object(PhpOffice\PhpWord\Element\Section)#1261 (16) {
          ["container":protected]=>
          string(7) "Section"
          ["style":"PhpOffice\PhpWord\Element\Section":private]=>
          object(PhpOffice\PhpWord\Style\Section)#1262 (28) {
            ["orientation":"PhpOffice\PhpWord\Style\Section":private]=>
            string(8) "portrait"
            ["paper":"PhpOffice\PhpWord\Style\Section":private]=>
            object(PhpOffice\PhpWord\Style\Paper)#1263 (8) {
              ["sizes":"PhpOffice\PhpWord\Style\Paper":private]=>
              array(6) {
                ["A3"]=>
                array(3) {
                  [0]=>
                  int(297)
                  [1]=>
                  int(420)
                  [2]=>
                  string(2) "mm"
                }
                ["A4"]=>
                array(3) {
                  [0]=>
                  int(210)
                  [1]=>
                  int(297)
                  [2]=>
                  string(2) "mm"
                }
                ["A5"]=>
                array(3) {
                  [0]=>
                  int(148)
                  [1]=>
                  int(210)
                  [2]=>
                  string(2) "mm"
                }
                ["Folio"]=>
                array(3) {
                  [0]=>
                  float(8.5)
                  [1]=>
                  int(13)
                  [2]=>
                  string(2) "in"
                }
                ["Legal"]=>
                array(3) {
                  [0]=>
                  float(8.5)
                  [1]=>
                  int(14)
                  [2]=>
                  string(2) "in"
                }
                ["Letter"]=>
                array(3) {
                  [0]=>
                  float(8.5)
                  [1]=>
                  int(11)
                  [2]=>
                  string(2) "in"
                }
              }
              ["size":"PhpOffice\PhpWord\Style\Paper":private]=>
              string(2) "A4"
              ["width":"PhpOffice\PhpWord\Style\Paper":private]=>
              int(11870)
              ["height":"PhpOffice\PhpWord\Style\Paper":private]=>
              int(16787)
              ["styleName":protected]=>
              NULL
              ["index":protected]=>
              NULL
              ["aliases":protected]=>
              array(0) {
              }
              ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
              bool(false)
            }
            ["pageSizeW":"PhpOffice\PhpWord\Style\Section":private]=>
            int(11906)
            ["pageSizeH":"PhpOffice\PhpWord\Style\Section":private]=>
            int(16838)
            ["marginTop":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1417)
            ["marginLeft":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1417)
            ["marginRight":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1417)
            ["marginBottom":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1417)
            ["gutter":"PhpOffice\PhpWord\Style\Section":private]=>
            int(0)
            ["headerHeight":"PhpOffice\PhpWord\Style\Section":private]=>
            int(720)
            ["footerHeight":"PhpOffice\PhpWord\Style\Section":private]=>
            int(720)
            ["pageNumberingStart":"PhpOffice\PhpWord\Style\Section":private]=>
            NULL
            ["colsNum":"PhpOffice\PhpWord\Style\Section":private]=>
            int(1)
            ["colsSpace":"PhpOffice\PhpWord\Style\Section":private]=>
            int(720)
            ["breakType":"PhpOffice\PhpWord\Style\Section":private]=>
            NULL
            ["lineNumbering":"PhpOffice\PhpWord\Style\Section":private]=>
            NULL
            ["borderTopSize":protected]=>
            NULL
            ["borderTopColor":protected]=>
            NULL
            ["borderLeftSize":protected]=>
            NULL
            ["borderLeftColor":protected]=>
            NULL
            ["borderRightSize":protected]=>
            NULL
            ["borderRightColor":protected]=>
            NULL
            ["borderBottomSize":protected]=>
            NULL
            ["borderBottomColor":protected]=>
            NULL
            ["styleName":protected]=>
            NULL
            ["index":protected]=>
            NULL
            ["aliases":protected]=>
            array(0) {
            }
            ["isAuto":"PhpOffice\PhpWord\Style\AbstractStyle":private]=>
            bool(false)
          }
          ["headers":"PhpOffice\PhpWord\Element\Section":private]=>
          array(0) {
          }
          ["footers":"PhpOffice\PhpWord\Element\Section":private]=>
          array(0) {
          }
          ["elements":protected]=>
          array(1) {
            [0]=>
            *RECURSION*
          }
          ["phpWord":protected]=>
          *RECURSION*
          ["sectionId":protected]=>
          int(1)
          ["docPart":protected]=>
          string(7) "Section"
          ["docPartId":protected]=>
          int(1)
          ["elementIndex":protected]=>
          int(1)
          ["elementId":protected]=>
          NULL
          ["relationId":protected]=>
          NULL
          ["nestedLevel":"PhpOffice\PhpWord\Element\AbstractElement":private]=>
          int(0)
          ["parentContainer":"PhpOffice\PhpWord\Element\AbstractElement":private]=>
          NULL
          ["mediaRelation":protected]=>
          bool(false)
          ["collectionRelation":protected]=>
          bool(false)
        }
      }
      ["collections":"PhpOffice\PhpWord\PhpWord":private]=>
      array(5) {
        ["Bookmarks"]=>
        object(PhpOffice\PhpWord\Collection\Bookmarks)#1248 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
        ["Titles"]=>
        object(PhpOffice\PhpWord\Collection\Titles)#1249 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
        ["Footnotes"]=>
        object(PhpOffice\PhpWord\Collection\Footnotes)#1250 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
        ["Endnotes"]=>
        object(PhpOffice\PhpWord\Collection\Endnotes)#1251 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
        ["Charts"]=>
        object(PhpOffice\PhpWord\Collection\Charts)#1252 (1) {
          ["items":"PhpOffice\PhpWord\Collection\AbstractCollection":private]=>
          array(0) {
          }
        }
      }
      ["metadata":"PhpOffice\PhpWord\PhpWord":private]=>
      array(3) {
        ["DocInfo"]=>
        object(PhpOffice\PhpWord\Metadata\DocInfo)#1253 (12) {
          ["creator":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["lastModifiedBy":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["created":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          int(1483515248)
          ["modified":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          int(1483515248)
          ["title":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["description":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["subject":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["keywords":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["category":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["company":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["manager":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          string(0) ""
          ["customProperties":"PhpOffice\PhpWord\Metadata\DocInfo":private]=>
          array(0) {
          }
        }
        ["Protection"]=>
        object(PhpOffice\PhpWord\Metadata\Protection)#1254 (1) {
          ["editing":"PhpOffice\PhpWord\Metadata\Protection":private]=>
          NULL
        }
        ["Compatibility"]=>
        object(PhpOffice\PhpWord\Metadata\Compatibility)#1255 (1) {
          ["ooxmlVersion":"PhpOffice\PhpWord\Metadata\Compatibility":private]=>
          int(12)
        }
      }
    }
    ["sectionId":protected]=>
    NULL
    ["docPart":protected]=>
    string(7) "Section"
    ["docPartId":protected]=>
    int(1)
    ["elementIndex":protected]=>
    int(1)
    ["elementId":protected]=>
    string(6) "5d531b"
    ["relationId":protected]=>
    NULL
    ["nestedLevel":"PhpOffice\PhpWord\Element\AbstractElement":private]=>
    int(0)
    ["parentContainer":"PhpOffice\PhpWord\Element\AbstractElement":private]=>
    string(7) "Section"
    ["mediaRelation":protected]=>
    bool(false)
    ["collectionRelation":protected]=>
    bool(false)
  }
}


问:
Repository Pattern Single Interface in Android
After studying a couple of blog posts on the topic, I got confused as there were different implementations by different developers but they have all used single interface for repository.

Assume, we have following interface for repository

```<code>interface Repository<T> {
    fun get(): List<T>
    fun save(items: List<T>)
}
</code>```

For a specific implementation of this repository with T = Users, Repository.get(), downloads some data from sever and cache it.

For another type of object, say Bundles I not only need these methods but some additional methods e.g. querying local database for specific column.

In that case, I can't understand, do I need to create a separate interface or add methods to existing single interface, in which case what should I do with the implementation of new methods in other repositories which do not need these methods? It it must to have same interface for all repositories. Personally, I think, its ok to create multiple interfaces for different repositories as long as I abstract them nicely.

答:
do I need to create a separate interface or add methods to existing single interface

You can do whatever you like. Android does not know anything about repositories and imposes no restrictions.

In my work, I do not create a generic interface (like the one that you show) in the first place. I cannot think of a project that I worked on where developers created a generic repository interface, either. I am sure that some people do create such an interface, but there is no requirement by the OS for one.

Personally, I think, its ok to create multiple interfaces for different repositories as long as I abstract them nicely.

You are welcome to do that.

Body:
After studying a couple of blog posts on the topic, I got confused as there were different implementations by different developers but they have all used single interface for repository.

Assume, we have following interface for repository

interface Repository<T> {
    fun get(): List<T>
    fun save(items: List<T>)
}

For a specific implementation of this repository with T = Users, Repository.get(), downloads some data from sever and cache it.

For another type of object, say Bundles I not only need these methods but some additional methods e.g. querying local database for specific column.

In that case, I can't understand, do I need to create a separate interface or add methods to existing single interface, in which case what should I do with the implementation of new methods in other repositories which do not need these methods? It it must to have same interface for all repositories. Personally, I think, its ok to create multiple interfaces for different repositories as long as I abstract them nicely.


问:
Can't get React Bootstrap button to span full width of column
I am using the React Bootstrap Container, Row and Column elements to layout a form that I have.

I have one row that contains 2 columns each with a button inside it. These buttons are generated from State.

I would like to have it so that the buttons span the whole length of the column they are in, so equal distant regardless of text they contain.

But can't work out how to do this. In the react bootstrap documentation it says that this should be possible by using the block attribute.

Below is my code.

```<code>//This is the state, the values for label are hardcoded for now, //but would be dynamic.

 state = {
        teamSelection: {
            teamAName: {
                elementType: 'button',
                label: 'Trail Blazers',
                selected: "true"
            },
            teamBName: {
                elementType: 'button',
                label: 'Warriors',
                selected: true
            }
        }
    }

//This generates the formElementArray to be used below.

 const formElementsArray = [];
        for (let key in this.state.teamSelection) {
            formElementsArray.push({
                id: key,
                config: this.state.teamSelection[key]
            });
        }

matchResultInputForm = (
            <Form >
                <Container fluid>
                    <Row>
                        <ButtonGroup>
                            {formElementsArray.map(formElement => (
                                <Col>
                                    <Button
                                        key={formElement.id}
                                        className="mr-1"
                                        color="primary"
                                        block
                                        size="lg"
                                        label={formElement.config.label}
                                        selectedteam={this.state.selectedteam}>{formElement.config.label}</Button>
                                </Col>
                            ))}
                        </ButtonGroup>
                    </Row>
                    ...
</code>```

So currently the buttons do not span the full width of the column and are auto sized based on text.

I have seen that there a few other questions on here that are similar but the solutions to these do not work for me.

e.g, I tried changing the ButtonGroup to a div and using
 but this didn't make a difference.

答:
I was able to resolve this.

I changed the column to be outside the ButtonGroup and also used the d-flex built in class for ButtonGroup.

```<code><Row>
    <Col>
    <ButtonGroup className="d-flex">
        {formElementsArray.map(formElement => (
                <Button
                    key={formElement.id}
                    className="btn-block mr-1 mt-1 btn-lg"
                    color="primary"
                    block
                    label={formElement.config.label}
                    selectedteam={this.state.selectedteam}>{formElement.config.label}</Button>

        ))}
    </ButtonGroup>
    </Col>
</Row>
</code>```

Body:
I am using the React Bootstrap Container, Row and Column elements to layout a form that I have.

I have one row that contains 2 columns each with a button inside it. These buttons are generated from State.

I would like to have it so that the buttons span the whole length of the column they are in, so equal distant regardless of text they contain.

But can't work out how to do this. In the react bootstrap documentation it says that this should be possible by using the block attribute.

Below is my code.

//This is the state, the values for label are hardcoded for now, //but would be dynamic.

 state = {
        teamSelection: {
            teamAName: {
                elementType: 'button',
                label: 'Trail Blazers',
                selected: "true"
            },
            teamBName: {
                elementType: 'button',
                label: 'Warriors',
                selected: true
            }
        }
    }

//This generates the formElementArray to be used below.

 const formElementsArray = [];
        for (let key in this.state.teamSelection) {
            formElementsArray.push({
                id: key,
                config: this.state.teamSelection[key]
            });
        }

matchResultInputForm = (
            <Form >
                <Container fluid>
                    <Row>
                        <ButtonGroup>
                            {formElementsArray.map(formElement => (
                                <Col>
                                    <Button
                                        key={formElement.id}
                                        className="mr-1"
                                        color="primary"
                                        block
                                        size="lg"
                                        label={formElement.config.label}
                                        selectedteam={this.state.selectedteam}>{formElement.config.label}</Button>
                                </Col>
                            ))}
                        </ButtonGroup>
                    </Row>
                    ...

So currently the buttons do not span the full width of the column and are auto sized based on text.

I have seen that there a few other questions on here that are similar but the solutions to these do not work for me.

e.g, I tried changing the ButtonGroup to a div and using
 but this didn't make a difference.

Body:
I was able to resolve this.

I changed the column to be outside the ButtonGroup and also used the d-flex built in class for ButtonGroup.

<Row>
    <Col>
    <ButtonGroup className="d-flex">
        {formElementsArray.map(formElement => (
                <Button
                    key={formElement.id}
                    className="btn-block mr-1 mt-1 btn-lg"
                    color="primary"
                    block
                    label={formElement.config.label}
                    selectedteam={this.state.selectedteam}>{formElement.config.label}</Button>

        ))}
    </ButtonGroup>
    </Col>
</Row>


问:
I need to write Regx for text field validation, which start with either 'iqn.yyyy-mm.com.' or 'eqn.'
I need to write Regx for text field validation, which start with either 'iqn.yyyy-mm.com.' or 'eqn.'
After this any number of character or numeric value is allowed
Here 'yyyy-mm' is year and month.</p>

答:
I think this should work :

```<code>^[ie]qn\.(?:\d{4}-\d{2}\.\w{2,6})?\.?.+$
</code>```

Regex101 Link here : Link Here

Body:
I think this should work :

^[ie]qn\.(?:\d{4}-\d{2}\.\w{2,6})?\.?.+$

Regex101 Link here : Link Here


问:
Is there a way to import multiple exports under single variable?
I am curious if there is more efficient and cleaner way to import picture1, picture2, picture3 and later use them in the img tags as well? In reality I have many more pictures and it is adding extra lines of code that I would love to avoid.

I am using pictures from picture.js like that:

```<code>import {
  picture1,
  picture2,
  picture3,
} from './picture';

<img src={picture1} />
<img src={picture2} />
<img src={picture3} />
</code>```

My picture.js

```<code>import picture1 from './picture_1.jpg';
import picture2 from './picture_2.jpg';
import picture3 from './picture_3.jpg';

export {
  picture1,
  picture1,
  picture1,
};
</code>```

Ideally would want to have something like that:

```<code>import pictures from './picture';

repeat <img src=picture[index]>
</code>```

答:
You can import all pictures with *. and then use template string to access with index.</p>

```<code>import * as pictures from './picture';

<img src={pictures[`picture${index}`]}
</code>```

Body:
I am curious if there is more efficient and cleaner way to import picture1, picture2, picture3 and later use them in the img tags as well? In reality I have many more pictures and it is adding extra lines of code that I would love to avoid.

I am using pictures from picture.js like that:

import {
  picture1,
  picture2,
  picture3,
} from './picture';

My picture.js

import picture1 from './picture_1.jpg';
import picture2 from './picture_2.jpg';
import picture3 from './picture_3.jpg';

export {
  picture1,
  picture1,
  picture1,
};

Ideally would want to have something like that:

import pictures from './picture';

repeat

Body:
You can import all pictures with *. and then use template string to access with index.

import * as pictures from './picture';

<img src={pictures[`picture${index}`]}


问:
How to select all records that are 10 minutes within current timestamp in MySQL?
I have timestamps in a table column called "last_seen" like so:

```<code>2012-01-25 18:46:42
2012-01-23 08:19:04
2012-01-23 08:19:04

etc...
</code>```

How can I get all records where the timestamp is within 10 minutes of the current timestamp (in the most efficient way)?

答:
For anyone wanting to extend the question beyond just one table and find any entries in any table in a database with date_modified within the last (say) 5 minutes, try this script.

Adjust the entries for database (I used a database called mgmt2go) and save the file below to an executable .sql file.

Adapt as you want for your situation, but if you only change the database setting, it will do the same for your database.

I run this SQL script from a command line and output the results to a file so I can refer to the output when I am debugging a system that writes all settings to a MySQL (actually MariaDB) database.  I needed to figure out what was being affected when i made changes through the system user interface.

```<code># For this setup, it is best to send the output to a file
# and then read the file to see what records in what tables are found
# Save this file as list_tables.sql (or whatever you want to save it as)
# and use it by entering, at the CLI
# mysql --user=UserName --password=UserPassword -vv 2>&1 < path_to_executable_file/list_tables.sql > path_to_output_file/test.output.txt
# If you want the filename to include the time period,
# concatentate the bash date function with the filename
# ie: "mgmt2goDbaseChangesSince_"$(date +%Y-%m-%d_%H:%M:%S --date -'5 min')
# so the full sql comand would now look like
# mysql --user=UserName --password=UserPassword -vv 2>&1 < path_to_executable_file/list_tables.sql > "path_to_output_file/mgmt2goDbaseChangesFrom_"$(date +%Y-%m-%d_%H:%M:%S --date -'5 min')"_to_"$(date +%H:%M:%S)

# Set the delimeter so you can distingish the delimiter surrounding the Procedure
# (as an intact entity to be passed to the server)
# from the statements inside the Procedure calls
DELIMITER $$

# In case a previous script run created the procedure,
# delete it before running this script again
DROP PROCEDURE IF EXISTS `mgmt2go`.rc_list_tables_procedure$$

# Create a procedure to identify all the tables in the database
# (in this case, I have a database named mgmt2go)
# that contain multiple fields (id, date_modified) against which you want to search
CREATE PROCEDURE `mgmt2go`.rc_list_tables_procedure( IN rc_cutoff_date DATETIME )
BEGIN
    # Always DECLARE in sequence: Variables, Cursors, Handler
    # Variables
    DECLARE rc_last_record BOOLEAN DEFAULT FALSE;
    DECLARE rc_table_name varchar(64);
    # Cursor
    DECLARE rc_table_list CURSOR FOR SELECT DISTINCT `TABLE_NAME`
        FROM `INFORMATION_SCHEMA`.`COLUMNS`
        WHERE `INFORMATION_SCHEMA`.`COLUMNS`.`TABLE_SCHEMA` = 'mgmt2go'
        AND `INFORMATION_SCHEMA`.`COLUMNS`.`COLUMN_NAME`
            IN ( 'id' , 'date_modified' )
        GROUP BY TABLE_NAME HAVING COUNT( DISTINCT COLUMN_NAME ) = 2
        ORDER BY `INFORMATION_SCHEMA`.`COLUMNS`.`TABLE_NAME`;
    # Handler
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET rc_last_record = TRUE;
    # Activate the LOOP
    OPEN rc_table_list;
        rc_for_each_loop: LOOP
            # Test if the previous iteration of the LOOP fetched the last record
            # and if so, exit the LOOP
            FETCH FROM rc_table_list INTO rc_table_name;
            IF rc_last_record = TRUE THEN
                LEAVE rc_for_each_loop;
            END IF;
            # Eliminate the entries in the job_queue table
            # since they are just temporary system entries
            IF rc_table_name = 'job_queue' THEN
                ITERATE rc_for_each_loop;
            END IF;
            # Find all records in all tables with a date_modified field
            # greater than or equal to the specified value in the CALL
            # We cannot directly use a variable in a SELECT statement
            # So we prepare a SELECT statement by concatenation
            # and then use the Prepare and Execute functions to run the SELECT
            SET @rc_query_for_modified := CONCAT(
                'SELECT "' , rc_table_name , '" , `id` ,`date_modified` '
                'FROM `mgmt2go`.`' , rc_table_name , '` '
                'WHERE '
                'TIMESTAMP( `mgmt2go`.`' , rc_table_name , '`.`date_modified` )'
                ' >= "' , rc_cutoff_date , '" '
                );
            PREPARE rc_test_modified_statement FROM @rc_query_for_modified;
            EXECUTE rc_test_modified_statement;
            DEALLOCATE PREPARE rc_test_modified_statement;
        END LOOP rc_for_each_loop;
    CLOSE rc_table_list;
END$$

# Reset the delimiter back to the default
DELIMITER ;$$

# Invoke the Procedure, providing the cutoff date = date record more current than
# You can provide an absolute time using
# CALL `mgmt2go`.rc_list_tables_procedure( "2019-01-02 16:49:28" );
# Or you can provide a time n (Seconds/Minutes/...) before a stated time (like NOW()
CALL `mgmt2go`.rc_list_tables_procedure( DATE_SUB( NOW() , INTERVAL 5 MINUTE ) );

# If you are also trying to see if any files have changed in the last n minutes
# and want to NOT search in a particular child directory (/cache in this case)
# at the CLI enter
# find path_to_directory -path path_to_child_directory_to_exclude -prune , -type f -mmin -120
# or
# find path_to_directory -mmin -120 -iname "*.*" | egrep -v "(child_directory_to_exclude)"
# where -120 is the number of minutes to look back (120 in this case)
# -mmin is minutes since modification and -cmin is minutes since creation
# -mtime is days since modification and -ctime is days since creation
</code>```

Body:
I have timestamps in a table column called "last_seen" like so:

2012-01-25 18:46:42
2012-01-23 08:19:04
2012-01-23 08:19:04

etc...

How can I get all records where the timestamp is within 10 minutes of the current timestamp (in the most efficient way)?

Body:
For anyone wanting to extend the question beyond just one table and find any entries in any table in a database with date_modified within the last (say) 5 minutes, try this script.

Adjust the entries for database (I used a database called mgmt2go) and save the file below to an executable .sql file.

Adapt as you want for your situation, but if you only change the database setting, it will do the same for your database.

I run this SQL script from a command line and output the results to a file so I can refer to the output when I am debugging a system that writes all settings to a MySQL (actually MariaDB) database.  I needed to figure out what was being affected when i made changes through the system user interface.

# For this setup, it is best to send the output to a file
# and then read the file to see what records in what tables are found
# Save this file as list_tables.sql (or whatever you want to save it as)
# and use it by entering, at the CLI
# mysql --user=UserName --password=UserPassword -vv 2>&1 < path_to_executable_file/list_tables.sql > path_to_output_file/test.output.txt
# If you want the filename to include the time period,
# concatentate the bash date function with the filename
# ie: "mgmt2goDbaseChangesSince_"$(date +%Y-%m-%d_%H:%M:%S --date -'5 min')
# so the full sql comand would now look like
# mysql --user=UserName --password=UserPassword -vv 2>&1 < path_to_executable_file/list_tables.sql > "path_to_output_file/mgmt2goDbaseChangesFrom_"$(date +%Y-%m-%d_%H:%M:%S --date -'5 min')"_to_"$(date +%H:%M:%S)

# Set the delimeter so you can distingish the delimiter surrounding the Procedure
# (as an intact entity to be passed to the server)
# from the statements inside the Procedure calls
DELIMITER $$

# In case a previous script run created the procedure,
# delete it before running this script again
DROP PROCEDURE IF EXISTS `mgmt2go`.rc_list_tables_procedure$$

# Create a procedure to identify all the tables in the database
# (in this case, I have a database named mgmt2go)
# that contain multiple fields (id, date_modified) against which you want to search
CREATE PROCEDURE `mgmt2go`.rc_list_tables_procedure( IN rc_cutoff_date DATETIME )
BEGIN
    # Always DECLARE in sequence: Variables, Cursors, Handler
    # Variables
    DECLARE rc_last_record BOOLEAN DEFAULT FALSE;
    DECLARE rc_table_name varchar(64);
    # Cursor
    DECLARE rc_table_list CURSOR FOR SELECT DISTINCT `TABLE_NAME`
        FROM `INFORMATION_SCHEMA`.`COLUMNS`
        WHERE `INFORMATION_SCHEMA`.`COLUMNS`.`TABLE_SCHEMA` = 'mgmt2go'
        AND `INFORMATION_SCHEMA`.`COLUMNS`.`COLUMN_NAME`
            IN ( 'id' , 'date_modified' )
        GROUP BY TABLE_NAME HAVING COUNT( DISTINCT COLUMN_NAME ) = 2
        ORDER BY `INFORMATION_SCHEMA`.`COLUMNS`.`TABLE_NAME`;
    # Handler
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET rc_last_record = TRUE;
    # Activate the LOOP
    OPEN rc_table_list;
        rc_for_each_loop: LOOP
            # Test if the previous iteration of the LOOP fetched the last record
            # and if so, exit the LOOP
            FETCH FROM rc_table_list INTO rc_table_name;
            IF rc_last_record = TRUE THEN
                LEAVE rc_for_each_loop;
            END IF;
            # Eliminate the entries in the job_queue table
            # since they are just temporary system entries
            IF rc_table_name = 'job_queue' THEN
                ITERATE rc_for_each_loop;
            END IF;
            # Find all records in all tables with a date_modified field
            # greater than or equal to the specified value in the CALL
            # We cannot directly use a variable in a SELECT statement
            # So we prepare a SELECT statement by concatenation
            # and then use the Prepare and Execute functions to run the SELECT
            SET @rc_query_for_modified := CONCAT(
                'SELECT "' , rc_table_name , '" , `id` ,`date_modified` '
                'FROM `mgmt2go`.`' , rc_table_name , '` '
                'WHERE '
                'TIMESTAMP( `mgmt2go`.`' , rc_table_name , '`.`date_modified` )'
                ' >= "' , rc_cutoff_date , '" '
                );
            PREPARE rc_test_modified_statement FROM @rc_query_for_modified;
            EXECUTE rc_test_modified_statement;
            DEALLOCATE PREPARE rc_test_modified_statement;
        END LOOP rc_for_each_loop;
    CLOSE rc_table_list;
END$$

# Reset the delimiter back to the default
DELIMITER ;$$

# Invoke the Procedure, providing the cutoff date = date record more current than
# You can provide an absolute time using
# CALL `mgmt2go`.rc_list_tables_procedure( "2019-01-02 16:49:28" );
# Or you can provide a time n (Seconds/Minutes/...) before a stated time (like NOW()
CALL `mgmt2go`.rc_list_tables_procedure( DATE_SUB( NOW() , INTERVAL 5 MINUTE ) );

# If you are also trying to see if any files have changed in the last n minutes
# and want to NOT search in a particular child directory (/cache in this case)
# at the CLI enter
# find path_to_directory -path path_to_child_directory_to_exclude -prune , -type f -mmin -120
# or
# find path_to_directory -mmin -120 -iname "*.*" | egrep -v "(child_directory_to_exclude)"
# where -120 is the number of minutes to look back (120 in this case)
# -mmin is minutes since modification and -cmin is minutes since creation
# -mtime is days since modification and -ctime is days since creation


问:
How can I use a SVG image as layer on OpenLayers-3
How can I use a SVG image as a Layer (so not as a map marker) with OpenLayers-3

I was unable to get any output of my SVG image when using any of the ol.source.Vector and ol.format.Feature instances.

Small example:

```<code>var mapLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
        url: 'image.svg',
        format: new ol.format.Feature() // http://openlayers.org/en/v3.12.1/apidoc/ol.format.Feature.html
    }),
});
</code>```

I was able to get output when using the ImageStatic layer, but this uses/generates(?) a static image so the advantages of SVG are gone.

Example:

```<code>// Not sure if I need this for SVG, but is is required for an image
var extent = [0, 0, 1000, 1000]; // random image size
var projection = new ol.proj.Projection({
    code: 'test',
    units: 'pixels',
    extent: extent
});

var mapLayer = new ol.layer.Image({
    source: new ol.source.ImageStatic({
        url: 'image.svg',
        projection: projection,
        imageExtent: extent
    })
});
</code>```

I already tried the trick with setting the Content-type: to image/svg+xml but this did not help me at all.

So, again:
How can I (if possible) use a SVG image a a layer with OpenLayers-3?

答:
@Alvin Lindstam's answers is almost there but doesn't show the full image on Chrome (or any on IE).  Because the SVG doesn't have a fixed size the width and height need to be set in an imageLoadFunction

var extent = [0, 0, 512, 512];
var projection = new ol.proj.Projection({
  code: 'static-image',
  units: 'pixels',
  extent: extent
});

var map = new ol.Map({
  layers: [
    new ol.layer.Image({
      source: new ol.source.ImageStatic({
        url: 'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg',
        projection: projection,
        imageExtent: extent,
        imageLoadFunction: function (image, src) {
           image.getImage().src = src;
           image.getImage().width = ol.extent.getWidth(extent);
           image.getImage().height = ol.extent.getHeight(extent);
        }
      })
    })
  ],
  target: 'map',
  view: new ol.View({
    projection: projection,
    center: ol.extent.getCenter(extent),
    zoom: 0
  })
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet"/>
<div id="map" class="map"></div></code>```

Body:
How can I use a SVG image as a Layer (so not as a map marker) with OpenLayers-3

I was unable to get any output of my SVG image when using any of the ol.source.Vector and ol.format.Feature instances.

Small example:

var mapLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
        url: 'image.svg',
        format: new ol.format.Feature() // http://openlayers.org/en/v3.12.1/apidoc/ol.format.Feature.html
    }),
});

I was able to get output when using the ImageStatic layer, but this uses/generates(?) a static image so the advantages of SVG are gone.

Example:

// Not sure if I need this for SVG, but is is required for an image
var extent = [0, 0, 1000, 1000]; // random image size
var projection = new ol.proj.Projection({
    code: 'test',
    units: 'pixels',
    extent: extent
});

var mapLayer = new ol.layer.Image({
    source: new ol.source.ImageStatic({
        url: 'image.svg',
        projection: projection,
        imageExtent: extent
    })
});

I already tried the trick with setting the Content-type: to image/svg+xml but this did not help me at all.

So, again:
How can I (if possible) use a SVG image a a layer with OpenLayers-3?

Body:
@Alvin Lindstam's answers is almost there but doesn't show the full image on Chrome (or any on IE).  Because the SVG doesn't have a fixed size the width and height need to be set in an imageLoadFunction

var extent = [0, 0, 512, 512];
var projection = new ol.proj.Projection({
  code: 'static-image',
  units: 'pixels',
  extent: extent
});

var map = new ol.Map({
  layers: [
    new ol.layer.Image({
      source: new ol.source.ImageStatic({
        url: 'https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg',
        projection: projection,
        imageExtent: extent,
        imageLoadFunction: function (image, src) {
           image.getImage().src = src;
           image.getImage().width = ol.extent.getWidth(extent);
           image.getImage().height = ol.extent.getHeight(extent);
        }
      })
    })
  ],
  target: 'map',
  view: new ol.View({
    projection: projection,
    center: ol.extent.getCenter(extent),
    zoom: 0
  })
});

<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet"/>
<div id="map" class="map"></div>


问:
Removing duplicates and keeping one copy
I have been going through the threads about removing duplicates from a table and keeping one copy .I have seen an illustration in the case one have a table with composite key.anyone with the idea ?

table contr with composite key checkno,salary_month,sal_year

```<code>delete (select * from CONTR t1
    INNER JOIN
 (select CHECKNO, SALARY_YEAR,SALARY_MONTH FROM CONTR
group by CHECKNO, SALARY_YEAR,SALARY_MONTH HAVING COUNT(*) > 1) dupes
ON
t1.CHECKNO = dupes.CHECKNO AND
t1.SALARY_YEAR= dupes.SALARY_YEAR AND
t1.SALARY_MONTH=dupes.SALARY_MONTH);
</code>```

I expected one duplicate to be removed and one maintained.

答:
Another way to achieve this assuming you have dupes with 3 columns you have mentioned is

Create a temp table with distinct values

Drop your table

Rename the temp table

Especially if you are dealing huge volume of data this way would be a lot faster than delete.

If the dup data you are working on is subset of your main table the steps would be

Create a temp table with distinct values

Delete all dup columns from main table

Insert data from temp table to main table

The SQL for the first step would be

```<code>create table tmp_CONTR AS
select distinct CHECKNO, SALARY_YEAR,SALARY_MONTH   -- this part can be modified to match your needs
  from CONTR t1;
</code>```

Body:
I have been going through the threads about removing duplicates from a table and keeping one copy .I have seen an illustration in the case one have a table with composite key.anyone with the idea ?

table contr with composite key checkno,salary_month,sal_year

delete (select * from CONTR t1
    INNER JOIN
 (select CHECKNO, SALARY_YEAR,SALARY_MONTH FROM CONTR
group by CHECKNO, SALARY_YEAR,SALARY_MONTH HAVING COUNT(*) > 1) dupes
ON
t1.CHECKNO = dupes.CHECKNO AND
t1.SALARY_YEAR= dupes.SALARY_YEAR AND
t1.SALARY_MONTH=dupes.SALARY_MONTH);

I expected one duplicate to be removed and one maintained.

Body:
Another way to achieve this assuming you have dupes with 3 columns you have mentioned is

Create a temp table with distinct values

Drop your table

Rename the temp table

Especially if you are dealing huge volume of data this way would be a lot faster than delete.

If the dup data you are working on is subset of your main table the steps would be

Create a temp table with distinct values

Delete all dup columns from main table

Insert data from temp table to main table

The SQL for the first step would be

create table tmp_CONTR AS
select distinct CHECKNO, SALARY_YEAR,SALARY_MONTH   -- this part can be modified to match your needs
  from CONTR t1;


问:
ASP.NET Page_Load values are lagging one postback behind
I have a foreach loop in the Page_Load method of my one page to determine whether to Enable a button or not.

Code:

```<code>foreach (var class in classes)
{
    for (var i = studentsList.Count - 1; i >= 0; i--)
    {
        if (studentsList[i].Id == class.student_id)
            studenstList.Remove(studentsList[i]);
    }
}
if (studentsList.Count == 0)
{
    button1.Enabled = false;
    button1.Text = "a";
}
else
{
    button1.Enabled = true;
    button1.Text = "b";
}
if (Page.IsPostBack) { return; }
</code>```

The issue:

The value of studentsList.Count is lagging behind by a postback. If after the loop it should be 1, it only has the value of 1 at the next postback. I've debugged to confirm this is the case.

答: Your problem is that you should wait for a corresponding event and write this logic in that event handler. For clarity, page load happens earlier than control events. </p>

Body:
I have a foreach loop in the Page_Load method of my one page to determine whether to Enable a button or not.

Code:

foreach (var class in classes)
{
    for (var i = studentsList.Count - 1; i >= 0; i--)
    {
        if (studentsList[i].Id == class.student_id)
            studenstList.Remove(studentsList[i]);
    }
}
if (studentsList.Count == 0)
{
    button1.Enabled = false;
    button1.Text = "a";
}
else
{
    button1.Enabled = true;
    button1.Text = "b";
}
if (Page.IsPostBack) { return; }

The issue:

The value of studentsList.Count is lagging behind by a postback. If after the loop it should be 1, it only has the value of 1 at the next postback. I've debugged to confirm this is the case.


问:
How to add external js file in angular 6 library
I am creating an angular library (version 6) which is based on angular material for which I need to include the hammer js library.

I know that in angular 6 we can add the external js library in the angular.json under the project's configuration. But this does not work in case of above library. I tried to add the external library in the following way.

```<code>"my-library": {
  "root": "projects/my-library",
  "sourceRoot": "projects/my-library/src",
  "projectType": "library",
  "architect": {
    "build": {
      "builder": "@angular-devkit/build-ng-packagr:build",
      "options": {
        "tsConfig": "projects/my-library/tsconfig.lib.json",
        "project": "projects/my-library/ng-package.json",
        "scripts": [
          "../node_modules/hammerjs/hammer.min.js"
        ]
      }
    }
}
</code>```

But I am getting this error.

Schema validation failed with the following errors:
    Data path "" should NOT have additional properties(scripts).

Please suggest what is the correct way to add external js file in the angular library.

答:
Regarding the OP's specific example trying to add hammer.js.  Just npm install hammerjs then edit your main.ts file and add import 'hammerjs' then it will be available globally.

Also see this article.

Body:
I am creating an angular library (version 6) which is based on angular material for which I need to include the hammer js library.

I know that in angular 6 we can add the external js library in the angular.json under the project's configuration. But this does not work in case of above library. I tried to add the external library in the following way.

"my-library": {
  "root": "projects/my-library",
  "sourceRoot": "projects/my-library/src",
  "projectType": "library",
  "architect": {
    "build": {
      "builder": "@angular-devkit/build-ng-packagr:build",
      "options": {
        "tsConfig": "projects/my-library/tsconfig.lib.json",
        "project": "projects/my-library/ng-package.json",
        "scripts": [
          "../node_modules/hammerjs/hammer.min.js"
        ]
      }
    }
}

But I am getting this error.

Schema validation failed with the following errors:
    Data path "" should NOT have additional properties(scripts).

Please suggest what is the correct way to add external js file in the angular library.