mirror of
https://github.com/humhub/humhub.git
synced 2025-01-17 14:18:27 +01:00
Rework Directory (#5057)
Co-authored-by: Lucas Bartholemy <lucas@bartholemy.com>
This commit is contained in:
parent
95be120d81
commit
afc8e51f0c
157
composer.lock
generated
157
composer.lock
generated
@ -53,7 +53,7 @@
|
|||||||
"version": "3.5.1",
|
"version": "3.5.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/jquery/jquery-dist.git",
|
"url": "git@github.com:jquery/jquery-dist.git",
|
||||||
"reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215"
|
"reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
@ -561,16 +561,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "firebase/php-jwt",
|
"name": "firebase/php-jwt",
|
||||||
"version": "v5.2.1",
|
"version": "v5.3.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/firebase/php-jwt.git",
|
"url": "https://github.com/firebase/php-jwt.git",
|
||||||
"reference": "f42c9110abe98dd6cfe9053c49bc86acc70b2d23"
|
"reference": "3c2d70f2e64e2922345e89f2ceae47d2463faae1"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/f42c9110abe98dd6cfe9053c49bc86acc70b2d23",
|
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/3c2d70f2e64e2922345e89f2ceae47d2463faae1",
|
||||||
"reference": "f42c9110abe98dd6cfe9053c49bc86acc70b2d23",
|
"reference": "3c2d70f2e64e2922345e89f2ceae47d2463faae1",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -609,9 +609,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||||
"source": "https://github.com/firebase/php-jwt/tree/v5.2.1"
|
"source": "https://github.com/firebase/php-jwt/tree/v5.3.0"
|
||||||
},
|
},
|
||||||
"time": "2021-02-12T00:02:00+00:00"
|
"time": "2021-05-20T17:37:02+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "imagine/imagine",
|
"name": "imagine/imagine",
|
||||||
@ -2671,16 +2671,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "markbaker/complex",
|
"name": "markbaker/complex",
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||||
"reference": "d18272926d58065140314c01e18ec3dd7ae854ea"
|
"reference": "6f724d7e04606fd8adaa4e3bb381c3e9db09c946"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/d18272926d58065140314c01e18ec3dd7ae854ea",
|
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/6f724d7e04606fd8adaa4e3bb381c3e9db09c946",
|
||||||
"reference": "d18272926d58065140314c01e18ec3dd7ae854ea",
|
"reference": "6f724d7e04606fd8adaa4e3bb381c3e9db09c946",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2760,9 +2760,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
||||||
"source": "https://github.com/MarkBaker/PHPComplex/tree/2.0.2"
|
"source": "https://github.com/MarkBaker/PHPComplex/tree/2.0.3"
|
||||||
},
|
},
|
||||||
"time": "2021-05-24T10:53:30+00:00"
|
"time": "2021-06-02T09:44:11+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "markbaker/matrix",
|
"name": "markbaker/matrix",
|
||||||
@ -4013,16 +4013,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpoffice/phpspreadsheet",
|
"name": "phpoffice/phpspreadsheet",
|
||||||
"version": "1.17.1",
|
"version": "1.18.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||||
"reference": "c55269cb06911575a126dc225a05c0e4626e5fb4"
|
"reference": "418cd304e8e6b417ea79c3b29126a25dc4b1170c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/c55269cb06911575a126dc225a05c0e4626e5fb4",
|
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/418cd304e8e6b417ea79c3b29126a25dc4b1170c",
|
||||||
"reference": "c55269cb06911575a126dc225a05c0e4626e5fb4",
|
"reference": "418cd304e8e6b417ea79c3b29126a25dc4b1170c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -4041,20 +4041,23 @@
|
|||||||
"ext-zlib": "*",
|
"ext-zlib": "*",
|
||||||
"ezyang/htmlpurifier": "^4.13",
|
"ezyang/htmlpurifier": "^4.13",
|
||||||
"maennchen/zipstream-php": "^2.1",
|
"maennchen/zipstream-php": "^2.1",
|
||||||
"markbaker/complex": "^1.5||^2.0",
|
"markbaker/complex": "^2.0",
|
||||||
"markbaker/matrix": "^1.2||^2.0",
|
"markbaker/matrix": "^2.0",
|
||||||
"php": "^7.2||^8.0",
|
"php": "^7.2 || ^8.0",
|
||||||
"psr/http-client": "^1.0",
|
"psr/http-client": "^1.0",
|
||||||
"psr/http-factory": "^1.0",
|
"psr/http-factory": "^1.0",
|
||||||
"psr/simple-cache": "^1.0"
|
"psr/simple-cache": "^1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"dompdf/dompdf": "^0.8.5",
|
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||||
|
"dompdf/dompdf": "^1.0",
|
||||||
"friendsofphp/php-cs-fixer": "^2.18",
|
"friendsofphp/php-cs-fixer": "^2.18",
|
||||||
"jpgraph/jpgraph": "^4.0",
|
"jpgraph/jpgraph": "^4.0",
|
||||||
"mpdf/mpdf": "^8.0",
|
"mpdf/mpdf": "^8.0",
|
||||||
"phpcompatibility/php-compatibility": "^9.3",
|
"phpcompatibility/php-compatibility": "^9.3",
|
||||||
"phpunit/phpunit": "^8.5||^9.3",
|
"phpstan/phpstan": "^0.12.82",
|
||||||
|
"phpstan/phpstan-phpunit": "^0.12.18",
|
||||||
|
"phpunit/phpunit": "^8.5",
|
||||||
"squizlabs/php_codesniffer": "^3.5",
|
"squizlabs/php_codesniffer": "^3.5",
|
||||||
"tecnickcom/tcpdf": "^6.3"
|
"tecnickcom/tcpdf": "^6.3"
|
||||||
},
|
},
|
||||||
@ -4108,9 +4111,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.17.1"
|
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.18.0"
|
||||||
},
|
},
|
||||||
"time": "2021-03-02T17:54:11+00:00"
|
"time": "2021-05-31T18:21:15+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpspec/prophecy",
|
"name": "phpspec/prophecy",
|
||||||
@ -4478,16 +4481,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "8.5.15",
|
"version": "8.5.16",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "038d4196d8e8cb405cd5e82cedfe413ad6eef9ef"
|
"reference": "cc66f2fc61296be66c99931a862200e7456b9a01"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/038d4196d8e8cb405cd5e82cedfe413ad6eef9ef",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/cc66f2fc61296be66c99931a862200e7456b9a01",
|
||||||
"reference": "038d4196d8e8cb405cd5e82cedfe413ad6eef9ef",
|
"reference": "cc66f2fc61296be66c99931a862200e7456b9a01",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -4559,7 +4562,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.15"
|
"source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.16"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -4571,7 +4574,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-03-17T07:27:54+00:00"
|
"time": "2021-06-05T04:46:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
@ -5936,16 +5939,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v4.4.22",
|
"version": "v4.4.25",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/process.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "f5481b22729d465acb1cea3455fc04ce84b0148b"
|
"reference": "cd61e6dd273975c6625316de9d141ebd197f93c9"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/process/zipball/f5481b22729d465acb1cea3455fc04ce84b0148b",
|
"url": "https://api.github.com/repos/symfony/process/zipball/cd61e6dd273975c6625316de9d141ebd197f93c9",
|
||||||
"reference": "f5481b22729d465acb1cea3455fc04ce84b0148b",
|
"reference": "cd61e6dd273975c6625316de9d141ebd197f93c9",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -5977,7 +5980,7 @@
|
|||||||
"description": "Executes commands in sub-processes",
|
"description": "Executes commands in sub-processes",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/process/tree/v4.4.22"
|
"source": "https://github.com/symfony/process/tree/v4.4.25"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -5993,7 +5996,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-04-07T16:22:29+00:00"
|
"time": "2021-05-26T11:20:16+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "theseer/tokenizer",
|
"name": "theseer/tokenizer",
|
||||||
@ -8714,16 +8717,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "softcreatr/jsonpath",
|
"name": "softcreatr/jsonpath",
|
||||||
"version": "0.7.4",
|
"version": "0.7.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/SoftCreatR/JSONPath.git",
|
"url": "https://github.com/SoftCreatR/JSONPath.git",
|
||||||
"reference": "e01ff3eae8d0b94648354cb02b614968e83d56a2"
|
"reference": "008569bf80aa3584834f7890781576bc7b65afa7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/SoftCreatR/JSONPath/zipball/e01ff3eae8d0b94648354cb02b614968e83d56a2",
|
"url": "https://api.github.com/repos/SoftCreatR/JSONPath/zipball/008569bf80aa3584834f7890781576bc7b65afa7",
|
||||||
"reference": "e01ff3eae8d0b94648354cb02b614968e83d56a2",
|
"reference": "008569bf80aa3584834f7890781576bc7b65afa7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -8775,7 +8778,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-05-07T14:31:33+00:00"
|
"time": "2021-06-02T22:15:26+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "squizlabs/php_codesniffer",
|
"name": "squizlabs/php_codesniffer",
|
||||||
@ -8895,16 +8898,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v4.4.24",
|
"version": "v4.4.25",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "1b15ca1b1bedda86f98064da9ff5d800560d4c6d"
|
"reference": "a62acecdf5b50e314a4f305cd01b5282126f3095"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/1b15ca1b1bedda86f98064da9ff5d800560d4c6d",
|
"url": "https://api.github.com/repos/symfony/console/zipball/a62acecdf5b50e314a4f305cd01b5282126f3095",
|
||||||
"reference": "1b15ca1b1bedda86f98064da9ff5d800560d4c6d",
|
"reference": "a62acecdf5b50e314a4f305cd01b5282126f3095",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -8964,7 +8967,7 @@
|
|||||||
"description": "Eases the creation of beautiful and testable command line interfaces",
|
"description": "Eases the creation of beautiful and testable command line interfaces",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/console/tree/v4.4.24"
|
"source": "https://github.com/symfony/console/tree/v4.4.25"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -8980,20 +8983,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-05-13T06:28:07+00:00"
|
"time": "2021-05-26T11:20:16+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/css-selector",
|
"name": "symfony/css-selector",
|
||||||
"version": "v4.4.24",
|
"version": "v4.4.25",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/css-selector.git",
|
"url": "https://github.com/symfony/css-selector.git",
|
||||||
"reference": "947cacaf1b3a2af6f13a435392873d5ddaba5f70"
|
"reference": "c1e29de6dc893b130b45d20d8051efbb040560a9"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/947cacaf1b3a2af6f13a435392873d5ddaba5f70",
|
"url": "https://api.github.com/repos/symfony/css-selector/zipball/c1e29de6dc893b130b45d20d8051efbb040560a9",
|
||||||
"reference": "947cacaf1b3a2af6f13a435392873d5ddaba5f70",
|
"reference": "c1e29de6dc893b130b45d20d8051efbb040560a9",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -9029,7 +9032,7 @@
|
|||||||
"description": "Converts CSS selectors to XPath expressions",
|
"description": "Converts CSS selectors to XPath expressions",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/css-selector/tree/v4.4.24"
|
"source": "https://github.com/symfony/css-selector/tree/v4.4.25"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -9045,7 +9048,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-05-16T09:52:47+00:00"
|
"time": "2021-05-26T17:39:37+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
@ -9116,16 +9119,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/dom-crawler",
|
"name": "symfony/dom-crawler",
|
||||||
"version": "v4.4.24",
|
"version": "v4.4.25",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/dom-crawler.git",
|
"url": "https://github.com/symfony/dom-crawler.git",
|
||||||
"reference": "fc0bd1f215b0cd9f4efdc63bb66808f3417331bc"
|
"reference": "41d15bb6d6b95d2be763c514bb2494215d9c5eef"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/fc0bd1f215b0cd9f4efdc63bb66808f3417331bc",
|
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/41d15bb6d6b95d2be763c514bb2494215d9c5eef",
|
||||||
"reference": "fc0bd1f215b0cd9f4efdc63bb66808f3417331bc",
|
"reference": "41d15bb6d6b95d2be763c514bb2494215d9c5eef",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -9169,7 +9172,7 @@
|
|||||||
"description": "Eases DOM navigation for HTML and XML documents",
|
"description": "Eases DOM navigation for HTML and XML documents",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/dom-crawler/tree/v4.4.24"
|
"source": "https://github.com/symfony/dom-crawler/tree/v4.4.25"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -9185,20 +9188,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-05-16T09:52:47+00:00"
|
"time": "2021-05-26T11:20:16+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher",
|
"name": "symfony/event-dispatcher",
|
||||||
"version": "v4.4.20",
|
"version": "v4.4.25",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||||
"reference": "c352647244bd376bf7d31efbd5401f13f50dad0c"
|
"reference": "047773e7016e4fd45102cedf4bd2558ae0d0c32f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c352647244bd376bf7d31efbd5401f13f50dad0c",
|
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/047773e7016e4fd45102cedf4bd2558ae0d0c32f",
|
||||||
"reference": "c352647244bd376bf7d31efbd5401f13f50dad0c",
|
"reference": "047773e7016e4fd45102cedf4bd2558ae0d0c32f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -9252,7 +9255,7 @@
|
|||||||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/event-dispatcher/tree/v4.4.20"
|
"source": "https://github.com/symfony/event-dispatcher/tree/v4.4.25"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -9268,7 +9271,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-01-27T09:09:26+00:00"
|
"time": "2021-05-26T17:39:37+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher-contracts",
|
"name": "symfony/event-dispatcher-contracts",
|
||||||
@ -9351,16 +9354,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/finder",
|
"name": "symfony/finder",
|
||||||
"version": "v4.4.24",
|
"version": "v4.4.25",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/finder.git",
|
"url": "https://github.com/symfony/finder.git",
|
||||||
"reference": "a96bc19ed87c88eec78e1a4c803bdc1446952983"
|
"reference": "ed33314396d968a8936c95f5bd1b88bd3b3e94a3"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/finder/zipball/a96bc19ed87c88eec78e1a4c803bdc1446952983",
|
"url": "https://api.github.com/repos/symfony/finder/zipball/ed33314396d968a8936c95f5bd1b88bd3b3e94a3",
|
||||||
"reference": "a96bc19ed87c88eec78e1a4c803bdc1446952983",
|
"reference": "ed33314396d968a8936c95f5bd1b88bd3b3e94a3",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -9392,7 +9395,7 @@
|
|||||||
"description": "Finds files and directories via an intuitive fluent interface",
|
"description": "Finds files and directories via an intuitive fluent interface",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/finder/tree/v4.4.24"
|
"source": "https://github.com/symfony/finder/tree/v4.4.25"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -9408,7 +9411,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-05-16T12:27:45+00:00"
|
"time": "2021-05-26T11:20:16+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php73",
|
"name": "symfony/polyfill-php73",
|
||||||
@ -9653,16 +9656,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/yaml",
|
"name": "symfony/yaml",
|
||||||
"version": "v4.4.24",
|
"version": "v4.4.25",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/yaml.git",
|
"url": "https://github.com/symfony/yaml.git",
|
||||||
"reference": "8b6d1b97521e2f125039b3fcb4747584c6dfa0ef"
|
"reference": "81cdac5536925c1c4b7b50aabc9ff6330b9eb5fc"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/8b6d1b97521e2f125039b3fcb4747584c6dfa0ef",
|
"url": "https://api.github.com/repos/symfony/yaml/zipball/81cdac5536925c1c4b7b50aabc9ff6330b9eb5fc",
|
||||||
"reference": "8b6d1b97521e2f125039b3fcb4747584c6dfa0ef",
|
"reference": "81cdac5536925c1c4b7b50aabc9ff6330b9eb5fc",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -9704,7 +9707,7 @@
|
|||||||
"description": "Loads and dumps YAML files",
|
"description": "Loads and dumps YAML files",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/yaml/tree/v4.4.24"
|
"source": "https://github.com/symfony/yaml/tree/v4.4.25"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -9720,7 +9723,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-05-16T09:52:47+00:00"
|
"time": "2021-05-26T17:39:37+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "yiisoft/yii2-debug",
|
"name": "yiisoft/yii2-debug",
|
||||||
|
27
protected/humhub/assets/DirectoryAsset.php
Normal file
27
protected/humhub/assets/DirectoryAsset.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\assets;
|
||||||
|
|
||||||
|
use humhub\components\assets\WebStaticAssetBundle;
|
||||||
|
use yii\web\View;
|
||||||
|
|
||||||
|
class DirectoryAsset extends WebStaticAssetBundle
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $js = [
|
||||||
|
'js/humhub/humhub.directory.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $jsOptions = ['position' => View::POS_END];
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\admin\controllers;
|
||||||
|
|
||||||
|
use humhub\modules\admin\components\Controller;
|
||||||
|
use humhub\modules\admin\models\forms\PeopleSettingsForm;
|
||||||
|
use humhub\modules\admin\permissions\ManageSettings;
|
||||||
|
use Yii;
|
||||||
|
use yii\web\HttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User People Configuration
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
class UserPeopleController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $adminOnly = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
$this->appendPageTitle(Yii::t('AdminModule.base', 'People'));
|
||||||
|
$this->subLayout = '@admin/views/layouts/user';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getAccessRules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['permissions' => [ManageSettings::class]]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration for People page
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws HttpException
|
||||||
|
*/
|
||||||
|
public function actionIndex()
|
||||||
|
{
|
||||||
|
$form = new PeopleSettingsForm();
|
||||||
|
|
||||||
|
if ($form->load(Yii::$app->request->post()) && $form->validate() && $form->save()) {
|
||||||
|
$this->view->saved();
|
||||||
|
return $this->redirect(['/admin/user-people']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('index', [
|
||||||
|
'model' => $form,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\admin\models\forms;
|
||||||
|
|
||||||
|
use humhub\modules\user\models\ProfileField;
|
||||||
|
use humhub\modules\user\models\ProfileFieldCategory;
|
||||||
|
use Yii;
|
||||||
|
use humhub\libs\DynamicConfig;
|
||||||
|
use yii\base\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleSettingsForm
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
class PeopleSettingsForm extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
public $detail1;
|
||||||
|
public $detail2;
|
||||||
|
public $detail3;
|
||||||
|
public $defaultSorting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Cached options for card details from tables of user profile and its categories
|
||||||
|
*/
|
||||||
|
private $detailOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
// Set default values
|
||||||
|
$this->detail1 = Yii::$app->settings->get('people.detail1', '');
|
||||||
|
$this->detail2 = Yii::$app->settings->get('people.detail2', '');
|
||||||
|
$this->detail3 = Yii::$app->settings->get('people.detail3', '');
|
||||||
|
$this->defaultSorting = Yii::$app->settings->get('people.defaultSorting', 'lastlogin');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['detail1', 'in', 'range' => $this->getDetailKeys()],
|
||||||
|
['detail2', 'in', 'range' => $this->getDetailKeys()],
|
||||||
|
['detail3', 'in', 'range' => $this->getDetailKeys()],
|
||||||
|
['defaultSorting', 'in', 'range' => array_keys(self::getSortingOptions())],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'detail1' => Yii::t('AdminModule.user', 'Information 1'),
|
||||||
|
'detail2' => Yii::t('AdminModule.user', 'Information 2'),
|
||||||
|
'detail3' => Yii::t('AdminModule.user', 'Information 3'),
|
||||||
|
'defaultSorting' => Yii::t('AdminModule.user', 'Default Sorting'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the form
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
Yii::$app->settings->set('people.detail1', $this->detail1);
|
||||||
|
Yii::$app->settings->set('people.detail2', $this->detail2);
|
||||||
|
Yii::$app->settings->set('people.detail3', $this->detail3);
|
||||||
|
Yii::$app->settings->set('people.defaultSorting', $this->defaultSorting);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDetailOptions(): array
|
||||||
|
{
|
||||||
|
if (isset($this->detailOptions)) {
|
||||||
|
return $this->detailOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->detailOptions = ['' => Yii::t('AdminModule.user', 'None')];
|
||||||
|
|
||||||
|
$profileFields = ProfileField::find()
|
||||||
|
->leftJoin('profile_field_category', 'profile_field_category.id = profile_field_category_id')
|
||||||
|
->orderBy('profile_field_category.sort_order, profile_field.sort_order')
|
||||||
|
->all();
|
||||||
|
foreach ($profileFields as $profileField) {
|
||||||
|
/* @var $profileField ProfileField */
|
||||||
|
/* @var $profileFieldCategory ProfileFieldCategory */
|
||||||
|
$profileFieldCategory = $profileField->getCategory()->one();
|
||||||
|
|
||||||
|
if (!isset($this->detailOptions[$profileFieldCategory->title])) {
|
||||||
|
$this->detailOptions[$profileFieldCategory->title] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->detailOptions[$profileFieldCategory->title][$profileField->internal_name] = $profileField->title . ($profileField->visible ? '' : ' (' . Yii::t('AdminModule.user', 'Not visible') . ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->detailOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getDetailKeys(): array
|
||||||
|
{
|
||||||
|
$keys = [];
|
||||||
|
$options = self::getDetailOptions();
|
||||||
|
|
||||||
|
foreach ($options as $key => $option) {
|
||||||
|
if (is_array($option)) {
|
||||||
|
$keys = array_merge($keys, array_keys($option));
|
||||||
|
} else {
|
||||||
|
$keys[] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getSortingOptions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'firstname' => Yii::t('AdminModule.user', 'First name'),
|
||||||
|
'lastname' => Yii::t('AdminModule.user', 'Last name'),
|
||||||
|
'lastlogin' => Yii::t('AdminModule.user', 'Last login'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,7 +20,7 @@ class MaintenanceModeCest
|
|||||||
$I->amGoingTo('try to login with correct credentials');
|
$I->amGoingTo('try to login with correct credentials');
|
||||||
$loginPage->login('Admin', 'test');
|
$loginPage->login('Admin', 'test');
|
||||||
$I->expectTo('see dashboard');
|
$I->expectTo('see dashboard');
|
||||||
$I->waitForText('DIRECTORY');
|
$I->waitForText('DASHBOARD');
|
||||||
$I->dontSee('Administration');
|
$I->dontSee('Administration');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
protected/humhub/modules/admin/views/user-people/index.php
Normal file
36
protected/humhub/modules/admin/views/user-people/index.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use humhub\modules\admin\models\forms\PeopleSettingsForm;
|
||||||
|
use humhub\modules\ui\form\widgets\ActiveForm;
|
||||||
|
use humhub\widgets\Button;
|
||||||
|
|
||||||
|
/* @var $model PeopleSettingsForm */
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
<h4><?= Yii::t('AdminModule.user', 'People'); ?></h4>
|
||||||
|
<div class="help-block">
|
||||||
|
<?= Yii::t('AdminModule.user', 'Select which user information should be displayed in the \'People\' overview. You can select any profile fields, even those you have created individually. '); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<?php $form = ActiveForm::begin(); ?>
|
||||||
|
|
||||||
|
<?= $form->field($model, 'detail1')->dropDownList($model->getDetailOptions()); ?>
|
||||||
|
<?= $form->field($model, 'detail2')->dropDownList($model->getDetailOptions()); ?>
|
||||||
|
<?= $form->field($model, 'detail3')->dropDownList($model->getDetailOptions()); ?>
|
||||||
|
|
||||||
|
<?= $form->field($model, 'defaultSorting')->dropDownList(PeopleSettingsForm::getSortingOptions()); ?>
|
||||||
|
|
||||||
|
<?= Button::save(Yii::t('AdminModule.user', 'Save'))->submit(); ?>
|
||||||
|
|
||||||
|
<?php ActiveForm::end(); ?>
|
||||||
|
</div>
|
@ -67,7 +67,7 @@ class AdminMenu extends LeftNavigation
|
|||||||
'url' => ['/admin/user'],
|
'url' => ['/admin/user'],
|
||||||
'icon' => 'user',
|
'icon' => 'user',
|
||||||
'sortOrder' => 200,
|
'sortOrder' => 200,
|
||||||
'isActive' => MenuLink::isActiveState('admin', ['user', 'group', 'approval', 'authentication', 'user-profile', 'pending-registrations', 'user-permissions']) ||
|
'isActive' => MenuLink::isActiveState('admin', ['user', 'group', 'approval', 'authentication', 'user-profile', 'pending-registrations', 'user-permissions', 'user-people']) ||
|
||||||
MenuLink::isActiveState('ldap', 'admin'),
|
MenuLink::isActiveState('ldap', 'admin'),
|
||||||
'isVisible' => Yii::$app->user->can([
|
'isVisible' => Yii::$app->user->can([
|
||||||
ManageUsers::class,
|
ManageUsers::class,
|
||||||
|
@ -80,6 +80,14 @@ class UserMenu extends TabMenu
|
|||||||
'isVisible' => Yii::$app->user->can(ManageGroups::class)
|
'isVisible' => Yii::$app->user->can(ManageGroups::class)
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
$this->addEntry(new MenuLink([
|
||||||
|
'label' => Yii::t('AdminModule.user', 'People'),
|
||||||
|
'url' => ['/admin/user-people'],
|
||||||
|
'sortOrder' => 600,
|
||||||
|
'isActive' => MenuLink::isActiveState('admin', 'user-people'),
|
||||||
|
'isVisible' => Yii::$app->user->can(ManageSettings::class)
|
||||||
|
]));
|
||||||
|
|
||||||
|
|
||||||
parent::init();
|
parent::init();
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,23 @@ humhub.module('content.container', function (module, require, $) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var relationship = function(evt) {
|
||||||
|
var postOptions = {};
|
||||||
|
var buttonOptions = evt.$trigger.data('button-options');
|
||||||
|
if (buttonOptions) {
|
||||||
|
postOptions.data = {options: buttonOptions};
|
||||||
|
}
|
||||||
|
client.post(evt, postOptions).then(function(response) {
|
||||||
|
var oldButton = evt.$trigger;
|
||||||
|
if (oldButton.closest('.btn-group').length) {
|
||||||
|
oldButton = oldButton.closest('.btn-group');
|
||||||
|
}
|
||||||
|
oldButton.replaceWith(response.data);
|
||||||
|
}).catch(function(e) {
|
||||||
|
module.log.error(e, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var enableModule = function (evt) {
|
var enableModule = function (evt) {
|
||||||
client.post(evt).then(function (response) {
|
client.post(evt).then(function (response) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@ -79,6 +96,7 @@ humhub.module('content.container', function (module, require, $) {
|
|||||||
module.export({
|
module.export({
|
||||||
follow: follow,
|
follow: follow,
|
||||||
unfollow: unfollow,
|
unfollow: unfollow,
|
||||||
|
relationship: relationship,
|
||||||
unload: unload,
|
unload: unload,
|
||||||
guid: guid,
|
guid: guid,
|
||||||
enableModule: enableModule,
|
enableModule: enableModule,
|
||||||
|
@ -10,7 +10,6 @@ namespace humhub\modules\directory;
|
|||||||
|
|
||||||
use humhub\modules\ui\menu\MenuLink;
|
use humhub\modules\ui\menu\MenuLink;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\helpers\Url;
|
|
||||||
use humhub\modules\user\models\Group;
|
use humhub\modules\user\models\Group;
|
||||||
use humhub\modules\directory\permissions\AccessDirectory;
|
use humhub\modules\directory\permissions\AccessDirectory;
|
||||||
|
|
||||||
@ -22,6 +21,7 @@ use humhub\modules\directory\permissions\AccessDirectory;
|
|||||||
*
|
*
|
||||||
* @package humhub.modules_core.directory
|
* @package humhub.modules_core.directory
|
||||||
* @since 0.5
|
* @since 0.5
|
||||||
|
* @deprecated since 1.9 but it can be activated temporary by console command `php yii directory/activate`
|
||||||
*/
|
*/
|
||||||
class Module extends \humhub\components\Module
|
class Module extends \humhub\components\Module
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ class Module extends \humhub\components\Module
|
|||||||
/**
|
/**
|
||||||
* @var bool defines if the directory is active, if not the directory is not visible and can't be accessed
|
* @var bool defines if the directory is active, if not the directory is not visible and can't be accessed
|
||||||
*/
|
*/
|
||||||
public $active = true;
|
public $active = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool defines if the directory is available for guest users, this flag will only have effect if guest access is allowed and the module is active
|
* @var bool defines if the directory is available for guest users, this flag will only have effect if guest access is allowed and the module is active
|
||||||
@ -56,6 +56,15 @@ class Module extends \humhub\components\Module
|
|||||||
*/
|
*/
|
||||||
public $showUserProfilePosts = true;
|
public $showUserProfilePosts = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inerhitdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
$this->active = $this->settings->get('isActive', false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool checks if the current user can access the directory
|
* @return bool checks if the current user can access the directory
|
||||||
@ -101,7 +110,7 @@ class Module extends \humhub\components\Module
|
|||||||
*/
|
*/
|
||||||
public function getPermissions($contentContainer = null)
|
public function getPermissions($contentContainer = null)
|
||||||
{
|
{
|
||||||
if (!$contentContainer) {
|
if ($this->active && !$contentContainer) {
|
||||||
return [
|
return [
|
||||||
new AccessDirectory(),
|
new AccessDirectory(),
|
||||||
];
|
];
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\directory\commands;
|
||||||
|
|
||||||
|
use humhub\components\SettingsManager;
|
||||||
|
use humhub\modules\directory\Module;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Management of activity of the deprecated module "Directory"
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
class DirectoryController extends \yii\console\Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate the deprecated module "Directory"
|
||||||
|
*/
|
||||||
|
public function actionActivate()
|
||||||
|
{
|
||||||
|
$this->getModuleSettings()->set('isActive', true);
|
||||||
|
$this->stdout('Module "Directory" is activated.' . "\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivate the deprecated module "Directory"
|
||||||
|
*/
|
||||||
|
public function actionDeactivate()
|
||||||
|
{
|
||||||
|
$this->getModuleSettings()->delete('isActive');
|
||||||
|
$this->stdout('Module "Directory" is deactivated.' . "\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getModuleSettings(): SettingsManager
|
||||||
|
{
|
||||||
|
/* @var Module $module */
|
||||||
|
$module = Yii::$app->getModule('directory');
|
||||||
|
return $module->settings;
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ return [
|
|||||||
'id' => 'directory',
|
'id' => 'directory',
|
||||||
'class' => Module::class,
|
'class' => Module::class,
|
||||||
'isCoreModule' => true,
|
'isCoreModule' => true,
|
||||||
|
'consoleControllerMap' => ['directory' => 'humhub\modules\directory\commands\DirectoryController'],
|
||||||
'events' => [
|
'events' => [
|
||||||
['class' => TopMenu::class, 'event' => TopMenu::EVENT_INIT, 'callback' => [Module::class, 'onTopMenuInit']],
|
['class' => TopMenu::class, 'event' => TopMenu::EVENT_INIT, 'callback' => [Module::class, 'onTopMenuInit']],
|
||||||
],
|
],
|
||||||
|
@ -11,6 +11,7 @@ namespace humhub\modules\friendship\controllers;
|
|||||||
use humhub\components\Controller;
|
use humhub\components\Controller;
|
||||||
use humhub\modules\friendship\models\Friendship;
|
use humhub\modules\friendship\models\Friendship;
|
||||||
use humhub\modules\friendship\Module;
|
use humhub\modules\friendship\Module;
|
||||||
|
use humhub\modules\friendship\widgets\FriendshipButton;
|
||||||
use humhub\modules\user\models\User;
|
use humhub\modules\user\models\User;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\web\HttpException;
|
use yii\web\HttpException;
|
||||||
@ -44,17 +45,11 @@ class RequestController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function actionAdd()
|
public function actionAdd()
|
||||||
{
|
{
|
||||||
$this->forcePostRequest();
|
$friend = $this->getFriendUser();
|
||||||
|
|
||||||
$friend = User::findOne(['id' => Yii::$app->request->get('userId')]);
|
|
||||||
|
|
||||||
if ($friend === null) {
|
|
||||||
throw new HttpException(404, 'User not found!');
|
|
||||||
}
|
|
||||||
|
|
||||||
Friendship::add(Yii::$app->user->getIdentity(), $friend);
|
Friendship::add(Yii::$app->user->getIdentity(), $friend);
|
||||||
|
|
||||||
return $this->redirect($friend->getUrl());
|
return $this->getActionResult($friend);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,6 +57,21 @@ class RequestController extends Controller
|
|||||||
* @throws HttpException
|
* @throws HttpException
|
||||||
*/
|
*/
|
||||||
public function actionDelete()
|
public function actionDelete()
|
||||||
|
{
|
||||||
|
$friend = $this->getFriendUser();
|
||||||
|
|
||||||
|
Friendship::cancel(Yii::$app->user->getIdentity(), $friend);
|
||||||
|
|
||||||
|
return $this->getActionResult($friend);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get friend User from request
|
||||||
|
*
|
||||||
|
* @return User
|
||||||
|
* @throws HttpException
|
||||||
|
*/
|
||||||
|
protected function getFriendUser(): User
|
||||||
{
|
{
|
||||||
$this->forcePostRequest();
|
$this->forcePostRequest();
|
||||||
|
|
||||||
@ -71,9 +81,26 @@ class RequestController extends Controller
|
|||||||
throw new HttpException(404, 'User not found!');
|
throw new HttpException(404, 'User not found!');
|
||||||
}
|
}
|
||||||
|
|
||||||
Friendship::cancel(Yii::$app->user->getIdentity(), $friend);
|
return $friend;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->redirect($friend->getUrl());
|
/**
|
||||||
|
* Get result for the friendship actions
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @return string|\yii\console\Response|\yii\web\Response
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
protected function getActionResult(User $user)
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax) {
|
||||||
|
return FriendshipButton::widget([
|
||||||
|
'user' => $user,
|
||||||
|
'options' => $this->request->post('options', []),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->redirect($this->request->getReferrer());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,12 @@
|
|||||||
|
|
||||||
namespace humhub\modules\friendship\widgets;
|
namespace humhub\modules\friendship\widgets;
|
||||||
|
|
||||||
use Yii;
|
|
||||||
use humhub\modules\friendship\models\Friendship;
|
use humhub\modules\friendship\models\Friendship;
|
||||||
|
use humhub\modules\user\models\User;
|
||||||
|
use Yii;
|
||||||
|
use yii\helpers\ArrayHelper;
|
||||||
|
use yii\helpers\Json;
|
||||||
|
use yii\helpers\Url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a membership button between the current and given user.
|
* Displays a membership button between the current and given user.
|
||||||
@ -20,10 +24,90 @@ class FriendshipButton extends \yii\base\Widget
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var User the target user
|
* @var User the target user
|
||||||
*/
|
*/
|
||||||
public $user;
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Options buttons
|
||||||
|
*/
|
||||||
|
public $options = [];
|
||||||
|
|
||||||
|
private function getDefaultOptions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'friends' => [
|
||||||
|
'title' => '<span class="glyphicon glyphicon-ok"></span> ' . Yii::t('FriendshipModule.base', 'Friends'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => Url::to(['/friendship/request/delete', 'userId' => $this->user->id]),
|
||||||
|
'data-action-confirm' => Yii::t('FriendshipModule.base', 'Would you like to end your friendship with {userName}?', ['{userName}' => '<strong>' . $this->user->getDisplayName() . '</strong>']),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
'class' => 'btn btn-info active',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'addFriend' => [
|
||||||
|
'title' => '<span class="glyphicon glyphicon-plus"></span> ' . Yii::t('FriendshipModule.base', 'Friends'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => Url::to(['/friendship/request/add', 'userId' => $this->user->id]),
|
||||||
|
'data-action-confirm' => Yii::t('FriendshipModule.base', 'Would you like to send a friendship request to {userName}?', ['{userName}' => '<strong>' . $this->user->getDisplayName() . '</strong>']),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
'class' => 'btn btn-info',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'acceptFriendRequest' => [
|
||||||
|
'title' => '<span class="glyphicon glyphicon-time"></span> ' . Yii::t('FriendshipModule.base', 'Accept Friend Request'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => Url::to(['/friendship/request/add', 'userId' => $this->user->id]),
|
||||||
|
'data-action-confirm' => Yii::t('FriendshipModule.base', 'Would you like to accept the friendship request?'),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
'class' => 'btn btn-info active',
|
||||||
|
],
|
||||||
|
'groupClass' => 'btn-group',
|
||||||
|
'togglerClass' => 'btn btn-info active',
|
||||||
|
],
|
||||||
|
'denyFriendRequest' => [
|
||||||
|
'title' => '<span class="fa fa-times"></span> ' . Yii::t('FriendshipModule.base', 'Deny friend request'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => Url::to(['/friendship/request/delete', 'userId' => $this->user->id]),
|
||||||
|
'data-action-confirm' => Yii::t('FriendshipModule.base', 'Would you like to withdraw the friendship request?'),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'cancelFriendRequest' => [
|
||||||
|
'title' => '<span class="glyphicon glyphicon-time"></span> ' . Yii::t('FriendshipModule.base', 'Pending'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => Url::to(['/friendship/request/delete', 'userId' => $this->user->id]),
|
||||||
|
'data-action-confirm' => Yii::t('FriendshipModule.base', 'Would you like to withdraw your friendship request?'),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
'class' => 'btn btn-info active',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDefaultOptions(array $defaultOptions)
|
||||||
|
{
|
||||||
|
$this->options = $this->getOptions($defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOptions(array $defaultOptions = null): array
|
||||||
|
{
|
||||||
|
if ($defaultOptions === null) {
|
||||||
|
$defaultOptions = $this->getDefaultOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ArrayHelper::merge($defaultOptions, $this->options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
@ -34,13 +118,14 @@ class FriendshipButton extends \yii\base\Widget
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do not display a buttton if user is it self or guest
|
// Do not display a buttton if user is it self or guest
|
||||||
if ($this->user->isCurrentUser() || \Yii::$app->user->isGuest) {
|
if ($this->user->isCurrentUser() || Yii::$app->user->isGuest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('friendshipButton', [
|
return $this->render('friendshipButton', [
|
||||||
'user' => $this->user,
|
'user' => $this->user,
|
||||||
'friendshipState' => Friendship::getStateForUser(Yii::$app->user->getIdentity(), $this->user)
|
'friendshipState' => Friendship::getStateForUser(Yii::$app->user->getIdentity(), $this->user),
|
||||||
|
'options' => $this->getOptions(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,36 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use yii\helpers\Html;
|
use yii\helpers\Html;
|
||||||
use yii\helpers\Url;
|
|
||||||
use humhub\modules\friendship\models\Friendship;
|
use humhub\modules\friendship\models\Friendship;
|
||||||
|
|
||||||
/* @var $user \humhub\modules\user\models\User */
|
/* @var $user \humhub\modules\user\models\User */
|
||||||
/* @var $friendshipState string */
|
/* @var $friendshipState string */
|
||||||
|
/* @var $options array */
|
||||||
?>
|
?>
|
||||||
<?php if ($friendshipState === Friendship::STATE_FRIENDS) : ?>
|
<?php if ($friendshipState === Friendship::STATE_FRIENDS) : ?>
|
||||||
<div class="btn-group">
|
<?= Html::a($options['friends']['title'], '#', $options['friends']['attrs']); ?>
|
||||||
<button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
||||||
<span class="glyphicon glyphicon-ok"></span> <?= Yii::t("FriendshipModule.base", "Friends"); ?> <span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><?= Html::a(Yii::t("FriendshipModule.base", "Unfriend"), Url::to(['/friendship/request/delete', 'userId' => $user->id]), ['data-method' => 'POST', 'data-ui-loader' => '']); ?></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<?php elseif ($friendshipState === Friendship::STATE_NONE) : ?>
|
<?php elseif ($friendshipState === Friendship::STATE_NONE) : ?>
|
||||||
<?= Html::a('<span class="glyphicon glyphicon-plus"></span> ' . Yii::t("FriendshipModule.base", "Add Friend"), Url::to(['/friendship/request/add', 'userId' => $user->id]), ['class' => 'btn btn-info', 'data-method' => 'POST', 'data-ui-loader' => '']); ?>
|
<?= Html::a($options['addFriend']['title'], '#', $options['addFriend']['attrs']); ?>
|
||||||
<?php elseif ($friendshipState === Friendship::STATE_REQUEST_RECEIVED) : ?>
|
<?php elseif ($friendshipState === Friendship::STATE_REQUEST_RECEIVED) : ?>
|
||||||
<div class="btn-group">
|
<div class="<?= $options['acceptFriendRequest']['groupClass'] ?>">
|
||||||
<?= Html::a(Yii::t("FriendshipModule.base", "Accept Friend Request"), Url::to(['/friendship/request/add', 'userId' => $user->id]), ['class' => 'btn btn-success', 'data-method' => 'POST', 'data-ui-loader' => '']); ?>
|
<?= Html::a($options['acceptFriendRequest']['title'], '#', $options['acceptFriendRequest']['attrs']); ?>
|
||||||
<button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button type="button" class="<?= $options['acceptFriendRequest']['togglerClass'] ?> dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
<span class="sr-only">Toggle Dropdown</span>
|
<span class="sr-only">Toggle Dropdown</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li>
|
<li>
|
||||||
<?= Html::a(Yii::t("FriendshipModule.base", "Deny friend request"), Url::to(['/friendship/request/delete', 'userId' => $user->id]), ['data-method' => 'POST', 'data-ui-loader' => '']); ?>
|
<?= Html::a($options['denyFriendRequest']['title'], '#', $options['denyFriendRequest']['attrs']); ?>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<?php elseif ($friendshipState === Friendship::STATE_REQUEST_SENT) : ?>
|
<?php elseif ($friendshipState === Friendship::STATE_REQUEST_SENT) : ?>
|
||||||
<?= Html::a(Yii::t("FriendshipModule.base", "Cancel friend request"), Url::to(['/friendship/request/delete', 'userId' => $user->id]), ['class' => 'btn btn-danger', 'data-method' => 'POST', 'data-ui-loader' => '']); ?>
|
<?= Html::a($options['cancelFriendRequest']['title'], '#', $options['cancelFriendRequest']['attrs']); ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
namespace humhub\modules\space;
|
namespace humhub\modules\space;
|
||||||
|
|
||||||
|
use humhub\modules\space\permissions\SpaceDirectoryAccess;
|
||||||
|
use humhub\modules\ui\menu\MenuLink;
|
||||||
use humhub\modules\user\events\UserEvent;
|
use humhub\modules\user\events\UserEvent;
|
||||||
use humhub\modules\space\models\Space;
|
use humhub\modules\space\models\Space;
|
||||||
use humhub\modules\space\models\Membership;
|
use humhub\modules\space\models\Membership;
|
||||||
@ -98,4 +100,29 @@ class Events extends BaseObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On build of the TopMenu
|
||||||
|
*
|
||||||
|
* @param Event $event
|
||||||
|
*/
|
||||||
|
public static function onTopMenuInit($event)
|
||||||
|
{
|
||||||
|
if (Yii::$app->user->isGuest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Yii::$app->user->can(SpaceDirectoryAccess::class)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$event->sender->addEntry(new MenuLink([
|
||||||
|
'id' => 'spaces',
|
||||||
|
'icon' => 'dot-circle-o',
|
||||||
|
'label' => Yii::t('SpaceModule.base', 'Spaces'),
|
||||||
|
'url' => ['/space/spaces'],
|
||||||
|
'sortOrder' => 250,
|
||||||
|
'isActive' => MenuLink::isActiveState('space', 'spaces'),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ class Module extends \humhub\components\Module
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
new permissions\SpaceDirectoryAccess(),
|
||||||
new permissions\CreatePrivateSpace(),
|
new permissions\CreatePrivateSpace(),
|
||||||
new permissions\CreatePublicSpace(),
|
new permissions\CreatePublicSpace(),
|
||||||
];
|
];
|
||||||
|
@ -0,0 +1,136 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\space\components;
|
||||||
|
|
||||||
|
use humhub\modules\space\models\Membership;
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
|
use humhub\modules\space\widgets\SpaceDirectoryFilters;
|
||||||
|
use Yii;
|
||||||
|
use yii\data\Pagination;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpaceDirectoryQuery is used to query Space records on the Spaces page.
|
||||||
|
*
|
||||||
|
* @author luke
|
||||||
|
*/
|
||||||
|
class SpaceDirectoryQuery extends ActiveQuerySpace
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Pagination
|
||||||
|
*/
|
||||||
|
public $pagination;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $pageSize = 18;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function __construct($config = [])
|
||||||
|
{
|
||||||
|
parent::__construct(Space::class, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
$this->visible();
|
||||||
|
|
||||||
|
$this->filterByKeyword();
|
||||||
|
$this->filterByConnection();
|
||||||
|
|
||||||
|
$this->order();
|
||||||
|
|
||||||
|
$this->paginate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByKeyword(): SpaceDirectoryQuery
|
||||||
|
{
|
||||||
|
$keyword = Yii::$app->request->get('keyword', '');
|
||||||
|
|
||||||
|
return $this->search($keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnection(): SpaceDirectoryQuery
|
||||||
|
{
|
||||||
|
switch (Yii::$app->request->get('connection')) {
|
||||||
|
case 'member':
|
||||||
|
return $this->filterByConnectionMember();
|
||||||
|
case 'follow':
|
||||||
|
return $this->filterByConnectionFollow();
|
||||||
|
case 'none':
|
||||||
|
return $this->filterByConnectionNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnectionMember(): SpaceDirectoryQuery
|
||||||
|
{
|
||||||
|
return $this->innerJoin('space_membership', 'space_membership.space_id = space.id')
|
||||||
|
->andWhere(['space_membership.user_id' => Yii::$app->user->id])
|
||||||
|
->andWhere(['space_membership.status' => Membership::STATUS_MEMBER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnectionFollow(): SpaceDirectoryQuery
|
||||||
|
{
|
||||||
|
return $this->innerJoin('user_follow', 'user_follow.object_model = :spaceClass AND user_follow.object_id = space.id', [':spaceClass' => Space::class])
|
||||||
|
->andWhere(['user_follow.user_id' => Yii::$app->user->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnectionNone(): SpaceDirectoryQuery
|
||||||
|
{
|
||||||
|
return $this->andWhere('space.id NOT IN (SELECT space_id FROM space_membership WHERE user_id = :userId AND status = :memberStatus)')
|
||||||
|
->andWhere('space.id NOT IN (SELECT object_id FROM user_follow WHERE user_id = :userId AND user_follow.object_model = :spaceClass)')
|
||||||
|
->addParams([
|
||||||
|
':userId' => Yii::$app->user->id,
|
||||||
|
':memberStatus' => Membership::STATUS_MEMBER,
|
||||||
|
':spaceClass' => Space::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function order(): SpaceDirectoryQuery
|
||||||
|
{
|
||||||
|
switch (SpaceDirectoryFilters::getValue('sort')) {
|
||||||
|
case 'name':
|
||||||
|
$this->addOrderBy('space.name');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'newer':
|
||||||
|
$this->addOrderBy('space.created_at DESC');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'older':
|
||||||
|
$this->addOrderBy('space.created_at');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function paginate(): SpaceDirectoryQuery
|
||||||
|
{
|
||||||
|
$countQuery = clone $this;
|
||||||
|
$this->pagination = new Pagination(['totalCount' => $countQuery->count(), 'pageSize' => $this->pageSize]);
|
||||||
|
|
||||||
|
return $this->offset($this->pagination->offset)->limit($this->pagination->limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isLastPage(): bool
|
||||||
|
{
|
||||||
|
return $this->pagination->getPage() == $this->pagination->getPageCount() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,15 +4,16 @@ use humhub\modules\search\engine\Search;
|
|||||||
use humhub\modules\user\models\User;
|
use humhub\modules\user\models\User;
|
||||||
use humhub\modules\space\Events;
|
use humhub\modules\space\Events;
|
||||||
use humhub\modules\space\Module;
|
use humhub\modules\space\Module;
|
||||||
use humhub\components\console\Application;
|
|
||||||
use humhub\commands\IntegrityController;
|
use humhub\commands\IntegrityController;
|
||||||
|
use humhub\widgets\TopMenu;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => 'space',
|
'id' => 'space',
|
||||||
'class' => Module::class,
|
'class' => Module::class,
|
||||||
'isCoreModule' => true,
|
'isCoreModule' => true,
|
||||||
'urlManagerRules' => [
|
'urlManagerRules' => [
|
||||||
['class' => 'humhub\modules\space\components\UrlRule']
|
['class' => 'humhub\modules\space\components\UrlRule'],
|
||||||
|
'spaces' => 'space/spaces',
|
||||||
],
|
],
|
||||||
'modules' => [
|
'modules' => [
|
||||||
'manage' => [
|
'manage' => [
|
||||||
@ -26,5 +27,6 @@ return [
|
|||||||
[User::class, User::EVENT_BEFORE_SOFT_DELETE, [Events::class, 'onUserSoftDelete']],
|
[User::class, User::EVENT_BEFORE_SOFT_DELETE, [Events::class, 'onUserSoftDelete']],
|
||||||
[Search::class, Search::EVENT_ON_REBUILD, [Events::class, 'onSearchRebuild']],
|
[Search::class, Search::EVENT_ON_REBUILD, [Events::class, 'onSearchRebuild']],
|
||||||
[IntegrityController::class, IntegrityController::EVENT_ON_RUN, [Events::class, 'onIntegrityCheck']],
|
[IntegrityController::class, IntegrityController::EVENT_ON_RUN, [Events::class, 'onIntegrityCheck']],
|
||||||
|
[TopMenu::class, TopMenu::EVENT_INIT, [Events::class, 'onTopMenuInit']],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -18,10 +18,12 @@ use humhub\modules\space\models\forms\RequestMembershipForm;
|
|||||||
use humhub\modules\space\models\Membership;
|
use humhub\modules\space\models\Membership;
|
||||||
use humhub\modules\space\models\Space;
|
use humhub\modules\space\models\Space;
|
||||||
use humhub\modules\space\permissions\InviteUsers;
|
use humhub\modules\space\permissions\InviteUsers;
|
||||||
|
use humhub\modules\space\widgets\MembershipButton;
|
||||||
use humhub\modules\user\models\UserPicker;
|
use humhub\modules\user\models\UserPicker;
|
||||||
use humhub\modules\user\widgets\UserListBox;
|
use humhub\modules\user\widgets\UserListBox;
|
||||||
use humhub\widgets\ModalClose;
|
use humhub\widgets\ModalClose;
|
||||||
use Yii;
|
use Yii;
|
||||||
|
use yii\helpers\Json;
|
||||||
use yii\web\HttpException;
|
use yii\web\HttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +96,7 @@ class MembershipController extends ContentContainerController
|
|||||||
|
|
||||||
$space->addMember(Yii::$app->user->id);
|
$space->addMember(Yii::$app->user->id);
|
||||||
|
|
||||||
return $this->htmlRedirect($space->getUrl());
|
return $this->getActionResult($space);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,9 +118,18 @@ class MembershipController extends ContentContainerController
|
|||||||
|
|
||||||
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
|
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
|
||||||
$space->requestMembership(Yii::$app->user->id, $model->message);
|
$space->requestMembership(Yii::$app->user->id, $model->message);
|
||||||
return $this->renderAjax('requestMembershipSave', ['space' => $space]);
|
|
||||||
|
return $this->renderAjax('requestMembershipSave', [
|
||||||
|
'spaceId' => $space->id,
|
||||||
|
'newMembershipButton' => MembershipButton::widget([
|
||||||
|
'space' => $space,
|
||||||
|
'options' => empty($model->options) ? [] : Json::decode($model->options)
|
||||||
|
]),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$model->options = $this->request->get('options');
|
||||||
|
|
||||||
return $this->renderAjax('requestMembership', ['model' => $model, 'space' => $space]);
|
return $this->renderAjax('requestMembership', ['model' => $model, 'space' => $space]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +171,7 @@ class MembershipController extends ContentContainerController
|
|||||||
|
|
||||||
$space->removeMember();
|
$space->removeMember();
|
||||||
|
|
||||||
return $this->goHome();
|
return $this->getActionResult($space);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,7 +236,7 @@ class MembershipController extends ContentContainerController
|
|||||||
$space->addMember(Yii::$app->user->id);
|
$space->addMember(Yii::$app->user->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->redirect($space->getUrl());
|
return $this->getActionResult($space);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,4 +267,23 @@ class MembershipController extends ContentContainerController
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get result for the membership actions
|
||||||
|
*
|
||||||
|
* @param Space $space
|
||||||
|
* @return string|\yii\console\Response|\yii\web\Response
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
protected function getActionResult(Space $space)
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax) {
|
||||||
|
return MembershipButton::widget([
|
||||||
|
'space' => $space,
|
||||||
|
'options' => $this->request->post('options', []),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->redirect($this->request->getReferrer());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\space\controllers;
|
||||||
|
|
||||||
|
use humhub\components\access\ControllerAccess;
|
||||||
|
use humhub\components\Controller;
|
||||||
|
use humhub\modules\space\components\SpaceDirectoryQuery;
|
||||||
|
use humhub\modules\space\permissions\SpaceDirectoryAccess;
|
||||||
|
use humhub\modules\space\widgets\SpaceDirectoryCard;
|
||||||
|
use Yii;
|
||||||
|
use yii\helpers\Url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpacesController displays users directory
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
class SpacesController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $subLayout = '@space/views/spaces/_layout';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
$this->setActionTitles([
|
||||||
|
'index' => Yii::t('SpaceModule.base', 'Spaces'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
parent::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getAccessRules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[ControllerAccess::RULE_LOGGED_IN_ONLY],
|
||||||
|
['permissions' => [SpaceDirectoryAccess::class]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to display spaces page
|
||||||
|
*/
|
||||||
|
public function actionIndex()
|
||||||
|
{
|
||||||
|
$spaceDirectoryQuery = new SpaceDirectoryQuery();
|
||||||
|
|
||||||
|
$urlParams = Yii::$app->request->getQueryParams();
|
||||||
|
unset($urlParams['page']);
|
||||||
|
array_unshift($urlParams, '/space/spaces/load-more');
|
||||||
|
$this->getView()->registerJsConfig('directory', [
|
||||||
|
'loadMoreUrl' => Url::to($urlParams),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->render('index', [
|
||||||
|
'spaces' => $spaceDirectoryQuery,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to load cards for next page by AJAX
|
||||||
|
*/
|
||||||
|
public function actionLoadMore()
|
||||||
|
{
|
||||||
|
$spaceQuery = new SpaceDirectoryQuery();
|
||||||
|
|
||||||
|
$spaceCards = '';
|
||||||
|
foreach ($spaceQuery->all() as $space) {
|
||||||
|
$spaceCards .= SpaceDirectoryCard::widget(['space' => $space]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $spaceCards;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,6 +15,7 @@ class RequestMembershipForm extends Model
|
|||||||
|
|
||||||
public $space_id;
|
public $space_id;
|
||||||
public $message;
|
public $message;
|
||||||
|
public $options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declares the validation rules.
|
* Declares the validation rules.
|
||||||
@ -22,7 +23,8 @@ class RequestMembershipForm extends Model
|
|||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
['message', 'required']
|
['message', 'required'],
|
||||||
|
['options', 'safe'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\space\permissions;
|
||||||
|
|
||||||
|
use humhub\libs\BasePermission;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
|
class SpaceDirectoryAccess extends BasePermission
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected $moduleId = 'space';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected $defaultState = self::STATE_ALLOW;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return Yii::t('SpaceModule.permissions', 'Can Access Space Directory');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getDescription()
|
||||||
|
{
|
||||||
|
return Yii::t('SpaceModule.permissions', 'Can access the space directory section.');
|
||||||
|
}
|
||||||
|
}
|
@ -21,8 +21,8 @@ class RequestMembershipCest
|
|||||||
|
|
||||||
$I->amUser1();
|
$I->amUser1();
|
||||||
$I->amOnSpace1();
|
$I->amOnSpace1();
|
||||||
$I->seeElement('#requestMembershipButton');
|
$I->seeElement('[data-space-request-membership]');
|
||||||
$I->click('#requestMembershipButton');
|
$I->click('[data-space-request-membership]');
|
||||||
|
|
||||||
$I->waitForText('Request space membership', null,'#globalModal');
|
$I->waitForText('Request space membership', null,'#globalModal');
|
||||||
$I->fillField('#request-message', 'Hi, I want to join this space.');
|
$I->fillField('#request-message', 'Hi, I want to join this space.');
|
||||||
@ -57,8 +57,8 @@ class RequestMembershipCest
|
|||||||
|
|
||||||
$I->amUser1();
|
$I->amUser1();
|
||||||
$I->amOnSpace1();
|
$I->amOnSpace1();
|
||||||
$I->seeElement('#requestMembershipButton');
|
$I->seeElement('[data-space-request-membership]');
|
||||||
$I->click('#requestMembershipButton');
|
$I->click('[data-space-request-membership]');
|
||||||
|
|
||||||
$I->waitForText('Request space membership', null,'#globalModal');
|
$I->waitForText('Request space membership', null,'#globalModal');
|
||||||
$I->fillField('#request-message', 'Hi, I want to join this space.');
|
$I->fillField('#request-message', 'Hi, I want to join this space.');
|
||||||
@ -90,7 +90,7 @@ class RequestMembershipCest
|
|||||||
$I->amUser1(true);
|
$I->amUser1(true);
|
||||||
|
|
||||||
$I->seeInNotifications('Admin Tester declined your membership request for the space Space 1', true);
|
$I->seeInNotifications('Admin Tester declined your membership request for the space Space 1', true);
|
||||||
$I->waitForElementVisible('#requestMembershipButton');
|
$I->waitForElementVisible('[data-space-request-membership]');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,8 +103,8 @@ class RequestMembershipCest
|
|||||||
|
|
||||||
$I->amUser1();
|
$I->amUser1();
|
||||||
$I->amOnSpace1();
|
$I->amOnSpace1();
|
||||||
$I->seeElement('#requestMembershipButton');
|
$I->seeElement('[data-space-request-membership]');
|
||||||
$I->click('#requestMembershipButton');
|
$I->click('[data-space-request-membership]');
|
||||||
|
|
||||||
$I->waitForText('Request space membership', null,'#globalModal');
|
$I->waitForText('Request space membership', null,'#globalModal');
|
||||||
$I->fillField('#request-message', 'Hi, I want to join this space.');
|
$I->fillField('#request-message', 'Hi, I want to join this space.');
|
||||||
@ -116,7 +116,7 @@ class RequestMembershipCest
|
|||||||
$I->click('Cancel pending membership application');
|
$I->click('Cancel pending membership application');
|
||||||
$I->waitForText('Admin Space 2 Post Private', null,'#wallStream'); // Back to dashboard
|
$I->waitForText('Admin Space 2 Post Private', null,'#wallStream'); // Back to dashboard
|
||||||
$I->amOnSpace1();
|
$I->amOnSpace1();
|
||||||
$I->waitForText('Request membership', null,'#requestMembershipButton');
|
$I->waitForText('Request membership', null,'[data-space-request-membership]');
|
||||||
|
|
||||||
$I->amAdmin(true);
|
$I->amAdmin(true);
|
||||||
$I->dontSeeInNotifications('Peter Tester requests membership for the space Space 1');
|
$I->dontSeeInNotifications('Peter Tester requests membership for the space Space 1');
|
||||||
|
@ -2,10 +2,16 @@
|
|||||||
|
|
||||||
use humhub\compat\CActiveForm;
|
use humhub\compat\CActiveForm;
|
||||||
use humhub\libs\Html;
|
use humhub\libs\Html;
|
||||||
|
use humhub\modules\space\models\forms\RequestMembershipForm;
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
|
|
||||||
|
/* @var $space Space */
|
||||||
|
/* @var $model RequestMembershipForm */
|
||||||
?>
|
?>
|
||||||
<div class="modal-dialog animated fadeIn">
|
<div class="modal-dialog animated fadeIn">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<?php $form = CActiveForm::begin(); ?>
|
<?php $form = CActiveForm::begin(); ?>
|
||||||
|
<?= $form->hiddenField($model, 'options') ?>
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
<h4 class="modal-title"
|
<h4 class="modal-title"
|
||||||
@ -30,7 +36,7 @@ use humhub\libs\Html;
|
|||||||
'label' => Yii::t('SpaceModule.base', 'Send'),
|
'label' => Yii::t('SpaceModule.base', 'Send'),
|
||||||
'ajaxOptions' => [
|
'ajaxOptions' => [
|
||||||
'type' => 'POST',
|
'type' => 'POST',
|
||||||
'beforeSend' => new yii\web\JsExpression('function(){ setModalLoader(); }'),
|
'beforeSend' => new yii\web\JsExpression('function(){ setModalLoader(evt); }'),
|
||||||
'success' => new yii\web\JsExpression('function(html){ $("#globalModal").html(html); }'),
|
'success' => new yii\web\JsExpression('function(html){ $("#globalModal").html(html); }'),
|
||||||
'url' => $space->createUrl('/space/membership/request-membership-form'),
|
'url' => $space->createUrl('/space/membership/request-membership-form'),
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use humhub\modules\space\widgets\MembershipButton;
|
|
||||||
use humhub\libs\Html;
|
use humhub\libs\Html;
|
||||||
|
|
||||||
|
/* @var $spaceId int */
|
||||||
|
/* @var $newMembershipButton string */
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="modal-dialog animated fadeIn">
|
<div class="modal-dialog animated fadeIn">
|
||||||
@ -28,5 +30,5 @@ use humhub\libs\Html;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script <?= Html::nonce() ?>>
|
<script <?= Html::nonce() ?>>
|
||||||
$('#requestMembershipButton').replaceWith('<?= MembershipButton::widget(['space' => $space]) ?>');
|
$('[data-space-request-membership=<?= $spaceId ?>]').replaceWith('<?= $newMembershipButton ?>');
|
||||||
</script>
|
</script>
|
||||||
|
9
protected/humhub/modules/space/views/spaces/_layout.php
Normal file
9
protected/humhub/modules/space/views/spaces/_layout.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use humhub\modules\ui\view\helpers\ThemeHelper;
|
||||||
|
|
||||||
|
/* @var $content string */
|
||||||
|
?>
|
||||||
|
<div class="<?php if (ThemeHelper::isFluid()): ?>container-fluid<?php else: ?>container<?php endif; ?> container-directory container-spaces">
|
||||||
|
<?= $content; ?>
|
||||||
|
</div>
|
59
protected/humhub/modules/space/views/spaces/index.php
Normal file
59
protected/humhub/modules/space/views/spaces/index.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
use humhub\assets\DirectoryAsset;
|
||||||
|
use humhub\modules\space\components\SpaceDirectoryQuery;
|
||||||
|
use humhub\modules\space\widgets\SpaceDirectoryCard;
|
||||||
|
use humhub\modules\space\widgets\SpaceDirectoryFilters;
|
||||||
|
use humhub\widgets\Button;
|
||||||
|
use humhub\widgets\LinkPager;
|
||||||
|
use yii\web\View;
|
||||||
|
|
||||||
|
/* @var $this View */
|
||||||
|
/* @var $spaces SpaceDirectoryQuery */
|
||||||
|
|
||||||
|
DirectoryAsset::register($this);
|
||||||
|
?>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
|
||||||
|
<div class="panel-heading">
|
||||||
|
<?= Yii::t('SpaceModule.base', '<strong>Spaces</strong> directory'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<?= SpaceDirectoryFilters::widget(); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row cards">
|
||||||
|
<?php if (!$spaces->exists()): ?>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<?= Yii::t('SpaceModule.base', 'No spaces found!'); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php foreach ($spaces->all() as $space) : ?>
|
||||||
|
<?= SpaceDirectoryCard::widget(['space' => $space]); ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (!$spaces->isLastPage()) : ?>
|
||||||
|
<div class="directory-load-more">
|
||||||
|
<?= Button::primary(Yii::t('SpaceModule.base', 'Load more'))
|
||||||
|
->icon('fa-angle-down')
|
||||||
|
->action('directory.loadMore')
|
||||||
|
->options([
|
||||||
|
'data-current-page' => $spaces->pagination->getPage() + 1,
|
||||||
|
'data-total-pages' => $spaces->pagination->getPageCount(),
|
||||||
|
]) ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
@ -45,7 +45,7 @@ class FollowButton extends Widget
|
|||||||
/**
|
/**
|
||||||
* @var array options for unfollow button
|
* @var array options for unfollow button
|
||||||
*/
|
*/
|
||||||
public $unfollowOptions = ['class' => 'btn btn-info btn-sm'];
|
public $unfollowOptions = ['class' => 'btn btn-primary btn-sm active'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
@ -57,7 +57,7 @@ class FollowButton extends Widget
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->unfollowLabel === null) {
|
if ($this->unfollowLabel === null) {
|
||||||
$this->unfollowLabel = Yii::t('SpaceModule.base', 'Unfollow');
|
$this->unfollowLabel = '<span class="glyphicon glyphicon-ok"></span> ' . Yii::t('SpaceModule.base', 'Following');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($this->followOptions['class'])) {
|
if (!isset($this->followOptions['class'])) {
|
||||||
@ -113,6 +113,11 @@ class FollowButton extends Widget
|
|||||||
$this->followOptions['data-ui-loader'] = '';
|
$this->followOptions['data-ui-loader'] = '';
|
||||||
$this->unfollowOptions['data-ui-loader'] = '';
|
$this->unfollowOptions['data-ui-loader'] = '';
|
||||||
|
|
||||||
|
// Confirm action "Unfollow"
|
||||||
|
$this->unfollowOptions['data-action-confirm'] = Yii::t('SpaceModule.base', 'Would you like to unfollow Space {spaceName}?', [
|
||||||
|
'{spaceName}' => '<strong>' . $this->space->getDisplayName() . '</strong>'
|
||||||
|
]);
|
||||||
|
|
||||||
$module = Yii::$app->getModule('space');
|
$module = Yii::$app->getModule('space');
|
||||||
|
|
||||||
// still enable unfollow if following was disabled afterwards.
|
// still enable unfollow if following was disabled afterwards.
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
namespace humhub\modules\space\widgets;
|
namespace humhub\modules\space\widgets;
|
||||||
|
|
||||||
use humhub\components\Widget;
|
use humhub\components\Widget;
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
|
use Yii;
|
||||||
|
use yii\helpers\ArrayHelper;
|
||||||
|
use yii\helpers\Json;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MembershipButton shows various membership related buttons in space header.
|
* MembershipButton shows various membership related buttons in space header.
|
||||||
@ -20,20 +24,115 @@ class MembershipButton extends Widget
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \humhub\modules\space\models\Space
|
* @var Space
|
||||||
*/
|
*/
|
||||||
public $space;
|
public $space;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Options buttons
|
||||||
|
*/
|
||||||
|
public $options = [];
|
||||||
|
|
||||||
|
private function getDefaultOptions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'requestMembership' => [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Join'),
|
||||||
|
'url' => $this->space->createUrl('/space/membership/request-membership-form', ['options' => Json::encode($this->options)]),
|
||||||
|
'attrs' => [
|
||||||
|
'class' => 'btn btn-info',
|
||||||
|
'data-space-request-membership' => $this->space->id,
|
||||||
|
'data-target' => '#globalModal',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'becomeMember' => [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Join'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => $this->space->createUrl('/space/membership/request-membership'),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
'class' => 'btn btn-info',
|
||||||
|
'data-space-request-membership' => $this->space->id,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'acceptInvite' => [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Accept Invite'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => $this->space->createUrl('/space/membership/invite-accept'),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
'class' => 'btn btn-info',
|
||||||
|
],
|
||||||
|
'groupClass' => 'btn-group',
|
||||||
|
'togglerClass' => 'btn btn-info',
|
||||||
|
],
|
||||||
|
'declineInvite' => [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Decline Invite'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => $this->space->createUrl('/space/membership/revoke-membership'),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'cancelPendingMembership' => [
|
||||||
|
'title' => '<span class="glyphicon glyphicon-time"></span> ' . Yii::t('SpaceModule.base', 'Pending'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => $this->space->createUrl('/space/membership/revoke-membership'),
|
||||||
|
'data-action-confirm' => Yii::t('SpaceModule.base', 'Would you like to withdraw your request to join Space {spaceName}?', ['{spaceName}' => '<strong>' . $this->space->getDisplayName() . '</strong>']),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
'class' => 'btn btn-info active',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'cancelMembership' => [
|
||||||
|
'visible' => false,
|
||||||
|
'title' => '<span class="glyphicon glyphicon-ok"></span> ' . Yii::t('SpaceModule.base', 'Member'),
|
||||||
|
'attrs' => [
|
||||||
|
'data-action-click' => 'content.container.relationship',
|
||||||
|
'data-action-url' => $this->space->createUrl('/space/membership/revoke-membership'),
|
||||||
|
'data-action-confirm' => Yii::t('SpaceModule.base', 'Would you like to end your membership in Space {spaceName}?', ['{spaceName}' => '<strong>' . $this->space->getDisplayName() . '</strong>']),
|
||||||
|
'data-button-options' => Json::encode($this->options),
|
||||||
|
'data-ui-loader' => '',
|
||||||
|
'class' => 'btn btn-info active',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'cannotCancelMembership' => [
|
||||||
|
'visible' => false,
|
||||||
|
'memberTitle' => '<span class="glyphicon glyphicon-ok"></span> ' . Yii::t('SpaceModule.base', 'Member'),
|
||||||
|
'ownerTitle' => '<span class="glyphicon glyphicon-user"></span> ' . Yii::t('SpaceModule.base', 'Owner'),
|
||||||
|
'attrs' => ['class' => 'btn btn-info active'],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDefaultOptions(array $defaultOptions)
|
||||||
|
{
|
||||||
|
$this->options = $this->getOptions($defaultOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOptions(array $defaultOptions = null): array
|
||||||
|
{
|
||||||
|
if ($defaultOptions === null) {
|
||||||
|
$defaultOptions = $this->getDefaultOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ArrayHelper::merge($defaultOptions, $this->options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$membership = $this->space->getMembership();
|
|
||||||
|
|
||||||
return $this->render('membershipButton', [
|
return $this->render('membershipButton', [
|
||||||
'space' => $this->space,
|
'space' => $this->space,
|
||||||
'membership' => $membership
|
'membership' => $this->space->getMembership(),
|
||||||
|
'options' => $this->getOptions(),
|
||||||
|
'canCancelMembership' => !$this->space->isSpaceOwner() && $this->space->canLeave(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\space\widgets;
|
||||||
|
|
||||||
|
use humhub\components\Widget;
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpaceDirectoryActionButtons shows space directory buttons (following and membership)
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class SpaceDirectoryActionButtons extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Space
|
||||||
|
*/
|
||||||
|
public $space;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Template for buttons
|
||||||
|
*/
|
||||||
|
public $template = '{buttons}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$html = FollowButton::widget([
|
||||||
|
'space' => $this->space,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$html .= MembershipButton::widget([
|
||||||
|
'space' => $this->space,
|
||||||
|
'options' => [
|
||||||
|
'requestMembership' => ['attrs' => ['class' => 'btn btn-info btn-sm']],
|
||||||
|
'becomeMember' => ['attrs' => ['class' => 'btn btn-info btn-sm']],
|
||||||
|
'acceptInvite' => ['attrs' => ['class' => 'btn btn-info btn-sm'], 'togglerClass' => 'btn btn-info btn-sm'],
|
||||||
|
'cancelPendingMembership' => ['attrs' => ['class' => 'btn btn-info btn-sm active']],
|
||||||
|
'cancelMembership' => ['visible' => true, 'attrs' => ['class' => 'btn btn-info btn-sm active']],
|
||||||
|
'cannotCancelMembership' => ['visible' => true, 'attrs' => ['class' => 'btn btn-info btn-sm active']],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (trim($html) === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace('{buttons}', $html, $this->template);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\space\widgets;
|
||||||
|
|
||||||
|
use humhub\components\Widget;
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpaceDirectoryCard shows a space on spaces directory
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class SpaceDirectoryCard extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Space
|
||||||
|
*/
|
||||||
|
public $space;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string HTML wrapper around card
|
||||||
|
*/
|
||||||
|
public $template = '<div class="card card-space col-lg-3 col-md-4 col-sm-6 col-xs-12">{card}</div>';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$card = $this->render('spaceDirectoryCard', [
|
||||||
|
'space' => $this->space
|
||||||
|
]);
|
||||||
|
|
||||||
|
return str_replace('{card}', $card, $this->template);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\space\widgets;
|
||||||
|
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use humhub\modules\ui\widgets\DirectoryFilters;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpaceDirectoryFilters displays the filters on the directory spaces page
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class SpaceDirectoryFilters extends DirectoryFilters
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $pageUrl = '/space/spaces';
|
||||||
|
|
||||||
|
protected function initDefaultFilters()
|
||||||
|
{
|
||||||
|
$this->addFilter('keyword', [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Find Spaces by their description or by their Tags'),
|
||||||
|
'placeholder' => Yii::t('SpaceModule.base', 'Search...'),
|
||||||
|
'type' => 'input',
|
||||||
|
'wrapperClass' => 'col-md-6 form-search-filter-keyword',
|
||||||
|
'afterInput' => Html::submitButton('<span class="fa fa-search"></span>', ['class' => 'form-button-search']),
|
||||||
|
'sortOrder' => 100,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->addFilter('sort', [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Sorting'),
|
||||||
|
'type' => 'dropdown',
|
||||||
|
'options' => [
|
||||||
|
'name' => Yii::t('SpaceModule.base', 'By Name'),
|
||||||
|
'newer' => Yii::t('SpaceModule.base', 'Newest first'),
|
||||||
|
'older' => Yii::t('SpaceModule.base', 'Oldest first'),
|
||||||
|
],
|
||||||
|
'sortOrder' => 200,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->addFilter('connection', [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Status'),
|
||||||
|
'type' => 'dropdown',
|
||||||
|
'options' => [
|
||||||
|
'' => Yii::t('SpaceModule.base', 'All'),
|
||||||
|
'member' => Yii::t('SpaceModule.base', 'Member'),
|
||||||
|
'follow' => Yii::t('SpaceModule.base', 'Following'),
|
||||||
|
'none' => Yii::t('SpaceModule.base', 'Neither member nor following'),
|
||||||
|
],
|
||||||
|
'sortOrder' => 300,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDefaultValue(string $filter): string
|
||||||
|
{
|
||||||
|
switch ($filter) {
|
||||||
|
case 'sort':
|
||||||
|
return 'name';
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getDefaultValue($filter);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\space\widgets;
|
||||||
|
|
||||||
|
use humhub\components\Widget;
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpaceDirectoryIcons shows footer icons for spaces cards
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class SpaceDirectoryIcons extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Space
|
||||||
|
*/
|
||||||
|
public $space;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
return $this->render('spaceDirectoryIcons', [
|
||||||
|
'space' => $this->space
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\space\widgets;
|
||||||
|
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use yii\helpers\Url;
|
||||||
|
use humhub\components\Widget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpaceDirectoryTagList displays the space tags on the directory spaces page
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class SpaceDirectoryTagList extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \humhub\modules\space\models\Space
|
||||||
|
*/
|
||||||
|
public $space;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int number of max. displayed tags
|
||||||
|
*/
|
||||||
|
public $maxTags = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Template for tags
|
||||||
|
*/
|
||||||
|
public $template = '{tags}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$html = '';
|
||||||
|
|
||||||
|
$tags = $this->space->getTags();
|
||||||
|
|
||||||
|
$count = count($tags);
|
||||||
|
|
||||||
|
if ($count === 0) {
|
||||||
|
return $html;
|
||||||
|
} elseif ($count > $this->maxTags) {
|
||||||
|
$tags = array_slice($tags, 0, $this->maxTags);
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = '';
|
||||||
|
foreach ($tags as $tag) {
|
||||||
|
if (trim($tag) !== '') {
|
||||||
|
$html .= Html::a(Html::encode($tag), Url::to(['/space/spaces', 'keyword' => trim($tag)]), ['class' => 'label label-default']) . " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($html === '') {
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace('{tags}', $html, $this->template);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,27 +4,39 @@ use humhub\modules\space\models\Space;
|
|||||||
use humhub\modules\space\models\Membership;
|
use humhub\modules\space\models\Membership;
|
||||||
use yii\helpers\Html;
|
use yii\helpers\Html;
|
||||||
|
|
||||||
|
/* @var $membership Membership */
|
||||||
|
/* @var $space Space */
|
||||||
|
/* @var $options array */
|
||||||
|
/* @var $canCancelMembership bool */
|
||||||
|
|
||||||
if ($membership === null) {
|
if ($membership === null) {
|
||||||
if ($space->canJoin()) {
|
if ($space->canJoin()) {
|
||||||
if ($space->join_policy == Space::JOIN_POLICY_APPLICATION) {
|
if ($space->join_policy == Space::JOIN_POLICY_APPLICATION) {
|
||||||
echo Html::a(Yii::t('SpaceModule.base', 'Request membership'), $space->createUrl('/space/membership/request-membership-form'), ['id' => 'requestMembershipButton', 'class' => 'btn btn-primary', 'data-target' => '#globalModal']);
|
echo Html::a($options['requestMembership']['title'], $options['requestMembership']['url'], $options['requestMembership']['attrs']);
|
||||||
} else {
|
} else {
|
||||||
echo Html::a(Yii::t('SpaceModule.base', 'Become member'), $space->createUrl('/space/membership/request-membership'), ['id' => 'requestMembershipButton', 'class' => 'btn btn-primary', 'data-method' => 'POST']);
|
echo Html::a($options['becomeMember']['title'], '#', $options['becomeMember']['attrs']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif ($membership->status == Membership::STATUS_INVITED) {
|
} elseif ($membership->status == Membership::STATUS_INVITED) {
|
||||||
?>
|
?>
|
||||||
<div class="btn-group">
|
<div class="<?= $options['acceptInvite']['groupClass'] ?>">
|
||||||
<?= Html::a(Yii::t('SpaceModule.base', 'Accept Invite'), $space->createUrl('/space/membership/invite-accept'), ['class' => 'btn btn-info', 'data-method' => 'POST']); ?>
|
<?= Html::a($options['acceptInvite']['title'], '#', $options['acceptInvite']['attrs']); ?>
|
||||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button type="button" class="<?= $options['acceptInvite']['togglerClass'] ?> dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
<span class="sr-only">Toggle Dropdown</span>
|
<span class="sr-only">Toggle Dropdown</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><?= Html::a(Yii::t('SpaceModule.base', 'Decline Invite'), $space->createUrl('/space/membership/revoke-membership'), ['data-method' => 'POST']); ?></li>
|
<li><?= Html::a($options['declineInvite']['title'], '#', $options['declineInvite']['attrs']); ?></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
} elseif ($membership->status == Membership::STATUS_APPLICANT) {
|
} elseif ($membership->status == Membership::STATUS_APPLICANT) {
|
||||||
echo Html::a(Yii::t('SpaceModule.base', 'Cancel pending membership application'), $space->createUrl('/space/membership/revoke-membership'), ['data-method' => 'POST', 'class' => 'btn btn-primary']);
|
echo Html::a($options['cancelPendingMembership']['title'], $space->createUrl('/space/membership/revoke-membership'), $options['cancelPendingMembership']['attrs']);
|
||||||
|
} elseif ($membership->status == Membership::STATUS_MEMBER) {
|
||||||
|
if ($canCancelMembership && $options['cancelMembership']['visible']) {
|
||||||
|
echo Html::a($options['cancelMembership']['title'], '#', $options['cancelMembership']['attrs']);
|
||||||
|
} elseif (!$canCancelMembership && $options['cannotCancelMembership']['visible']) {
|
||||||
|
$memberTitle = (!$space->isSpaceOwner() ? $options['cannotCancelMembership']['ownerTitle'] : $options['cannotCancelMembership']['memberTitle']);
|
||||||
|
echo Html::a($memberTitle, $space->createUrl(), $options['cannotCancelMembership']['attrs']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ use humhub\modules\space\widgets\MembershipButton;
|
|||||||
[FollowButton::class, [
|
[FollowButton::class, [
|
||||||
'space' => $container,
|
'space' => $container,
|
||||||
'followOptions' => ['class' => 'btn btn-primary'],
|
'followOptions' => ['class' => 'btn btn-primary'],
|
||||||
'unfollowOptions' => ['class' => 'btn btn-info']
|
'unfollowOptions' => ['class' => 'btn btn-primary active']
|
||||||
], ['sortOrder' => 30]]
|
], ['sortOrder' => 30]]
|
||||||
]]); ?>
|
]]); ?>
|
||||||
<?= HeaderControlsMenu::widget(['space' => $container]); ?>
|
<?= HeaderControlsMenu::widget(['space' => $container]); ?>
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
|
use humhub\modules\space\widgets\Image;
|
||||||
|
use humhub\modules\space\widgets\SpaceDirectoryActionButtons;
|
||||||
|
use humhub\modules\space\widgets\SpaceDirectoryIcons;
|
||||||
|
use humhub\modules\space\widgets\SpaceDirectoryTagList;
|
||||||
|
use yii\web\View;
|
||||||
|
|
||||||
|
/* @var $this View */
|
||||||
|
/* @var $space Space */
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="card-panel">
|
||||||
|
<div class="card-bg-image"<?php if ($space->getProfileBannerImage()->hasImage()) : ?> style="background-image: url('<?= $space->getProfileBannerImage()->getUrl() ?>')"<?php endif; ?>></div>
|
||||||
|
<div class="card-header">
|
||||||
|
<?= Image::widget([
|
||||||
|
'space' => $space,
|
||||||
|
'link' => true,
|
||||||
|
'linkOptions' => ['data-contentcontainer-id' => $space->contentcontainer_id, 'class' => 'card-image-link'],
|
||||||
|
'width' => 94,
|
||||||
|
]); ?>
|
||||||
|
<div class="card-icons">
|
||||||
|
<?= SpaceDirectoryIcons::widget(['space' => $space]); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<strong class="card-title"><?= Html::containerLink($space); ?></strong>
|
||||||
|
<?php if (trim($space->description) !== '') : ?>
|
||||||
|
<div class="card-details"><?= Html::encode($space->description); ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?= SpaceDirectoryTagList::widget([
|
||||||
|
'space' => $space,
|
||||||
|
'template' => '<div class="card-tags">{tags}</div>',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<?= SpaceDirectoryActionButtons::widget([
|
||||||
|
'space' => $space,
|
||||||
|
'template' => '<div class="card-footer">{buttons}</div>',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
|
use yii\helpers\Url;
|
||||||
|
use yii\web\View;
|
||||||
|
|
||||||
|
/* @var $this View */
|
||||||
|
/* @var $space Space */
|
||||||
|
?>
|
||||||
|
|
||||||
|
<a href="#" class="fa fa-users" data-action-click="ui.modal.load" data-action-url="<?= Url::to(['/space/membership/members-list', 'container' => $space]) ?>"> <span><?= $space->getMemberships()->count() ?></span></a>
|
124
protected/humhub/modules/ui/widgets/DirectoryFilters.php
Normal file
124
protected/humhub/modules/ui/widgets/DirectoryFilters.php
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\ui\widgets;
|
||||||
|
|
||||||
|
use humhub\components\Widget;
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use Yii;
|
||||||
|
use yii\helpers\ArrayHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DirectoryFilters displays the filters on the directory people/spaces pages
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
abstract class DirectoryFilters extends Widget
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array Filters
|
||||||
|
*/
|
||||||
|
protected $filters = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Main page URL, used to reset and submit a form with filters
|
||||||
|
*/
|
||||||
|
public $pageUrl;
|
||||||
|
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
$this->initDefaultFilters();
|
||||||
|
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
ArrayHelper::multisort($this->filters, 'sortOrder');
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function initDefaultFilters();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
return $this->render('@humhub/modules/ui/widgets/views/directoryFilters', ['directoryFilters' => $this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderFilters(): string
|
||||||
|
{
|
||||||
|
$filtersHtml = '';
|
||||||
|
foreach ($this->filters as $filter => $data) {
|
||||||
|
$filtersHtml .= $this->render('@humhub/modules/ui/widgets/views/directoryFilter', [
|
||||||
|
'filter' => $filter,
|
||||||
|
'data' => array_merge(self::getDefaultFilterData(), $data),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return $filtersHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDefaultFilterData(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'wrapperClass' => 'col-md-2',
|
||||||
|
'titleClass' => 'form-search-field-info',
|
||||||
|
'inputClass' => 'form-control form-search-filter',
|
||||||
|
'beforeInput' => '',
|
||||||
|
'afterInput' => '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function renderFilterInput(string $filter, array $data): string
|
||||||
|
{
|
||||||
|
$inputOptions = ['class' => $data['inputClass']];
|
||||||
|
|
||||||
|
if (isset($data['inputOptions'])) {
|
||||||
|
$inputOptions = array_merge($inputOptions, $data['inputOptions']);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($data['type']) {
|
||||||
|
case 'dropdown':
|
||||||
|
case 'dropdownlist':
|
||||||
|
$inputOptions['data-action-change'] = 'directory.applyFilters';
|
||||||
|
$inputHtml = Html::dropDownList($filter, self::getValue($filter), $data['options'], $inputOptions);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'input':
|
||||||
|
case 'text':
|
||||||
|
default:
|
||||||
|
if (isset($data['placeholder'])) {
|
||||||
|
$inputOptions['placeholder'] = $data['placeholder'];
|
||||||
|
}
|
||||||
|
$inputHtml = Html::textInput($filter, self::getValue($filter), $inputOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data['beforeInput'].$inputHtml.$data['afterInput'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addFilter(string $filterKey, array $filterData)
|
||||||
|
{
|
||||||
|
$this->filters[$filterKey] = $filterData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDefaultValue(string $filter): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getValue(string $filter)
|
||||||
|
{
|
||||||
|
$defaultValue = self::getDefaultValue($filter);
|
||||||
|
|
||||||
|
if (preg_match('/^(.+?)\[(.+?)\]$/', $filter, $arrayMatch)) {
|
||||||
|
$array = Yii::$app->request->get($arrayMatch[1]);
|
||||||
|
return isset($array[$arrayMatch[2]]) ? $array[$arrayMatch[2]] : $defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Yii::$app->request->get($filter, $defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
use humhub\modules\ui\widgets\DirectoryFilters;
|
||||||
|
|
||||||
|
/* @var $filter string */
|
||||||
|
/* @var $data array */
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="<?= $data['wrapperClass'] ?>">
|
||||||
|
<div class="<?= $data['titleClass'] ?>"><?= $data['title'] ?></div>
|
||||||
|
<?= DirectoryFilters::renderFilterInput($filter, $data) ?>
|
||||||
|
</div>
|
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use humhub\modules\ui\widgets\DirectoryFilters;
|
||||||
|
use yii\helpers\Url;
|
||||||
|
|
||||||
|
/* @var $directoryFilters DirectoryFilters */
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?= Html::beginForm(Url::to([$directoryFilters->pageUrl]), 'get', ['class' => 'form-search']); ?>
|
||||||
|
<?= Html::hiddenInput('page', '1'); ?>
|
||||||
|
<div class="row">
|
||||||
|
<?= $directoryFilters->renderFilters() ?>
|
||||||
|
<div class="col-md-2 form-search-without-info">
|
||||||
|
<?= Html::a(Yii::t('UiModule.base', 'Reset filters'), Url::to([$directoryFilters->pageUrl]), ['class' => 'form-search-reset']); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?= Html::endForm(); ?>
|
@ -2,13 +2,16 @@
|
|||||||
|
|
||||||
namespace humhub\modules\user;
|
namespace humhub\modules\user;
|
||||||
|
|
||||||
|
use humhub\components\Event;
|
||||||
use humhub\modules\content\models\ContentContainer;
|
use humhub\modules\content\models\ContentContainer;
|
||||||
|
use humhub\modules\ui\menu\MenuLink;
|
||||||
use humhub\modules\user\models\User;
|
use humhub\modules\user\models\User;
|
||||||
use humhub\modules\user\models\Password;
|
use humhub\modules\user\models\Password;
|
||||||
use humhub\modules\user\models\Profile;
|
use humhub\modules\user\models\Profile;
|
||||||
use humhub\modules\user\models\GroupUser;
|
use humhub\modules\user\models\GroupUser;
|
||||||
use humhub\modules\user\models\Mentioning;
|
use humhub\modules\user\models\Mentioning;
|
||||||
use humhub\modules\user\models\Follow;
|
use humhub\modules\user\models\Follow;
|
||||||
|
use humhub\modules\user\permissions\PeopleAccess;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\BaseObject;
|
use yii\base\BaseObject;
|
||||||
|
|
||||||
@ -154,4 +157,29 @@ class Events extends BaseObject
|
|||||||
Yii::$app->queue->push(new jobs\DeleteExpiredSessions());
|
Yii::$app->queue->push(new jobs\DeleteExpiredSessions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On build of the TopMenu
|
||||||
|
*
|
||||||
|
* @param Event $event
|
||||||
|
*/
|
||||||
|
public static function onTopMenuInit($event)
|
||||||
|
{
|
||||||
|
if (Yii::$app->user->isGuest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Yii::$app->user->can(PeopleAccess::class)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$event->sender->addEntry(new MenuLink([
|
||||||
|
'id' => 'people',
|
||||||
|
'icon' => 'users',
|
||||||
|
'label' => Yii::t('UserModule.base', 'People'),
|
||||||
|
'url' => ['/user/people'],
|
||||||
|
'sortOrder' => 200,
|
||||||
|
'isActive' => MenuLink::isActiveState('user', 'people'),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
namespace humhub\modules\user;
|
namespace humhub\modules\user;
|
||||||
|
|
||||||
|
use humhub\modules\space\models\Space;
|
||||||
use humhub\modules\user\models\Group;
|
use humhub\modules\user\models\Group;
|
||||||
use Yii;
|
use Yii;
|
||||||
|
|
||||||
@ -146,9 +147,13 @@ class Module extends \humhub\components\Module
|
|||||||
return [
|
return [
|
||||||
new permissions\ViewAboutPage(),
|
new permissions\ViewAboutPage(),
|
||||||
];
|
];
|
||||||
|
} elseif ($contentContainer instanceof Space) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [
|
||||||
|
new permissions\PeopleAccess(),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
225
protected/humhub/modules/user/components/PeopleQuery.php
Normal file
225
protected/humhub/modules/user/components/PeopleQuery.php
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\components;
|
||||||
|
|
||||||
|
use humhub\modules\user\models\fieldtype\Select;
|
||||||
|
use humhub\modules\user\models\Group;
|
||||||
|
use humhub\modules\user\models\ProfileField;
|
||||||
|
use humhub\modules\user\models\User;
|
||||||
|
use humhub\modules\user\widgets\PeopleFilters;
|
||||||
|
use Yii;
|
||||||
|
use yii\data\Pagination;
|
||||||
|
use yii\db\Expression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleQuery is used to query User records on the People page.
|
||||||
|
*
|
||||||
|
* @author luke
|
||||||
|
*/
|
||||||
|
class PeopleQuery extends ActiveQueryUser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Group
|
||||||
|
*/
|
||||||
|
public $filteredGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Pagination
|
||||||
|
*/
|
||||||
|
public $pagination;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $pageSize = 18;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function __construct($config = [])
|
||||||
|
{
|
||||||
|
parent::__construct(User::class, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
$this->visible();
|
||||||
|
|
||||||
|
$this->filterByKeyword();
|
||||||
|
$this->filterByGroup();
|
||||||
|
$this->filterByConnection();
|
||||||
|
$this->filterByProfileFields();
|
||||||
|
|
||||||
|
$this->order();
|
||||||
|
|
||||||
|
$this->paginate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByKeyword(): PeopleQuery
|
||||||
|
{
|
||||||
|
$keyword = Yii::$app->request->get('keyword', '');
|
||||||
|
|
||||||
|
return $this->search($keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByProfileFields(): PeopleQuery
|
||||||
|
{
|
||||||
|
$fields = Yii::$app->request->get('fields', []);
|
||||||
|
|
||||||
|
// Remove empty filters
|
||||||
|
$fields = array_filter($fields, function($value) {
|
||||||
|
return $value !== '';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (empty($fields)) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip fields if they are not defined for directory filters
|
||||||
|
$filteredProfileFields = ProfileField::find()
|
||||||
|
->where(['directory_filter' => 1])
|
||||||
|
->andWhere(['IN', 'internal_name', array_keys($fields)])
|
||||||
|
->all();
|
||||||
|
$checkedFilteredFields = [];
|
||||||
|
foreach ($filteredProfileFields as $filteredField) {
|
||||||
|
/* @var $filteredField ProfileField */
|
||||||
|
if (!isset($fields[$filteredField->internal_name])) {
|
||||||
|
// Skip unknown field
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$checkedFilteredFields[$filteredField->internal_name] = [
|
||||||
|
'value' => $fields[$filteredField->internal_name],
|
||||||
|
'condition' => $filteredField->getFieldType() instanceof Select ? '=' : 'LIKE',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($checkedFilteredFields)) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->joinWith('profile');
|
||||||
|
|
||||||
|
foreach ($checkedFilteredFields as $field => $data) {
|
||||||
|
$this->andWhere([$data['condition'], 'profile.' . $field, $data['value']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByGroup(): PeopleQuery
|
||||||
|
{
|
||||||
|
$groupId = Yii::$app->request->get('groupId', 0);
|
||||||
|
|
||||||
|
if ($groupId) {
|
||||||
|
$group = Group::findOne(['id' => $groupId, 'show_at_directory' => 1]);
|
||||||
|
if ($group) {
|
||||||
|
$this->filteredGroup = $group;
|
||||||
|
$this->isGroupMember($group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnection(): PeopleQuery
|
||||||
|
{
|
||||||
|
switch (Yii::$app->request->get('connection')) {
|
||||||
|
case 'followers':
|
||||||
|
return $this->filterByConnectionFollowers();
|
||||||
|
case 'following':
|
||||||
|
return $this->filterByConnectionFollowing();
|
||||||
|
case 'friends':
|
||||||
|
return $this->filterByConnectionFriends();
|
||||||
|
case 'pending_friends':
|
||||||
|
return $this->filterByConnectionPendingFriends();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnectionFollowers(): PeopleQuery
|
||||||
|
{
|
||||||
|
return $this->innerJoin('user_follow', 'user_follow.object_model = :user_class AND user_follow.user_id = user.id', [':user_class' => User::class])
|
||||||
|
->andWhere(['user_follow.object_id' => Yii::$app->user->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnectionFollowing(): PeopleQuery
|
||||||
|
{
|
||||||
|
return $this->innerJoin('user_follow', 'user_follow.object_model = :user_class AND user_follow.object_id = user.id', [':user_class' => User::class])
|
||||||
|
->andWhere(['user_follow.user_id' => Yii::$app->user->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnectionFriends(): PeopleQuery
|
||||||
|
{
|
||||||
|
if (!Yii::$app->getModule('friendship')->settings->get('enable')) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->innerJoin('user_friendship AS uf_current', 'uf_current.friend_user_id = user.id')
|
||||||
|
->andWhere(['uf_current.user_id' => Yii::$app->user->id])
|
||||||
|
->innerJoin('user_friendship AS uf_friend', 'uf_friend.user_id = user.id')
|
||||||
|
->andWhere(['uf_friend.friend_user_id' => Yii::$app->user->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterByConnectionPendingFriends(): PeopleQuery
|
||||||
|
{
|
||||||
|
if (!Yii::$app->getModule('friendship')->settings->get('enable')) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->innerJoin('user_friendship AS uf_current', 'uf_current.friend_user_id = user.id')
|
||||||
|
->andWhere(['uf_current.user_id' => Yii::$app->user->id])
|
||||||
|
->leftJoin('user_friendship AS uf_friend', 'uf_friend.user_id = user.id')
|
||||||
|
->andWhere(['IS', 'uf_friend.friend_user_id', new Expression('NULL')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isFilteredByGroup(): bool
|
||||||
|
{
|
||||||
|
return $this->filteredGroup instanceof Group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function order(): PeopleQuery
|
||||||
|
{
|
||||||
|
switch (PeopleFilters::getValue('sort')) {
|
||||||
|
case 'firstname':
|
||||||
|
$this->joinWith('profile');
|
||||||
|
$this->addOrderBy('profile.firstname');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'lastname':
|
||||||
|
$this->joinWith('profile');
|
||||||
|
$this->addOrderBy('profile.lastname');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'lastlogin':
|
||||||
|
$this->addOrderBy('last_login DESC');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function paginate(): PeopleQuery
|
||||||
|
{
|
||||||
|
$countQuery = clone $this;
|
||||||
|
$this->pagination = new Pagination(['totalCount' => $countQuery->count(), 'pageSize' => $this->pageSize]);
|
||||||
|
|
||||||
|
return $this->offset($this->pagination->offset)->limit($this->pagination->limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isLastPage(): bool
|
||||||
|
{
|
||||||
|
return $this->pagination->getPage() == $this->pagination->getPageCount() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,13 +6,15 @@ use humhub\commands\IntegrityController;
|
|||||||
use humhub\modules\content\components\ContentAddonActiveRecord;
|
use humhub\modules\content\components\ContentAddonActiveRecord;
|
||||||
use humhub\modules\content\components\ContentActiveRecord;
|
use humhub\modules\content\components\ContentActiveRecord;
|
||||||
use humhub\commands\CronController;
|
use humhub\commands\CronController;
|
||||||
|
use humhub\widgets\TopMenu;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => 'user',
|
'id' => 'user',
|
||||||
'class' => \humhub\modules\user\Module::class,
|
'class' => \humhub\modules\user\Module::class,
|
||||||
'isCoreModule' => true,
|
'isCoreModule' => true,
|
||||||
'urlManagerRules' => [
|
'urlManagerRules' => [
|
||||||
['class' => 'humhub\modules\user\components\UrlRule']
|
['class' => 'humhub\modules\user\components\UrlRule'],
|
||||||
|
'people' => 'user/people',
|
||||||
],
|
],
|
||||||
'consoleControllerMap' => [
|
'consoleControllerMap' => [
|
||||||
'user' => 'humhub\modules\user\commands\UserController'
|
'user' => 'humhub\modules\user\commands\UserController'
|
||||||
@ -23,6 +25,7 @@ return [
|
|||||||
['class' => ContentAddonActiveRecord::class, 'event' => ContentAddonActiveRecord::EVENT_BEFORE_DELETE, 'callback' => [Events::class, 'onContentDelete']],
|
['class' => ContentAddonActiveRecord::class, 'event' => ContentAddonActiveRecord::EVENT_BEFORE_DELETE, 'callback' => [Events::class, 'onContentDelete']],
|
||||||
['class' => IntegrityController::class, 'event' => IntegrityController::EVENT_ON_RUN, 'callback' => [Events::class, 'onIntegrityCheck']],
|
['class' => IntegrityController::class, 'event' => IntegrityController::EVENT_ON_RUN, 'callback' => [Events::class, 'onIntegrityCheck']],
|
||||||
['class' => CronController::class, 'event' => CronController::EVENT_ON_HOURLY_RUN, 'callback' => [Events::class, 'onHourlyCron']],
|
['class' => CronController::class, 'event' => CronController::EVENT_ON_HOURLY_RUN, 'callback' => [Events::class, 'onHourlyCron']],
|
||||||
|
['class' => TopMenu::class, 'event' => TopMenu::EVENT_INIT, 'callback' => [Events::class, 'onTopMenuInit']],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
?>
|
?>
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\controllers;
|
||||||
|
|
||||||
|
use humhub\components\access\ControllerAccess;
|
||||||
|
use humhub\components\Controller;
|
||||||
|
use humhub\modules\user\components\PeopleQuery;
|
||||||
|
use humhub\modules\user\permissions\PeopleAccess;
|
||||||
|
use humhub\modules\user\widgets\PeopleCard;use Yii;
|
||||||
|
use yii\helpers\Url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleController displays users directory
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
class PeopleController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $subLayout = '@user/views/people/_layout';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
$this->setActionTitles([
|
||||||
|
'index' => Yii::t('UserModule.base', 'People'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
parent::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getAccessRules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[ControllerAccess::RULE_LOGGED_IN_ONLY],
|
||||||
|
['permissions' => [PeopleAccess::class]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to display people page
|
||||||
|
*/
|
||||||
|
public function actionIndex()
|
||||||
|
{
|
||||||
|
$peopleQuery = new PeopleQuery();
|
||||||
|
|
||||||
|
$urlParams = Yii::$app->request->getQueryParams();
|
||||||
|
unset($urlParams['page']);
|
||||||
|
array_unshift($urlParams, '/user/people/load-more');
|
||||||
|
$this->getView()->registerJsConfig('directory', [
|
||||||
|
'loadMoreUrl' => Url::to($urlParams),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->render('index', [
|
||||||
|
'people' => $peopleQuery,
|
||||||
|
'showInviteButton' => !Yii::$app->user->isGuest && Yii::$app->getModule('user')->settings->get('auth.internalUsersCanInvite'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to load cards for next page by AJAX
|
||||||
|
*/
|
||||||
|
public function actionLoadMore()
|
||||||
|
{
|
||||||
|
$peopleQuery = new PeopleQuery();
|
||||||
|
|
||||||
|
$peopleCards = '';
|
||||||
|
foreach ($peopleQuery->all() as $user) {
|
||||||
|
$peopleCards .= PeopleCard::widget(['user' => $user]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $peopleCards;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use yii\db\Migration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class m210506_060737_profile_field_directory_filter
|
||||||
|
*/
|
||||||
|
class m210506_060737_profile_field_directory_filter extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeUp()
|
||||||
|
{
|
||||||
|
$this->addColumn('profile_field', 'directory_filter', $this->tinyInteger(1)->notNull()->defaultValue(0));
|
||||||
|
$this->createIndex('index_directory_filter', 'profile_field', 'directory_filter');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeDown()
|
||||||
|
{
|
||||||
|
$this->dropColumn('profile_field', 'directory_filter');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,6 +11,8 @@ namespace humhub\modules\user\models;
|
|||||||
use humhub\components\ActiveRecord;
|
use humhub\components\ActiveRecord;
|
||||||
use humhub\libs\Helpers;
|
use humhub\libs\Helpers;
|
||||||
use humhub\modules\user\models\fieldtype\BaseType;
|
use humhub\modules\user\models\fieldtype\BaseType;
|
||||||
|
use humhub\modules\user\models\fieldtype\Select;
|
||||||
|
use humhub\modules\user\models\fieldtype\Text;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\db\ActiveQuery;
|
use yii\db\ActiveQuery;
|
||||||
|
|
||||||
@ -38,6 +40,7 @@ use yii\db\ActiveQuery;
|
|||||||
* @property string $translation_category
|
* @property string $translation_category
|
||||||
* @property integer $is_system
|
* @property integer $is_system
|
||||||
* @property integer $searchable
|
* @property integer $searchable
|
||||||
|
* @property integer $directory_filter
|
||||||
*/
|
*/
|
||||||
class ProfileField extends ActiveRecord
|
class ProfileField extends ActiveRecord
|
||||||
{
|
{
|
||||||
@ -64,7 +67,7 @@ class ProfileField extends ActiveRecord
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[['profile_field_category_id', 'field_type_class', 'internal_name', 'title', 'sort_order'], 'required'],
|
[['profile_field_category_id', 'field_type_class', 'internal_name', 'title', 'sort_order'], 'required'],
|
||||||
[['profile_field_category_id', 'required', 'editable', 'searchable', 'show_at_registration', 'visible', 'sort_order'], 'integer'],
|
[['profile_field_category_id', 'required', 'editable', 'searchable', 'show_at_registration', 'visible', 'sort_order', 'directory_filter'], 'integer'],
|
||||||
[['module_id', 'field_type_class', 'title'], 'string', 'max' => 255],
|
[['module_id', 'field_type_class', 'title'], 'string', 'max' => 255],
|
||||||
['internal_name', 'string', 'max' => 100],
|
['internal_name', 'string', 'max' => 100],
|
||||||
[['ldap_attribute', 'translation_category'], 'string', 'max' => 255],
|
[['ldap_attribute', 'translation_category'], 'string', 'max' => 255],
|
||||||
@ -103,6 +106,7 @@ class ProfileField extends ActiveRecord
|
|||||||
'translation_category' => Yii::t('UserModule.profile', 'Translation Category ID'),
|
'translation_category' => Yii::t('UserModule.profile', 'Translation Category ID'),
|
||||||
'required' => Yii::t('UserModule.profile', 'Required'),
|
'required' => Yii::t('UserModule.profile', 'Required'),
|
||||||
'searchable' => Yii::t('UserModule.profile', 'Searchable'),
|
'searchable' => Yii::t('UserModule.profile', 'Searchable'),
|
||||||
|
'directory_filter' => Yii::t('UserModule.profile', 'Use as Directory filter'),
|
||||||
'title' => Yii::t('UserModule.profile', 'Title'),
|
'title' => Yii::t('UserModule.profile', 'Title'),
|
||||||
'description' => Yii::t('UserModule.profile', 'Description'),
|
'description' => Yii::t('UserModule.profile', 'Description'),
|
||||||
'sort_order' => Yii::t('UserModule.profile', 'Sort order'),
|
'sort_order' => Yii::t('UserModule.profile', 'Sort order'),
|
||||||
@ -169,6 +173,7 @@ class ProfileField extends ActiveRecord
|
|||||||
$categories = ProfileFieldCategory::find()->orderBy('sort_order')->all();
|
$categories = ProfileFieldCategory::find()->orderBy('sort_order')->all();
|
||||||
$profileFieldTypes = new fieldtype\BaseType();
|
$profileFieldTypes = new fieldtype\BaseType();
|
||||||
$isVirtualField = (!$this->isNewRecord && $this->getFieldType()->isVirtual);
|
$isVirtualField = (!$this->isNewRecord && $this->getFieldType()->isVirtual);
|
||||||
|
$canBeDirectoryFilter = (!$this->isNewRecord && $this->getFieldType()->canBeDirectoryFilter);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'ProfileField' => [
|
'ProfileField' => [
|
||||||
@ -227,6 +232,10 @@ class ProfileField extends ActiveRecord
|
|||||||
'type' => 'checkbox',
|
'type' => 'checkbox',
|
||||||
'isVisible' => (!$isVirtualField)
|
'isVisible' => (!$isVirtualField)
|
||||||
],
|
],
|
||||||
|
'directory_filter' => [
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'isVisible' => ($canBeDirectoryFilter)
|
||||||
|
],
|
||||||
'profile_field_category_id' => [
|
'profile_field_category_id' => [
|
||||||
'type' => 'dropdownlist',
|
'type' => 'dropdownlist',
|
||||||
'items' => \yii\helpers\ArrayHelper::map($categories, 'id', 'title'),
|
'items' => \yii\helpers\ArrayHelper::map($categories, 'id', 'title'),
|
||||||
|
@ -46,7 +46,6 @@ class BaseType extends Model
|
|||||||
*/
|
*/
|
||||||
public $profileField = null;
|
public $profileField = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var boolean is a virtual field (readonly)
|
* @var boolean is a virtual field (readonly)
|
||||||
* @see BaseTypeVirtual
|
* @see BaseTypeVirtual
|
||||||
@ -54,6 +53,12 @@ class BaseType extends Model
|
|||||||
*/
|
*/
|
||||||
public $isVirtual = false;
|
public $isVirtual = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var boolean can be used as directory filter (readonly)
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
public $canBeDirectoryFilter = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Links a ProfileField to the ProfileFieldType.
|
* Links a ProfileField to the ProfileFieldType.
|
||||||
*
|
*
|
||||||
|
@ -64,7 +64,7 @@ abstract class BaseTypeVirtual extends BaseType
|
|||||||
*/
|
*/
|
||||||
protected static function getHiddenFormFields()
|
protected static function getHiddenFormFields()
|
||||||
{
|
{
|
||||||
return ['searchable', 'required', 'show_at_registration', 'editable'];
|
return ['searchable', 'required', 'show_at_registration', 'editable', 'directory_filter'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,6 +85,7 @@ abstract class BaseTypeVirtual extends BaseType
|
|||||||
$this->profileField->searchable = 0;
|
$this->profileField->searchable = 0;
|
||||||
$this->profileField->required = 0;
|
$this->profileField->required = 0;
|
||||||
$this->profileField->show_at_registration = 0;
|
$this->profileField->show_at_registration = 0;
|
||||||
|
$this->profileField->directory_filter = 0;
|
||||||
return parent::save();
|
return parent::save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,11 @@ class Select extends BaseType
|
|||||||
*/
|
*/
|
||||||
public $options;
|
public $options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inerhitdoc
|
||||||
|
*/
|
||||||
|
public $canBeDirectoryFilter = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rules for validating the Field Type Settings Form
|
* Rules for validating the Field Type Settings Form
|
||||||
*
|
*
|
||||||
|
@ -64,6 +64,11 @@ class Text extends BaseType
|
|||||||
*/
|
*/
|
||||||
public $regexpErrorMessage;
|
public $regexpErrorMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inerhitdoc
|
||||||
|
*/
|
||||||
|
public $canBeDirectoryFilter = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rules for validating the Field Type Settings Form
|
* Rules for validating the Field Type Settings Form
|
||||||
*
|
*
|
||||||
|
40
protected/humhub/modules/user/permissions/PeopleAccess.php
Normal file
40
protected/humhub/modules/user/permissions/PeopleAccess.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\permissions;
|
||||||
|
|
||||||
|
use humhub\libs\BasePermission;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
|
class PeopleAccess extends BasePermission
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected $moduleId = 'user';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected $defaultState = self::STATE_ALLOW;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return Yii::t('UserModule.permissions', 'Can Access People');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getDescription()
|
||||||
|
{
|
||||||
|
return Yii::t('UserModule.permissions', 'Can access the people section.');
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
namespace user\functional;
|
namespace user\functional;
|
||||||
|
|
||||||
use humhub\modules\user\models\User;
|
|
||||||
use user\FunctionalTester;
|
use user\FunctionalTester;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\helpers\Url;
|
use yii\helpers\Url;
|
||||||
@ -23,7 +22,7 @@ class MailInviteCest
|
|||||||
|
|
||||||
$I->amUser2();
|
$I->amUser2();
|
||||||
$I->amOnDirectory()->clickMembers();
|
$I->amOnDirectory()->clickMembers();
|
||||||
$I->amGoingTo('invte a user by mail');
|
$I->amGoingTo('invite a user by mail');
|
||||||
|
|
||||||
$I->see('Send invite', 'button');
|
$I->see('Send invite', 'button');
|
||||||
|
|
||||||
@ -49,11 +48,11 @@ class MailInviteCest
|
|||||||
|
|
||||||
$I->amOnRoute('/user/registration', ['token' => $token]);
|
$I->amOnRoute('/user/registration', ['token' => $token]);
|
||||||
$I->see('Account registration');
|
$I->see('Account registration');
|
||||||
$I->fillField( 'User[username]', 'NewUser');
|
$I->fillField('User[username]', 'NewUser');
|
||||||
$I->fillField( 'Password[newPassword]', 'NewUser123');
|
$I->fillField('Password[newPassword]', 'NewUser123');
|
||||||
$I->fillField( 'Password[newPasswordConfirm]', 'NewUser123');
|
$I->fillField('Password[newPasswordConfirm]', 'NewUser123');
|
||||||
$I->fillField( 'Profile[firstname]', 'New');
|
$I->fillField('Profile[firstname]', 'New');
|
||||||
$I->fillField( 'Profile[lastname]', 'User');
|
$I->fillField('Profile[lastname]', 'User');
|
||||||
$I->click('#registration-form [type="submit"]');
|
$I->click('#registration-form [type="submit"]');
|
||||||
|
|
||||||
|
|
||||||
@ -91,14 +90,13 @@ class MailInviteCest
|
|||||||
|
|
||||||
$I->amOnRoute('/user/registration', ['token' => $token]);
|
$I->amOnRoute('/user/registration', ['token' => $token]);
|
||||||
$I->see('Account registration');
|
$I->see('Account registration');
|
||||||
$I->fillField( 'User[username]', 'NewUser');
|
$I->fillField('User[username]', 'NewUser');
|
||||||
$I->fillField( 'Password[newPassword]', 'NewUser123');
|
$I->fillField('Password[newPassword]', 'NewUser123');
|
||||||
$I->fillField( 'Password[newPasswordConfirm]', 'NewUser123');
|
$I->fillField('Password[newPasswordConfirm]', 'NewUser123');
|
||||||
$I->fillField( 'Profile[firstname]', 'New');
|
$I->fillField('Profile[firstname]', 'New');
|
||||||
$I->fillField( 'Profile[lastname]', 'User');
|
$I->fillField('Profile[lastname]', 'User');
|
||||||
$I->click('#registration-form [type="submit"]');
|
$I->click('#registration-form [type="submit"]');
|
||||||
|
|
||||||
|
|
||||||
$I->see('Dashboard');
|
$I->see('Dashboard');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
protected/humhub/modules/user/views/people/_layout.php
Normal file
9
protected/humhub/modules/user/views/people/_layout.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use humhub\modules\ui\view\helpers\ThemeHelper;
|
||||||
|
|
||||||
|
/* @var $content string */
|
||||||
|
?>
|
||||||
|
<div class="<?php if (ThemeHelper::isFluid()): ?>container-fluid<?php else: ?>container<?php endif; ?> container-directory container-people">
|
||||||
|
<?= $content; ?>
|
||||||
|
</div>
|
63
protected/humhub/modules/user/views/people/index.php
Normal file
63
protected/humhub/modules/user/views/people/index.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
use humhub\assets\DirectoryAsset;
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use humhub\modules\user\components\PeopleQuery;
|
||||||
|
use humhub\modules\user\widgets\PeopleCard;
|
||||||
|
use humhub\modules\user\widgets\PeopleFilters;
|
||||||
|
use humhub\widgets\Button;
|
||||||
|
use humhub\widgets\ModalButton;
|
||||||
|
|
||||||
|
/* @var $this \yii\web\View */
|
||||||
|
/* @var $people PeopleQuery */
|
||||||
|
/* @var $showInviteButton bool */
|
||||||
|
|
||||||
|
DirectoryAsset::register($this);
|
||||||
|
?>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
|
||||||
|
<div class="panel-heading">
|
||||||
|
<?php if ($people->isFilteredByGroup()) : ?>
|
||||||
|
<?= Yii::t('UserModule.base', '<strong>Group</strong> members - {group}', ['{group}' => Html::encode($people->filteredGroup->name)]); ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<?= Yii::t('UserModule.base', '<strong>People</strong>'); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($showInviteButton): ?>
|
||||||
|
<?= ModalButton::primary(Yii::t('UserModule.base', 'Send invite'))
|
||||||
|
->load(['/user/invite'])->icon('invite')->sm()->right() ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<?= PeopleFilters::widget(); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row cards">
|
||||||
|
<?php if (!$people->exists()): ?>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<?= Yii::t('UserModule.base', 'No results found! Try other keywords or remove filters.'); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php foreach ($people->all() as $user) : ?>
|
||||||
|
<?= PeopleCard::widget(['user' => $user]); ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (!$people->isLastPage()) : ?>
|
||||||
|
<div class="directory-load-more">
|
||||||
|
<?= Button::primary(Yii::t('UserModule.base', 'Load more'))
|
||||||
|
->icon('fa-angle-down')
|
||||||
|
->action('directory.loadMore')
|
||||||
|
->options([
|
||||||
|
'data-current-page' => $people->pagination->getPage() + 1,
|
||||||
|
'data-total-pages' => $people->pagination->getPageCount(),
|
||||||
|
]) ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\widgets;
|
||||||
|
|
||||||
|
use humhub\components\Widget;
|
||||||
|
use humhub\modules\friendship\widgets\FriendshipButton;
|
||||||
|
use humhub\modules\user\models\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleActionsButton shows directory options (following or friendship) for listed users
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class PeopleActionButtons extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User
|
||||||
|
*/
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Template for buttons
|
||||||
|
*/
|
||||||
|
public $template = '{buttons}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$html = UserFollowButton::widget([
|
||||||
|
'user' => $this->user,
|
||||||
|
'followOptions' => ['class' => 'btn btn-primary btn-sm'],
|
||||||
|
'unfollowOptions' => ['class' => 'btn btn-primary btn-sm active'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$html .= FriendshipButton::widget([
|
||||||
|
'user' => $this->user,
|
||||||
|
'options' => [
|
||||||
|
'friends' => ['attrs' => ['class' => 'btn btn-info btn-sm active']],
|
||||||
|
'addFriend' => ['attrs' => ['class' => 'btn btn-info btn-sm']],
|
||||||
|
'acceptFriendRequest' => ['attrs' => ['class' => 'btn btn-info btn-sm active'], 'togglerClass' => 'btn btn-info btn-sm active'],
|
||||||
|
'cancelFriendRequest' => ['attrs' => ['class' => 'btn btn-info btn-sm active']],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (trim($html) === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace('{buttons}', $html, $this->template);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
protected/humhub/modules/user/widgets/PeopleCard.php
Normal file
52
protected/humhub/modules/user/widgets/PeopleCard.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\widgets;
|
||||||
|
|
||||||
|
use humhub\components\Widget;
|
||||||
|
use humhub\modules\admin\models\forms\PeopleSettingsForm;
|
||||||
|
use humhub\modules\user\models\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleActionsButton shows directory options (following or friendship) for listed users
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class PeopleCard extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User
|
||||||
|
*/
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string HTML wrapper around card
|
||||||
|
*/
|
||||||
|
public $template = '<div class="card card-people col-lg-3 col-md-4 col-sm-6 col-xs-12">{card}</div>';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$card = $this->render('peopleCard', [
|
||||||
|
'user' => $this->user
|
||||||
|
]);
|
||||||
|
|
||||||
|
return str_replace('{card}', $card, $this->template);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function config($name): string
|
||||||
|
{
|
||||||
|
$peopleSettingsForm = new PeopleSettingsForm();
|
||||||
|
|
||||||
|
return isset($peopleSettingsForm->$name) ? $peopleSettingsForm->$name : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
82
protected/humhub/modules/user/widgets/PeopleDetails.php
Normal file
82
protected/humhub/modules/user/widgets/PeopleDetails.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\widgets;
|
||||||
|
|
||||||
|
use humhub\components\Widget;
|
||||||
|
use humhub\modules\user\models\ProfileField;
|
||||||
|
use humhub\modules\user\models\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleDetails shows details for back side of the people card
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class PeopleDetails extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User
|
||||||
|
*/
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Separator between lines
|
||||||
|
*/
|
||||||
|
public $separator = '<br>';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Template for lines
|
||||||
|
*/
|
||||||
|
public $template = '{lines}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$lines = [];
|
||||||
|
|
||||||
|
for ($i = 1; $i <= 3; $i++) {
|
||||||
|
if ($profileField = $this->getProfileFieldValue(PeopleCard::config('detail' . $i))) {
|
||||||
|
$lines[] = $profileField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($lines)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace('{lines}', implode($this->separator, $lines), $this->template);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user profile field value by internal name
|
||||||
|
*
|
||||||
|
* @param string $internalName
|
||||||
|
* @return false|string
|
||||||
|
*/
|
||||||
|
private function getProfileFieldValue(string $internalName)
|
||||||
|
{
|
||||||
|
if (empty($internalName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profileField = ProfileField::find()
|
||||||
|
->where(['visible' => 1])
|
||||||
|
->andWhere(['internal_name' => $internalName])
|
||||||
|
->one();
|
||||||
|
|
||||||
|
if (!$profileField) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $profileField->getUserValue($this->user, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
136
protected/humhub/modules/user/widgets/PeopleFilters.php
Normal file
136
protected/humhub/modules/user/widgets/PeopleFilters.php
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\widgets;
|
||||||
|
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use humhub\modules\admin\models\forms\PeopleSettingsForm;
|
||||||
|
use humhub\modules\ui\widgets\DirectoryFilters;
|
||||||
|
use humhub\modules\user\models\Group;
|
||||||
|
use humhub\modules\user\models\ProfileField;
|
||||||
|
use Yii;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleFilters displays the filters on the directory people page
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class PeopleFilters extends DirectoryFilters
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public $pageUrl = '/user/people';
|
||||||
|
|
||||||
|
protected function initDefaultFilters()
|
||||||
|
{
|
||||||
|
// Keyword
|
||||||
|
$this->addFilter('keyword', [
|
||||||
|
'title' => Yii::t('UserModule.base', 'Find people by their profile data or user tags'),
|
||||||
|
'placeholder' => Yii::t('UserModule.base', 'Search...'),
|
||||||
|
'type' => 'input',
|
||||||
|
'wrapperClass' => 'col-md-6 form-search-filter-keyword',
|
||||||
|
'afterInput' => Html::submitButton('<span class="fa fa-search"></span>', ['class' => 'form-button-search']),
|
||||||
|
'sortOrder' => 100,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Group
|
||||||
|
$groupOptions = [];
|
||||||
|
$groups = Group::findAll(['show_at_directory' => 1]);
|
||||||
|
if ($groups) {
|
||||||
|
$groupOptions[''] = Yii::t('UserModule.base', 'Any');
|
||||||
|
foreach ($groups as $group) {
|
||||||
|
$groupOptions[$group->id] = $group->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addFilter('groupId', [
|
||||||
|
'title' => Yii::t('UserModule.base', 'User Group'),
|
||||||
|
'type' => 'dropdown',
|
||||||
|
'options' => $groupOptions,
|
||||||
|
'sortOrder' => 200,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorting
|
||||||
|
$this->addFilter('sort', [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Sorting'),
|
||||||
|
'type' => 'dropdown',
|
||||||
|
'options' => PeopleSettingsForm::getSortingOptions(),
|
||||||
|
'sortOrder' => 300,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Connection
|
||||||
|
$connectionOptions = [
|
||||||
|
'' => Yii::t('UserModule.base', 'All'),
|
||||||
|
'followers' => Yii::t('UserModule.base', 'Followers'),
|
||||||
|
'following' => Yii::t('UserModule.base', 'Following'),
|
||||||
|
];
|
||||||
|
if (Yii::$app->getModule('friendship')->settings->get('enable')) {
|
||||||
|
$connectionOptions['friends'] = Yii::t('UserModule.base', 'Friends');
|
||||||
|
$connectionOptions['pending_friends'] = Yii::t('UserModule.base', 'Pending Requests');
|
||||||
|
}
|
||||||
|
$this->addFilter('connection', [
|
||||||
|
'title' => Yii::t('SpaceModule.base', 'Status'),
|
||||||
|
'type' => 'dropdown',
|
||||||
|
'options' => $connectionOptions,
|
||||||
|
'sortOrder' => 400,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Profile fields
|
||||||
|
$profileFields = ProfileField::findAll(['directory_filter' => 1]);
|
||||||
|
$profileFieldSortOrder = 1000;
|
||||||
|
foreach ($profileFields as $profileField) {
|
||||||
|
$this->initProfileFieldFilter($profileField, $profileFieldSortOrder);
|
||||||
|
$profileFieldSortOrder += 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function initProfileFieldFilter(ProfileField $profileField, $sortOrder = 1000)
|
||||||
|
{
|
||||||
|
$profileFieldType = $profileField->getFieldType();
|
||||||
|
|
||||||
|
if (!$profileFieldType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$definition = $profileFieldType->getFieldFormDefinition();
|
||||||
|
$fieldType = isset($definition[$profileField->internal_name]['type']) ? $definition[$profileField->internal_name]['type'] : null;
|
||||||
|
|
||||||
|
$filterData = [
|
||||||
|
'title' => Yii::t($profileField->getTranslationCategory(), $profileField->title),
|
||||||
|
'type' => $fieldType,
|
||||||
|
'sortOrder' => $sortOrder,
|
||||||
|
];
|
||||||
|
|
||||||
|
switch ($fieldType) {
|
||||||
|
case 'text':
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'dropdownlist':
|
||||||
|
$filterData['options'] = array_merge(['' => Yii::t('UserModule.base', 'Any')], $definition[$profileField->internal_name]['items']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Skip not supported type
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addFilter('fields[' . $profileField->internal_name . ']', $filterData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDefaultValue(string $filter): string
|
||||||
|
{
|
||||||
|
switch ($filter) {
|
||||||
|
case 'sort':
|
||||||
|
return PeopleCard::config('defaultSorting');
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
37
protected/humhub/modules/user/widgets/PeopleIcons.php
Normal file
37
protected/humhub/modules/user/widgets/PeopleIcons.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\widgets;
|
||||||
|
|
||||||
|
use humhub\components\Widget;
|
||||||
|
use humhub\modules\user\models\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleIcons shows footer icons for people cards
|
||||||
|
*
|
||||||
|
* @since 1.9
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class PeopleIcons extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User
|
||||||
|
*/
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
return $this->render('peopleIcons', [
|
||||||
|
'user' => $this->user
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
protected/humhub/modules/user/widgets/PeopleTagList.php
Normal file
74
protected/humhub/modules/user/widgets/PeopleTagList.php
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace humhub\modules\user\widgets;
|
||||||
|
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use yii\helpers\Url;
|
||||||
|
use humhub\components\Widget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PeopleTagList displays the user tags on the directory people page
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
|
* @author Luke
|
||||||
|
*/
|
||||||
|
class PeopleTagList extends Widget
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \humhub\modules\user\models\User
|
||||||
|
*/
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int number of max. displayed tags
|
||||||
|
*/
|
||||||
|
public $maxTags = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Template for tags
|
||||||
|
*/
|
||||||
|
public $template = '{tags}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$html = '';
|
||||||
|
|
||||||
|
$tags = $this->user->getTags();
|
||||||
|
|
||||||
|
$count = count($tags);
|
||||||
|
|
||||||
|
if ($count === 0) {
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($count > $this->maxTags) {
|
||||||
|
$tags = array_slice($tags, 0, $this->maxTags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($tags)) {
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($tags as $tag) {
|
||||||
|
if (trim($tag) !== '') {
|
||||||
|
$html .= Html::a(Html::encode($tag), Url::to(['/user/people', 'keyword' => trim($tag)]), ['class' => 'label label-default']) . ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($html === '') {
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace('{tags}', $html, $this->template);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -44,7 +44,7 @@ class UserFollowButton extends \yii\base\Widget
|
|||||||
/**
|
/**
|
||||||
* @var array options for unfollow button
|
* @var array options for unfollow button
|
||||||
*/
|
*/
|
||||||
public $unfollowOptions = ['class' => 'btn btn-info'];
|
public $unfollowOptions = ['class' => 'btn btn-primary active'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
@ -52,10 +52,10 @@ class UserFollowButton extends \yii\base\Widget
|
|||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
if ($this->followLabel === null) {
|
if ($this->followLabel === null) {
|
||||||
$this->followLabel = Yii::t("UserModule.base", "Follow");
|
$this->followLabel = Yii::t('UserModule.base', 'Follow');
|
||||||
}
|
}
|
||||||
if ($this->unfollowLabel === null) {
|
if ($this->unfollowLabel === null) {
|
||||||
$this->unfollowLabel = Yii::t("UserModule.base", "Unfollow");
|
$this->unfollowLabel = '<span class="glyphicon glyphicon-ok"></span> ' . Yii::t('UserModule.base', 'Following');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($this->followOptions['class'])) {
|
if (!isset($this->followOptions['class'])) {
|
||||||
@ -111,6 +111,11 @@ class UserFollowButton extends \yii\base\Widget
|
|||||||
$this->followOptions['data-ui-loader'] = '';
|
$this->followOptions['data-ui-loader'] = '';
|
||||||
$this->unfollowOptions['data-ui-loader'] = '';
|
$this->unfollowOptions['data-ui-loader'] = '';
|
||||||
|
|
||||||
|
// Confirm action "Unfollow"
|
||||||
|
$this->unfollowOptions['data-action-confirm'] = Yii::t('SpaceModule.base', 'Would you like to unfollow {userName}?', [
|
||||||
|
'{userName}' => '<strong>' . $this->user->getDisplayName() . '</strong>'
|
||||||
|
]);
|
||||||
|
|
||||||
$module = Yii::$app->getModule('user');
|
$module = Yii::$app->getModule('user');
|
||||||
|
|
||||||
// still enable unfollow if following was disabled afterwards.
|
// still enable unfollow if following was disabled afterwards.
|
||||||
|
53
protected/humhub/modules/user/widgets/views/peopleCard.php
Normal file
53
protected/humhub/modules/user/widgets/views/peopleCard.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
use humhub\libs\Html;
|
||||||
|
use humhub\modules\user\models\User;
|
||||||
|
use humhub\modules\user\widgets\PeopleActionButtons;
|
||||||
|
use humhub\modules\user\widgets\Image;
|
||||||
|
use humhub\modules\user\widgets\PeopleDetails;
|
||||||
|
use humhub\modules\user\widgets\PeopleIcons;
|
||||||
|
use humhub\modules\user\widgets\PeopleTagList;
|
||||||
|
use yii\web\View;
|
||||||
|
|
||||||
|
/* @var $this View */
|
||||||
|
/* @var $user User */
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="card-panel">
|
||||||
|
<div class="card-bg-image"<?php if ($user->getProfileBannerImage()->hasImage()) : ?> style="background-image: url('<?= $user->getProfileBannerImage()->getUrl() ?>')"<?php endif; ?>></div>
|
||||||
|
<div class="card-header">
|
||||||
|
<?= Image::widget([
|
||||||
|
'user' => $user,
|
||||||
|
'htmlOptions' => ['class' => 'card-image-wrapper'],
|
||||||
|
'linkOptions' => ['data-contentcontainer-id' => $user->contentcontainer_id, 'class' => 'card-image-link'],
|
||||||
|
'width' => 94,
|
||||||
|
]); ?>
|
||||||
|
<?php /*<div class="card-icons">
|
||||||
|
<?= PeopleIcons::widget(['user' => $user]); ?>
|
||||||
|
</div> */ ?>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<strong class="card-title"><?= Html::containerLink($user); ?></strong>
|
||||||
|
<?php if (trim($user->profile->title) !== '') : ?>
|
||||||
|
<div><?= Html::encode($user->profile->title); ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?= PeopleDetails::widget([
|
||||||
|
'user' => $user,
|
||||||
|
'template' => '<div class="card-details">{lines}</div>',
|
||||||
|
'separator' => '<br>',
|
||||||
|
]); ?>
|
||||||
|
<?= PeopleTagList::widget([
|
||||||
|
'user' => $user,
|
||||||
|
'template' => '<div class="card-tags">{tags}</div>',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
||||||
|
<?= PeopleActionButtons::widget([
|
||||||
|
'user' => $user,
|
||||||
|
'template' => '<div class="card-footer">{buttons}</div>',
|
||||||
|
]); ?>
|
||||||
|
</div>
|
17
protected/humhub/modules/user/widgets/views/peopleIcons.php
Normal file
17
protected/humhub/modules/user/widgets/views/peopleIcons.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.humhub.org/
|
||||||
|
* @copyright Copyright (c) 2021 HumHub GmbH & Co. KG
|
||||||
|
* @license https://www.humhub.com/licences
|
||||||
|
*/
|
||||||
|
|
||||||
|
use humhub\modules\user\models\User;
|
||||||
|
use yii\web\View;
|
||||||
|
|
||||||
|
/* @var $this View */
|
||||||
|
/* @var $user User */
|
||||||
|
?>
|
||||||
|
|
||||||
|
<a href="#" class="fa fa-envelope-o"></a>
|
||||||
|
<a href="#" class="fa fa-comment-o"></a>
|
||||||
|
<a href="#" class="fa fa-mobile-phone"></a>
|
@ -11,6 +11,6 @@ use tests\codeception\_support\BasePage;
|
|||||||
class DirectoryMemberPage extends BasePage
|
class DirectoryMemberPage extends BasePage
|
||||||
{
|
{
|
||||||
|
|
||||||
public $route = 'directory/directory/members';
|
public $route = 'user/people';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,10 @@ use tests\codeception\_support\BasePage;
|
|||||||
class DirectoryPage extends BasePage
|
class DirectoryPage extends BasePage
|
||||||
{
|
{
|
||||||
|
|
||||||
public $route = 'directory/directory';
|
public $route = 'user/people';
|
||||||
|
|
||||||
public function clickMembers()
|
public function clickMembers()
|
||||||
{
|
{
|
||||||
$this->actor->click('Members');
|
|
||||||
if($this->actor instanceof \AcceptanceTester) {
|
if($this->actor instanceof \AcceptanceTester) {
|
||||||
$this->actor->waitForText('Member directory', 30);
|
$this->actor->waitForText('Member directory', 30);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ class AjaxButton extends Widget
|
|||||||
$return = 'return false';
|
$return = 'return false';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->view->registerJs("$('#{$this->htmlOptions['id']}').click(function() {
|
$this->view->registerJs("$('#{$this->htmlOptions['id']}').click(function(evt) {
|
||||||
$.ajax(" . Json::encode($this->ajaxOptions) . ");
|
$.ajax(" . Json::encode($this->ajaxOptions) . ");
|
||||||
{$return};
|
{$return};
|
||||||
});");
|
});");
|
||||||
|
63
static/js/humhub/humhub.directory.js
Normal file
63
static/js/humhub/humhub.directory.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
humhub.module('directory', function(module, require, $) {
|
||||||
|
const client = require('client');
|
||||||
|
const loader = require('ui.loader');
|
||||||
|
|
||||||
|
const applyFilters = function(evt) {
|
||||||
|
$(evt.$trigger).closest('form').submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadMore = function(evt) {
|
||||||
|
const urlParams = {page: $(evt.$trigger).data('current-page') + 1};
|
||||||
|
|
||||||
|
client.get(module.config.loadMoreUrl, {data: urlParams}).then(function (response) {
|
||||||
|
$('.container-directory .card:hidden').show();
|
||||||
|
$('.container-directory .cards').append(response.response);
|
||||||
|
if (urlParams.page == $(evt.$trigger).data('total-pages')) {
|
||||||
|
// Remove button "Load more" because the last page was loaded
|
||||||
|
$(evt.$trigger).parent().remove();
|
||||||
|
} else {
|
||||||
|
$(evt.$trigger).data('current-page', urlParams.page);
|
||||||
|
hideLastNotCompletedRow();
|
||||||
|
}
|
||||||
|
}).catch(function(err) {
|
||||||
|
module.log.error(err, true);
|
||||||
|
reject();
|
||||||
|
}).finally(function() {
|
||||||
|
loader.reset(evt.$trigger);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideLastNotCompletedRow = function() {
|
||||||
|
const cardsNum = $('.container-directory .card').length;
|
||||||
|
if (!cardsNum) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadMoreButton = $('.directory-load-more button');
|
||||||
|
if (loadMoreButton.data('current-page') === loadMoreButton.data('total-pages')) {
|
||||||
|
// No reason to hide a not completed row if current page is last
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display button to load more cards
|
||||||
|
loadMoreButton.parent().show();
|
||||||
|
|
||||||
|
const cardsPerRow = Math.floor($('.container-directory .row').outerWidth() / $('.container-directory .card:first').width());
|
||||||
|
const hideLastCardsNum = cardsNum % cardsPerRow;
|
||||||
|
if (hideLastCardsNum > 0 && cardsNum > cardsPerRow) {
|
||||||
|
// Hide cards from not completed row
|
||||||
|
$('.container-directory .card').slice(-hideLastCardsNum).hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const init = function() {
|
||||||
|
hideLastNotCompletedRow();
|
||||||
|
$('input.form-search-filter[name=keyword]').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.export({
|
||||||
|
init,
|
||||||
|
applyFilters,
|
||||||
|
loadMore,
|
||||||
|
});
|
||||||
|
});
|
@ -399,7 +399,11 @@ humhub.module('ui.additions', function (module, require, $) {
|
|||||||
/**
|
/**
|
||||||
* @deprecated since v1.2
|
* @deprecated since v1.2
|
||||||
*/
|
*/
|
||||||
function setModalLoader() {
|
function setModalLoader(evt) {
|
||||||
$(".modal-footer .btn").hide();
|
var modalFooter = $('.modal-footer');
|
||||||
$(".modal-footer .loader").removeClass("hidden");
|
if (typeof evt === 'object') {
|
||||||
}
|
modalFooter = $(evt.target).closest('.modal-footer');
|
||||||
|
}
|
||||||
|
modalFooter.find('.btn').hide();
|
||||||
|
modalFooter.find('.loader').removeClass('hidden');
|
||||||
|
}
|
@ -85,7 +85,20 @@
|
|||||||
&:active,
|
&:active,
|
||||||
&.active {
|
&.active {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
background: darken(@primary, 5%) !important;
|
border: 1px solid @primary;
|
||||||
|
padding: 7px 15px;
|
||||||
|
color: @primary !important;
|
||||||
|
background: @text-color-contrast !important;
|
||||||
|
box-shadow: none;
|
||||||
|
&.btn-sm {
|
||||||
|
padding: 3px 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active:hover,
|
||||||
|
&.active:focus {
|
||||||
|
border: 1px solid darken(@primary, 5%);
|
||||||
|
color: darken(@primary, 5%) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +130,20 @@
|
|||||||
&:active,
|
&:active,
|
||||||
&.active {
|
&.active {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
background: darken(@info, 5%);
|
border: 1px solid @info;
|
||||||
|
padding: 7px 15px;
|
||||||
|
color: @info !important;
|
||||||
|
background: @text-color-contrast !important;
|
||||||
|
box-shadow: none;
|
||||||
|
&.btn-sm {
|
||||||
|
padding: 3px 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active:hover,
|
||||||
|
&.active:focus {
|
||||||
|
border: 1px solid darken(@info, 5%);
|
||||||
|
color: darken(@info, 5%) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
184
static/less/directory.less
Normal file
184
static/less/directory.less
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
.container-directory {
|
||||||
|
&.container-fluid {
|
||||||
|
@media (min-width: 500px) {
|
||||||
|
.card {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1000px) {
|
||||||
|
.card {
|
||||||
|
width: 33.33333333%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1300px) {
|
||||||
|
.card {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1600px) {
|
||||||
|
.card {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1900px) {
|
||||||
|
.card {
|
||||||
|
width: 16.66666667%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-search {
|
||||||
|
.row > div {
|
||||||
|
padding-bottom: 3px;
|
||||||
|
}
|
||||||
|
.form-search-filter-keyword {
|
||||||
|
position: relative;
|
||||||
|
.form-button-search {
|
||||||
|
position: absolute;
|
||||||
|
right: 18px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-control.form-search-filter {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
margin: 3px 0 0;
|
||||||
|
padding: 8px 30px 10px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: solid 1px #c5c5c5;
|
||||||
|
}
|
||||||
|
.form-button-search {
|
||||||
|
background: none;
|
||||||
|
border: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #000;
|
||||||
|
top: initial;
|
||||||
|
bottom: 9px;
|
||||||
|
}
|
||||||
|
.form-search-field-info {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-search-reset {
|
||||||
|
text-decoration: underline;
|
||||||
|
display: block;
|
||||||
|
margin-top: 26px;
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cards {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.card-panel {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 15px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-icons .fa {
|
||||||
|
color: #21a1b3;
|
||||||
|
span {
|
||||||
|
font: 12px 'Open Sans', sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-bg-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 86px;
|
||||||
|
background-color: #cfcfcf;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
.card-header {
|
||||||
|
position: absolute;
|
||||||
|
padding: 16px;
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
.card-image-wrapper {
|
||||||
|
display: table-cell;
|
||||||
|
width: 98px;
|
||||||
|
}
|
||||||
|
.card-image-link {
|
||||||
|
display: inline-block;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
.card-icons {
|
||||||
|
display: table-cell;
|
||||||
|
padding: 0 0 2px 5px;
|
||||||
|
text-align: right;
|
||||||
|
vertical-align: bottom;
|
||||||
|
font-size: 16px;
|
||||||
|
.fa {
|
||||||
|
color: #21a1b3;
|
||||||
|
&.fa-mobile-phone {
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 15px;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card-body {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 44px 16px 24px 16px;
|
||||||
|
overflow: auto;
|
||||||
|
.card-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
.card-details {
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #57646c;
|
||||||
|
a {
|
||||||
|
color: #21a1b3;
|
||||||
|
text-decoration: underline;
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card-tags {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card-footer {
|
||||||
|
padding: 0 16px 20px;
|
||||||
|
a.btn {
|
||||||
|
float: left;
|
||||||
|
margin: 0 8px 4px 0;
|
||||||
|
white-space: normal;
|
||||||
|
hyphens: none;
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.btn-group a.btn {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory-load-more {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
padding: 12px 0 15px;
|
||||||
|
}
|
||||||
|
}
|
@ -204,6 +204,11 @@
|
|||||||
@import "print.less";
|
@import "print.less";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@prev-directory: false;
|
||||||
|
& when not(@prev-directory) {
|
||||||
|
@import "directory.less";
|
||||||
|
}
|
||||||
|
|
||||||
@import "../css/select2Theme/build.less";
|
@import "../css/select2Theme/build.less";
|
||||||
|
|
||||||
// LEGACY/DEPRECATED User- & Space picker
|
// LEGACY/DEPRECATED User- & Space picker
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user