Compare commits
414
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3b1951d25 | ||
|
|
cad205960d | ||
|
|
73e049e47d | ||
|
|
0ae3e4fe08 | ||
|
|
28addf5e33 | ||
|
|
d5a33b382e | ||
|
|
2fdec0a65f | ||
|
|
6fb6aef199 | ||
|
|
f69b8f39ad | ||
|
|
35bda2828c | ||
|
|
bda659b910 | ||
|
|
c8ec9c4eeb | ||
|
|
9451357e02 | ||
|
|
727e449ebc | ||
|
|
b5425423d6 | ||
|
|
66e78aff6a | ||
|
|
497ff1b96d | ||
|
|
c429024a54 | ||
|
|
0778a1d30c | ||
|
|
3748d00c2f | ||
|
|
a525d9c085 | ||
|
|
dff8dcf565 | ||
|
|
0d22a14604 | ||
|
|
724478d0c9 | ||
|
|
0ba0d1c15d | ||
|
|
9593b6502e | ||
|
|
e53283da65 | ||
|
|
f0d1cb8020 | ||
|
|
9076f81185 | ||
|
|
b7d4ab9515 | ||
|
|
2b98c60d2a | ||
|
|
99ed8806da | ||
|
|
d0fbce13fb | ||
|
|
675aec669b | ||
|
|
ca718a5efe | ||
|
|
3aabb8fa7b | ||
|
|
2fffea39fa | ||
|
|
7584491ff5 | ||
|
|
84b2902613 | ||
|
|
2d6be0cb2e | ||
|
|
e6c02617e6 | ||
|
|
0b56b41c3c | ||
|
|
f89e11b5fb | ||
|
|
785168ecc2 | ||
|
|
9f430cee11 | ||
|
|
785387b796 | ||
|
|
f940930c66 | ||
|
|
8cb06bf641 | ||
|
|
000352052d | ||
|
|
988f153d9f | ||
|
|
6dd452317b | ||
|
|
34feaac2ac | ||
|
|
e25f47a511 | ||
|
|
cc999dd24e | ||
|
|
28f67ffe3c | ||
|
|
4f6a006ad9 | ||
|
|
662700b4f2 | ||
|
|
eabbf48ee0 | ||
|
|
6ec692bd1c | ||
|
|
aa0ef7ccc6 | ||
|
|
e26e6fd460 | ||
|
|
2ded2924a1 | ||
|
|
87f1920373 | ||
|
|
b7f911c9b8 | ||
|
|
84aea5c847 | ||
|
|
98fc287f10 | ||
|
|
686edf1c6f | ||
|
|
deb094b5c9 | ||
|
|
d425133cae | ||
|
|
9b6ae9f9f8 | ||
|
|
4a95a9692d | ||
|
|
06439bc9a0 | ||
|
|
12683df0ab | ||
|
|
0cb53b2d80 | ||
|
|
5fd9b1871f | ||
|
|
fb51ae80ac | ||
|
|
b9d141c4f1 | ||
|
|
af4edac469 | ||
|
|
0451f9942c | ||
|
|
657c030033 | ||
|
|
d761914786 | ||
|
|
625bdbb2e2 | ||
|
|
d5f9e1fc2b | ||
|
|
ce058ae824 | ||
|
|
dee5060a24 | ||
|
|
c70e8a6b0d | ||
|
|
cb9b96c861 | ||
|
|
4bd5a61fde | ||
|
|
46ff310b01 | ||
|
|
96b05a7b25 | ||
|
|
563528cdc6 | ||
|
|
efa3289491 | ||
|
|
3460f607b5 | ||
|
|
0384fab421 | ||
|
|
b3ac9b9eec | ||
|
|
bfa0685f2e | ||
|
|
59226dbdc4 | ||
|
|
446e8352b5 | ||
|
|
190ca25b2a | ||
|
|
f121ee356b | ||
|
|
b3d59fc182 | ||
|
|
20f6295f84 | ||
|
|
2c36203690 | ||
|
|
458d8ec61c | ||
|
|
284dfa3fe8 | ||
|
|
08e97fe2cb | ||
|
|
7e63047313 | ||
|
|
d9834fe068 | ||
|
|
dc43a9503d | ||
|
|
a75425ca12 | ||
|
|
8c20654280 | ||
|
|
bceef69a72 | ||
|
|
1e310f0da5 | ||
|
|
ab90b907f8 | ||
|
|
f1aacf8008 | ||
|
|
ce82b67c47 | ||
|
|
3024ae8b23 | ||
|
|
7dcb8e280c | ||
|
|
f9dfe076a0 | ||
|
|
db88079f26 | ||
|
|
3f1ae0f5a1 | ||
|
|
f699d2c569 | ||
|
|
fdb63fcd8a | ||
|
|
52fb27b4fe | ||
|
|
7234fa0810 | ||
|
|
581e32e98b | ||
|
|
06780015d4 | ||
|
|
35bdd38f4c | ||
|
|
eacba1bec3 | ||
|
|
975cc50272 | ||
|
|
52b0ec7c72 | ||
|
|
de02944d0d | ||
|
|
da1c8652e6 | ||
|
|
012ba1fd36 | ||
|
|
cbfc5fcee5 | ||
|
|
232e1d5ec9 | ||
|
|
aca3c778e0 | ||
|
|
88a2463d13 | ||
|
|
f3e797a59a | ||
|
|
0869ac7c24 | ||
|
|
304518fbe7 | ||
|
|
49577a7e1a | ||
|
|
606ee2016d | ||
|
|
8608a2d67b | ||
|
|
3bac8dc09b | ||
|
|
f61b8a7bcc | ||
|
|
b6d3daaa35 | ||
|
|
33a928febb | ||
|
|
06c84867ec | ||
|
|
8a9543cd2d | ||
|
|
4f67b69984 | ||
|
|
28df8681e4 | ||
|
|
4222dbc243 | ||
|
|
2f27e7f5c9 | ||
|
|
c5fb951546 | ||
|
|
ecd7aa27f0 | ||
|
|
ecd01e1396 | ||
|
|
76b226629f | ||
|
|
97fae9bf9d | ||
|
|
5621b5acba | ||
|
|
ff237599a8 | ||
|
|
679ca91fc9 | ||
|
|
1dea234cb7 | ||
|
|
e42d06904e | ||
|
|
cb2fa84ade | ||
|
|
0a0b0e7518 | ||
|
|
65dc4fd37e | ||
|
|
b13f6bbea9 | ||
|
|
10e463b8b4 | ||
|
|
316f7a9a16 | ||
|
|
5e79d0208a | ||
|
|
5cdca60cce | ||
|
|
86a2d277f6 | ||
|
|
ad59bc0adc | ||
|
|
556d863b45 | ||
|
|
673531ae22 | ||
|
|
a9d5c0de28 | ||
|
|
b43e37fa83 | ||
|
|
6c4b30f1f7 | ||
|
|
c4a4354aff | ||
|
|
ad77de0424 | ||
|
|
c4d4ac2bfe | ||
|
|
0718772740 | ||
|
|
0ace8c9cb6 | ||
|
|
0482121441 | ||
|
|
0df8eaa2e3 | ||
|
|
66a570bbf7 | ||
|
|
0badc52f17 | ||
|
|
4cf1fedc61 | ||
|
|
341b5dc9ec | ||
|
|
f5e2aec818 | ||
|
|
77a65b71a2 | ||
|
|
5f1cf06e36 | ||
|
|
b734c3de18 | ||
|
|
808bb0eb86 | ||
|
|
682f3b75bf | ||
|
|
5b9b5c0d38 | ||
|
|
3a0a132701 | ||
|
|
60c3582947 | ||
|
|
9039334138 | ||
|
|
5ee403ab28 | ||
|
|
fdf44e8b4a | ||
|
|
91cdbec3af | ||
|
|
45354a3192 | ||
|
|
846cfef1b8 | ||
|
|
80dba6d9b7 | ||
|
|
bf615f8494 | ||
|
|
4c67d442d6 | ||
|
|
36615aac21 | ||
|
|
4e6fc7c074 | ||
|
|
e0357d0003 | ||
|
|
8533c8cdc6 | ||
|
|
bb3d000e5e | ||
|
|
842b54d879 | ||
|
|
256e24c5a4 | ||
|
|
07df49c481 | ||
|
|
a11a29de19 | ||
|
|
044eb7e532 | ||
|
|
7f93a5035c | ||
|
|
358027a8e0 | ||
|
|
98fe43e12c | ||
|
|
c096a30b81 | ||
|
|
02157f332e | ||
|
|
cd28625309 | ||
|
|
6868af609f | ||
|
|
445f369ff2 | ||
|
|
2a1ffb4259 | ||
|
|
4876cb631e | ||
|
|
4c35d95a73 | ||
|
|
8f4e6268a4 | ||
|
|
d7b60690b2 | ||
|
|
4de93f9fd9 | ||
|
|
f26c384257 | ||
|
|
78213e6f41 | ||
|
|
a188c707d8 | ||
|
|
ff4585327e | ||
|
|
fa1d302ea6 | ||
|
|
52394c6289 | ||
|
|
76fa76a5af | ||
|
|
d6a441cb96 | ||
|
|
85bbc384a7 | ||
|
|
80105c857e | ||
|
|
09151e97d1 | ||
|
|
9802161af1 | ||
|
|
00d7bd562c | ||
|
|
124ad2f061 | ||
|
|
a37767c2e8 | ||
|
|
d5950d9cd7 | ||
|
|
82283e65be | ||
|
|
2f760fd56d | ||
|
|
939610cf9d | ||
|
|
6d107d0881 | ||
|
|
b7434d0a0b | ||
|
|
55ef5e4af1 | ||
|
|
dc289723a9 | ||
|
|
b15bbae037 | ||
|
|
7cd084e621 | ||
|
|
0857b4efd9 | ||
|
|
0c01b35188 | ||
|
|
9d33ae6d49 | ||
|
|
a9aaf797cd | ||
|
|
4b6f0b14ad | ||
|
|
a111b67c53 | ||
|
|
91ef424bd0 | ||
|
|
7589051216 | ||
|
|
fbb59277b9 | ||
|
|
0d8e927b08 | ||
|
|
72f7b9a047 | ||
|
|
139373145a | ||
|
|
0357417163 | ||
|
|
d5d4216a80 | ||
|
|
b982831fbf | ||
|
|
75c4a4a649 | ||
|
|
fb977ce1b9 | ||
|
|
7d051d1f6a | ||
|
|
f5e1e24df8 | ||
|
|
5ddb31b57b | ||
|
|
01a28fc65a | ||
|
|
67cd7fb36f | ||
|
|
5f8dab0068 | ||
|
|
40949eaa90 | ||
|
|
f25ef4ab1b | ||
|
|
f3873ed61c | ||
|
|
bbffbd5616 | ||
|
|
d9feb92612 | ||
|
|
5662dc7cf7 | ||
|
|
39279a1633 | ||
|
|
e8b91db6f2 | ||
|
|
df9ff7b259 | ||
|
|
a0f3409f82 | ||
|
|
694724945d | ||
|
|
5cbe19064b | ||
|
|
4ac084139c | ||
|
|
f92c1d0089 | ||
|
|
bcd19058ea | ||
|
|
d43073a011 | ||
|
|
8bd30d0301 | ||
|
|
f087da1b43 | ||
|
|
7a681fd7f7 | ||
|
|
2e483c7598 | ||
|
|
f98065e849 | ||
|
|
48294842bf | ||
|
|
65e9ca1c32 | ||
|
|
233f2007b0 | ||
|
|
5b29082ca6 | ||
|
|
48c0abbe89 | ||
|
|
8476d5fbd7 | ||
|
|
ea5aa8d873 | ||
|
|
3229a84ee5 | ||
|
|
f8127f3ed6 | ||
|
|
44677aea78 | ||
|
|
5b7b81ff4d | ||
|
|
68d37e87f6 | ||
|
|
51d6850cd6 | ||
|
|
8f66a96ec0 | ||
|
|
9ce9f62a45 | ||
|
|
a33023a4aa | ||
|
|
d2d0a48e9c | ||
|
|
e55672bdcd | ||
|
|
5ef2630810 | ||
|
|
8c4b1ad69b | ||
|
|
59dede6049 | ||
|
|
f304ef0141 | ||
|
|
3cfadc380d | ||
|
|
b73b575b71 | ||
|
|
9b64b54d7b | ||
|
|
e826b474b8 | ||
|
|
9d63c8d8b0 | ||
|
|
aa4161e451 | ||
|
|
9029f14523 | ||
|
|
98c8313475 | ||
|
|
8351137206 | ||
|
|
79ec8e1d2e | ||
|
|
418d9ac4ca | ||
|
|
d0be4d1e49 | ||
|
|
4cfd93161b | ||
|
|
05efb6b9f2 | ||
|
|
66caf7ce05 | ||
|
|
9c02c63704 | ||
|
|
8458622e32 | ||
|
|
f1121107c5 | ||
|
|
d954743e8b | ||
|
|
0a6528a845 | ||
|
|
f744ca81ca | ||
|
|
3a82696d62 | ||
|
|
cd6f1b4cfa | ||
|
|
28478ba165 | ||
|
|
d746d5b52b | ||
|
|
f6fd924cbd | ||
|
|
0d1d692c45 | ||
|
|
6f6497d540 | ||
|
|
7889548a7e | ||
|
|
fc1141184c | ||
|
|
0993d812cb | ||
|
|
be81834aad | ||
|
|
e389760204 | ||
|
|
6f799f00bb | ||
|
|
debe80a314 | ||
|
|
af3db57b29 | ||
|
|
8edde44c0d | ||
|
|
cd369c327f | ||
|
|
206e5201b8 | ||
|
|
aa462c2454 | ||
|
|
ae1123ba39 | ||
|
|
bd06797c24 | ||
|
|
5b79fd4323 | ||
|
|
53d532da82 | ||
|
|
fa21c407b4 | ||
|
|
d54f160d6a | ||
|
|
5df5fa8480 | ||
|
|
ddd3530993 | ||
|
|
befb95a4ac | ||
|
|
dc185bdc2e | ||
|
|
42967e72cd | ||
|
|
85e10b5631 | ||
|
|
54e5927bb1 | ||
|
|
9517d07692 | ||
|
|
93abfd2485 | ||
|
|
5aec27478a | ||
|
|
9f955d4544 | ||
|
|
597d161a38 | ||
|
|
48d301330f | ||
|
|
03f0d71dbb | ||
|
|
778c87ffa3 | ||
|
|
ed0b35f9d7 | ||
|
|
cfc3a148e7 | ||
|
|
a698d7a7db | ||
|
|
ba107184e1 | ||
|
|
7abd60e785 | ||
|
|
0d5e6d4133 | ||
|
|
790cc772a9 | ||
|
|
0d8148f22d | ||
|
|
bef37a5cce | ||
|
|
be4a136476 | ||
|
|
5fc4393729 | ||
|
|
097d76de93 | ||
|
|
0076cfba2e | ||
|
|
6b24c8a461 | ||
|
|
3733d24da8 | ||
|
|
b2b8084cfe | ||
|
|
ab3d8eab41 | ||
|
|
b89941b909 | ||
|
|
bce98e6eaf | ||
|
|
f90aee4108 | ||
|
|
2189bbed5e | ||
|
|
ebc7330717 | ||
|
|
bab897f01e | ||
|
|
fb2c705ac4 | ||
|
|
6021f1ea9a | ||
|
|
181e1fb721 | ||
|
|
5b54f6d45f | ||
|
|
15a29de894 | ||
|
|
db912c4c91 | ||
|
|
949b1f7c61 |
+4
-5
@@ -1,8 +1,8 @@
|
|||||||
APP_ENV=testing
|
APP_KEY=
|
||||||
APP_DEBUG=true
|
APP_ENV=
|
||||||
APP_KEY=ZKZAzM23wQ6BPji6zffBjaTzZ3yW7zKQ
|
APP_DEBUG=
|
||||||
|
|
||||||
DB_HOST=localhost
|
DB_HOST=
|
||||||
DB_DATABASE=
|
DB_DATABASE=
|
||||||
DB_USERNAME=
|
DB_USERNAME=
|
||||||
DB_PASSWORD=
|
DB_PASSWORD=
|
||||||
@@ -17,4 +17,3 @@ MAIL_PASSWORD=
|
|||||||
SITE_URL=/
|
SITE_URL=/
|
||||||
UPLOAD_URL=/public/uploads
|
UPLOAD_URL=/public/uploads
|
||||||
THUMBNAILS_URL=/uploads/thumbnails
|
THUMBNAILS_URL=/uploads/thumbnails
|
||||||
THEME=
|
|
||||||
+9
-2
@@ -1,8 +1,9 @@
|
|||||||
# published files from modules
|
# published files from modules
|
||||||
/resources/views/modules
|
|
||||||
/public/modules
|
/public/modules
|
||||||
/resources/views/vendor
|
|
||||||
/public/assets
|
/public/assets
|
||||||
|
/resources/views/modules
|
||||||
|
/resources/views/visitor
|
||||||
|
/resources/views/vendor
|
||||||
|
|
||||||
# directories with custom templates
|
# directories with custom templates
|
||||||
**/views/**/custom/*
|
**/views/**/custom/*
|
||||||
@@ -26,3 +27,9 @@
|
|||||||
|
|
||||||
# meta information created by installer
|
# meta information created by installer
|
||||||
.install
|
.install
|
||||||
|
/node_modules/
|
||||||
|
/public/css/
|
||||||
|
/public/js
|
||||||
|
/public/fonts
|
||||||
|
/bower_components
|
||||||
|
.sass-cache
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Content;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
|
||||||
|
interface AdvancedContentModifier {
|
||||||
|
/**
|
||||||
|
* Save module-specific values into database
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
* @param array $inputData
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function createNew(Content &$content, array $inputData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method used for editing existing content page.
|
||||||
|
*
|
||||||
|
* Reason why it is separated from createNew() method is simple - we need to save history of changes.
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
* @param $request
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function edit(Content $content, $request);
|
||||||
|
/**
|
||||||
|
* Method called right after content page is marked as deleted
|
||||||
|
*
|
||||||
|
* This method is supposed to clean after "deleted" page.
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function delete(Content $content);
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Content;
|
||||||
|
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface ContentTitles
|
||||||
|
*
|
||||||
|
* Classes which implement this interface get the ability to rewrite default text on edit/create/overview of content
|
||||||
|
* page.
|
||||||
|
*
|
||||||
|
* @package App\CMS\Handlers\Contracts
|
||||||
|
*/
|
||||||
|
interface ContentTitles
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get translated title for pages overview of given type.
|
||||||
|
*
|
||||||
|
* This value is used for rendering list of all content pages of given type in administration.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getOverviewTitle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Title displayed above for for creating new content page
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getCreateNewTitle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Title for form displayed for editin content page
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function getEditTitle(Content $content);
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Contracts;
|
namespace App\CMS\Handlers\Contracts;
|
||||||
|
|
||||||
interface HistoryHandler
|
interface HistoryHandler
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts;
|
||||||
|
|
||||||
|
interface Interaction {
|
||||||
|
/**
|
||||||
|
* Perform given action
|
||||||
|
*
|
||||||
|
* @param $data array input data
|
||||||
|
* @param $parameters array parameters
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle($data, $parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $data array input data
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValidationRules($data = []);
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Modules;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
|
||||||
|
interface AppHandler extends BaseModuleHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Render given module into visitor area.
|
||||||
|
*
|
||||||
|
* @param Content $content DB model from table contents
|
||||||
|
* @param array $parameters parameters used for modifications/custom settings of given model
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function render(Content $content, $parameters);
|
||||||
|
|
||||||
|
public static function getHistoryHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for section names in creating/editing content resource
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function getExtendedFormSections();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for views used in extended part of form for creating new content
|
||||||
|
*
|
||||||
|
* This method should return pairs <section, view-name>. View is returned only as name in plain text
|
||||||
|
*
|
||||||
|
* @return array of views/templates/html codes divided into section
|
||||||
|
*/
|
||||||
|
public static function getExtendedFormInputsCreate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for extended part of form for editing existing content
|
||||||
|
*
|
||||||
|
* Basically, this method may be
|
||||||
|
*
|
||||||
|
* @return array of views/templates/html codes divided into section
|
||||||
|
*/
|
||||||
|
public static function getExtendedFormInputsEdit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this module support categories?
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function supportCategories();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Modules;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
interface BaseModuleHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register admin menu (or multiple ones)
|
||||||
|
*
|
||||||
|
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
|
||||||
|
* starting any middleware..
|
||||||
|
*
|
||||||
|
* @param User $user model of logged user
|
||||||
|
*/
|
||||||
|
public static function registerAdminMenu(User $user);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Modules;
|
||||||
|
|
||||||
|
use App\Models\Module;
|
||||||
|
|
||||||
|
interface InstallableModule {
|
||||||
|
/**
|
||||||
|
* Install module.
|
||||||
|
*
|
||||||
|
* This method is called after inserting info about module into database. It can be called only using Artisan in
|
||||||
|
* CLI.
|
||||||
|
*/
|
||||||
|
public static function install();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstalls module
|
||||||
|
*
|
||||||
|
* @param Module $module
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function uninstall(Module $module);
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Modules;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface TemplateHandler
|
||||||
|
*
|
||||||
|
* Inerface used for registering template into CMS core.
|
||||||
|
*
|
||||||
|
* @package App\CMS\Handlers\Contracts
|
||||||
|
*/
|
||||||
|
interface TemplateHandler extends BaseModuleHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get list of registered templates and supported modules.
|
||||||
|
*
|
||||||
|
* Returned array is expected to be array of arrays with following items: module, namespace and templateName.
|
||||||
|
* Example:
|
||||||
|
* return [
|
||||||
|
* ['module' => 'Article', 'templateName' => 'article::template.name']
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* When no "namespace" is specified, value strtolower(module) is used instaed.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getPublicTemplatePaths();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Content object to be rendered using Blade template
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
*/
|
||||||
|
public static function beforeRender(Content & $content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify input data into format which can be understood by edit template
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
*/
|
||||||
|
public static function beforePopulatingEditForm(Content & $content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slightly modify Content object before saving into database.
|
||||||
|
*
|
||||||
|
* This way we can do almost whatever we want - even in template
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
* @param $request
|
||||||
|
*/
|
||||||
|
public static function beforeSave(Content & $content, $request);
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Repositories;
|
||||||
|
|
||||||
|
interface BaseRepository {
|
||||||
|
public function getOne($id = null);
|
||||||
|
public function all();
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Repositories;
|
||||||
|
|
||||||
|
interface Content extends BaseRepository
|
||||||
|
{
|
||||||
|
const STATUS_DRAFT = 'draft';
|
||||||
|
const STATUS_PROTECTED = 'protected';
|
||||||
|
const STATUS_PUBLIC = 'public';
|
||||||
|
|
||||||
|
public function getOverview($handler = null, $statuses = null);
|
||||||
|
|
||||||
|
public function getHomepage();
|
||||||
|
|
||||||
|
public function getByURL($url);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Repositories;
|
||||||
|
|
||||||
|
use App\Models\Content\Content as ContentModel;
|
||||||
|
use App\Models\Module as ModuleModel;
|
||||||
|
|
||||||
|
interface Module extends BaseRepository
|
||||||
|
{
|
||||||
|
public function getCreateContentTitle(ModuleModel $module);
|
||||||
|
|
||||||
|
public function getUpdateContentTitle(ModuleModel $module, ContentModel $content = null);
|
||||||
|
|
||||||
|
public function getOverviewTitle(ModuleModel $module);
|
||||||
|
|
||||||
|
public function getByHandler($handler);
|
||||||
|
|
||||||
|
public function call(ModuleModel $module, $method, $parameters = []);
|
||||||
|
|
||||||
|
public function callOnString($moduleHandler, $method, $parameters = []);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Repositories;
|
||||||
|
|
||||||
|
use App\Models\Module as ModuleModel;
|
||||||
|
use App\Models\Templates\Template as TemplateModel;
|
||||||
|
|
||||||
|
interface Template
|
||||||
|
{
|
||||||
|
const EDITED_TEMPLATES_DIRECTORY = 'custom';
|
||||||
|
const ASSETS_DIRECTORY = 'assets';
|
||||||
|
const MODULES_DIRECTORY = 'modules';
|
||||||
|
const TEMPLATE_SUFFIX = '.blade.php';
|
||||||
|
const CUSTOM_EDIT_DIRECTORY = 1;
|
||||||
|
const ORIGINAL_DIRECTORY = 2;
|
||||||
|
|
||||||
|
public function setModel(TemplateModel $model);
|
||||||
|
|
||||||
|
public function getPathToTemplate();
|
||||||
|
|
||||||
|
public function getForModule(ModuleModel $module);
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Contracts;
|
namespace App\CMS\Handlers\Contracts;
|
||||||
|
|
||||||
interface SearchHandler {
|
interface SearchHandler {
|
||||||
public function getId();
|
public function getId();
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Contracts;
|
namespace App\CMS\Handlers\Contracts;
|
||||||
|
|
||||||
interface SearchPresenterHandler
|
interface SearchPresenterHandler
|
||||||
{
|
{
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\Contracts;
|
namespace App\CMS\Contracts\Widgets;
|
||||||
|
|
||||||
interface AdminDashboardWidget extends PublicWidget
|
interface AdminDashboardWidget extends PublicWidget
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Contracts\Widgets;
|
||||||
|
|
||||||
|
interface InstallableWidget extends PublicWidget {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function for installing given widget
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function install();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function for uninstalling widget
|
||||||
|
*/
|
||||||
|
public static function uninstall();
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\Contracts;
|
namespace App\CMS\Widgets\Contracts;
|
||||||
|
|
||||||
interface MenuExtensionHandler {
|
interface MenuExtensionHandler {
|
||||||
|
|
||||||
+6
-17
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\Contracts;
|
namespace App\CMS\Contracts\Widgets;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
use App\Models\Widget;
|
use App\Models\Widgets\Widget;
|
||||||
|
|
||||||
interface PublicWidget
|
interface PublicWidget
|
||||||
{
|
{
|
||||||
@@ -28,22 +28,11 @@ interface PublicWidget
|
|||||||
public static function getPresenter();
|
public static function getPresenter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Widget $widget
|
* Get widget settings for saving into database
|
||||||
* @param \stdClass $data
|
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @param Request $request
|
||||||
*/
|
|
||||||
public static function save(Widget $widget, \stdClass $data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function for installing given widget
|
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function install();
|
public static function save(Request $request);
|
||||||
|
|
||||||
/**
|
|
||||||
* Function for uninstalling widget
|
|
||||||
*/
|
|
||||||
public static function uninstall();
|
|
||||||
}
|
}
|
||||||
+5
-5
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\Contracts;
|
namespace App\CMS\Contracts\Widgets;
|
||||||
|
|
||||||
use App\Models\Widget;
|
use App\Models\Widgets\Widget;
|
||||||
use App\Models\WidgetType;
|
use App\Models\Widgets\WidgetType;
|
||||||
|
|
||||||
interface WidgetRenderer
|
interface WidgetRenderer
|
||||||
{
|
{
|
||||||
@@ -11,11 +11,11 @@ interface WidgetRenderer
|
|||||||
*
|
*
|
||||||
* This method renders some HTML code for displaying.
|
* This method renders some HTML code for displaying.
|
||||||
*
|
*
|
||||||
* @param object $settings
|
* @param Widget $settings
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function render($settings);
|
public static function render(Widget $settings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display form for creating new instance of widget
|
* Display form for creating new instance of widget
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\ActionLogType;
|
use App\Models\ActionLogType;
|
||||||
|
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\ActionLogType;
|
use App\Models\ActionLog\ActionLogType;
|
||||||
|
|
||||||
class ActionLogTypesForLogger extends BaseEnumeration
|
class ActionLogTypesForLogger extends BaseEnumeration
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Enumerations\Exceptions\EnumerationExistsException;
|
use App\CMS\Exceptions\Enumerations\EnumerationExistsException;
|
||||||
|
|
||||||
abstract class BaseEnumeration
|
abstract class BaseEnumeration
|
||||||
{
|
{
|
||||||
@@ -47,7 +47,7 @@ abstract class BaseEnumeration
|
|||||||
public static function push($key, $translation, $overwrite = false)
|
public static function push($key, $translation, $overwrite = false)
|
||||||
{
|
{
|
||||||
// item exists and we do not want to overwrite items
|
// item exists and we do not want to overwrite items
|
||||||
if (!$overwrite && isset(self::$items[get_called_class()][$key])) {
|
if (!$overwrite && !is_null($key) && isset(self::$items[get_called_class()][$key])) {
|
||||||
throw new EnumerationExistsException(get_called_class() . ': ' . $key . ' already in ' . $translation);
|
throw new EnumerationExistsException(get_called_class() . ': ' . $key . ' already in ' . $translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\Content;
|
|
||||||
|
use App\CMS\Contracts\Repositories\Content;
|
||||||
|
|
||||||
class ContentStatuses extends BaseEnumeration
|
class ContentStatuses extends BaseEnumeration
|
||||||
{
|
{
|
||||||
@@ -9,7 +10,6 @@ class ContentStatuses extends BaseEnumeration
|
|||||||
{
|
{
|
||||||
$roles = [
|
$roles = [
|
||||||
Content::STATUS_DRAFT => 'admin/contents.status_' . Content::STATUS_DRAFT,
|
Content::STATUS_DRAFT => 'admin/contents.status_' . Content::STATUS_DRAFT,
|
||||||
Content::STATUS_DELETED => 'admin/contents.status_' . Content::STATUS_DELETED,
|
|
||||||
Content::STATUS_PROTECTED => 'admin/contents.status_' . Content::STATUS_PROTECTED,
|
Content::STATUS_PROTECTED => 'admin/contents.status_' . Content::STATUS_PROTECTED,
|
||||||
Content::STATUS_PUBLIC => 'admin/contents.status_' . Content::STATUS_PUBLIC
|
Content::STATUS_PUBLIC => 'admin/contents.status_' . Content::STATUS_PUBLIC
|
||||||
];
|
];
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\Module;
|
use App\Models\Module;
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\Module;
|
use App\Models\Module;
|
||||||
|
|
||||||
+5
-2
@@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\Module;
|
use App\Models\Module;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
class ModulesHandlerToId extends BaseEnumeration
|
class ModulesHandlerToId extends BaseEnumeration
|
||||||
{
|
{
|
||||||
@@ -12,7 +13,9 @@ class ModulesHandlerToId extends BaseEnumeration
|
|||||||
*/
|
*/
|
||||||
protected static function init()
|
protected static function init()
|
||||||
{
|
{
|
||||||
$modules = Module::all(['handler', 'id']);
|
$modules = Cache::rememberForever('module-handler-to-id-enumeration', function () {
|
||||||
|
return Module::all(['handler', 'id']);
|
||||||
|
});
|
||||||
|
|
||||||
foreach ($modules as $module) {
|
foreach ($modules as $module) {
|
||||||
self::push($module->handler, $module->id);
|
self::push($module->handler, $module->id);
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
* Time: 10:33
|
* Time: 10:33
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\TemplatePath;
|
use App\Models\Templates\TemplatePath;
|
||||||
|
|
||||||
class TemplatePaths extends BaseEnumeration
|
class TemplatePaths extends BaseEnumeration
|
||||||
{
|
{
|
||||||
+2
-2
@@ -6,9 +6,9 @@
|
|||||||
* Time: 10:33
|
* Time: 10:33
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\TemplatePath;
|
use App\Models\Templates\TemplatePath;
|
||||||
|
|
||||||
class TemplatePathsHumanReadable extends BaseEnumeration
|
class TemplatePathsHumanReadable extends BaseEnumeration
|
||||||
{
|
{
|
||||||
+2
-2
@@ -6,9 +6,9 @@
|
|||||||
* Time: 10:33
|
* Time: 10:33
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\TemplatePath;
|
use App\Models\Templates\TemplatePath;
|
||||||
|
|
||||||
class TemplatePathsHumanReadableRootOnly extends BaseEnumeration
|
class TemplatePathsHumanReadableRootOnly extends BaseEnumeration
|
||||||
{
|
{
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
* Time: 15:50
|
* Time: 15:50
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\Template;
|
use App\Models\Templates\Template;
|
||||||
|
|
||||||
class Templates extends BaseEnumeration
|
class Templates extends BaseEnumeration
|
||||||
{
|
{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
* Time: 23:20
|
* Time: 23:20
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ class UserStates extends BaseEnumeration
|
|||||||
public static function init()
|
public static function init()
|
||||||
{
|
{
|
||||||
$items = [
|
$items = [
|
||||||
User::STATE_DELETED => 'admin/userManagement.status_' . User::STATE_DELETED,
|
|
||||||
User::STATE_BLOCKED => 'admin/userManagement.status_' . User::STATE_BLOCKED,
|
User::STATE_BLOCKED => 'admin/userManagement.status_' . User::STATE_BLOCKED,
|
||||||
User::STATE_ACTIVE => 'admin/userManagement.status_' . User::STATE_ACTIVE
|
User::STATE_ACTIVE => 'admin/userManagement.status_' . User::STATE_ACTIVE
|
||||||
];
|
];
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\WidgetType;
|
use App\Models\Widgets\WidgetType;
|
||||||
|
|
||||||
class WidgetTypes extends BaseEnumeration
|
class WidgetTypes extends BaseEnumeration
|
||||||
{
|
{
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations;
|
namespace App\CMS\Enumerations;
|
||||||
|
|
||||||
use App\Models\WidgetType;
|
use App\Models\Widgets\WidgetType;
|
||||||
|
|
||||||
class WidgetTypesWithHandlers extends BaseEnumeration
|
class WidgetTypesWithHandlers extends BaseEnumeration
|
||||||
{
|
{
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Enumerations\Exceptions;
|
namespace App\CMS\Exceptions\Enumerations;
|
||||||
|
|
||||||
class EnumerationExistsException extends \Exception {
|
class EnumerationExistsException extends \Exception {
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Exceptions\FileManager;
|
||||||
|
|
||||||
|
class SubdirectoryExistsInDirectory extends \Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Exceptions\Validation;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ValidationFailedException extends \Exception {
|
||||||
|
protected $validator;
|
||||||
|
|
||||||
|
public function __construct($validator, $message = null, $code = null, Exception $previous = null)
|
||||||
|
{
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
|
||||||
|
$this->validator = $validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidator(){
|
||||||
|
return $this->validator;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\Exceptions;
|
namespace App\CMS\Widgets\Exceptions;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\Exceptions;
|
namespace App\CMS\Widgets\Exceptions;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Handlers;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Modules\BaseModuleHandler;
|
||||||
|
use App\CMS\Enumerations\TemplatePathsHumanReadableRootOnly;
|
||||||
|
use App\CMS\Enumerations\WidgetTypes;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
abstract class BaseHandler implements BaseModuleHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register admin menu (or multiple ones)
|
||||||
|
*
|
||||||
|
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
|
||||||
|
* starting any middleware..
|
||||||
|
*
|
||||||
|
* @param User $user model of logged user
|
||||||
|
*/
|
||||||
|
public static function registerAdminMenu(User $user)
|
||||||
|
{
|
||||||
|
$menu = \Menu::instance('mainMenu');
|
||||||
|
if (!is_null($menu)) {
|
||||||
|
// menus were already defined
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create instance of main menu
|
||||||
|
\Menu::create('mainMenu', function ($menu) {
|
||||||
|
// $menu->route('admin.dashboard', trans('admin/mainMenu.dashboard'), [], 10, ['icon' => 'fa fa-fw fa-dashboard']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Content pages
|
||||||
|
*
|
||||||
|
* Submenus can be registered later
|
||||||
|
*/
|
||||||
|
$menu->dropdown(trans('admin/mainMenu.contentPages'), function ($sub) {
|
||||||
|
$sub->route('content.overview', trans('admin/mainMenu.contentPageOverview'), [], 10000, ['icon' => 'fa fa-fw fa-list']);
|
||||||
|
}, 20, ['icon' => 'fa fa-fw fa-database']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File manager
|
||||||
|
*/
|
||||||
|
$menu->route('upload.overview', trans('admin/mainMenu.fileManager'), [], 40, ['icon' => 'fa fa-fw fa-folder']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widgets and widget areas
|
||||||
|
*/
|
||||||
|
$menu->dropdown(trans('admin/mainMenu.widgets'), function ($sub) {
|
||||||
|
// create list of all widget types
|
||||||
|
$widgets = WidgetTypes::getWithTranslations();
|
||||||
|
|
||||||
|
if (!empty($widgets)) {
|
||||||
|
$sub->dropdown(trans('admin/mainMenu.newWidget'), function ($sub) use ($widgets) {
|
||||||
|
$i = 1;
|
||||||
|
foreach ($widgets as $type => $name) {
|
||||||
|
$sub->route('widgets.new', $name, ['type' => $type], $i++);
|
||||||
|
}
|
||||||
|
}, 10, ['icon' => 'fa fa-fw fa-plus']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sub->route('widgets.overview', trans('admin/mainMenu.widgetsOverview'), [], 20, ['icon' => 'fa fa-fw fa-list']);
|
||||||
|
|
||||||
|
// menu for widget areas
|
||||||
|
$sub->dropdown(trans('admin/mainMenu.widgetAreas'), function ($sub) {
|
||||||
|
$sub->route('widgetareas.new', trans('admin/mainMenu.newWidgetArea'), [], 1, ['icon' => 'fa fa-fw fa-plus']);
|
||||||
|
$sub->route('widgetareas.overview', trans('admin/mainMenu.widgetAreaOverview'), [], 2, ['icon' => 'fa fa-fw fa-list']);
|
||||||
|
}, 50, ['icon' => 'fa fa-fw fa-object-group']);
|
||||||
|
}, 50, ['icon' => 'fa fa-fw fa-puzzle-piece']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Divide system entries and other links in menu
|
||||||
|
*/
|
||||||
|
$menu->addDivider(9999);
|
||||||
|
|
||||||
|
$menu->dropdown(trans('admin/mainMenu.system'), function ($sub) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User management
|
||||||
|
*/
|
||||||
|
$sub->dropdown(trans('admin/mainMenu.userManagement'), function ($sub) {
|
||||||
|
$sub->route('users.new', trans('admin/mainMenu.newUser'), [], 10, ['icon' => 'fa fa-fw fa-user-plus']);
|
||||||
|
$sub->route('users.overview', trans('admin/mainMenu.usersOverview'), [], 30, ['icon' => 'fa fa-fw fa-users']);
|
||||||
|
}, 20, ['icon' => 'fa fa-fw fa-users']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Templates
|
||||||
|
*/
|
||||||
|
$templatePaths = TemplatePathsHumanReadableRootOnly::getWithTranslations();
|
||||||
|
if (!empty($templatePaths)) {
|
||||||
|
$sub->dropdown(trans('admin/mainMenu.templates'), function ($sub) use ($templatePaths) {
|
||||||
|
$i = 1;
|
||||||
|
foreach ($templatePaths as $id => $name) {
|
||||||
|
$sub->route('templates.overview', $name, ['id' => $id], $i++);
|
||||||
|
}
|
||||||
|
}, 60, ['icon' => 'fa fa-fw fa-file-code-o']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sub->route('log.overview', trans('admin/mainMenu.actionLog'), [], 70, ['icon' => 'fa fa-fw fa-history']);
|
||||||
|
$sub->route('settings.overview', trans('admin/mainMenu.settings'), [], 80, ['icon' => 'fa fa-fw fa-gear']);
|
||||||
|
}, 10000, ['icon' => 'fa fa-fw fa-gears']);
|
||||||
|
});
|
||||||
|
|
||||||
|
// create menu with user profile
|
||||||
|
\Menu::create('profileMenu', function ($menu) {
|
||||||
|
$menu->route('users.detail', trans('admin/userManagement.profile'), [], 10, ['icon' => 'fa fa-fw fa-user icon']);
|
||||||
|
$menu->addDivider(999);
|
||||||
|
$menu->route('logout', trans('admin/common.logout'), [], 1000, ['icon' => 'fa fa-fw fa-power-off icon']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Handlers;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Modules\AppHandler;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Handler
|
||||||
|
*
|
||||||
|
* Handler is a class which handles module-specific behaviour which cannot be done by module itself, resp. cannot be
|
||||||
|
* done by some abstract magic.
|
||||||
|
*
|
||||||
|
* @package App\CMS\Handlers\
|
||||||
|
*/
|
||||||
|
abstract class Handler extends BaseHandler implements AppHandler
|
||||||
|
{
|
||||||
|
public static function getHistoryHandler()
|
||||||
|
{
|
||||||
|
return History::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render given module into visitor area.
|
||||||
|
*
|
||||||
|
* @param Content $content DB model from table contents
|
||||||
|
* @param array $parameters parameters used for modifications/custom settings of given model
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function render(Content $content, $parameters)
|
||||||
|
{
|
||||||
|
return Controller::VisitorsView($content->template, ['page' => $content, 'extra' => $parameters]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getExtendedFormSections()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'basicInfo' => trans('admin/contents.basicInfo'),
|
||||||
|
'meta' => trans('admin/contents.metaOptions'),
|
||||||
|
'publication' => trans('admin/contents.publicationOptions'),
|
||||||
|
'appearance' => trans('admin/contents.appearance'),
|
||||||
|
'files' => trans('admin/contents.files')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getExtendedFormInputsCreate()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'basicInfo' => 'admin.content.formParts.basicInformation',
|
||||||
|
'meta' => 'admin.content.formParts.metaInformation',
|
||||||
|
'publication' => 'admin.content.formParts.publicationSetup',
|
||||||
|
'appearance' => 'admin.content.formParts.appearance',
|
||||||
|
'files' => 'admin.content.formParts.files'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getExtendedFormInputsEdit()
|
||||||
|
{
|
||||||
|
return self::getExtendedFormInputsCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers;
|
namespace App\CMS\Handlers;
|
||||||
|
|
||||||
use App\Enumerations\ContentStatuses;
|
use App\CMS\Enumerations\ContentStatuses;
|
||||||
use App\Handlers\Contracts\HistoryHandler;
|
use App\CMS\Handlers\Contracts\HistoryHandler;
|
||||||
use App\Helpers\Differ;
|
use App\CMS\Helpers\Differ;
|
||||||
|
|
||||||
class History implements HistoryHandler
|
class History implements HistoryHandler
|
||||||
{
|
{
|
||||||
@@ -25,6 +25,15 @@ class History implements HistoryHandler
|
|||||||
break;
|
break;
|
||||||
case 'metaDescription':
|
case 'metaDescription':
|
||||||
return Differ::htmlDiff($changeset->old_value, $changeset->new_value);
|
return Differ::htmlDiff($changeset->old_value, $changeset->new_value);
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
if (!$changeset->old_value) {
|
||||||
|
// old value is null -> new file was uploaded
|
||||||
|
return trans('admin/history.uploadedFile', ['file' => $changeset->new_value]);
|
||||||
|
} else {
|
||||||
|
return trans('admin/history.deletedFile', ['file' => $changeset->old_value]);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'status':
|
case 'status':
|
||||||
$statuses = ContentStatuses::getWithTranslations();
|
$statuses = ContentStatuses::getWithTranslations();
|
||||||
@@ -34,7 +43,7 @@ class History implements HistoryHandler
|
|||||||
'to' => $statuses[$changeset->new_value]
|
'to' => $statuses[$changeset->new_value]
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
case 'is_homepage':
|
case 'isHomepage':
|
||||||
return trans('admin/history.setupAsHomepage');
|
return trans('admin/history.setupAsHomepage');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Cms\Handlers\Interactions;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Interaction as InteractionContract;
|
||||||
|
use App\CMS\Exceptions\Validation\ValidationFailedException;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
|
class Interaction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle interaction with application
|
||||||
|
*
|
||||||
|
* @param string $interactionClass
|
||||||
|
* @param array $data
|
||||||
|
* @param array $extraParameters
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
* @throws ValidationFailedException
|
||||||
|
*/
|
||||||
|
public static function handle($interactionClass, $data, ...$extraParameters)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $interaction InteractionContract
|
||||||
|
*/
|
||||||
|
|
||||||
|
$interaction = app($interactionClass);
|
||||||
|
// validate interaction
|
||||||
|
$validator = Validator::make($data, $interaction->getValidationRules($extraParameters));
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new ValidationFailedException($validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle it
|
||||||
|
|
||||||
|
return $interaction->handle($data, $extraParameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Registrators\Items;
|
namespace App\CMS\Handlers\Registrators\Items;
|
||||||
|
|
||||||
class SettingExtension
|
class SettingExtension
|
||||||
{
|
{
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Registrators;
|
namespace App\CMS\Handlers\Registrators;
|
||||||
|
|
||||||
use App\Widgets\Contracts\MenuExtensionHandler;
|
use App\CMS\Widgets\Contracts\MenuExtensionHandler;
|
||||||
|
|
||||||
class MenuExtensionRegistrator {
|
class MenuExtensionRegistrator {
|
||||||
|
|
||||||
+5
-5
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Registrators;
|
namespace App\CMS\Handlers\Registrators;
|
||||||
|
|
||||||
use App\Enumerations\Exceptions\EnumerationExistsException;
|
use App\CMS\Enumerations\Exceptions\EnumerationExistsException;
|
||||||
use App\Handlers\Contracts\SearchHandler;
|
use App\CMS\Handlers\Contracts\SearchHandler;
|
||||||
use App\Handlers\Contracts\SearchPresenterHandler;
|
use App\CMS\Handlers\Contracts\SearchPresenterHandler;
|
||||||
use App\Handlers\Registrators\Items\SearchEngine;
|
use App\CMS\Handlers\Registrators\Items\SearchEngine;
|
||||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
class SearchEngineRegistrator
|
class SearchEngineRegistrator
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Registrators;
|
namespace App\CMS\Handlers\Registrators;
|
||||||
|
|
||||||
use App\Enumerations\Exceptions\EnumerationExistsException;
|
use App\CMS\Enumerations\Exceptions\EnumerationExistsException;
|
||||||
use App\Handlers\Registrators\Items\SettingExtension;
|
use App\CMS\Handlers\Registrators\Items\SettingExtension;
|
||||||
|
|
||||||
class SettingsExtensionRegistrator
|
class SettingsExtensionRegistrator
|
||||||
{
|
{
|
||||||
+60
-20
@@ -1,10 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Registrators;
|
namespace App\CMS\Handlers\Registrators;
|
||||||
|
|
||||||
use App\Enumerations\TemplatePaths;
|
use App\CMS\Contracts\Repositories\Template;
|
||||||
use App\Enumerations\Templates;
|
use App\CMS\Enumerations\TemplatePaths;
|
||||||
use App\Models\Template;
|
use App\CMS\Enumerations\Templates;
|
||||||
use App\Models\TemplatePath;
|
use App\Models\Templates\Template as TemplateModel;
|
||||||
|
use App\Models\Templates\TemplatePath;
|
||||||
use Illuminate\Support\Facades\File;
|
use Illuminate\Support\Facades\File;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||||
@@ -28,6 +29,10 @@ class TemplateRegistrator
|
|||||||
* @var int ID of module
|
* @var int ID of module
|
||||||
*/
|
*/
|
||||||
protected $moduleId;
|
protected $moduleId;
|
||||||
|
/**
|
||||||
|
* @var array list of all registered template paths
|
||||||
|
*/
|
||||||
|
protected $paths = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set base path
|
* Set base path
|
||||||
@@ -64,7 +69,7 @@ class TemplateRegistrator
|
|||||||
*/
|
*/
|
||||||
public function setNamespace($namespace)
|
public function setNamespace($namespace)
|
||||||
{
|
{
|
||||||
$this->namespace = $namespace . '::';
|
$this->namespace = $namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,28 +78,52 @@ class TemplateRegistrator
|
|||||||
public function unsetNamespace()
|
public function unsetNamespace()
|
||||||
{
|
{
|
||||||
$this->namespace = null;
|
$this->namespace = null;
|
||||||
|
$this->setModuleId(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers new template path.
|
* Registers new template path.
|
||||||
* This method registeres given path itself with all subdirectories
|
* This method registeres given path itself with all subdirectories
|
||||||
*
|
*
|
||||||
|
* @param $baseDirectory
|
||||||
* @param string $path path relatively to root of the project
|
* @param string $path path relatively to root of the project
|
||||||
* @param string $name human readable identification of given template path
|
* @param string $name human readable identification of given template path
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function register($path, $name)
|
public function register($baseDirectory, $path, $name)
|
||||||
{
|
{
|
||||||
// check if base directory was set
|
$this->paths[] = [
|
||||||
if (!$this->baseDirectory || !is_dir($this->baseDirectory)) {
|
'namespace' => $this->namespace,
|
||||||
throw new \Exception('Set $baseDirectory before registering template path.');
|
'moduleId' => $this->moduleId,
|
||||||
|
'baseDirectory' => $baseDirectory,
|
||||||
|
'path' => $this->baseDirectory . DIRECTORY_SEPARATOR . $path,
|
||||||
|
'name' => $name
|
||||||
|
];
|
||||||
|
$this->unsetNamespace();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->registeredPath = $this->baseDirectory . DIRECTORY_SEPARATOR . $path;
|
/**
|
||||||
|
* Save templates into database
|
||||||
|
*/
|
||||||
|
public function saveTemplates()
|
||||||
|
{
|
||||||
|
if (!is_array($this->paths) || empty($this->paths)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->paths as $path) {
|
||||||
|
if (!empty($path['namespace'])) {
|
||||||
|
$this->setNamespace($path['namespace'] . '::');
|
||||||
|
}
|
||||||
|
$this->setModuleId($path['moduleId']);
|
||||||
|
$this->setBaseDirectory($path['baseDirectory']);
|
||||||
|
|
||||||
|
$this->registeredPath = $this->baseDirectory . DIRECTORY_SEPARATOR . $path['path'];
|
||||||
// register path
|
// register path
|
||||||
$this->registerPath($this->registeredPath, $name);
|
$this->registerPath($this->registeredPath, $path['name']);
|
||||||
|
$this->unsetNamespace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +135,10 @@ class TemplateRegistrator
|
|||||||
*/
|
*/
|
||||||
protected function relativePath($directory)
|
protected function relativePath($directory)
|
||||||
{
|
{
|
||||||
return trim(str_replace(base_path(), '', $directory), '/');
|
$directory = str_replace('/', DIRECTORY_SEPARATOR, $directory);
|
||||||
|
$directory = str_replace('\\', DIRECTORY_SEPARATOR, $directory);
|
||||||
|
|
||||||
|
return trim(str_replace(base_path(), '', $directory), '\\/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,6 +149,10 @@ class TemplateRegistrator
|
|||||||
*/
|
*/
|
||||||
protected function scanForSubdirectories($directory, $name)
|
protected function scanForSubdirectories($directory, $name)
|
||||||
{
|
{
|
||||||
|
if (!is_dir($directory)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$directories = File::directories($directory);
|
$directories = File::directories($directory);
|
||||||
|
|
||||||
foreach ($directories as $dir) {
|
foreach ($directories as $dir) {
|
||||||
@@ -166,7 +202,7 @@ class TemplateRegistrator
|
|||||||
* @param $path
|
* @param $path
|
||||||
* @param $templatePathId
|
* @param $templatePathId
|
||||||
*
|
*
|
||||||
* @throws \App\Enumerations\Exceptions\EnumerationExistsException
|
* @throws \App\CMS\Enumerations\Exceptions\EnumerationExistsException
|
||||||
*/
|
*/
|
||||||
protected function registerTemplates($path, $templatePathId)
|
protected function registerTemplates($path, $templatePathId)
|
||||||
{
|
{
|
||||||
@@ -184,7 +220,6 @@ class TemplateRegistrator
|
|||||||
$registeredTemplates = Templates::getWithTranslations();
|
$registeredTemplates = Templates::getWithTranslations();
|
||||||
|
|
||||||
if (!in_array($templateName, $registeredTemplates)) {
|
if (!in_array($templateName, $registeredTemplates)) {
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'template_name' => $templateName,
|
'template_name' => $templateName,
|
||||||
'name' => $templateName,
|
'name' => $templateName,
|
||||||
@@ -195,7 +230,7 @@ class TemplateRegistrator
|
|||||||
];
|
];
|
||||||
|
|
||||||
// save template into database
|
// save template into database
|
||||||
$newTemplate = Template::create($params);
|
$newTemplate = TemplateModel::create($params);
|
||||||
|
|
||||||
// push template into enumeration - so it will not be registered again
|
// push template into enumeration - so it will not be registered again
|
||||||
Templates::push($newTemplate->id, $templateName);
|
Templates::push($newTemplate->id, $templateName);
|
||||||
@@ -211,7 +246,7 @@ class TemplateRegistrator
|
|||||||
* @param null $parent
|
* @param null $parent
|
||||||
*
|
*
|
||||||
* @return mixed|null
|
* @return mixed|null
|
||||||
* @throws \App\Enumerations\Exceptions\EnumerationExistsException
|
* @throws \App\CMS\Enumerations\Exceptions\EnumerationExistsException
|
||||||
*/
|
*/
|
||||||
protected function saveTemplatePath($path, $name, $parent = null)
|
protected function saveTemplatePath($path, $name, $parent = null)
|
||||||
{
|
{
|
||||||
@@ -268,12 +303,17 @@ class TemplateRegistrator
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function getTemplateName($template)
|
protected function getTemplateName($template)
|
||||||
{
|
{
|
||||||
$templateName = str_replace($this->registeredPath . DIRECTORY_SEPARATOR, '', $template);
|
$templateName = $template;
|
||||||
|
|
||||||
|
$templateName = str_replace($this->registeredPath, '', $templateName);
|
||||||
|
$templateName = str_replace('\\', DIRECTORY_SEPARATOR, $templateName);
|
||||||
|
$templateName = str_replace('/', DIRECTORY_SEPARATOR, $templateName);
|
||||||
$templateName = str_replace(DIRECTORY_SEPARATOR, '.', $templateName);
|
$templateName = str_replace(DIRECTORY_SEPARATOR, '.', $templateName);
|
||||||
$templateName = str_replace(Template::TEMPLATE_SUFFIX, '', $templateName);
|
$templateName = str_replace(Template::TEMPLATE_SUFFIX, '', $templateName);
|
||||||
|
$templateName = preg_replace('/\.{2,}/', '.', $templateName);
|
||||||
|
|
||||||
return $this->namespace . $templateName;
|
return $this->namespace . trim($templateName, '.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Handlers\Registrators;
|
||||||
|
|
||||||
|
use App\CMS\Enumerations\WidgetTypesWithHandlers;
|
||||||
|
use App\Models\Widgets\WidgetType;
|
||||||
|
|
||||||
|
class WidgetRegistrator
|
||||||
|
{
|
||||||
|
protected $registeredWidgets = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method used for registering new widgets
|
||||||
|
*
|
||||||
|
* @param $classname
|
||||||
|
* @param null $templateId
|
||||||
|
* @param null $moduleId
|
||||||
|
*/
|
||||||
|
public function register($classname, $templateId = null, $moduleId = null)
|
||||||
|
{
|
||||||
|
$this->registeredWidgets[] = [
|
||||||
|
'class' => $classname,
|
||||||
|
'templateId' => $templateId,
|
||||||
|
'moduleId' => $moduleId
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install all non-installed widgets
|
||||||
|
*/
|
||||||
|
public function installWidgets()
|
||||||
|
{
|
||||||
|
$installed = WidgetTypesWithHandlers::getSimple();
|
||||||
|
foreach ($this->registeredWidgets as $registeredWidget) {
|
||||||
|
$classname = $registeredWidget['class'];
|
||||||
|
$templateId = $registeredWidget['templateId'];
|
||||||
|
$moduleId = $registeredWidget['moduleId'];
|
||||||
|
|
||||||
|
// register widget as new widget type
|
||||||
|
if (!in_array($classname, $installed)) {
|
||||||
|
$widgetName = call_user_func($classname . '::getName');
|
||||||
|
$widgetDescription = call_user_func($classname . '::getDescription');
|
||||||
|
|
||||||
|
// create row in widget types
|
||||||
|
WidgetType::create([
|
||||||
|
'handler' => $classname,
|
||||||
|
'name' => $widgetName,
|
||||||
|
'module_id' => $moduleId,
|
||||||
|
'template_id' => $templateId,
|
||||||
|
'description' => $widgetDescription
|
||||||
|
]);
|
||||||
|
|
||||||
|
// install widget (if neccessary)
|
||||||
|
if (is_callable([$classname, 'install'])) {
|
||||||
|
call_user_func($classname . '::install');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Search;
|
namespace App\CMS\Handlers\Search;
|
||||||
|
|
||||||
use App\Models\Content as ContentModel;
|
use App\Models\Content\Content as ContentModel;
|
||||||
|
|
||||||
class Content extends Search
|
class Content extends Search
|
||||||
{
|
{
|
||||||
@@ -16,9 +16,9 @@ class Content extends Search
|
|||||||
{
|
{
|
||||||
$token = $this->tokenize($term);
|
$token = $this->tokenize($term);
|
||||||
|
|
||||||
return ContentModel::where('content', 'LIKE', $token)
|
return ContentModel::where('pageContent', 'LIKE', $token)
|
||||||
->orWhere('meta_description', 'LIKE', $token)
|
->orWhere('metaDescription', 'LIKE', $token)
|
||||||
->orWhere('meta_keywords', 'LIKE', $token)
|
->orWhere('metaKeywords', 'LIKE', $token)
|
||||||
->orWhere('title', 'LIKE', $token)
|
->orWhere('title', 'LIKE', $token)
|
||||||
->orWhere('url', 'LIKE', $token)
|
->orWhere('url', 'LIKE', $token)
|
||||||
->get();
|
->get();
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Search;
|
namespace App\CMS\Handlers\Search;
|
||||||
|
|
||||||
use App\Models\File;
|
use App\Models\FileManager\File;
|
||||||
|
|
||||||
class Files extends Search
|
class Files extends Search
|
||||||
{
|
{
|
||||||
@@ -27,6 +27,7 @@ class Files extends Search
|
|||||||
$token = $this->tokenize($term);
|
$token = $this->tokenize($term);
|
||||||
|
|
||||||
return File::where('original_filename', 'LIKE', $token)
|
return File::where('original_filename', 'LIKE', $token)
|
||||||
|
->orWhere('name', 'LIKE', $token)
|
||||||
->orWhere('keywords', 'LIKE', $token)
|
->orWhere('keywords', 'LIKE', $token)
|
||||||
->orWhere('description', 'LIKE', $token)
|
->orWhere('description', 'LIKE', $token)
|
||||||
->orWhere('mime_type', 'LIKE', $token)
|
->orWhere('mime_type', 'LIKE', $token)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Handlers\Search\Presenters;
|
||||||
|
|
||||||
|
use App\CMS\Enumerations\ContentStatuses;
|
||||||
|
use App\CMS\Handlers\Contracts\SearchPresenterHandler;
|
||||||
|
|
||||||
|
class AdminContent implements SearchPresenterHandler
|
||||||
|
{
|
||||||
|
public function render($foundItems)
|
||||||
|
{
|
||||||
|
return view('admin.search.results.content', [
|
||||||
|
'pages' => $foundItems,
|
||||||
|
'statuses' => ContentStatuses::getWithTranslations(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Search\Presenters;
|
namespace App\CMS\Handlers\Search\Presenters;
|
||||||
|
|
||||||
use App\Handlers\Contracts\SearchPresenterHandler;
|
use App\CMS\Handlers\Contracts\SearchPresenterHandler;
|
||||||
|
|
||||||
class AdminFiles implements SearchPresenterHandler
|
class AdminFiles implements SearchPresenterHandler
|
||||||
{
|
{
|
||||||
@@ -14,6 +14,6 @@ class AdminFiles implements SearchPresenterHandler
|
|||||||
*/
|
*/
|
||||||
public function render($foundItems)
|
public function render($foundItems)
|
||||||
{
|
{
|
||||||
return view('admin.fileManager.filesTiles', ['files' => $foundItems]);
|
return view('admin.fileManager.filesTiles', ['files' => $foundItems, 'hideDelete' => true]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Handlers\Search;
|
namespace App\CMS\Handlers\Search;
|
||||||
|
|
||||||
use App\Handlers\Contracts\SearchHandler;
|
use App\CMS\Handlers\Contracts\SearchHandler;
|
||||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
abstract class Search implements SearchHandler
|
abstract class Search implements SearchHandler
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Modules\TemplateHandler;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
use App\Models\Module;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\QueryException;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class CurrentTemplate implements TemplateHandler
|
||||||
|
{
|
||||||
|
protected static $template;
|
||||||
|
protected static $initialized = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for currently set template
|
||||||
|
* @return Module
|
||||||
|
* @throws \ErrorException
|
||||||
|
*/
|
||||||
|
public static function get()
|
||||||
|
{
|
||||||
|
if (!self::$initialized) {
|
||||||
|
self::$template = Cache::rememberForever('current-template', function () {
|
||||||
|
$template = Module::where('is_template', true)
|
||||||
|
->where('enabled', true)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// todo remove after adding $casts into Module model
|
||||||
|
if ($template) {
|
||||||
|
$template->module_settings = json_decode($template->module_settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
self::$initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$template;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut for getting template handler
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \ErrorException
|
||||||
|
*/
|
||||||
|
public static function handler()
|
||||||
|
{
|
||||||
|
$template = self::get();
|
||||||
|
|
||||||
|
if (!$template) {
|
||||||
|
throw new \ErrorException('No template selected, no handler available!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $template->handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset currently set template and load another one on next call of get() method.
|
||||||
|
*/
|
||||||
|
public static function reset()
|
||||||
|
{
|
||||||
|
self::$initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register admin menu (or multiple ones)
|
||||||
|
*
|
||||||
|
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
|
||||||
|
* starting any middleware..
|
||||||
|
*
|
||||||
|
* @param User $user model of logged user
|
||||||
|
*/
|
||||||
|
public static function registerAdminMenu(User $user)
|
||||||
|
{
|
||||||
|
call_user_func_array([self::handler(), 'registerAdminMenu'], [$user]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of registered templates and supported modules.
|
||||||
|
*
|
||||||
|
* Returned array is expected to be array of arrays with following items: module, namespace and templateName.
|
||||||
|
* Example:
|
||||||
|
* return [
|
||||||
|
* ['module' => 'Article', 'templateName' => 'article::template.name']
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* When no "namespace" is specified, value strtolower(module) is used instaed.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getPublicTemplatePaths()
|
||||||
|
{
|
||||||
|
return call_user_func([self::handler(), 'getPublicTemplatePaths']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Content object to be rendered using Blade template
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
*/
|
||||||
|
public static function beforeRender(Content & $content)
|
||||||
|
{
|
||||||
|
call_user_func_array([self::handler(), 'beforeRender'], [&$content]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify input data into format which can be understood by edit template
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
*/
|
||||||
|
public static function beforePopulatingEditForm(Content & $content)
|
||||||
|
{
|
||||||
|
call_user_func_array([self::handler(), 'beforePopulatingEditForm'], [&$content]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slightly modify Content object before saving into database.
|
||||||
|
*
|
||||||
|
* This way we can do almost whatever we want - even in template
|
||||||
|
*
|
||||||
|
* @param Content $content
|
||||||
|
* @param $request
|
||||||
|
*/
|
||||||
|
public static function beforeSave(Content & $content, $request)
|
||||||
|
{
|
||||||
|
call_user_func_array([self::handler(), 'beforeSave'], [&$content, $request]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
class Date
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Print date in configured format
|
||||||
|
*
|
||||||
|
* @param $datestamp
|
||||||
|
* @param bool $withTime
|
||||||
|
*
|
||||||
|
* @return false|string
|
||||||
|
*/
|
||||||
|
public static function date($datestamp, $withTime = true)
|
||||||
|
{
|
||||||
|
$timestamp = strtotime($datestamp);
|
||||||
|
|
||||||
|
if ($timestamp <= 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$format = $withTime ? config('app.datetime_format') : config('app.date_format');
|
||||||
|
|
||||||
|
return date($format, $timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dateFormatted($format, $datestamp)
|
||||||
|
{
|
||||||
|
$timestamp = strtotime($datestamp);
|
||||||
|
|
||||||
|
if ($timestamp <= 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return date($format, $timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function monthName($datestamp) {
|
||||||
|
$timestamp = strtotime($datestamp);
|
||||||
|
|
||||||
|
if ($timestamp <= 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$months = [
|
||||||
|
trans('common.months.january'),
|
||||||
|
trans('common.months.february'),
|
||||||
|
trans('common.months.march'),
|
||||||
|
trans('common.months.april'),
|
||||||
|
trans('common.months.may'),
|
||||||
|
trans('common.months.june'),
|
||||||
|
trans('common.months.july'),
|
||||||
|
trans('common.months.august'),
|
||||||
|
trans('common.months.semptember'),
|
||||||
|
trans('common.months.october'),
|
||||||
|
trans('common.months.november'),
|
||||||
|
trans('common.months.december'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$monthNumber = date('n', $timestamp);
|
||||||
|
|
||||||
|
return $months[$monthNumber - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Helpers;
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Paul's Simple Differ Algorithm v 0.1
|
Paul's Simple Differ Algorithm v 0.1
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Helpers;
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
use App\Models\File;
|
use App\Models\FileManager\File;
|
||||||
|
|
||||||
class FileManager
|
class FileManager
|
||||||
{
|
{
|
||||||
@@ -17,34 +17,42 @@ class FileManager
|
|||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'image':
|
case 'image':
|
||||||
|
|
||||||
// try to check if file have thumbnail
|
$url = Path::thumbnail($file->filename);
|
||||||
if (file_exists(config('app.thumbnail_url') . '/' . $file->filename)) {
|
|
||||||
$url = config('app.thumbnail_url') . '/' . $file->filename;
|
|
||||||
} else {
|
|
||||||
$url = config('app.upload_url') . '/' . $file->filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
return '<img src="' . $url . '" alt="' . $file->description . '" />';
|
return '<img src="' . $url . '" alt="' . $file->description . '" />';
|
||||||
break;
|
break;
|
||||||
case 'text':
|
case 'text':
|
||||||
return '<i class="fa fa-file-text-o"></i>';
|
return self::getIcon($file, 'fa-file-text-o');
|
||||||
break;
|
break;
|
||||||
case 'application':
|
case 'application':
|
||||||
switch ($subtype) {
|
switch ($subtype) {
|
||||||
case 'pdf':
|
case 'pdf':
|
||||||
return '<i class="fa fa-file-pdf-o"></i>';
|
return self::getIcon($file, 'fa-file-pdf-o');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return '<i class="fa fa-newspaper-o"></i>';
|
return self::getIcon($file, 'fa-newspaper-o');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return '<i class="fa fa-question"></i>';
|
return self::getIcon($file, 'fa-question');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut for displaying icons
|
||||||
|
*
|
||||||
|
* @param $file
|
||||||
|
* @param $icon
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function getIcon($file, $icon)
|
||||||
|
{
|
||||||
|
return '<p><i class="fa fa-2x ' . $icon . '"></i><br /><span>' . e(str_limit($file->original_filename, 15)) . '</span></p>';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@@ -83,7 +91,6 @@ class FileManager
|
|||||||
return '<img src="' . $url . '" alt="' . $file->description . '" />';
|
return '<img src="' . $url . '" alt="' . $file->description . '" />';
|
||||||
break;
|
break;
|
||||||
case 'text':
|
case 'text':
|
||||||
|
|
||||||
$string = '<pre><code>';
|
$string = '<pre><code>';
|
||||||
$string .= htmlspecialchars(file_get_contents($path));
|
$string .= htmlspecialchars(file_get_contents($path));
|
||||||
$string .= '</pre></code>';
|
$string .= '</pre></code>';
|
||||||
@@ -91,14 +98,7 @@ class FileManager
|
|||||||
return $string;
|
return $string;
|
||||||
break;
|
break;
|
||||||
case 'application':
|
case 'application':
|
||||||
switch ($subtype) {
|
return '<iframe src = "'.asset('resources/assets/admin/js/viewerJs/').'/#'.Path::upload($file->filename).'" style="width: 100%; height: 50em" allowfullscreen webkitallowfullscreen></iframe>';
|
||||||
case 'pdf':
|
|
||||||
return '<i class="fa fa-file-pdf-o"></i>';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return '<i class="fa fa-newspaper-o"></i>';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return self::getPreview($file);
|
return self::getPreview($file);
|
||||||
@@ -119,19 +119,12 @@ class FileManager
|
|||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'text':
|
case 'text':
|
||||||
|
return [trans('admin/fileManager.encoding') => mb_detect_encoding(file_get_contents($path))];
|
||||||
return [
|
|
||||||
trans('admin/fileManager.encoding') => mb_detect_encoding(file_get_contents($path))
|
|
||||||
];
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'image':
|
case 'image':
|
||||||
list ($width, $height) = getimagesize($path);
|
list ($width, $height) = getimagesize($path);
|
||||||
|
return [trans('admin/fileManager.resolution') => $height . ' x ' . $width,];
|
||||||
return [
|
|
||||||
trans('admin/fileManager.resolution') => $height . ' x ' . $width,
|
|
||||||
];
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
class Gravatar
|
||||||
|
{
|
||||||
|
public static function img($email, $size = 50)
|
||||||
|
{
|
||||||
|
return "//www.gravatar.com/avatar/" . md5(strtolower(trim($email))) . "?s=" . $size;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
use App\CMS\Handlers\Contracts\AppHandler;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
use Webwizo\Shortcodes\Facades\Shortcode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PageRenderer
|
||||||
|
*
|
||||||
|
* Simple class for rendering page for visitor
|
||||||
|
*
|
||||||
|
* @package App\CMS\Helpers
|
||||||
|
*/
|
||||||
|
class PageRenderer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Render page
|
||||||
|
*
|
||||||
|
* @param Content $page
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function render(Content $page)
|
||||||
|
{
|
||||||
|
// do something template-specific
|
||||||
|
$parameters = call_user_func_array([CurrentTemplate::handler(), 'beforeRender'], [&$page]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var $handler AppHandler
|
||||||
|
*/
|
||||||
|
// get handler
|
||||||
|
$handler = new $page->moduleHandler;
|
||||||
|
|
||||||
|
$page->content = Shortcode::compile($page->content);
|
||||||
|
|
||||||
|
// render page
|
||||||
|
return $handler->render($page, $parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,46 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Helpers;
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
class Template
|
class Path
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Getter for real template name
|
|
||||||
*
|
|
||||||
* @param $template
|
|
||||||
*
|
|
||||||
* @return null|string
|
|
||||||
*/
|
|
||||||
public static function name($template)
|
|
||||||
{
|
|
||||||
$namespace = null;
|
|
||||||
if (strpos($template, '::')) {
|
|
||||||
list($namespace, $template) = explode('::', $template);
|
|
||||||
$namespace .= '::';
|
|
||||||
}
|
|
||||||
|
|
||||||
$theme = config('app.theme');
|
|
||||||
|
|
||||||
// list of prefixes
|
|
||||||
$prefixes = [$theme . '.custom.', $theme . '.', ''];
|
|
||||||
|
|
||||||
$view = null;
|
|
||||||
foreach ($prefixes as $prefix) {
|
|
||||||
if (view()->exists($namespace . 'visitor.' . $prefix . $template)) {
|
|
||||||
$view = $namespace . 'visitor.' . $prefix . $template;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_null($view)) {
|
|
||||||
throw new InvalidArgumentException('Cannot find template for ' . $namespace . $template);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $view;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get URL to uploaded file
|
* Get URL to uploaded file
|
||||||
*
|
*
|
||||||
@@ -59,6 +24,25 @@ class Template
|
|||||||
return config('app.upload_url') . '/' . $filename;
|
return config('app.upload_url') . '/' . $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function thumbnail($filename)
|
||||||
|
{
|
||||||
|
// try to check if file have thumbnail
|
||||||
|
if (file_exists(config('app.thumbnail_path') . '/' . $filename)) {
|
||||||
|
$url = config('app.thumbnail_url') . '/' . $filename;
|
||||||
|
} else {
|
||||||
|
$url = self::upload($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get path to given asset
|
||||||
|
*
|
||||||
|
* @param $path
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public static function asset($path)
|
public static function asset($path)
|
||||||
{
|
{
|
||||||
if (env('APP_DEBUG')) {
|
if (env('APP_DEBUG')) {
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
use App\Models\FileManager\Directory;
|
||||||
|
use App\Models\FileManager\File;
|
||||||
|
|
||||||
|
class RootDirectory
|
||||||
|
{
|
||||||
|
protected static $directory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create root directory
|
||||||
|
*
|
||||||
|
* @return Directory
|
||||||
|
*/
|
||||||
|
protected static function create()
|
||||||
|
{
|
||||||
|
$directory = new Directory();
|
||||||
|
$directory->name = 'Root';
|
||||||
|
$directory->is_root = true;
|
||||||
|
$directory->save();
|
||||||
|
|
||||||
|
Directory::whereNull('parent_id')
|
||||||
|
->where('is_root', false)
|
||||||
|
->update(['parent_id' => $directory->id]);
|
||||||
|
|
||||||
|
File::where('directory_id', null)
|
||||||
|
->update(['directory_id' => $directory->id]);
|
||||||
|
|
||||||
|
return $directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get root directory
|
||||||
|
*
|
||||||
|
* @return Directory
|
||||||
|
*/
|
||||||
|
public static function get()
|
||||||
|
{
|
||||||
|
self::$directory = Directory::where('is_root', true)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (is_null(self::$directory)) {
|
||||||
|
self::$directory = self::create();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
use App\Models\Settings as SettingsModel;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Settings
|
||||||
|
*
|
||||||
|
* Helper class for easier obtaining system settings
|
||||||
|
*
|
||||||
|
* @package App\CMS\Helpers
|
||||||
|
*/
|
||||||
|
class Settings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array List of all used settings
|
||||||
|
*/
|
||||||
|
protected static $settings;
|
||||||
|
/**
|
||||||
|
* @var bool Are data already initialized?
|
||||||
|
*/
|
||||||
|
protected static $initialized = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for settings determined with key.
|
||||||
|
*
|
||||||
|
* @param string $key settings key
|
||||||
|
* @param string|null $default default value, which will be returned when given key does not exist
|
||||||
|
*
|
||||||
|
* @param null $exists
|
||||||
|
*
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
public static function get($key, $default = null, & $exists = null)
|
||||||
|
{
|
||||||
|
self::init();
|
||||||
|
|
||||||
|
if (isset(self::$settings->$key)) {
|
||||||
|
$exists = true;
|
||||||
|
self::$initialized = true;
|
||||||
|
return self::$settings->$key;
|
||||||
|
}
|
||||||
|
|
||||||
|
$exists = false;
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut for obtaining settings saved as JSON
|
||||||
|
*
|
||||||
|
* @param $key
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function getJson($key)
|
||||||
|
{
|
||||||
|
return json_decode(self::get($key, '{}'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all settings
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function all()
|
||||||
|
{
|
||||||
|
self::init();
|
||||||
|
|
||||||
|
return self::$settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize settings array
|
||||||
|
*/
|
||||||
|
private static function init()
|
||||||
|
{
|
||||||
|
if (!self::$initialized) {
|
||||||
|
self::$settings = Cache::remember('settings', config('cache.settingCacheLifetime'), function () {
|
||||||
|
$model = new SettingsModel();
|
||||||
|
return $model->getAll();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
|
class Template
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Getter for real template name
|
||||||
|
*
|
||||||
|
* @param $template
|
||||||
|
*
|
||||||
|
* @param bool $throwExceptions
|
||||||
|
*
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
public static function name($template, $throwExceptions = true)
|
||||||
|
{
|
||||||
|
$namespace = null;
|
||||||
|
if (strpos($template, '::')) {
|
||||||
|
list($namespace, $template) = explode('::', $template);
|
||||||
|
$namespace .= '::';
|
||||||
|
}
|
||||||
|
|
||||||
|
// list of prefixes
|
||||||
|
$prefixes = ['custom.', ''];
|
||||||
|
|
||||||
|
$view = null;
|
||||||
|
foreach ($prefixes as $prefix) {
|
||||||
|
if (view()->exists($namespace . 'visitor.' . $prefix . $template)) {
|
||||||
|
$view = $namespace . 'visitor.' . $prefix . $template;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($view)) {
|
||||||
|
if ($throwExceptions) {
|
||||||
|
throw new InvalidArgumentException('Cannot find template for ' . $namespace . $template);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers\Traits;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Nullable
|
||||||
|
*
|
||||||
|
* @package App\CMS\Helpers\Traits
|
||||||
|
*/
|
||||||
|
trait Nullable {
|
||||||
|
/**
|
||||||
|
* Get null or parsed date
|
||||||
|
*
|
||||||
|
* @param $date
|
||||||
|
*
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
public function nullableDate($date) {
|
||||||
|
return empty($date) ? null : Carbon::parse($date)->toDateTimeString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get null or input value
|
||||||
|
*
|
||||||
|
* @param $string
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
public function nullable($string) {
|
||||||
|
return empty($string) ? null : $string;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
class Widget
|
||||||
|
{
|
||||||
|
public static function render(\App\Models\Widgets\Widget $widget)
|
||||||
|
{
|
||||||
|
$handler = $widget->widget_type_handler;
|
||||||
|
|
||||||
|
if (is_string($widget->settings)) {
|
||||||
|
$widget->settings = json_decode($widget->settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
$presenter = call_user_func([$handler, 'getPresenter']);
|
||||||
|
|
||||||
|
return call_user_func([$presenter, 'render'], $widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Helpers;
|
||||||
|
|
||||||
|
use App\Models\Widgets\WidgetArea;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class WidgetAreas
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array list of inicialized widget areas
|
||||||
|
*/
|
||||||
|
protected static $widgetAreas = [];
|
||||||
|
protected static $initialized = false;
|
||||||
|
|
||||||
|
protected static function saveRenderedWidgetArea($widgets)
|
||||||
|
{
|
||||||
|
foreach ($widgets as $widget) {
|
||||||
|
if (!isset(self::$widgetAreas[$widget->widget_area_code])) {
|
||||||
|
self::$widgetAreas[$widget->widget_area_code] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$widgetAreas[$widget->widget_area_code] .= Widget::render($widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function loadWidgetArea($uniqueCode)
|
||||||
|
{
|
||||||
|
$widgets = Cache::remember('widget-' . $uniqueCode, setting('widgetCacheLifetime', 5), function () use ($uniqueCode) {
|
||||||
|
$widgetArea = new WidgetArea();
|
||||||
|
return $widgetArea->getWidgets($uniqueCode)
|
||||||
|
->get();
|
||||||
|
});
|
||||||
|
|
||||||
|
WidgetArea::where('code', $uniqueCode)
|
||||||
|
->increment('viewed');
|
||||||
|
|
||||||
|
self::saveRenderedWidgetArea($widgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function initWidgetAreas()
|
||||||
|
{
|
||||||
|
if (self::$initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$widgets = Cache::remember('widgets', setting('widgetCacheLifetime', 5), function () {
|
||||||
|
$widgetArea = new WidgetArea();
|
||||||
|
return $widgetArea->getWidgets()
|
||||||
|
->get();
|
||||||
|
});
|
||||||
|
|
||||||
|
self::saveRenderedWidgetArea($widgets);
|
||||||
|
self::$initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renderer for whole widget area.
|
||||||
|
*
|
||||||
|
* @param $uniqueCode
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function render($uniqueCode)
|
||||||
|
{
|
||||||
|
if (!self::$initialized) {
|
||||||
|
self::initWidgetAreas();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset(self::$widgetAreas[$uniqueCode])) {
|
||||||
|
self::loadWidgetArea($uniqueCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo isset(self::$widgetAreas[$uniqueCode]) ? self::$widgetAreas[$uniqueCode] : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Define function for escaping characters.
|
||||||
|
*
|
||||||
|
* This funcion prevents of creating build-in function, which escapes also accents...
|
||||||
|
*
|
||||||
|
* @param $value
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function e($value)
|
||||||
|
{
|
||||||
|
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut for \App\CMS\Helpers\Settings::get()
|
||||||
|
*
|
||||||
|
* @param $key
|
||||||
|
* @param null $default
|
||||||
|
*
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
function setting($key, $default = null) {
|
||||||
|
return \App\CMS\Helpers\Settings::get($key, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
function asset_path($path) {
|
||||||
|
return env('SITE_URL').'/assets/'.$path;
|
||||||
|
}
|
||||||
|
|
||||||
|
function template_name($name, $throwExceptions = true) {
|
||||||
|
return \App\CMS\Helpers\Template::name($name, $throwExceptions);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Interactions\Admin\Content;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Interaction;
|
||||||
|
use App\CMS\Enumerations\ContentStatuses;
|
||||||
|
|
||||||
|
class ChangeStatus implements Interaction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change status of content page
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param array $parameters
|
||||||
|
*
|
||||||
|
* @return mixed|void
|
||||||
|
*/
|
||||||
|
public function handle($data, $parameters)
|
||||||
|
{
|
||||||
|
list ($page) = $parameters;
|
||||||
|
|
||||||
|
$page->status = $data['status'];
|
||||||
|
$page->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if status is valid
|
||||||
|
*
|
||||||
|
* @param array $parameters
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValidationRules($parameters = [])
|
||||||
|
{
|
||||||
|
$statuses = ContentStatuses::getWithTranslations();
|
||||||
|
|
||||||
|
return ['status' => 'in:' . implode(',', array_keys($statuses))];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Interactions\Admin\Content;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Interaction;
|
||||||
|
use App\CMS\Contracts\Repositories\Module;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
|
||||||
|
class DeletePage implements Interaction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Perform given action
|
||||||
|
*
|
||||||
|
* @param $data array input data
|
||||||
|
* @param $parameters array parameters
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle($data, $parameters)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $page Content
|
||||||
|
* @var $module Module
|
||||||
|
*/
|
||||||
|
|
||||||
|
$module = App::make(Module::class);
|
||||||
|
list ($page) = $parameters;
|
||||||
|
|
||||||
|
// delete page
|
||||||
|
$page->delete();
|
||||||
|
|
||||||
|
// let module to delete some extra content created during page's life
|
||||||
|
$module->callOnString($page->moduleHandler, 'delete', [$page]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $data array input data
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValidationRules($data = [])
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Cms\Interactions\Admin\Content;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Interaction;
|
||||||
|
use App\CMS\Contracts\Repositories\Module;
|
||||||
|
use App\CMS\Enumerations\ContentStatuses;
|
||||||
|
use App\CMS\Helpers\CurrentTemplate;
|
||||||
|
use App\Events\EditContent as EditContentEvent;
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
use App\Models\FileManager\File;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
|
||||||
|
|
||||||
|
class EditContent implements Interaction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Module
|
||||||
|
*/
|
||||||
|
protected $module;
|
||||||
|
/**
|
||||||
|
* @var File
|
||||||
|
*/
|
||||||
|
protected $file;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->module = App::make(Module::class);
|
||||||
|
$this->file = App::make(File::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit page
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param array $parameters
|
||||||
|
*
|
||||||
|
* @return mixed|void
|
||||||
|
*/
|
||||||
|
public function handle($data, $parameters)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $page Content
|
||||||
|
*/
|
||||||
|
list($page, $titlePhoto, $relatedFiles) = $parameters;
|
||||||
|
|
||||||
|
// let template to modify request and content page
|
||||||
|
CurrentTemplate::beforeSave($page, $data);
|
||||||
|
|
||||||
|
// upload file - if provided
|
||||||
|
$data['titlePhoto'] = isset($data['existingTitlePhoto']) ? $data['existingTitlePhoto'] : null;
|
||||||
|
|
||||||
|
if (!is_null($titlePhoto)) {
|
||||||
|
$file = $this->file->upload($titlePhoto);
|
||||||
|
$data['titlePhoto'] = $file ? $file['filename'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$page->update($data);
|
||||||
|
$this->module->callOnString($page->moduleHandler, 'edit', [$page, $data]);
|
||||||
|
|
||||||
|
// move to interaction
|
||||||
|
$keepAssigned = isset($data->keepAssigned) ? $data->keepAssigned : [];
|
||||||
|
$page->uploadRelatedFiles($relatedFiles, $keepAssigned);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate this interaction
|
||||||
|
*
|
||||||
|
* @param array $parameters
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValidationRules($parameters = [])
|
||||||
|
{
|
||||||
|
$id = $parameters[0]->id;
|
||||||
|
|
||||||
|
// get all available statuses
|
||||||
|
$statuses = ContentStatuses::getSimple();
|
||||||
|
$statuses = implode(',', $statuses);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'title' => 'required',
|
||||||
|
'url' => 'required|unique:contents,url,' . $id.',id,deleted_at,NULL,language,' . LaravelLocalization::getCurrentLocale(),
|
||||||
|
'publishedFrom' => 'date',
|
||||||
|
'publishedTo' => 'date',
|
||||||
|
'status' => 'required|in:' . $statuses,
|
||||||
|
'parentPage' => 'exists:contents,id'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Cms\Interactions\Admin\Content;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Interaction;
|
||||||
|
use App\CMS\Contracts\Repositories\Content as ContentRepository;
|
||||||
|
use App\CMS\Contracts\Repositories\Module;
|
||||||
|
use App\CMS\Enumerations\ContentStatuses;
|
||||||
|
use App\CMS\Helpers\CurrentTemplate;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
use App\Models\FileManager\File;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
|
||||||
|
|
||||||
|
class NewContent implements Interaction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ContentRepository
|
||||||
|
*/
|
||||||
|
protected $content;
|
||||||
|
/**
|
||||||
|
* @var File
|
||||||
|
*/
|
||||||
|
protected $file;
|
||||||
|
/**
|
||||||
|
* @var Module
|
||||||
|
*/
|
||||||
|
protected $module;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->content = App::make(ContentRepository::class);
|
||||||
|
$this->module = App::make(Module::class);
|
||||||
|
$this->file = App::make(File::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new content page
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param $parameters
|
||||||
|
*
|
||||||
|
* @return Content
|
||||||
|
*/
|
||||||
|
public function handle($data, $parameters)
|
||||||
|
{
|
||||||
|
list($moduleHandler, $titlePhoto, $relatedFiles) = $parameters;
|
||||||
|
|
||||||
|
// upload file - if provided
|
||||||
|
$file = !is_null($titlePhoto) ? $this->file->upload($titlePhoto) : null;
|
||||||
|
|
||||||
|
$data['userId'] = \Auth::user()->id;
|
||||||
|
$data['language'] = LaravelLocalization::getCurrentLocale();
|
||||||
|
$data['titlePhoto'] = $file ? $file['filename'] : null;
|
||||||
|
$data['moduleHandler'] = $moduleHandler;
|
||||||
|
|
||||||
|
$page = Content::create($data);
|
||||||
|
|
||||||
|
// save module-specific stuff
|
||||||
|
$this->module->callOnString($moduleHandler, 'createNew', [&$page, $data]);
|
||||||
|
|
||||||
|
// let template to modify data and content page
|
||||||
|
CurrentTemplate::beforeSave($page, $data);
|
||||||
|
|
||||||
|
// save content of page before (possible) uploading related files
|
||||||
|
$page->save();
|
||||||
|
|
||||||
|
// upload files assigned to content page
|
||||||
|
$page->uploadRelatedFiles($relatedFiles);
|
||||||
|
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidationRules($parameters = [])
|
||||||
|
{
|
||||||
|
// get all available statuses
|
||||||
|
$statuses = ContentStatuses::getSimple();
|
||||||
|
$statuses = implode(',', $statuses);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'titlePhoto' => 'image',
|
||||||
|
'title' => 'required',
|
||||||
|
'url' => 'required|unique:contents,url,NULL,id,deleted_at,NULL,language,' . LaravelLocalization::getCurrentLocale(),
|
||||||
|
'status' => 'required|in:'.$statuses,
|
||||||
|
'parentPage' => 'exists:contents,id',
|
||||||
|
'publishedFrom' => 'date',
|
||||||
|
'publishedTo' => 'date',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Interactions\Admin\Content;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Interaction;
|
||||||
|
use App\CMS\Enumerations\ContentStatuses;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
|
||||||
|
|
||||||
|
class SetHomepage implements Interaction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set homepage of given page
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param array $parameters
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle($data, $parameters)
|
||||||
|
{
|
||||||
|
list ($page) = $parameters;
|
||||||
|
// disable any other existing homepage
|
||||||
|
Content::where('isHomepage', true)
|
||||||
|
->where('language', LaravelLocalization::getCurrentLocale())
|
||||||
|
->update(['isHomepage' => false]);
|
||||||
|
|
||||||
|
// set new homepage
|
||||||
|
$page->isHomepage = true;
|
||||||
|
$page->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if status is valid
|
||||||
|
*
|
||||||
|
* @param array $parameters
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValidationRules($parameters = [])
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Interactions\Admin\FileManager;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Interaction;
|
||||||
|
use App\CMS\Exceptions\FileManager\SubdirectoryExistsInDirectory;
|
||||||
|
use App\CMS\Repositories\FileManager\Directory as DirectoryRepository;
|
||||||
|
use App\Models\FileManager\Directory;
|
||||||
|
|
||||||
|
class CreateDirectory implements Interaction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DirectoryRepository
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
public function __construct(DirectoryRepository $repository)
|
||||||
|
{
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform given action
|
||||||
|
*
|
||||||
|
* @param $data array input data
|
||||||
|
* @param $parameters array parameters
|
||||||
|
*
|
||||||
|
* @return Directory
|
||||||
|
* @throws SubdirectoryExistsInDirectory
|
||||||
|
*/
|
||||||
|
public function handle($data, $parameters)
|
||||||
|
{
|
||||||
|
$data['parentDirectory'] = isset($data['parentDirectory']) ? $data['parentDirectory'] : null;
|
||||||
|
|
||||||
|
// todo this should probably go into validation, but we are not able to get $data in getValidationRules
|
||||||
|
// check if created folder does not exist in current directory
|
||||||
|
if ($this->repository->checkIfNameExists($data['name'], $data['parentDirectory'])) {
|
||||||
|
throw new SubdirectoryExistsInDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo use Directory::create() and rename columns/fields in request
|
||||||
|
// create new database entry
|
||||||
|
$directory = new Directory();
|
||||||
|
$directory->name = $data['name'];
|
||||||
|
$directory->parent_id = $data['parentDirectory'];
|
||||||
|
$directory->user_id = \Auth::user()->id;
|
||||||
|
$directory->description = $data['description'];
|
||||||
|
$directory->save();
|
||||||
|
|
||||||
|
return $directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $data array input data
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws SubdirectoryExistsInDirectory
|
||||||
|
*/
|
||||||
|
public function getValidationRules($data = [])
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'required|max:255',
|
||||||
|
'parentDirectory' => 'exists:directories,id'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\MenuPresenters;
|
namespace App\CMS\MenuPresenters;
|
||||||
|
|
||||||
use Pingpong\Menus\MenuItem;
|
use Pingpong\Menus\MenuItem;
|
||||||
use Pingpong\Menus\Presenters\Presenter;
|
use Pingpong\Menus\Presenters\Presenter;
|
||||||
@@ -77,6 +77,6 @@ class FoundationDrilldownMenuPresenter extends Presenter
|
|||||||
<ul class="vertical menu">
|
<ul class="vertical menu">
|
||||||
' . $this->getChildMenuItems($item) . '
|
' . $this->getChildMenuItems($item) . '
|
||||||
</ul>
|
</ul>
|
||||||
</li>' . PHP_EOL;;
|
</li>' . PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\MenuPresenters;
|
namespace App\CMS\MenuPresenters;
|
||||||
|
|
||||||
use Pingpong\Menus\Presenters\Presenter;
|
use Pingpong\Menus\Presenters\Presenter;
|
||||||
|
|
||||||
@@ -56,6 +56,6 @@ class FoundationDropdownMenuPresenter extends Presenter
|
|||||||
<ul class="vertical menu">
|
<ul class="vertical menu">
|
||||||
' . $this->getChildMenuItems($item) . '
|
' . $this->getChildMenuItems($item) . '
|
||||||
</ul>
|
</ul>
|
||||||
</li>' . PHP_EOL;;
|
</li>' . PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\MenuPresenters;
|
namespace App\CMS\MenuPresenters;
|
||||||
|
|
||||||
class FoundationInitializedDropdownMenuPresenter extends FoundationDropdownMenuPresenter
|
class FoundationInitializedDropdownMenuPresenter extends FoundationDropdownMenuPresenter
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\MenuPresenters;
|
||||||
|
|
||||||
|
use Pingpong\Menus\MenuItem;
|
||||||
|
use Pingpong\Menus\Presenters\Presenter;
|
||||||
|
|
||||||
|
class MetismenuPresenter extends Presenter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getOpenTagWrapper()
|
||||||
|
{
|
||||||
|
return PHP_EOL . '<ul class="nav metismenu" id="sidebar-menu">' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getCloseTagWrapper()
|
||||||
|
{
|
||||||
|
return PHP_EOL . '</ul>' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getMenuWithoutDropdownWrapper($item)
|
||||||
|
{
|
||||||
|
return '<li' . $this->getActiveState($item) . '><a href="' . $item->getUrl() . '">' . $item->getIcon() . ' ' . $item->title . '</a></li>' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getActiveState(MenuItem $item)
|
||||||
|
{
|
||||||
|
if ($item->isDivider()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$active = ' class="active"';
|
||||||
|
|
||||||
|
if (empty($item->getChilds())) {
|
||||||
|
// for direct menu input return if page is active
|
||||||
|
return \Request::is($item->getRequest()) ? $active : null;
|
||||||
|
} else {
|
||||||
|
// on nested menu inputs loop over children and in case any of them is active, mark active also root level
|
||||||
|
foreach ($item->getChilds() as $child) {
|
||||||
|
if ($this->getActiveState($child)) {
|
||||||
|
return $active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getDividerWrapper()
|
||||||
|
{
|
||||||
|
return '<li class="divider"></li>' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMultiLevelDropdownWrapper($item)
|
||||||
|
{
|
||||||
|
return $this->getMenuWithDropDownWrapper($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getMenuWithDropDownWrapper($item)
|
||||||
|
{
|
||||||
|
$active = $this->getActiveState($item);
|
||||||
|
return '<li' . $active . '>
|
||||||
|
<a href="#">' . $item->getIcon() . ' ' . $item->title . ' <i class="fa arrow"></i></a>
|
||||||
|
<ul>
|
||||||
|
' . $this->getChildMenuItems($item) . '
|
||||||
|
</ul>
|
||||||
|
</li>' . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\MenuPresenters;
|
||||||
|
|
||||||
|
use Pingpong\Menus\MenuItem;
|
||||||
|
use Pingpong\Menus\Presenters\Presenter;
|
||||||
|
|
||||||
|
class ProfileMenuPresenter extends Presenter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getOpenTagWrapper()
|
||||||
|
{
|
||||||
|
return PHP_EOL . '<div class="dropdown-menu profile-dropdown-menu">' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getCloseTagWrapper()
|
||||||
|
{
|
||||||
|
return PHP_EOL . '</div>' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getMenuWithoutDropdownWrapper($item)
|
||||||
|
{
|
||||||
|
return '<a href="' . $item->getUrl() . '" class="dropdown-item">' . $item->getIcon() . ' ' . $item->title . '</a>' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getActiveState(MenuItem $item)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getDividerWrapper()
|
||||||
|
{
|
||||||
|
return '<div class="dropdown-divider"></div>' . PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMultiLevelDropdownWrapper($item)
|
||||||
|
{
|
||||||
|
return null;//$this->getMenuWithDropDownWrapper($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function getMenuWithDropDownWrapper($item)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Observers;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Repositories\Content as ContentContract;
|
||||||
|
use App\Events\CreateNewContent;
|
||||||
|
use App\Events\DeleteContent;
|
||||||
|
use App\Events\EditContent;
|
||||||
|
use App\Events\MakeDraftFromContent;
|
||||||
|
use App\Events\PublishContent;
|
||||||
|
use App\Events\SetHomepage;
|
||||||
|
use App\Models\Content\Content as ContentModel;
|
||||||
|
use App\Models\Content\ContentHistory;
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Content
|
||||||
|
*
|
||||||
|
* Model observer for logging changes on content page.
|
||||||
|
*
|
||||||
|
* @package App\CMS\Observers
|
||||||
|
*/
|
||||||
|
class Content
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $changeset;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->changeset = uniqid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log changes on edit
|
||||||
|
*
|
||||||
|
* @param ContentModel $content
|
||||||
|
*/
|
||||||
|
public function updated(ContentModel $content)
|
||||||
|
{
|
||||||
|
$fields = $this->getDirtyFields($content->getDirty(), $content->getOriginal());
|
||||||
|
|
||||||
|
$normalFieldsEdited = 0;
|
||||||
|
foreach ($fields as $field => $change) {
|
||||||
|
if ($field == 'viewed')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$history = [
|
||||||
|
'user_id' => \Auth::user()->id,
|
||||||
|
'content_id' => $content->id,
|
||||||
|
'edit_batch' => $this->changeset,
|
||||||
|
'column' => $field,
|
||||||
|
'old_value' => $change['old'],
|
||||||
|
'new_value' => $change['new']
|
||||||
|
];
|
||||||
|
|
||||||
|
// save history
|
||||||
|
ContentHistory::create($history);
|
||||||
|
|
||||||
|
// fire event
|
||||||
|
$this->fireEvent($field, $change, $content, $normalFieldsEdited);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($normalFieldsEdited > 0) {
|
||||||
|
Event::fire(new EditContent($content, $this->changeset));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire event when new instance of model is stored into database
|
||||||
|
*
|
||||||
|
* @param ContentModel $content
|
||||||
|
*/
|
||||||
|
public function created(ContentModel $content)
|
||||||
|
{
|
||||||
|
Event::fire(new CreateNewContent($content));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ContentModel $content
|
||||||
|
*/
|
||||||
|
public function deleted(ContentModel $content)
|
||||||
|
{
|
||||||
|
Event::fire(new DeleteContent($content));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all dirty changed from model.
|
||||||
|
*
|
||||||
|
* If user did not change moduleSettings column, return result from ContentModel::getDirty(). Otherwise append all
|
||||||
|
* changed columns from module settings.
|
||||||
|
*
|
||||||
|
* @param $changed
|
||||||
|
* @param $original
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getDirtyFields($changed, $original)
|
||||||
|
{
|
||||||
|
unset($changed['updated_at']);
|
||||||
|
|
||||||
|
$changes = $this->getNewAndOldValues(array_keys($changed), $changed, $original);
|
||||||
|
|
||||||
|
if (!isset($changed['moduleSettings'])) {
|
||||||
|
return $changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
$moduleSettings = (array)json_decode($changed['moduleSettings']);
|
||||||
|
$originalSettings = isset($original['moduleSettings']) ? (array)json_decode($original['moduleSettings']) : [];
|
||||||
|
unset($changed['moduleSettings']);
|
||||||
|
|
||||||
|
$settingChanged = array_keys(array_diff_assoc($moduleSettings, $originalSettings));
|
||||||
|
$changesInSettings = $this->getNewAndOldValues($settingChanged, $moduleSettings, $originalSettings);
|
||||||
|
|
||||||
|
return array_merge($changes, $changesInSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get original and changed values in one array
|
||||||
|
*
|
||||||
|
* @param $fields
|
||||||
|
* @param $new
|
||||||
|
* @param $original
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getNewAndOldValues($fields, $new, $original)
|
||||||
|
{
|
||||||
|
$changes = [];
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$changes[$field] = [
|
||||||
|
'new' => isset($new[$field]) ? $new[$field] : null,
|
||||||
|
'old' => isset($original[$field]) ? $original[$field] : null
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire events for publishing/making draft and setting homepage
|
||||||
|
*
|
||||||
|
* @param $field
|
||||||
|
* @param $change
|
||||||
|
* @param ContentModel $content
|
||||||
|
* @param $normalFieldsEdited
|
||||||
|
*/
|
||||||
|
protected function fireEvent($field, $change, ContentModel $content, &$normalFieldsEdited)
|
||||||
|
{
|
||||||
|
switch ($field) {
|
||||||
|
case 'status':
|
||||||
|
if ($change['new'] !== ContentContract::STATUS_DRAFT) {
|
||||||
|
Event::fire(new PublishContent($content, $this->changeset));
|
||||||
|
} else {
|
||||||
|
Event::fire(new MakeDraftFromContent($content, $this->changeset));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'isHomepage':
|
||||||
|
Event::fire(new SetHomepage($content, $this->changeset));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$normalFieldsEdited++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,32 @@
|
|||||||
<?php
|
<?php
|
||||||
|
namespace App\Cms\Repositories\ActionLog;
|
||||||
|
|
||||||
namespace App\Models;
|
use App\Models\User;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
/**
|
class Actions
|
||||||
* Class ActionLog
|
|
||||||
*/
|
|
||||||
class ActionLog extends Model
|
|
||||||
{
|
{
|
||||||
protected $table = 'action_log';
|
/**
|
||||||
public $timestamps = false;
|
* @param null $userId
|
||||||
protected $fillable = [
|
*
|
||||||
'type_id',
|
* @return array
|
||||||
'user_id',
|
*/
|
||||||
'ip',
|
public function getLoggedActions($userId = null)
|
||||||
'user_agent',
|
{
|
||||||
'parameters'
|
$actions = $this->getLogActionsQuery(true);
|
||||||
];
|
|
||||||
protected $guarded = [];
|
$user = null;
|
||||||
|
if ($userId) {
|
||||||
|
$user = User::findOrFail($userId);
|
||||||
|
$actions->where('users.id', $userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
$actions = $actions->paginate(25);
|
||||||
|
|
||||||
|
$this->translateLogMessages($actions);
|
||||||
|
|
||||||
|
return [$user, $actions];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query factory for loading action logs with their type (therefore with name and value)
|
* Query factory for loading action logs with their type (therefore with name and value)
|
||||||
@@ -36,7 +43,6 @@ class ActionLog extends Model
|
|||||||
->orderBy('action_log.created_at', 'DESC');
|
->orderBy('action_log.created_at', 'DESC');
|
||||||
|
|
||||||
if ($joinUser) {
|
if ($joinUser) {
|
||||||
|
|
||||||
$actions = $actions->join('users', 'users.id', '=', 'action_log.user_id')
|
$actions = $actions->join('users', 'users.id', '=', 'action_log.user_id')
|
||||||
->select('action_log.*', 'action_log_types.*', 'users.email', 'users.name as user_name');
|
->select('action_log.*', 'action_log_types.*', 'users.email', 'users.name as user_name');
|
||||||
}
|
}
|
||||||
@@ -75,8 +81,6 @@ class ActionLog extends Model
|
|||||||
* Method used for translating and filling parameters into value of log.
|
* Method used for translating and filling parameters into value of log.
|
||||||
*
|
*
|
||||||
* @param $messages
|
* @param $messages
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function translateLogMessages(&$messages)
|
public function translateLogMessages(&$messages)
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Repositories\Content;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Repositories\Content as IContent;
|
||||||
|
use App\CMS\Enumerations\ContentStatuses;
|
||||||
|
use App\CMS\Repositories\Repository;
|
||||||
|
use App\Models\Content\Content as ContentModel;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
|
||||||
|
|
||||||
|
class Content extends Repository implements IContent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ContentModel
|
||||||
|
*/
|
||||||
|
protected $model;
|
||||||
|
|
||||||
|
public function __construct(ContentModel $model)
|
||||||
|
{
|
||||||
|
$this->model = $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for query with setup filter for non-deleted and non-draft pages
|
||||||
|
*/
|
||||||
|
protected function getPageQuery()
|
||||||
|
{
|
||||||
|
return ContentModel::where('status', '!=', IContent::STATUS_DRAFT)
|
||||||
|
->select('contents.*')
|
||||||
|
->with('author')
|
||||||
|
->join('modules', 'modules.handler', '=', 'contents.moduleHandler')
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->where('publishedFrom', '<=', Carbon::now())
|
||||||
|
->orWhereNull('publishedFrom');
|
||||||
|
})
|
||||||
|
->where(function ($query) {
|
||||||
|
$query->where('publishedTo', '>=', Carbon::now())
|
||||||
|
->orWhereNull('publishedTo');
|
||||||
|
})
|
||||||
|
->where('language', LaravelLocalization::getCurrentLocale())
|
||||||
|
->whereNull('contents.deleted_at')
|
||||||
|
->where('modules.enabled', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return $this->getPageQuery()
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getOne($id = null)
|
||||||
|
{
|
||||||
|
if (is_null($id)) {
|
||||||
|
$page = new ContentModel();
|
||||||
|
$page->user_id = \Auth::user()->id;
|
||||||
|
$page->language = LaravelLocalization::getCurrentLocale();
|
||||||
|
$page->status = IContent::STATUS_DRAFT;
|
||||||
|
$page->moduleSettings = [];
|
||||||
|
} else {
|
||||||
|
$page = $this->model->findOrFail($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for homepage content page
|
||||||
|
* @return Content
|
||||||
|
*/
|
||||||
|
public function getHomepage()
|
||||||
|
{
|
||||||
|
return $this->getPageQuery()
|
||||||
|
->where('isHomepage', 1)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for any page specified by its url.
|
||||||
|
*
|
||||||
|
* @param $url
|
||||||
|
*
|
||||||
|
* @return Content
|
||||||
|
*/
|
||||||
|
public function getByURL($url)
|
||||||
|
{
|
||||||
|
return $this->getPageQuery()
|
||||||
|
->where('url', $url)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for overview of all content pages.
|
||||||
|
* These content pages may be filtered by using some handler
|
||||||
|
*
|
||||||
|
* @param bool $handler
|
||||||
|
* @param null $statuses
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public function getOverview($handler = null, $statuses = null)
|
||||||
|
{
|
||||||
|
$query = ContentModel::select('contents.*', 'modules.name AS module_name', 'modules.id AS module_id')
|
||||||
|
->join('modules', 'modules.handler', '=', 'contents.moduleHandler')
|
||||||
|
->join('users', 'users.id', '=', 'contents.userId')
|
||||||
|
->addSelect(DB::raw('COALESCE(users.name, users.email) AS author_name'))
|
||||||
|
->addSelect('users.email AS author_email')
|
||||||
|
->whereNull('contents.deleted_at')
|
||||||
|
->where('contents.language', LaravelLocalization::getCurrentLocale())
|
||||||
|
->where('modules.enabled', 1)
|
||||||
|
->orderBy('contents.created_at', 'DESC');
|
||||||
|
|
||||||
|
// filter results using handler
|
||||||
|
if (!is_null($handler)) {
|
||||||
|
$query = $query->where('contents.moduleHandler', $handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add filtering by status
|
||||||
|
if (is_array($statuses) && in_array($statuses, ContentStatuses::getSimple())) {
|
||||||
|
$query = $query->whereIn('contents.status', $statuses);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pages = $query->paginate(setting('paginatedResults', 20));
|
||||||
|
|
||||||
|
return $pages;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Repositories\FileManager;
|
||||||
|
|
||||||
|
use App\CMS\Helpers\RootDirectory;
|
||||||
|
use App\Models\FileManager\Directory as DirectoryModel;
|
||||||
|
|
||||||
|
class Directory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Checks if directory with given name does not exist in current directory
|
||||||
|
*
|
||||||
|
* @param $name
|
||||||
|
* @param $parentDirectoryId
|
||||||
|
* @param bool $ignoredId
|
||||||
|
*/
|
||||||
|
public function checkIfNameExists($name, $parentDirectoryId, $ignoredId = false)
|
||||||
|
{
|
||||||
|
$exists = DirectoryModel::where('name', $name)
|
||||||
|
->where('parent_id', $parentDirectoryId);
|
||||||
|
|
||||||
|
if ($ignoredId !== false) {
|
||||||
|
$exists = $exists->where('id', '!=', $ignoredId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $exists->exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(DirectoryModel $directory, $data) {
|
||||||
|
$directory->name = $data['name'];
|
||||||
|
$directory->description = $data['description'];
|
||||||
|
$directory->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param DirectoryModel $directory
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function getAllSubdirectories(DirectoryModel &$directory)
|
||||||
|
{
|
||||||
|
if (!$directory->exists) {
|
||||||
|
$directory = DirectoryModel::where('is_root', true)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (is_null($directory)) {
|
||||||
|
$directory = RootDirectory::get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$subdirectories = $directory->allSubdirectories();
|
||||||
|
|
||||||
|
return $subdirectories;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Repositories;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Repositories\Module as IModule;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
use App\Models\Module as ModuleModel;
|
||||||
|
|
||||||
|
class Module extends Repository implements IModule
|
||||||
|
{
|
||||||
|
public function __construct(ModuleModel $module)
|
||||||
|
{
|
||||||
|
$this->model = $module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOne($id = null)
|
||||||
|
{
|
||||||
|
if (is_null($id)) {
|
||||||
|
return new ModuleModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_numeric($id)) {
|
||||||
|
return ModuleModel::findOrFail($id);
|
||||||
|
} else {
|
||||||
|
return ModuleModel::where('alias', $id)
|
||||||
|
->firstOrFail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreateContentTitle(ModuleModel $module)
|
||||||
|
{
|
||||||
|
$pageHeading = trans('admin/contents.new', ['name' => trans($module->name)]);
|
||||||
|
$moduleHeading = $this->call($module, 'getCreateNewTitle');
|
||||||
|
|
||||||
|
return is_null($moduleHeading) ? $pageHeading : $moduleHeading;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUpdateContentTitle(ModuleModel $module, Content $content = null)
|
||||||
|
{
|
||||||
|
$pageHeading = trans('admin/contents.edit', ['name' => trans($module->name)]);
|
||||||
|
$moduleHeading = $this->call($module, 'getEditTitle', [$content]);
|
||||||
|
|
||||||
|
return is_null($moduleHeading) ? $pageHeading : $moduleHeading;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOverviewTitle(ModuleModel $module)
|
||||||
|
{
|
||||||
|
$pageHeading = 'admin/contents.overview';
|
||||||
|
$moduleHeading = $this->call($module, 'getOverviewTitle');
|
||||||
|
|
||||||
|
return is_null($moduleHeading) ? $pageHeading : $moduleHeading;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return ModuleModel::where('enabled', true)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByHandler($handler)
|
||||||
|
{
|
||||||
|
return ModuleModel::where('handler', $handler)
|
||||||
|
->firstOrFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function call(ModuleModel $module, $method, $parameters = [])
|
||||||
|
{
|
||||||
|
if (!is_null($module) && is_callable([$module->handler, $method])) {
|
||||||
|
return call_user_func_array([$module->handler, $method], $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function callOnString($moduleHandler, $method, $parameters = [])
|
||||||
|
{
|
||||||
|
if (is_callable([$moduleHandler, $method])) {
|
||||||
|
return call_user_func_array([$moduleHandler, $method], $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Repositories;
|
||||||
|
|
||||||
|
abstract class Repository
|
||||||
|
{
|
||||||
|
protected $model;
|
||||||
|
|
||||||
|
public function __call($method, $args)
|
||||||
|
{
|
||||||
|
return call_user_func_array([$this->model, $method], $args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Cms\Repositories\Templates;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Repositories\Template as ITemplate;
|
||||||
|
use App\CMS\Repositories\Repository;
|
||||||
|
use App\Models\Module;
|
||||||
|
use App\Models\Templates\Template as TemplateModel;
|
||||||
|
|
||||||
|
class Template extends Repository implements ITemplate
|
||||||
|
{
|
||||||
|
public function setModel(TemplateModel $model)
|
||||||
|
{
|
||||||
|
$this->model = $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for absolute path to template
|
||||||
|
*
|
||||||
|
* @param null $mode
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPathToTemplate($mode = null)
|
||||||
|
{
|
||||||
|
$templateName = $this->model->template_name;
|
||||||
|
$path = $this->model->templatePath;
|
||||||
|
|
||||||
|
// delete namespace if given
|
||||||
|
if (strpos($this->model->template_name, '::')) {
|
||||||
|
list(, $templateName) = explode('::', $templateName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get template name, do not care about directories (they are already contained in path)
|
||||||
|
$parts = explode('.', $templateName);
|
||||||
|
$templateName = last($parts);
|
||||||
|
|
||||||
|
// just a shortcut for this unbelievable long constant name...
|
||||||
|
$_ = DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
|
// path parts
|
||||||
|
$absolutePath = base_path($path->path);
|
||||||
|
$templatePath = str_replace('.', $_, $templateName);
|
||||||
|
$file = $templatePath . ITemplate::TEMPLATE_SUFFIX;
|
||||||
|
|
||||||
|
// compose two versions of path - original and with "custom" directory
|
||||||
|
$original = $absolutePath . $_ . $file;
|
||||||
|
$edited = $absolutePath . $_ . ITemplate::EDITED_TEMPLATES_DIRECTORY . $_ . $file;
|
||||||
|
|
||||||
|
// decide which path will be returned
|
||||||
|
switch ($mode) {
|
||||||
|
case ITemplate::CUSTOM_EDIT_DIRECTORY:
|
||||||
|
return $edited;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ITemplate::ORIGINAL_DIRECTORY:
|
||||||
|
return $original;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (file_exists($absolutePath . $_ . ITemplate::EDITED_TEMPLATES_DIRECTORY . $_ . $file)) {
|
||||||
|
return $edited;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $original;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getForModule(Module $module)
|
||||||
|
{
|
||||||
|
return TemplateModel::where('module_id', $module->id)
|
||||||
|
->select(['template_name', 'name', 'description'])
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Shortcodes;
|
||||||
|
|
||||||
|
use App\Models\Widgets\Widget as WidgetModel;
|
||||||
|
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
|
||||||
|
|
||||||
|
class Widget
|
||||||
|
{
|
||||||
|
protected static $widgets = [];
|
||||||
|
protected static $initialized = false;
|
||||||
|
|
||||||
|
protected function getRenderedWidget(WidgetModel $widget)
|
||||||
|
{
|
||||||
|
$widget->settings = json_decode($widget->settings);
|
||||||
|
|
||||||
|
$handler = $widget->widget_type_handler;
|
||||||
|
$presenter = call_user_func([$handler, 'getPresenter']);
|
||||||
|
|
||||||
|
return call_user_func([$presenter, 'render'], $widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load one widget from database
|
||||||
|
*
|
||||||
|
* @param $containerId
|
||||||
|
*/
|
||||||
|
protected function loadWidget($containerId)
|
||||||
|
{
|
||||||
|
$widget = WidgetModel::where('container_id', $containerId)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$widget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$widget->timestamps = false;
|
||||||
|
$widget->viewed++;
|
||||||
|
$widget->save();
|
||||||
|
$widget->timestamps = true;
|
||||||
|
|
||||||
|
self::$widgets[$containerId] = $this->getRenderedWidget($widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all frequently used widgets
|
||||||
|
*
|
||||||
|
* Frequency of loaded widgets is counted only using direct loading, widgets displayed in widget areas are omitted
|
||||||
|
*/
|
||||||
|
protected function initWidgets()
|
||||||
|
{
|
||||||
|
if (self::$initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$widgets = WidgetModel::where('viewed', '>=', setting('preloadFrequentedWidgetsTreshold', 10))
|
||||||
|
->where('language', LaravelLocalization::getCurrentLocale())
|
||||||
|
->get();
|
||||||
|
|
||||||
|
foreach ($widgets as $widget) {
|
||||||
|
self::$widgets[$widget->container_id] = $this->getRenderedWidget($widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register new shortcode
|
||||||
|
*
|
||||||
|
* Initfrequently used widgets and if not presented yet - load desired widget specified as content of shortcode
|
||||||
|
*
|
||||||
|
* @param $shortcode
|
||||||
|
* @param $containerId
|
||||||
|
* @param $compiler
|
||||||
|
* @param $name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function register($shortcode, $containerId, $compiler, $name)
|
||||||
|
{
|
||||||
|
$this->initWidgets();
|
||||||
|
|
||||||
|
if (!isset(self::$widgets[$containerId])) {
|
||||||
|
$this->loadWidget($containerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$widgets[$containerId];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\HtmlCode;
|
namespace App\CMS\Widgets\HtmlCode;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Widgets\PublicWidget;
|
||||||
|
use App\CMS\Widgets\Exceptions\MissingParameterException;
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
use App\Models\Widget;
|
use App\Models\Widgets\Widget;
|
||||||
use App\Widgets\Contracts\WidgetRenderer;
|
|
||||||
use App\Widgets\Exceptions\MissingParameterException;
|
|
||||||
use App\Widgets\NonInstallableWidget;
|
|
||||||
|
|
||||||
class HtmlCode extends NonInstallableWidget
|
class HtmlCode implements PublicWidget
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Name getter
|
* Name getter
|
||||||
@@ -40,25 +39,17 @@ class HtmlCode extends NonInstallableWidget
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Widget $widget
|
* @param Request $data
|
||||||
* @param \stdClass $data
|
|
||||||
*
|
*
|
||||||
* @return Widget
|
* @return array
|
||||||
* @throws MissingParameterException
|
* @throws MissingParameterException
|
||||||
*/
|
*/
|
||||||
public static function save(Widget $widget, \stdClass $data)
|
public static function save(Request $data)
|
||||||
{
|
{
|
||||||
if (!isset($data->code) || empty($data->code)) {
|
if (!isset($data->code) || empty($data->code)) {
|
||||||
throw new MissingParameterException('code');
|
throw new MissingParameterException('code');
|
||||||
}
|
}
|
||||||
|
|
||||||
$widgetSettings = [
|
return ['code' => $data->code];
|
||||||
'code' => $data->code,
|
|
||||||
'containerClass' => isset($data->containerClass) ? $data->containerClass : ''
|
|
||||||
];
|
|
||||||
|
|
||||||
$widget->settings = json_encode($widgetSettings);
|
|
||||||
|
|
||||||
return $widget;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+14
-9
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\HtmlCode\Presenters;
|
namespace App\CMS\Widgets\HtmlCode\Presenters;
|
||||||
|
|
||||||
use App\Models\Widget;
|
use App\Models\Widgets\Widget;
|
||||||
use App\Models\WidgetType;
|
use App\Models\Widgets\WidgetType;
|
||||||
use App\Widgets\Contracts\WidgetRenderer;
|
use App\CMS\Contracts\Widgets\WidgetRenderer;
|
||||||
|
|
||||||
class HtmlCode implements WidgetRenderer
|
class HtmlCode implements WidgetRenderer
|
||||||
{
|
{
|
||||||
@@ -12,14 +12,15 @@ class HtmlCode implements WidgetRenderer
|
|||||||
*
|
*
|
||||||
* This method renders some HTML code for displaying.
|
* This method renders some HTML code for displaying.
|
||||||
*
|
*
|
||||||
* @param object $settings
|
* @param Widget $widget
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function render($settings)
|
public static function render(Widget $widget)
|
||||||
{
|
{
|
||||||
|
$settings = $widget->settings;
|
||||||
$code = '
|
$code = '
|
||||||
<div class="html-code-widget ' . $settings->containerClass . '">
|
<div class="html-code-widget ' . $widget->container_class . '">
|
||||||
' . $settings->code . '
|
' . $settings->code . '
|
||||||
</div>';
|
</div>';
|
||||||
|
|
||||||
@@ -35,7 +36,11 @@ class HtmlCode implements WidgetRenderer
|
|||||||
*/
|
*/
|
||||||
public static function renderAddForm(WidgetType $type)
|
public static function renderAddForm(WidgetType $type)
|
||||||
{
|
{
|
||||||
return view('admin.widgets.htmlCode.new', ['type' => $type]);
|
return view('admin.widgets.htmlCode.new', [
|
||||||
|
'type' => $type,
|
||||||
|
'widget' => new Widget(),
|
||||||
|
'settings' => new \stdClass()
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,7 +52,7 @@ class HtmlCode implements WidgetRenderer
|
|||||||
*/
|
*/
|
||||||
public static function renderEditForm(Widget $widget)
|
public static function renderEditForm(Widget $widget)
|
||||||
{
|
{
|
||||||
$settings = json_decode($widget->settings);
|
$settings = $widget->settings;
|
||||||
return view('admin.widgets.htmlCode.edit', ['widget' => $widget, 'settings' => $settings]);
|
return view('admin.widgets.htmlCode.edit', ['widget' => $widget, 'settings' => $settings]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\Menu\Extensions;
|
namespace App\CMS\Widgets\Menu\Extensions;
|
||||||
|
|
||||||
use App\Widgets\Contracts\MenuExtensionHandler;
|
use App\CMS\Widgets\Contracts\MenuExtensionHandler;
|
||||||
|
|
||||||
class URL implements MenuExtensionHandler {
|
class URL implements MenuExtensionHandler {
|
||||||
public function getPossibleValues()
|
public function getPossibleValues()
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\CMS\Widgets\Menu;
|
||||||
|
|
||||||
|
use App\CMS\Contracts\Widgets\PublicWidget;
|
||||||
|
use App\CMS\Widgets\Contracts\WidgetRenderer;
|
||||||
|
use App\CMS\Widgets\Exceptions\MissingParameterException;
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Content\Content;
|
||||||
|
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
|
||||||
|
use App\CMS\Contracts\Repositories\Content as IContent;
|
||||||
|
|
||||||
|
class Menu implements PublicWidget
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Name getter
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getName()
|
||||||
|
{
|
||||||
|
return 'widgets/menu.widgetName';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for description
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getDescription()
|
||||||
|
{
|
||||||
|
return 'widgets/menu.widgetDescription';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for presenter/renderer of this widget
|
||||||
|
*
|
||||||
|
* @return WidgetRenderer
|
||||||
|
*/
|
||||||
|
public static function getPresenter()
|
||||||
|
{
|
||||||
|
return Presenters\Menu::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\Models\Widget $widget
|
||||||
|
* @param \stdClass $data
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function save(Request $data)
|
||||||
|
{
|
||||||
|
if (!isset($data->settings) || empty($data->settings) || !json_decode($data->settings)) {
|
||||||
|
throw new MissingParameterException('settings');
|
||||||
|
}
|
||||||
|
|
||||||
|
$links = json_decode($data->settings);
|
||||||
|
$pages = self::selectContentPages(array_keys((array)$links));
|
||||||
|
|
||||||
|
foreach ($links as $link) {
|
||||||
|
if (!isset($pages[$link->id])) {
|
||||||
|
unset($links->{$link->id});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['links' => $links];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function selectContentPages($ids)
|
||||||
|
{
|
||||||
|
$allowedStatuses = [IContent::STATUS_PUBLIC];
|
||||||
|
|
||||||
|
if (\Auth::user()) {
|
||||||
|
$allowedStatuses[] = IContent::STATUS_PROTECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pages = Content::where('language', LaravelLocalization::getCurrentLocale())
|
||||||
|
->whereIn('id', $ids)
|
||||||
|
->whereIn('status', $allowedStatuses)
|
||||||
|
->get();
|
||||||
|
$used = [];
|
||||||
|
foreach ($pages as $page) {
|
||||||
|
$used[$page->id] = $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $used;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,47 +1,35 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Widgets\Menu\Presenters;
|
namespace App\CMS\Widgets\Menu\Presenters;
|
||||||
|
|
||||||
use App\Models\Content;
|
use App\CMS\Contracts\Repositories\Content as ContentContract;
|
||||||
use App\Models\Widget;
|
use App\CMS\Contracts\Widgets\WidgetRenderer;
|
||||||
use App\Models\WidgetType;
|
use App\CMS\Widgets\Menu\Menu as WidgetMenu;
|
||||||
use App\Widgets\Contracts\WidgetRenderer;
|
use App\Models\Widgets\Widget;
|
||||||
|
use App\Models\Widgets\WidgetType;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use Illuminate\Support\Facades\Request;
|
use Illuminate\Support\Facades\Request;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
class Menu implements WidgetRenderer
|
class Menu implements WidgetRenderer
|
||||||
{
|
{
|
||||||
protected static function selectContentPages($ids)
|
|
||||||
{
|
|
||||||
$pages = Content::where('status', '!=', Content::STATUS_DELETED)
|
|
||||||
->whereIn('id', $ids)
|
|
||||||
->get();
|
|
||||||
$used = [];
|
|
||||||
|
|
||||||
foreach ($pages as $page) {
|
|
||||||
$used[$page->id] = $page;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $used;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method used for displaying widget.
|
* Method used for displaying widget.
|
||||||
*
|
*
|
||||||
* This method renders some HTML code for displaying.
|
* This method renders some HTML code for displaying.
|
||||||
*
|
*
|
||||||
* @param object $settings
|
* @param Widget $widget
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public static function render($settings)
|
public static function render(Widget $widget)
|
||||||
{
|
{
|
||||||
|
$settings = $widget->settings;
|
||||||
$links = (array)$settings->links;
|
$links = (array)$settings->links;
|
||||||
|
|
||||||
$pageIds = array_keys($links);
|
$pageIds = array_keys($links);
|
||||||
|
|
||||||
// get pages
|
// get pages
|
||||||
$pages = self::selectContentPages($pageIds);
|
$pages = WidgetMenu::selectContentPages($pageIds);
|
||||||
|
|
||||||
// sort links using "order"
|
// sort links using "order"
|
||||||
uasort($links, function ($a, $b) {
|
uasort($links, function ($a, $b) {
|
||||||
@@ -53,24 +41,28 @@ class Menu implements WidgetRenderer
|
|||||||
$parameters = Route::current()
|
$parameters = Route::current()
|
||||||
->parameters();
|
->parameters();
|
||||||
|
|
||||||
$code = '<ul class="menu ' . $settings->containerClass . '">';
|
$code = '<ul class="menu ' . $widget->container_class . '"';
|
||||||
|
|
||||||
|
if ($widget->container_id) {
|
||||||
|
$code .= ' id="' . e($widget->container_id) . '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
$code .= '>';
|
||||||
|
|
||||||
foreach ($links as $pageId => $link) {
|
foreach ($links as $pageId => $link) {
|
||||||
if (!isset($pages[$pageId])) {
|
if (!isset($pages[$pageId])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$page = $pages[$pageId];
|
|
||||||
|
|
||||||
$active = false;
|
$page = $pages[$pageId];
|
||||||
if (($page->is_homepage && $route == 'page.index') || ($route == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url)) {
|
$active = ($page->isHomepage && $route == 'page.index') || ($route == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url);
|
||||||
$active = true;
|
$route = $page->isHomepage ? route('page.index') : route('page.content', ['url' => $page->url]);
|
||||||
}
|
|
||||||
|
|
||||||
$code .= '<li';
|
$code .= '<li';
|
||||||
if ($active) {
|
if ($active) {
|
||||||
$code .= ' class="is-active active"';
|
$code .= ' class="is-active active"';
|
||||||
}
|
}
|
||||||
$code .= '><a href="' . route('page.content', ['url' => $page->url]) . '">' . e($page->title) . '</a></li>';
|
$code .= '><a href="' . $route . '">' . e($page->title) . '</a></li>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$code .= "</ul>";
|
$code .= "</ul>";
|
||||||
@@ -87,24 +79,19 @@ class Menu implements WidgetRenderer
|
|||||||
*/
|
*/
|
||||||
public static function renderAddForm(WidgetType $type)
|
public static function renderAddForm(WidgetType $type)
|
||||||
{
|
{
|
||||||
$extensions = App::make('registerMenuExtension')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$widget = new Widget();
|
$widget = new Widget();
|
||||||
$content = new Content();
|
$content = app(ContentContract::class);
|
||||||
|
|
||||||
// get list of all pages
|
// get list of all pages
|
||||||
$pages = $content->getOverview()
|
$pages = $content->getOverview();
|
||||||
->get();
|
$widget->settings = new \stdClass();
|
||||||
|
$widget->settings->links = [];
|
||||||
|
|
||||||
$widget->settingsObj = new \stdClass();
|
|
||||||
$widget->settingsObj->links = new \stdClass();
|
|
||||||
|
|
||||||
return view('admin.widgets.menu.new', [
|
return view('admin.widgets.menu.new', [
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'widget' => $widget,
|
'widget' => $widget,
|
||||||
'pages' => $pages,
|
'pages' => $pages,
|
||||||
'extensions' => $extensions
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,20 +104,19 @@ class Menu implements WidgetRenderer
|
|||||||
*/
|
*/
|
||||||
public static function renderEditForm(Widget $widget)
|
public static function renderEditForm(Widget $widget)
|
||||||
{
|
{
|
||||||
// $extensions = App::make('registerMenuExtension')
|
/**
|
||||||
// ->get();
|
* @var $content ContentContract
|
||||||
$content = new Content();
|
*/
|
||||||
|
$content = App::make(ContentContract::class);
|
||||||
|
|
||||||
// get list of all pages
|
// get list of all pages
|
||||||
$pages = $content->getOverview()
|
$pages = $content->getOverview();
|
||||||
->get();
|
|
||||||
|
|
||||||
// make object from JSON
|
// make object from JSON
|
||||||
$widget->settingsObj = json_decode($widget->settings);
|
if (!isset($widget->settings->links)) {
|
||||||
if (!isset($widget->settingsObj->links)) {
|
|
||||||
$links = new \stdClass();
|
$links = new \stdClass();
|
||||||
} else {
|
} else {
|
||||||
$links = (array)$widget->settingsObj->links;
|
$links = (array)$widget->settings->links;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort links using "order"
|
// sort links using "order"
|
||||||
@@ -138,7 +124,7 @@ class Menu implements WidgetRenderer
|
|||||||
return $a->order - $b->order;
|
return $a->order - $b->order;
|
||||||
});
|
});
|
||||||
|
|
||||||
$widget->settingsObj->links = (object)$links;
|
$widget->settings->links = (object)$links;
|
||||||
|
|
||||||
return view('admin.widgets.menu.edit', ['widget' => $widget, 'pages' => $pages]);
|
return view('admin.widgets.menu.edit', ['widget' => $widget, 'pages' => $pages]);
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user