mirror of
https://github.com/espocrm/espocrm.git
synced 2026-03-07 03:37:02 +00:00
Compare commits
417 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09e364625d | ||
|
|
35f575ed7f | ||
|
|
7b0d46b37f | ||
|
|
f474137b91 | ||
|
|
7a18d88c50 | ||
|
|
8d1c9fe666 | ||
|
|
e6566bccdc | ||
|
|
14ed7282f3 | ||
|
|
b13145adce | ||
|
|
3cfca9845a | ||
|
|
afa8d07bb4 | ||
|
|
02434e0ca1 | ||
|
|
11f76c507b | ||
|
|
c68f3eb44d | ||
|
|
6a1d8dcdca | ||
|
|
ba358e5847 | ||
|
|
5e174fd5a9 | ||
|
|
9af2500292 | ||
|
|
8e9dea260e | ||
|
|
29ed6cb3b0 | ||
|
|
4670bb49e8 | ||
|
|
fcc18befc3 | ||
|
|
52ac9b1621 | ||
|
|
9bca545f01 | ||
|
|
80032f8ed7 | ||
|
|
a63a690307 | ||
|
|
24dc2716f7 | ||
|
|
3f40896374 | ||
|
|
8d8778b397 | ||
|
|
68d3b422cc | ||
|
|
145420aaaa | ||
|
|
34ee17b7f5 | ||
|
|
2a0646d1dd | ||
|
|
52620e84cd | ||
|
|
4747113742 | ||
|
|
f26d7c6a62 | ||
|
|
2e0d8cfd43 | ||
|
|
db57c53652 | ||
|
|
badf1aec6f | ||
|
|
19bb4514df | ||
|
|
778be7fea8 | ||
|
|
326970bcd4 | ||
|
|
9411bce8b0 | ||
|
|
244c1a426b | ||
|
|
b3f9ca8721 | ||
|
|
8c66a83054 | ||
|
|
df6a1f6613 | ||
|
|
1033a926fc | ||
|
|
d339c04177 | ||
|
|
edcf0aae84 | ||
|
|
20f97caab3 | ||
|
|
86be4e7352 | ||
|
|
697e271e66 | ||
|
|
5f74504da8 | ||
|
|
fb3d46d389 | ||
|
|
875971fb6e | ||
|
|
1939a58f17 | ||
|
|
40b3374fdd | ||
|
|
c564b1b75a | ||
|
|
c28e73ce3f | ||
|
|
788a6bfdc3 | ||
|
|
15d1f79115 | ||
|
|
bf699d88f7 | ||
|
|
d7f8e4e050 | ||
|
|
3872d7897a | ||
|
|
17a1f6ce63 | ||
|
|
eaa155eff7 | ||
|
|
13fba6d71c | ||
|
|
0d423aa349 | ||
|
|
2fca224ba4 | ||
|
|
574f85df46 | ||
|
|
b7176983e2 | ||
|
|
e8f19ff0dc | ||
|
|
d3cb4607ea | ||
|
|
8ae0696f07 | ||
|
|
299c3c13fc | ||
|
|
a79a8bcef6 | ||
|
|
2a0dd46b5e | ||
|
|
6c287bc2e2 | ||
|
|
7add59ffcb | ||
|
|
9747c43988 | ||
|
|
8b9a0f1437 | ||
|
|
1315ca007c | ||
|
|
e753d767fc | ||
|
|
db893859c2 | ||
|
|
16af3d2ad8 | ||
|
|
f334080fe6 | ||
|
|
b2acfbed98 | ||
|
|
2aca6ca28a | ||
|
|
c96040edec | ||
|
|
e0ebb44e64 | ||
|
|
ee1af88f8d | ||
|
|
1659e583ea | ||
|
|
6f0575d798 | ||
|
|
ba05c45f47 | ||
|
|
353caf29b3 | ||
|
|
7600d473bb | ||
|
|
c9ff48245e | ||
|
|
4ed4a94209 | ||
|
|
c88e01fe75 | ||
|
|
9e46edce79 | ||
|
|
bae5c67839 | ||
|
|
635d5d9c6c | ||
|
|
65be8c385f | ||
|
|
c3d44e2472 | ||
|
|
4a781ed5f4 | ||
|
|
d9995512a1 | ||
|
|
6ed2466785 | ||
|
|
724c74b488 | ||
|
|
67887c5ba4 | ||
|
|
ea2a0068ed | ||
|
|
0bfdea5976 | ||
|
|
305ebc293f | ||
|
|
f17f74672e | ||
|
|
fcaf184b13 | ||
|
|
efe653f1f6 | ||
|
|
c1022bf8f3 | ||
|
|
0f4c3988f8 | ||
|
|
498b7b5679 | ||
|
|
ca445a3cb7 | ||
|
|
8a293749e0 | ||
|
|
5c034279e8 | ||
|
|
9460943ad2 | ||
|
|
5eaeabe231 | ||
|
|
2202b00600 | ||
|
|
68ba5a5c4a | ||
|
|
e80b490152 | ||
|
|
380937b644 | ||
|
|
ac72305101 | ||
|
|
a41779b0bb | ||
|
|
86cdbf24b7 | ||
|
|
5d7bc98088 | ||
|
|
1359e8eb2f | ||
|
|
f3a7003444 | ||
|
|
624f76b1a0 | ||
|
|
484ffa071c | ||
|
|
850fb3cb15 | ||
|
|
40075ed2e3 | ||
|
|
f68bb4b491 | ||
|
|
473e1109b4 | ||
|
|
c4b8b90ff5 | ||
|
|
70b4017353 | ||
|
|
e6f7bf4d6c | ||
|
|
69385519d7 | ||
|
|
235ee7c383 | ||
|
|
a6dba9f09a | ||
|
|
f1352430b9 | ||
|
|
b9b63a8a7c | ||
|
|
5358bf4a43 | ||
|
|
1c7a7d8147 | ||
|
|
ca055e8ca9 | ||
|
|
081c058229 | ||
|
|
a5c941b1b2 | ||
|
|
d43e63b89e | ||
|
|
102886e23d | ||
|
|
3b8b9e392e | ||
|
|
226152135d | ||
|
|
7f6a5b626e | ||
|
|
c5fa26ffcb | ||
|
|
7b2bbcfd05 | ||
|
|
e5b336d4f3 | ||
|
|
2d786d9660 | ||
|
|
a587efddde | ||
|
|
81dd2bc800 | ||
|
|
b1273176a9 | ||
|
|
46beb8b6b7 | ||
|
|
264efa2e8d | ||
|
|
f538f05ec3 | ||
|
|
069a50c717 | ||
|
|
08f1329868 | ||
|
|
e48043c2e8 | ||
|
|
024aeb6d01 | ||
|
|
c79ef63c4d | ||
|
|
54798b94c9 | ||
|
|
f70f22c503 | ||
|
|
33adc65dac | ||
|
|
a6541f6f21 | ||
|
|
0b44fee0e5 | ||
|
|
d03aec270e | ||
|
|
08bca7daf7 | ||
|
|
d5cb1f5c1b | ||
|
|
68b16d3de9 | ||
|
|
daffa60cd4 | ||
|
|
25cb6cdfb3 | ||
|
|
7afecc4cdd | ||
|
|
0e9373cf5e | ||
|
|
7992b78d4e | ||
|
|
fed5e6ded7 | ||
|
|
82ddd2e562 | ||
|
|
1470cea4ed | ||
|
|
43e8929368 | ||
|
|
6db3600a4b | ||
|
|
9b2324755b | ||
|
|
dc77b3c73e | ||
|
|
7627afb7d2 | ||
|
|
e68ad81d57 | ||
|
|
73b84d720a | ||
|
|
0743582ef6 | ||
|
|
f73d26fcf3 | ||
|
|
b1dd9f30fb | ||
|
|
27071695cb | ||
|
|
1f551b6052 | ||
|
|
947ebbb6f5 | ||
|
|
3a706cad86 | ||
|
|
8cb1709966 | ||
|
|
7533fc337e | ||
|
|
601f908992 | ||
|
|
ff72489f39 | ||
|
|
db442e0769 | ||
|
|
189bbd784d | ||
|
|
2940de57b6 | ||
|
|
cceb9eccc3 | ||
|
|
410ba24bef | ||
|
|
292e90e6b7 | ||
|
|
3f9b229a9e | ||
|
|
05c2270f36 | ||
|
|
f22fdd6724 | ||
|
|
8059669a21 | ||
|
|
28a8ad927a | ||
|
|
6f7d27a5fd | ||
|
|
d89a173a41 | ||
|
|
ba5fef320e | ||
|
|
a7982acc8f | ||
|
|
17742fccf1 | ||
|
|
7a2b563cd4 | ||
|
|
549984d1ed | ||
|
|
d9256074fe | ||
|
|
97be52a0bc | ||
|
|
26a4d24492 | ||
|
|
03dad5a178 | ||
|
|
4c0453d0e3 | ||
|
|
1299853961 | ||
|
|
e6d792ef5a | ||
|
|
e8e8d0d7b2 | ||
|
|
cec0c7b374 | ||
|
|
fd73a0b8a5 | ||
|
|
120ff8543e | ||
|
|
7b8fa73474 | ||
|
|
85164758ce | ||
|
|
8a38568617 | ||
|
|
0c9e795dfd | ||
|
|
ee1a50aa16 | ||
|
|
a13b6af04a | ||
|
|
f847535aea | ||
|
|
b1b03c6dc1 | ||
|
|
eeb10c6bce | ||
|
|
05241cefa5 | ||
|
|
1861e2cd87 | ||
|
|
8a17cbe23c | ||
|
|
484458c2ba | ||
|
|
c62cc15159 | ||
|
|
17f8b09782 | ||
|
|
9fd05672ae | ||
|
|
69d96450da | ||
|
|
7393040c12 | ||
|
|
9097e644d4 | ||
|
|
837b1691d1 | ||
|
|
2cdec34062 | ||
|
|
a33e10e92d | ||
|
|
86631117a2 | ||
|
|
05dfcf7511 | ||
|
|
3e1582bd6b | ||
|
|
743f348fcf | ||
|
|
2b2ac2a76d | ||
|
|
a7d2d41b0f | ||
|
|
6ef0081ace | ||
|
|
4f3304d55f | ||
|
|
47b6093752 | ||
|
|
ea8d930e56 | ||
|
|
79f3d86384 | ||
|
|
fff201b7cd | ||
|
|
1ad454ce0b | ||
|
|
e090fe699b | ||
|
|
f677b5614b | ||
|
|
f7b240e6a9 | ||
|
|
ea3a60aaf7 | ||
|
|
6a7cfa58ae | ||
|
|
482f0cc314 | ||
|
|
28ada61f3d | ||
|
|
7057210e90 | ||
|
|
8c5bc59c45 | ||
|
|
b7370ff238 | ||
|
|
fb36f769d9 | ||
|
|
f07b728851 | ||
|
|
7d4ada7ec2 | ||
|
|
1c31a6689f | ||
|
|
a839144796 | ||
|
|
87cbe603d2 | ||
|
|
ec96916013 | ||
|
|
2c811a4faa | ||
|
|
6e089c1e25 | ||
|
|
2e203341b7 | ||
|
|
5bea143bf0 | ||
|
|
732494e251 | ||
|
|
39e1303cbe | ||
|
|
62c3549004 | ||
|
|
9bcc942f0f | ||
|
|
e34ee34d7b | ||
|
|
dedef4b36f | ||
|
|
e6f6e0fcf1 | ||
|
|
11a9e2ab9c | ||
|
|
9077542f61 | ||
|
|
cb6faaa769 | ||
|
|
a209d5aaaf | ||
|
|
767cdc75ee | ||
|
|
3eef0e088a | ||
|
|
1e5ef6a070 | ||
|
|
a2edc3cf4e | ||
|
|
9a5dc7b4d1 | ||
|
|
7b0fd40d3e | ||
|
|
169df31cab | ||
|
|
44b0ba2f33 | ||
|
|
8d70956607 | ||
|
|
5ad20c8666 | ||
|
|
790d4a88b5 | ||
|
|
b72ac42068 | ||
|
|
0a379be049 | ||
|
|
e0e08a1c17 | ||
|
|
0d825120bb | ||
|
|
7b81b66b76 | ||
|
|
d39f4e2533 | ||
|
|
598a2f9f05 | ||
|
|
ce9089b838 | ||
|
|
45b06fc154 | ||
|
|
f44177a994 | ||
|
|
d91b13a7c1 | ||
|
|
bd1894322c | ||
|
|
90874535ea | ||
|
|
8c919dbca4 | ||
|
|
05223c5272 | ||
|
|
afee6d564b | ||
|
|
b4e879a369 | ||
|
|
de4d96e260 | ||
|
|
89056f61c2 | ||
|
|
afac29151c | ||
|
|
e54430fb1b | ||
|
|
7d8736b98c | ||
|
|
216e9419d4 | ||
|
|
359fdd4dab | ||
|
|
2044a87630 | ||
|
|
171feed28e | ||
|
|
92dbbbd390 | ||
|
|
3166cb862e | ||
|
|
b606cb2e04 | ||
|
|
724ef00d52 | ||
|
|
0b7857b495 | ||
|
|
a150eb7f0e | ||
|
|
4cb21a4fdb | ||
|
|
46e13b0269 | ||
|
|
d4d5138991 | ||
|
|
9fd00d9f0a | ||
|
|
9361938285 | ||
|
|
cb054b2f2b | ||
|
|
f8ff6e6cf5 | ||
|
|
918c1b2114 | ||
|
|
2026bcb021 | ||
|
|
ce5393155a | ||
|
|
6f4b752b10 | ||
|
|
2a5a453517 | ||
|
|
191bba7afc | ||
|
|
f50d2ef9e3 | ||
|
|
1ad744d151 | ||
|
|
ba0f86c8d4 | ||
|
|
372c84bfa3 | ||
|
|
6ec18950e4 | ||
|
|
6c3168a356 | ||
|
|
109ee17a47 | ||
|
|
21702b3c34 | ||
|
|
159a2ee99d | ||
|
|
d6151d33b4 | ||
|
|
2217e03fa8 | ||
|
|
794c7eb523 | ||
|
|
98f61c0c4b | ||
|
|
5f5a450d95 | ||
|
|
0ba9679a75 | ||
|
|
85e60d4e32 | ||
|
|
a074b8a214 | ||
|
|
ac593c1d3d | ||
|
|
170e62bc8b | ||
|
|
5d19ae42dc | ||
|
|
9f3fdd01bf | ||
|
|
65e94e237d | ||
|
|
7935bc59fe | ||
|
|
f49677b5c0 | ||
|
|
b69f829a3e | ||
|
|
13dfc90a1b | ||
|
|
6d49d39480 | ||
|
|
f473ea9cea | ||
|
|
db8536ac55 | ||
|
|
e402745a86 | ||
|
|
abcaaddc2f | ||
|
|
3ac375c95c | ||
|
|
56f65e0fc0 | ||
|
|
471df0034e | ||
|
|
a1b3be9ef3 | ||
|
|
c4f70482ac | ||
|
|
31a8fa387d | ||
|
|
a0d6cb9be4 | ||
|
|
4586d26bd6 | ||
|
|
1609adc766 | ||
|
|
aa0a9cf708 | ||
|
|
d7dfe5fea4 | ||
|
|
340ed5acec | ||
|
|
7ec3e38e6d | ||
|
|
879bf13809 | ||
|
|
b44bbaffa2 | ||
|
|
4c562cb603 | ||
|
|
8eb2be46ca | ||
|
|
cd7571387c | ||
|
|
1b3496edd9 | ||
|
|
356da4e70d | ||
|
|
f3deffb3f6 | ||
|
|
8398cc4364 | ||
|
|
6ddda814c0 | ||
|
|
76ffa2def9 | ||
|
|
2fdc0a3a93 | ||
|
|
0dcc8d08d1 |
@@ -1,3 +1,9 @@
|
||||
## Pull Requests
|
||||
|
||||
Before we can merge your pull request you need to accept our CLA [here](https://github.com/espocrm/cla). It's very simple to do.
|
||||
|
||||
[Code Style Guidelines](https://github.com/espocrm/espocrm/wiki/Code-Style-Guidelines).
|
||||
[Code Style Guidelines](https://github.com/espocrm/espocrm/wiki/Code-Style-Guidelines).
|
||||
|
||||
## Issues
|
||||
|
||||
We don't provide developer help or any kind of support on github. Please use our [forum](http://forum.espocrm.com/) for this.
|
||||
|
||||
42
application/Espo/Acl/ActionHistoryRecord.php
Normal file
42
application/Espo/Acl/ActionHistoryRecord.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
|
||||
use \Espo\Entities\User as EntityUser;
|
||||
use \Espo\ORM\Entity;
|
||||
|
||||
class ActionHistoryRecord extends \Espo\Core\Acl\Base
|
||||
{
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
return $entity->get('userId') === $user->id;
|
||||
}
|
||||
}
|
||||
|
||||
61
application/Espo/Acl/ScheduledJob.php
Normal file
61
application/Espo/Acl/ScheduledJob.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
|
||||
use \Espo\Entities\User as EntityUser;
|
||||
use \Espo\ORM\Entity;
|
||||
|
||||
class ScheduledJob extends \Espo\Core\Acl\Base
|
||||
{
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($entity->get('isInternal')) return false;
|
||||
return $this->checkEntity($user, $entity, $data, 'read');
|
||||
}
|
||||
|
||||
public function checkEntityEdit(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($entity->get('isInternal')) return false;
|
||||
return $this->checkEntity($user, $entity, $data, 'edit');
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($entity->get('isInternal')) return false;
|
||||
return $this->checkEntity($user, $entity, $data, 'delete');
|
||||
}
|
||||
|
||||
public function checkEntityCreate(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($entity->get('isInternal')) return false;
|
||||
return $this->checkEntity($user, $entity, $data, 'create');
|
||||
}
|
||||
}
|
||||
|
||||
71
application/Espo/Controllers/ActionHistoryRecord.php
Normal file
71
application/Espo/Controllers/ActionHistoryRecord.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Controllers;
|
||||
|
||||
use \Espo\Core\Exceptions\Forbidden;
|
||||
|
||||
class ActionHistoryRecord extends \Espo\Core\Controllers\Record
|
||||
{
|
||||
public function actionUpdate($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionCreate($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionListLinked($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionMassUpdate($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionCreateLink($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionRemoveLink($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionMassDelete($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class Admin extends \Espo\Core\Controllers\Base
|
||||
{
|
||||
$scheduledJob = $this->getContainer()->get('scheduledJob');
|
||||
|
||||
return $scheduledJob->getAllNamesOnly();
|
||||
return $scheduledJob->getAvailableList();
|
||||
}
|
||||
|
||||
public function postActionUploadUpgradePackage($params, $data)
|
||||
|
||||
@@ -65,6 +65,9 @@ class App extends \Espo\Core\Controllers\Base
|
||||
$settings->$item = $this->getConfig()->get($item);
|
||||
}
|
||||
|
||||
unset($userData['authTokenId']);
|
||||
unset($userData['password']);
|
||||
|
||||
return array(
|
||||
'user' => $userData,
|
||||
'acl' => $this->getAcl()->getMap(),
|
||||
|
||||
@@ -54,7 +54,7 @@ class Attachment extends \Espo\Core\Controllers\Record
|
||||
|
||||
$attachment = $this->getEntityManager()->getEntity('Attachment');
|
||||
$this->getEntityManager()->saveEntity($attachment);
|
||||
$this->getContainer()->get('fileManager')->putContents('data/upload/' . $attachment->id, $contents);
|
||||
$this->getContainer()->get('fileStorageManager')->putContents($attachment, $contents);
|
||||
|
||||
return array(
|
||||
'attachmentId' => $attachment->id
|
||||
|
||||
@@ -42,20 +42,37 @@ class AuthToken extends \Espo\Core\Controllers\Record
|
||||
|
||||
public function actionUpdate($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionCreate($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionListLinked($params, $data, $request)
|
||||
{
|
||||
if (
|
||||
is_array($data) &&
|
||||
array_key_exists('isActive', $data) &&
|
||||
$data['isActive'] === false &&
|
||||
count(array_keys($data)) === 1)
|
||||
{
|
||||
return parent::actionUpdate($params, $data, $request);
|
||||
}
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionMassUpdate($params, $data, $request)
|
||||
{
|
||||
if (empty($data['attributes'])) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$attributes = $data['attributes'];
|
||||
|
||||
if (
|
||||
is_object($attributes) &&
|
||||
isset($attributes->isActive) &&
|
||||
$attributes->isActive === false &&
|
||||
count(array_keys(get_object_vars($attributes))) === 1
|
||||
) {
|
||||
return parent::actionMassUpdate($params, $data, $request);
|
||||
}
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
public function actionCreate($params, $data, $request)
|
||||
{
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Controllers;
|
||||
|
||||
@@ -34,17 +34,19 @@ use \Espo\Core\Exceptions\Error;
|
||||
class EmailTemplate extends \Espo\Core\Controllers\Record
|
||||
{
|
||||
public function actionParse($params, $data, $request)
|
||||
{
|
||||
{
|
||||
$id = $request->get('id');
|
||||
$emailAddress = $request->get('emailAddress');
|
||||
if (empty($id)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
|
||||
return $this->getRecordService()->parse($id, array(
|
||||
'emailAddress' => $request->get('emailAddress'),
|
||||
'parentType' => $request->get('parentType'),
|
||||
'parentId' => $request->get('parentId'),
|
||||
'relatedType' => $request->get('relatedType'),
|
||||
'relatedId' => $request->get('relatedId')
|
||||
), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
|
||||
namespace Espo\Controllers;
|
||||
|
||||
use \Espo\Core\Exceptions\Error,
|
||||
\Espo\Core\Exceptions\Forbidden,
|
||||
\Espo\Core\Exceptions\NotFound,
|
||||
\Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Exceptions\Error;
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
|
||||
class FieldManager extends \Espo\Core\Controllers\Base
|
||||
{
|
||||
@@ -49,7 +49,7 @@ class FieldManager extends \Espo\Core\Controllers\Base
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$data = $this->getContainer()->get('fieldManager')->read($params['name'], $params['scope']);
|
||||
$data = $this->getContainer()->get('fieldManager')->read($params['scope'], $params['name']);
|
||||
|
||||
if (!isset($data)) {
|
||||
throw new BadRequest();
|
||||
@@ -65,16 +65,16 @@ class FieldManager extends \Espo\Core\Controllers\Base
|
||||
}
|
||||
|
||||
$fieldManager = $this->getContainer()->get('fieldManager');
|
||||
$fieldManager->create($data['name'], $data, $params['scope']);
|
||||
$fieldManager->create($params['scope'], $data['name'], $data);
|
||||
|
||||
try {
|
||||
$this->getContainer()->get('dataManager')->rebuild($params['scope']);
|
||||
} catch (Error $e) {
|
||||
$fieldManager->delete($data['name'], $params['scope']);
|
||||
$fieldManager->delete($params['scope'], $data['name']);
|
||||
throw new Error($e->getMessage());
|
||||
}
|
||||
|
||||
return $fieldManager->read($data['name'], $params['scope']);
|
||||
return $fieldManager->read($params['scope'], $data['name']);
|
||||
}
|
||||
|
||||
public function putActionUpdate($params, $data)
|
||||
@@ -84,7 +84,7 @@ class FieldManager extends \Espo\Core\Controllers\Base
|
||||
}
|
||||
|
||||
$fieldManager = $this->getContainer()->get('fieldManager');
|
||||
$fieldManager->update($params['name'], $data, $params['scope']);
|
||||
$fieldManager->update($params['scope'], $params['name'], $data);
|
||||
|
||||
if ($fieldManager->isChanged()) {
|
||||
$this->getContainer()->get('dataManager')->rebuild($params['scope']);
|
||||
@@ -92,7 +92,7 @@ class FieldManager extends \Espo\Core\Controllers\Base
|
||||
$this->getContainer()->get('dataManager')->clearCache();
|
||||
}
|
||||
|
||||
return $fieldManager->read($params['name'], $params['scope']);
|
||||
return $fieldManager->read($params['scope'], $params['name']);
|
||||
}
|
||||
|
||||
public function deleteActionDelete($params, $data)
|
||||
@@ -101,11 +101,11 @@ class FieldManager extends \Espo\Core\Controllers\Base
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$res = $this->getContainer()->get('fieldManager')->delete($params['name'], $params['scope']);
|
||||
$result = $this->getContainer()->get('fieldManager')->delete($params['scope'], $params['name']);
|
||||
|
||||
$this->getContainer()->get('dataManager')->rebuildMetadata();
|
||||
|
||||
return $res;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function postActionResetToDefault($params, $data)
|
||||
@@ -114,7 +114,7 @@ class FieldManager extends \Espo\Core\Controllers\Base
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$this->getContainer()->get('fieldManager')->resetToDefault($data['name'], $data['scope']);
|
||||
$this->getContainer()->get('fieldManager')->resetToDefault($data['scope'], $data['name']);
|
||||
|
||||
$this->getContainer()->get('dataManager')->rebuildMetadata();
|
||||
|
||||
|
||||
@@ -68,9 +68,9 @@ class Import extends \Espo\Core\Controllers\Record
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
protected function getFileManager()
|
||||
protected function getFileStorageManager()
|
||||
{
|
||||
return $this->getContainer()->get('fileManager');
|
||||
return $this->getContainer()->get('fileStorageManager');
|
||||
}
|
||||
|
||||
protected function getEntityManager()
|
||||
@@ -92,7 +92,7 @@ class Import extends \Espo\Core\Controllers\Record
|
||||
$attachment->set('name', 'import-file.csv');
|
||||
$this->getEntityManager()->saveEntity($attachment);
|
||||
|
||||
$this->getFileManager()->putContents('data/upload/' . $attachment->id, $contents);
|
||||
$this->getFileStorageManager()->putContents($attachment, $contents);
|
||||
|
||||
return array(
|
||||
'attachmentId' => $attachment->id
|
||||
@@ -167,12 +167,18 @@ class Import extends \Espo\Core\Controllers\Record
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
$timezone = 'UTC';
|
||||
if (isset($data['timezone'])) {
|
||||
$timezone = $data['timezone'];
|
||||
}
|
||||
|
||||
$importParams = array(
|
||||
'headerRow' => !empty($data['headerRow']),
|
||||
'fieldDelimiter' => $data['fieldDelimiter'],
|
||||
'textQualifier' => $data['textQualifier'],
|
||||
'dateFormat' => $data['dateFormat'],
|
||||
'timeFormat' => $data['timeFormat'],
|
||||
'timezone' => $timezone,
|
||||
'personNameFormat' => $data['personNameFormat'],
|
||||
'decimalMark' => $data['decimalMark'],
|
||||
'currency' => $data['currency'],
|
||||
|
||||
46
application/Espo/Controllers/LastViewed.php
Normal file
46
application/Espo/Controllers/LastViewed.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Controllers;
|
||||
|
||||
use \Espo\Core\Exceptions\Forbidden;
|
||||
|
||||
class LastViewed extends \Espo\Core\Controllers\Base
|
||||
{
|
||||
public function getActionIndex($params, $data, $request)
|
||||
{
|
||||
$result = $this->getServiceFactory()->create('LastViewed')->get();
|
||||
|
||||
return [
|
||||
'total' => $result['total'],
|
||||
'list' => isset($result['collection']) ? $result['collection']->toArray() : $result['list']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,10 @@ use \Espo\Core\Exceptions\Forbidden;
|
||||
|
||||
class Metadata extends \Espo\Core\Controllers\Base
|
||||
{
|
||||
|
||||
public function actionRead($params, $data)
|
||||
{
|
||||
$data = $this->getMetadata()->getAll();
|
||||
unset($data['formula']);
|
||||
return $data;
|
||||
return $this->getMetadata()->getAllForFrontend();
|
||||
}
|
||||
|
||||
public function getActionGet($params, $data, $request)
|
||||
|
||||
@@ -69,6 +69,11 @@ class Acl
|
||||
return $this->getAclManager()->get($this->getUser(), $permission);
|
||||
}
|
||||
|
||||
public function checkReadNo($scope)
|
||||
{
|
||||
return $this->getAclManager()->checkReadNo($this->getUser(), $scope);
|
||||
}
|
||||
|
||||
public function checkReadOnlyTeam($scope)
|
||||
{
|
||||
return $this->getAclManager()->checkReadOnlyTeam($this->getUser(), $scope);
|
||||
|
||||
@@ -106,6 +106,14 @@ class Base implements Injectable
|
||||
return $data->read === 'team';
|
||||
}
|
||||
|
||||
public function checkReadNo(User $user, $data)
|
||||
{
|
||||
if (empty($data) || !is_object($data) || !isset($data->read)) {
|
||||
return false;
|
||||
}
|
||||
return $data->read === 'no';
|
||||
}
|
||||
|
||||
public function checkReadOnlyOwn(User $user, $data)
|
||||
{
|
||||
if (empty($data) || !is_object($data) || !isset($data->read)) {
|
||||
|
||||
@@ -36,7 +36,7 @@ use \Espo\Entities\User;
|
||||
|
||||
use \Espo\Core\Utils\Config;
|
||||
use \Espo\Core\Utils\Metadata;
|
||||
use \Espo\Core\Utils\FieldManager;
|
||||
use \Espo\Core\Utils\FieldManagerUtil;
|
||||
use \Espo\Core\Utils\File\Manager as FileManager;
|
||||
|
||||
class Table
|
||||
@@ -77,7 +77,7 @@ class Table
|
||||
|
||||
protected $forbiddenFieldsCache = array();
|
||||
|
||||
public function __construct(User $user, Config $config = null, FileManager $fileManager = null, Metadata $metadata = null, FieldManager $fieldManager = null)
|
||||
public function __construct(User $user, Config $config = null, FileManager $fileManager = null, Metadata $metadata = null, FieldManagerUtil $fieldManager = null)
|
||||
{
|
||||
$this->data = (object) [
|
||||
'table' => (object) [],
|
||||
|
||||
@@ -107,7 +107,7 @@ class AclManager
|
||||
$config = $this->getContainer()->get('config');
|
||||
$fileManager = $this->getContainer()->get('fileManager');
|
||||
$metadata = $this->getContainer()->get('metadata');
|
||||
$fieldManager = $this->getContainer()->get('fieldManager');
|
||||
$fieldManager = $this->getContainer()->get('fieldManagerUtil');
|
||||
|
||||
$this->tableHashMap[$key] = new $this->tableClassName($user, $config, $fileManager, $metadata, $fieldManager);
|
||||
}
|
||||
@@ -133,6 +133,15 @@ class AclManager
|
||||
return $this->getTable($user)->get($permission);
|
||||
}
|
||||
|
||||
public function checkReadNo(User $user, $scope)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
$data = $this->getTable($user)->getScopeData($scope);
|
||||
return $this->getImplementation($scope)->checkReadNo($user, $data);
|
||||
}
|
||||
|
||||
public function checkReadOnlyTeam(User $user, $scope)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
|
||||
@@ -37,7 +37,7 @@ use \Espo\Entities\Portal;
|
||||
|
||||
use \Espo\Core\Utils\Config;
|
||||
use \Espo\Core\Utils\Metadata;
|
||||
use \Espo\Core\Utils\FieldManager;
|
||||
use \Espo\Core\Utils\FieldManagerUtil;
|
||||
use \Espo\Core\Utils\File\Manager as FileManager;
|
||||
|
||||
class Table extends \Espo\Core\Acl\Table
|
||||
@@ -52,7 +52,7 @@ class Table extends \Espo\Core\Acl\Table
|
||||
|
||||
protected $valuePermissionList = [];
|
||||
|
||||
public function __construct(User $user, Portal $portal, Config $config = null, FileManager $fileManager = null, Metadata $metadata = null, FieldManager $fieldManager = null)
|
||||
public function __construct(User $user, Portal $portal, Config $config = null, FileManager $fileManager = null, Metadata $metadata = null, FieldManagerUtil $fieldManager = null)
|
||||
{
|
||||
if (empty($portal)) {
|
||||
throw new Error("No portal was passed to AclPortal\\Table constructor.");
|
||||
|
||||
@@ -128,6 +128,14 @@ class Container
|
||||
return new \Espo\Core\Utils\Api\Slim();
|
||||
}
|
||||
|
||||
protected function loadFileStorageManager()
|
||||
{
|
||||
return new \Espo\Core\FileStorage\Manager(
|
||||
$this->get('metadata')->get(['app', 'fileStorage', 'implementationClassNameMap']),
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
protected function loadFileManager()
|
||||
{
|
||||
return new \Espo\Core\Utils\File\Manager(
|
||||
@@ -327,6 +335,13 @@ class Container
|
||||
);
|
||||
}
|
||||
|
||||
protected function loadFieldManagerUtil()
|
||||
{
|
||||
return new \Espo\Core\Utils\FieldManagerUtil(
|
||||
$this->get('metadata')
|
||||
);
|
||||
}
|
||||
|
||||
protected function loadThemeManager()
|
||||
{
|
||||
return new \Espo\Core\Utils\ThemeManager(
|
||||
@@ -343,6 +358,13 @@ class Container
|
||||
);
|
||||
}
|
||||
|
||||
protected function loadInjectableFactory()
|
||||
{
|
||||
return new \Espo\Core\InjectableFactory(
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
public function setUser(\Espo\Entities\User $user)
|
||||
{
|
||||
$this->set('user', $user);
|
||||
|
||||
@@ -67,7 +67,7 @@ class Record extends Base
|
||||
public function actionRead($params, $data, $request)
|
||||
{
|
||||
$id = $params['id'];
|
||||
$entity = $this->getRecordService()->getEntity($id);
|
||||
$entity = $this->getRecordService()->readEntity($id);
|
||||
|
||||
if (empty($entity)) {
|
||||
throw new NotFound();
|
||||
@@ -258,6 +258,14 @@ class Record extends Base
|
||||
$params['attributeList'] = $data['attributeList'];
|
||||
}
|
||||
|
||||
if (isset($data['fieldList'])) {
|
||||
$params['fieldList'] = $data['fieldList'];
|
||||
}
|
||||
|
||||
if (isset($data['format'])) {
|
||||
$params['format'] = $data['format'];
|
||||
}
|
||||
|
||||
return array(
|
||||
'id' => $this->getRecordService()->export($params)
|
||||
);
|
||||
|
||||
@@ -59,6 +59,8 @@ class DataManager
|
||||
|
||||
$result &= $this->rebuildDatabase($entityList);
|
||||
|
||||
$this->rebuildScheduledJobs();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -121,6 +123,40 @@ class DataManager
|
||||
return empty($ormData) ? false : true;
|
||||
}
|
||||
|
||||
public function rebuildScheduledJobs()
|
||||
{
|
||||
$metadata = $this->getContainer()->get('metadata');
|
||||
$entityManager = $this->getContainer()->get('entityManager');
|
||||
|
||||
$jobs = $metadata->get(['entityDefs', 'ScheduledJob', 'jobs'], array());
|
||||
|
||||
foreach ($jobs as $jobName => $defs) {
|
||||
if ($jobName && !empty($defs['isSystem']) && !empty($defs['scheduling'])) {
|
||||
if (!$entityManager->getRepository('ScheduledJob')->where(array(
|
||||
'job' => $jobName,
|
||||
'status' => 'Active',
|
||||
'scheduling' => $defs['scheduling']
|
||||
))->findOne()) {
|
||||
$job = $entityManager->getRepository('ScheduledJob')->where(array(
|
||||
'job' => $jobName
|
||||
))->findOne();
|
||||
if ($job) {
|
||||
$entityManager->removeEntity($job);
|
||||
}
|
||||
$job = $entityManager->getEntity('ScheduledJob');
|
||||
$job->set(array(
|
||||
'job' => $jobName,
|
||||
'status' => 'Active',
|
||||
'scheduling' => $defs['scheduling'],
|
||||
'isInternal' => true,
|
||||
'name' => $jobName
|
||||
));
|
||||
$entityManager->saveEntity($job);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update cache timestamp
|
||||
*
|
||||
|
||||
65
application/Espo/Core/Export/Csv.php
Normal file
65
application/Espo/Core/Export/Csv.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Export;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class Csv extends \Espo\Core\Injectable
|
||||
{
|
||||
protected $dependencyList = [
|
||||
'config',
|
||||
'preferences'
|
||||
];
|
||||
|
||||
public function process($entityType, $params, $dataList)
|
||||
{
|
||||
if (!is_array($params['attributeList'])) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$attributeList = $params['attributeList'];
|
||||
|
||||
$delimiter = $this->getInjection('preferences')->get('exportDelimiter');
|
||||
if (empty($delimiter)) {
|
||||
$delimiter = $this->getInjection('config')->get('exportDelimiter', ';');
|
||||
}
|
||||
|
||||
$fp = fopen('php://temp', 'w');
|
||||
fputcsv($fp, $attributeList, $delimiter);
|
||||
foreach ($dataList as $row) {
|
||||
fputcsv($fp, $row, $delimiter);
|
||||
}
|
||||
rewind($fp);
|
||||
$csv = stream_get_contents($fp);
|
||||
fclose($fp);
|
||||
|
||||
return $csv;
|
||||
}
|
||||
}
|
||||
449
application/Espo/Core/Export/Xlsx.php
Normal file
449
application/Espo/Core/Export/Xlsx.php
Normal file
@@ -0,0 +1,449 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Export;
|
||||
|
||||
use \Espo\ORM\Entity;
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class Xlsx extends \Espo\Core\Injectable
|
||||
{
|
||||
protected $dependencyList = [
|
||||
'language',
|
||||
'metadata',
|
||||
'config',
|
||||
'dateTime',
|
||||
'entityManager',
|
||||
'fileStorageManager',
|
||||
'fileManager'
|
||||
];
|
||||
|
||||
protected function getConfig()
|
||||
{
|
||||
return $this->getInjection('config');
|
||||
}
|
||||
|
||||
protected function getMetadata()
|
||||
{
|
||||
return $this->getInjection('metadata');
|
||||
}
|
||||
|
||||
protected function getEntityManager()
|
||||
{
|
||||
return $this->getInjection('entityManager');
|
||||
}
|
||||
|
||||
public function loadAdditionalFields(Entity $entity, $fieldList)
|
||||
{
|
||||
foreach ($entity->getRelationList() as $link) {
|
||||
if ($entity->getRelationType($link) === 'belongsToParent') {
|
||||
if (in_array($link, $fieldList)) {
|
||||
$parent = $entity->get($link);
|
||||
if ($parent instanceof Entity) {
|
||||
$entity->set($link . 'Name', $parent->get('name'));
|
||||
}
|
||||
}
|
||||
} else if ($entity->getRelationType($link) === 'belongsTo' && $entity->getRelationParam($link, 'noJoin') && $entity->hasField($link . 'Name')) {
|
||||
if (in_array($link, $fieldList)) {
|
||||
$related = $entity->get($link);
|
||||
if ($related instanceof Entity) {
|
||||
$entity->set($link . 'Name', $related->get('name'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function addAdditionalAttributes($entityType, &$attributeList, $fieldList)
|
||||
{
|
||||
$linkList = [];
|
||||
|
||||
if (!in_array('id', $attributeList)) {
|
||||
$attributeList[] = 'id';
|
||||
}
|
||||
|
||||
$linkDefs = $this->getMetadata()->get(['entityDefs', $entityType, 'links']);
|
||||
if (is_array($linkDefs)) {
|
||||
foreach ($linkDefs as $link => $defs) {
|
||||
if (empty($defs['type'])) continue;
|
||||
if ($defs['type'] === 'belongsToParent') {
|
||||
$linkList[] = $link;
|
||||
} else if ($defs['type'] === 'belongsTo' && !empty($defs['noJoin'])) {
|
||||
if ($this->getMetadata()->get(['entityDefs', $entityType, 'fields', $link])) {
|
||||
$linkList[] = $link;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($linkList as $item) {
|
||||
if (in_array($item, $fieldList) && !in_array($item . 'Name', $attributeList)) {
|
||||
$attributeList[] = $item . 'Name';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($fieldList as $field) {
|
||||
$type = $this->getMetadata()->get(['entityDefs', $entityType, 'fields', $field, 'type']);
|
||||
if ($type === 'currencyConverted') {
|
||||
if (!in_array($field, $attributeList)) {
|
||||
$attributeList[] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function process($entityType, $params, $dataList)
|
||||
{
|
||||
if (!is_array($params['fieldList'])) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$phpExcel = new \PHPExcel();
|
||||
$sheet = $phpExcel->setActiveSheetIndex(0);
|
||||
|
||||
if (isset($params['exportName'])) {
|
||||
$exportName = $params['exportName'];
|
||||
} else {
|
||||
$exportName = $this->getInjection('language')->translate($entityType, 'scopeNamesPlural');
|
||||
}
|
||||
|
||||
$sheetName = substr($exportName, 0, 30);
|
||||
$badCharList = ['*', ':', '/', '\\', '?', '[', ']'];
|
||||
foreach ($badCharList as $badChar) {
|
||||
$sheetName = str_replace($badCharList, ' ', $sheetName);
|
||||
}
|
||||
$sheetName = str_replace('\'', '', $sheetName);
|
||||
|
||||
$sheet->setTitle($sheetName);
|
||||
|
||||
$fieldList = $params['fieldList'];
|
||||
|
||||
$titleStyle = array(
|
||||
'font' => array(
|
||||
'bold' => true,
|
||||
'size' => 12
|
||||
)
|
||||
);
|
||||
$dateStyle = array(
|
||||
'font' => array(
|
||||
'size' => 12
|
||||
)
|
||||
);
|
||||
|
||||
$sheet->setCellValue('A1', $exportName);
|
||||
|
||||
$sheet->setCellValue('B1', \PHPExcel_Shared_Date::PHPToExcel(strtotime(date('Y-m-d H:i:s'))));
|
||||
|
||||
|
||||
$sheet->getStyle('A1')->applyFromArray($titleStyle);
|
||||
$sheet->getStyle('B1')->applyFromArray($dateStyle);
|
||||
|
||||
$sheet->getStyle('B1')->getNumberFormat()
|
||||
->setFormatCode($this->getInjection('dateTime')->getDateTimeFormat());
|
||||
|
||||
$azRange = range('A', 'Z');
|
||||
$azRangeCopied = $azRange;
|
||||
foreach ($azRangeCopied as $i => $char1) {
|
||||
foreach ($azRangeCopied as $j => $char2) {
|
||||
$azRange[] = $char1 . $char2;
|
||||
if ($i * count($azRangeCopied) + $j === count($fieldList)) {
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rowNumber = 3;
|
||||
|
||||
$linkColList = [];
|
||||
|
||||
$lastIndex = 0;
|
||||
|
||||
foreach ($fieldList as $i => $name) {
|
||||
$col = $azRange[$i];
|
||||
|
||||
$defs = $this->getInjection('metadata')->get(['entityDefs', $entityType, 'fields', $name]);
|
||||
|
||||
if (!$defs) {
|
||||
$defs['type'] = 'base';
|
||||
}
|
||||
|
||||
$label = $name;
|
||||
if (strpos($name, '_') !== false) {
|
||||
list($linkName, $foreignField) = explode('_', $name);
|
||||
$foreigScope = $this->getInjection('metadata')->get(['entityDefs', $entityType, 'links', $linkName, 'entity']);
|
||||
if ($foreigScope) {
|
||||
$label = $this->getInjection('language')->translate($linkName, 'links', $entityType) . '.' . $this->getInjection('language')->translate($foreignField, 'fields', $foreigScope);
|
||||
}
|
||||
} else {
|
||||
$label = $this->getInjection('language')->translate($name, 'fields', $entityType);
|
||||
}
|
||||
|
||||
$sheet->setCellValue($col . $rowNumber, $label);
|
||||
$sheet->getColumnDimension($col)->setAutoSize(true);
|
||||
if (
|
||||
$defs['type'] == 'phone'
|
||||
|| $defs['type'] == 'email'
|
||||
|| $defs['type'] == 'url'
|
||||
|| $defs['type'] == 'link'
|
||||
|| $defs['type'] == 'linkParent'
|
||||
) {
|
||||
$linkColList[] = $col;
|
||||
} else if ($name == 'name') {
|
||||
$linkColList[] = $col;
|
||||
}
|
||||
$lastIndex = $i;
|
||||
}
|
||||
|
||||
$col = $azRange[$i];
|
||||
|
||||
$headerStyle = array(
|
||||
'font' => array(
|
||||
'bold' => true,
|
||||
'size' => 12
|
||||
)
|
||||
);
|
||||
|
||||
$sheet->getStyle("A$rowNumber:$col$rowNumber")->applyFromArray($headerStyle);
|
||||
$sheet->setAutoFilter("A$rowNumber:$col$rowNumber");
|
||||
|
||||
$rowNumber++;
|
||||
foreach ($dataList as $row) {
|
||||
$i = 0;
|
||||
foreach ($fieldList as $i => $name) {
|
||||
$col = $azRange[$i];
|
||||
|
||||
$defs = $this->getInjection('metadata')->get(['entityDefs', $entityType, 'fields', $name]);
|
||||
if (!$defs) {
|
||||
$defs = array();
|
||||
$defs['type'] = 'base';
|
||||
}
|
||||
$link = null;
|
||||
if ($defs['type'] == 'link') {
|
||||
if (array_key_exists($name.'Name', $row)) {
|
||||
$sheet->setCellValue("$col$rowNumber", $row[$name.'Name']);
|
||||
}
|
||||
} else if ($defs['type'] == 'linkParent') {
|
||||
if (array_key_exists($name.'Name', $row)) {
|
||||
$sheet->setCellValue("$col$rowNumber", $row[$name.'Name']);
|
||||
}
|
||||
} else if ($defs['type'] == 'int') {
|
||||
$sheet->setCellValue("$col$rowNumber", $row[$name] ?: 0);
|
||||
} else if ($defs['type'] == 'currency') {
|
||||
if (array_key_exists($name.'Currency', $row) && array_key_exists($name, $row)) {
|
||||
$sheet->setCellValue("$col$rowNumber", $row[$name] ? $row[$name] : '');
|
||||
$currency = $row[$name . 'Currency'];
|
||||
$currencySymbol = $this->getMetadata()->get(['app', 'currency', 'symbolMap', $currency], '');
|
||||
|
||||
$sheet->getStyle("$col$rowNumber")
|
||||
->getNumberFormat()
|
||||
->setFormatCode('[$'.$currencySymbol.'-409]#,##0.00;-[$'.$currencySymbol.'-409]#,##0.00');
|
||||
}
|
||||
} else if ($defs['type'] == 'currencyConverted') {
|
||||
if (array_key_exists($name, $row)) {
|
||||
$currency = $this->getConfig()->get('baseCurrency');
|
||||
$currencySymbol = $this->getMetadata()->get(['app', 'currency', 'symbolMap', $currency], '');
|
||||
|
||||
$sheet->getStyle("$col$rowNumber")
|
||||
->getNumberFormat()
|
||||
->setFormatCode('[$'.$currencySymbol.'-409]#,##0.00;-[$'.$currencySymbol.'-409]#,##0.00');
|
||||
|
||||
$sheet->setCellValue("$col$rowNumber", $row[$name] ? $row[$name] : '');
|
||||
}
|
||||
} else if ($defs['type'] == 'personName') {
|
||||
if (!empty($row['name'])) {
|
||||
$sheet->setCellValue("$col$rowNumber", $row['name']);
|
||||
} else {
|
||||
$personName = '';
|
||||
if (!empty($row['firstName'])) {
|
||||
$personName .= $row['firstName'];
|
||||
}
|
||||
if (!empty($row['lastName'])) {
|
||||
if (!empty($row['firstName'])) {
|
||||
$personName .= ' ';
|
||||
}
|
||||
$personName .= $row['lastName'];
|
||||
}
|
||||
$sheet->setCellValue("$col$rowNumber", $personName);
|
||||
}
|
||||
} else if ($defs['type'] == 'date') {
|
||||
if (isset($row[$name])) {
|
||||
$sheet->setCellValue("$col$rowNumber", \PHPExcel_Shared_Date::PHPToExcel(strtotime($row[$name])));
|
||||
}
|
||||
} else if ($defs['type'] == 'datetime' || $defs['type'] == 'datetimeOptional') {
|
||||
if (isset($row[$name])) {
|
||||
$sheet->setCellValue("$col$rowNumber", \PHPExcel_Shared_Date::PHPToExcel(strtotime($row[$name])));
|
||||
}
|
||||
} else if ($defs['type'] == 'image') {
|
||||
if (isset($row[$name . 'Id']) && $row[$name . 'Id']) {
|
||||
$attachment = $this->getEntityManager()->getEntity('Attachment', $row[$name . 'Id']);
|
||||
|
||||
if ($attachment) {
|
||||
$objDrawing = new \PHPExcel_Worksheet_Drawing();
|
||||
$filePath = $this->getInjection('fileStorageManager')->getLocalFilePath($attachment);
|
||||
|
||||
if ($filePath && file_exists($filePath)) {
|
||||
$objDrawing->setPath($filePath);
|
||||
$objDrawing->setHeight(100);
|
||||
$objDrawing->setCoordinates("$col$rowNumber");
|
||||
$objDrawing->setWorksheet($sheet);
|
||||
$sheet->getRowDimension($rowNumber)->setRowHeight(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if ($defs['type'] == 'file') {
|
||||
if (array_key_exists($name.'Name', $row)) {
|
||||
$sheet->setCellValue("$col$rowNumber", $row[$name.'Name']);
|
||||
}
|
||||
} else if ($defs['type'] == 'enum') {
|
||||
if (array_key_exists($name, $row)) {
|
||||
$value = $this->getInjection('language')->translateOption($row[$name], $name, $entityType);
|
||||
$sheet->setCellValue("$col$rowNumber", $value);
|
||||
}
|
||||
} else {
|
||||
if (array_key_exists($name, $row)) {
|
||||
$sheet->setCellValue("$col$rowNumber", $row[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$link = false;
|
||||
|
||||
if ($name == 'name') {
|
||||
if (array_key_exists('id', $row)) {
|
||||
$link = $this->getConfig()->getSiteUrl() . "/#".$entityType . "/view/" . $row['id'];
|
||||
}
|
||||
} else if ($defs['type'] == 'url') {
|
||||
if (array_key_exists($name, $row) && filter_var($row[$name], FILTER_VALIDATE_URL)) {
|
||||
$link = $row[$name];
|
||||
}
|
||||
} else if ($defs['type'] == 'link') {
|
||||
if (array_key_exists($name.'Id', $row)) {
|
||||
$foreignEntity = $this->getMetadata()->get(['entityDefs', $entityType, 'links', $name, 'entity']);
|
||||
if ($foreignEntity) {
|
||||
$link = $this->getConfig()->getSiteUrl() . "/#" . $foreignEntity. "/view/". $row[$name.'Id'];
|
||||
}
|
||||
}
|
||||
} else if ($defs['type'] == 'file') {
|
||||
if (array_key_exists($name.'Id', $row)) {
|
||||
$link = $this->getConfig()->getSiteUrl() . "/?entryPoint=download&id=" . $row[$name.'Id'];
|
||||
}
|
||||
} else if ($defs['type'] == 'linkParent') {
|
||||
if (array_key_exists($name.'Id', $row) && array_key_exists($name.'Type', $row)) {
|
||||
$link = $this->getConfig()->getSiteUrl() . "/#".$row[$name.'Type']."/view/". $row[$name.'Id'];
|
||||
}
|
||||
} else if ($defs['type'] == 'phone') {
|
||||
if (array_key_exists($name, $row)) {
|
||||
$link = "tel:".$row[$name];
|
||||
}
|
||||
} else if ($defs['type'] == 'email' && array_key_exists($name, $row)) {
|
||||
if (array_key_exists($name, $row)) {
|
||||
$link = "mailto:".$row[$name];
|
||||
}
|
||||
}
|
||||
if ($link) {
|
||||
$sheet->getCell("$col$rowNumber")->getHyperlink()->setUrl($link);
|
||||
$sheet->getCell("$col$rowNumber")->getHyperlink()->setTooltip($link);
|
||||
}
|
||||
}
|
||||
$rowNumber++;
|
||||
}
|
||||
|
||||
$startingRowNumber = 4;
|
||||
|
||||
foreach ($fieldList as $i => $name) {
|
||||
$col = $azRange[$i];
|
||||
|
||||
$defs = $this->getInjection('metadata')->get(['entityDefs', $entityType, 'fields', $name]);
|
||||
if (!$defs) {
|
||||
$defs['type'] = 'base';
|
||||
}
|
||||
|
||||
if ($col == 'A') {
|
||||
$sheet->getStyle("A2:A$rowNumber")
|
||||
->getNumberFormat()
|
||||
->setFormatCode(\PHPExcel_Style_NumberFormat::FORMAT_TEXT);
|
||||
} else {
|
||||
switch($defs['type']) {
|
||||
case 'currency':
|
||||
case 'currencyConverted': {
|
||||
|
||||
} break;
|
||||
case 'int': {
|
||||
$sheet->getStyle($col.$startingRowNumber.':'.$col.$rowNumber)
|
||||
->getNumberFormat()
|
||||
->setFormatCode('0');
|
||||
} break;
|
||||
case 'date': {
|
||||
$sheet->getStyle($col.$startingRowNumber.':'.$col.$rowNumber)
|
||||
->getNumberFormat()
|
||||
->setFormatCode($this->getInjection('dateTime')->getDateFormat());
|
||||
} break;
|
||||
case 'datetime': {
|
||||
$sheet->getStyle($col.$startingRowNumber.':'.$col.$rowNumber)
|
||||
->getNumberFormat()
|
||||
->setFormatCode($this->getInjection('dateTime')->getDateTimeFormat());
|
||||
} break;
|
||||
case 'datetimeOptional': {
|
||||
$sheet->getStyle($col.$startingRowNumber.':'.$col.$rowNumber)
|
||||
->getNumberFormat()
|
||||
->setFormatCode($this->getInjection('dateTime')->getDateTimeFormat());
|
||||
} break;
|
||||
default: {
|
||||
$sheet->getStyle($col.$startingRowNumber.':'.$col.$rowNumber)
|
||||
->getNumberFormat()
|
||||
->setFormatCode('@');
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$linkStyle = [
|
||||
'font' => [
|
||||
'color' => ['rgb' => '345b7c'],
|
||||
'underline' => 'single'
|
||||
]
|
||||
];
|
||||
foreach ($linkColList as $linkColumn) {
|
||||
$sheet->getStyle($linkColumn.$startingRowNumber.':'.$linkColumn.$rowNumber)->applyFromArray($linkStyle);
|
||||
}
|
||||
|
||||
$objWriter = \PHPExcel_IOFactory::createWriter($phpExcel, 'Excel2007');
|
||||
|
||||
if (!$this->getInjection('fileManager')->isDir('data/cache/')) {
|
||||
$this->getInjection('fileManager')->mkdir('data/cache/');
|
||||
}
|
||||
$tempFileName = 'data/cache/' . 'export_' . substr(md5(rand()), 0, 7);
|
||||
|
||||
$objWriter->save($tempFileName);
|
||||
$fp = fopen($tempFileName, 'r');
|
||||
$xlsx = stream_get_contents($fp);
|
||||
$this->getInjection('fileManager')->unlink($tempFileName);
|
||||
|
||||
return $xlsx;
|
||||
}
|
||||
}
|
||||
115
application/Espo/Core/FileStorage/Manager.php
Normal file
115
application/Espo/Core/FileStorage/Manager.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\FileStorage;
|
||||
|
||||
use \Espo\Entities\Attachment;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class Manager
|
||||
{
|
||||
private $implementations = array();
|
||||
|
||||
private $implementationClassNameMap = array();
|
||||
|
||||
private $container;
|
||||
|
||||
public function __construct(array $implementationClassNameMap, $container)
|
||||
{
|
||||
$this->implementationClassNameMap = $implementationClassNameMap;
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
private function getImplementation($storage = null)
|
||||
{
|
||||
if (!$storage) {
|
||||
$storage = 'EspoUploadDir';
|
||||
}
|
||||
|
||||
if (array_key_exists($storage, $this->implementations)) {
|
||||
return $this->implementations[$storage];
|
||||
}
|
||||
|
||||
if (!array_key_exists($storage, $this->implementationClassNameMap)) {
|
||||
throw new Error("FileStorageManager: Unknown storage '{$storage}'");
|
||||
}
|
||||
$className = $this->implementationClassNameMap[$storage];
|
||||
|
||||
$implementation = new $className();
|
||||
foreach ($implementation->getDependencyList() as $dependencyName) {
|
||||
$implementation->inject($dependencyName, $this->container->get($dependencyName));
|
||||
}
|
||||
$this->implementations[$storage] = $implementation;
|
||||
|
||||
return $implementation;
|
||||
}
|
||||
|
||||
public function isFile(Attachment $attachment)
|
||||
{
|
||||
$implementation = $this->getImplementation($attachment->get('storage'));
|
||||
return $implementation->isFile($attachment);
|
||||
}
|
||||
|
||||
public function getContents(Attachment $attachment)
|
||||
{
|
||||
$implementation = $this->getImplementation($attachment->get('storage'));
|
||||
return $implementation->getContents($attachment);
|
||||
}
|
||||
|
||||
public function putContents(Attachment $attachment, $contents)
|
||||
{
|
||||
$implementation = $this->getImplementation($attachment->get('storage'));
|
||||
return $implementation->putContents($attachment, $contents);
|
||||
}
|
||||
|
||||
public function unlink(Attachment $attachment)
|
||||
{
|
||||
$implementation = $this->getImplementation($attachment->get('storage'));
|
||||
return $implementation->unlink($attachment);
|
||||
}
|
||||
|
||||
public function getLocalFilePath(Attachment $attachment)
|
||||
{
|
||||
$implementation = $this->getImplementation($attachment->get('storage'));
|
||||
return $implementation->getLocalFilePath($attachment);
|
||||
}
|
||||
|
||||
public function hasDownloadUrl(Attachment $attachment)
|
||||
{
|
||||
$implementation = $this->getImplementation($attachment->get('storage'));
|
||||
return $implementation->hasDownloadUrl($attachment);
|
||||
}
|
||||
|
||||
public function getDownloadUrl(Attachment $attachment)
|
||||
{
|
||||
$implementation = $this->getImplementation($attachment->get('storage'));
|
||||
return $implementation->getDownloadUrl($attachment);
|
||||
}
|
||||
}
|
||||
89
application/Espo/Core/FileStorage/Storages/Base.php
Normal file
89
application/Espo/Core/FileStorage/Storages/Base.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\FileStorage\Storages;
|
||||
|
||||
use \Espo\Core\Interfaces\Injectable;
|
||||
|
||||
abstract class Base implements Injectable
|
||||
{
|
||||
protected $dependencyList = [];
|
||||
|
||||
protected $injections = array();
|
||||
|
||||
public function inject($name, $object)
|
||||
{
|
||||
$this->injections[$name] = $object;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->init();
|
||||
}
|
||||
|
||||
protected function init()
|
||||
{
|
||||
}
|
||||
|
||||
protected function getInjection($name)
|
||||
{
|
||||
return $this->injections[$name];
|
||||
}
|
||||
|
||||
protected function addDependency($name)
|
||||
{
|
||||
$this->dependencyList[] = $name;
|
||||
}
|
||||
|
||||
protected function addDependencyList(array $list)
|
||||
{
|
||||
foreach ($list as $item) {
|
||||
$this->addDependency($item);
|
||||
}
|
||||
}
|
||||
|
||||
public function getDependencyList()
|
||||
{
|
||||
return $this->dependencyList;
|
||||
}
|
||||
|
||||
abstract public function hasDownloadUrl(\Espo\Entities\Attachment $attachment);
|
||||
|
||||
abstract public function getDownloadUrl(\Espo\Entities\Attachment $attachment);
|
||||
|
||||
abstract public function unlink(\Espo\Entities\Attachment $attachment);
|
||||
|
||||
abstract public function getContents(\Espo\Entities\Attachment $attachment);
|
||||
|
||||
abstract public function isFile(\Espo\Entities\Attachment $attachment);
|
||||
|
||||
abstract public function putContents(\Espo\Entities\Attachment $attachment, $contents);
|
||||
|
||||
abstract public function getLocalFilePath(\Espo\Entities\Attachment $attachment);
|
||||
}
|
||||
85
application/Espo/Core/FileStorage/Storages/EspoUploadDir.php
Normal file
85
application/Espo/Core/FileStorage/Storages/EspoUploadDir.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\FileStorage\Storages;
|
||||
|
||||
use \Espo\Entities\Attachment;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class EspoUploadDir extends Base
|
||||
{
|
||||
protected $dependencyList = ['fileManager'];
|
||||
|
||||
protected function getFileManager()
|
||||
{
|
||||
return $this->getInjection('fileManager');
|
||||
}
|
||||
|
||||
public function unlink(Attachment $attachment)
|
||||
{
|
||||
return $this->getFileManager()->unlink($this->getFilePath($attachment));
|
||||
}
|
||||
|
||||
public function isFile(Attachment $attachment)
|
||||
{
|
||||
return $this->getFileManager()->isFile($this->getFilePath($attachment));
|
||||
}
|
||||
|
||||
public function getContents(Attachment $attachment)
|
||||
{
|
||||
return $this->getFileManager()->getContents($this->getFilePath($attachment));
|
||||
}
|
||||
|
||||
public function putContents(Attachment $attachment, $contents)
|
||||
{
|
||||
return $this->getFileManager()->putContents($this->getFilePath($attachment), $contents);
|
||||
}
|
||||
|
||||
public function getLocalFilePath(Attachment $attachment)
|
||||
{
|
||||
return $this->getFilePath($attachment);
|
||||
}
|
||||
|
||||
protected function getFilePath(Attachment $attachment)
|
||||
{
|
||||
$sourceId = $attachment->getSourceId();
|
||||
return 'data/upload/' . $sourceId;
|
||||
}
|
||||
|
||||
public function getDownloadUrl(Attachment $attachment)
|
||||
{
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
public function hasDownloadUrl(Attachment $attachment)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
@@ -65,6 +65,13 @@ class AttributeFetcher
|
||||
$methodName = 'getFetched';
|
||||
}
|
||||
|
||||
if ($entity->getAttributeParam($attribute, 'isParentName') && $methodName == 'get') {
|
||||
$relationName = $entity->getAttributeParam($attribute, 'relation');
|
||||
if ($parent = $entity->get($relationName)) {
|
||||
return $parent->get('name');
|
||||
}
|
||||
}
|
||||
|
||||
return $entity->$methodName($attribute);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\ArrayGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class IncludesType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value') || !is_array($item->value)) {
|
||||
throw new Error('Value for \'Array\\Includses\' item is not array.');
|
||||
}
|
||||
if (count($item->value) < 2) {
|
||||
throw new Error('Bad arguments passed to \'Array\\Includses\'.');
|
||||
}
|
||||
$list = $this->evaluate($item->value[0]);
|
||||
$needle = $this->evaluate($item->value[1]);
|
||||
|
||||
if (!is_array($list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array($needle, $list);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\DateTimeGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class DateType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->addDependency('dateTime');
|
||||
}
|
||||
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 1) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
if (empty($value)) return 0;
|
||||
|
||||
if (strlen($value) > 11) {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDateTime($value, null, 'D');
|
||||
} else {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDate($value, 'D');
|
||||
}
|
||||
|
||||
return intval($resultString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\DateTimeGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class DayOfWeekType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->addDependency('dateTime');
|
||||
}
|
||||
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 1) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
if (empty($value)) return 0;
|
||||
|
||||
if (strlen($value) > 11) {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDateTime($value, null, 'D');
|
||||
} else {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDate($value, 'D');
|
||||
}
|
||||
|
||||
$result = intval($resultString) + 1;
|
||||
if ($result == 8) {
|
||||
$result = 1;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\DatetimeGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class DiffType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->addDependency('dateTime');
|
||||
}
|
||||
|
||||
protected $intevalTypePropertyMap = array(
|
||||
'years' => 'y', 'months' => 'm', 'days' => 'd', 'hours' => 'h', 'minutes' => 'i', 'seconds' => 's'
|
||||
);
|
||||
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 2) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$dateTime1String = $this->evaluate($item->value[0]);
|
||||
$dateTime2String = $this->evaluate($item->value[1]);
|
||||
|
||||
if (!$dateTime1String) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$dateTime2String) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!is_string($dateTime1String)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (!is_string($dateTime2String)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$intervalType = 'days';
|
||||
if (count($item->value) > 2) {
|
||||
$intervalType = $this->evaluate($item->value[2]);
|
||||
}
|
||||
|
||||
if (!is_string($intervalType)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (!array_key_exists($intervalType, $this->intevalTypePropertyMap)) {
|
||||
throw new Error('Not supported interval type' . $intervalType);
|
||||
}
|
||||
|
||||
|
||||
$isTime = false;
|
||||
if (strlen($dateTime1String) > 10) {
|
||||
$isTime = true;
|
||||
}
|
||||
|
||||
try {
|
||||
$dateTime1 = new \DateTime($dateTime1String);
|
||||
$dateTime2 = new \DateTime($dateTime2String);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$t1 = $dateTime1->getTimestamp();
|
||||
$t2 = $dateTime2->getTimestamp();
|
||||
|
||||
$secondsDiff = $t1 - $t2;
|
||||
|
||||
if ($intervalType === 'seconds') {
|
||||
$number = $secondsDiff;
|
||||
} else if ($intervalType === 'minutes') {
|
||||
$number = floor($secondsDiff / 60);
|
||||
} else if ($intervalType === 'hours') {
|
||||
$number = floor($secondsDiff / (60 * 60));
|
||||
} else if ($intervalType === 'days') {
|
||||
$number = floor($secondsDiff / (60 * 60 * 24));
|
||||
} else {
|
||||
$property = $this->intevalTypePropertyMap[$intervalType];
|
||||
$interval = $dateTime2->diff($dateTime1);
|
||||
$number = $interval->$property;
|
||||
if ($interval->invert) {
|
||||
$number *= -1;
|
||||
}
|
||||
|
||||
if ($intervalType === 'months') {
|
||||
$number += $interval->y * 12;
|
||||
}
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
@@ -58,10 +58,15 @@ class FormatType extends \Espo\Core\Formula\Functions\Base
|
||||
}
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
$format = null;
|
||||
if (count($item->value) > 2) {
|
||||
$format = $this->evaluate($item->value[2]);
|
||||
}
|
||||
|
||||
if (strlen($value) > 11) {
|
||||
return $this->getInjection('dateTime')->convertSystemDateTime($value, $timezone);
|
||||
return $this->getInjection('dateTime')->convertSystemDateTime($value, $timezone, $format);
|
||||
} else {
|
||||
return $this->getInjection('dateTime')->convertSystemDate($value);
|
||||
return $this->getInjection('dateTime')->convertSystemDate($value, $format);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\DateTimeGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class HourType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->addDependency('dateTime');
|
||||
}
|
||||
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 1) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
if (empty($value)) return -1;
|
||||
|
||||
if (strlen($value) > 11) {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDateTime($value, null, 'H');
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return intval($resultString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\DateTimeGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class MinuteType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->addDependency('dateTime');
|
||||
}
|
||||
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 1) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
if (empty($value)) return -1;
|
||||
|
||||
if (strlen($value) > 11) {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDateTime($value, null, 'm');
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return intval($resultString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\DateTimeGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class MonthType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->addDependency('dateTime');
|
||||
}
|
||||
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 1) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
if (empty($value)) return 0;
|
||||
|
||||
if (strlen($value) > 11) {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDateTime($value, null, 'M');
|
||||
} else {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDate($value, 'M');
|
||||
}
|
||||
|
||||
return intval($resultString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\DateTimeGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class YearType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->addDependency('dateTime');
|
||||
}
|
||||
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 1) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
if (empty($value)) return 0;
|
||||
|
||||
if (strlen($value) > 11) {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDateTime($value, null, 'YYYY');
|
||||
} else {
|
||||
$resultString = $this->getInjection('dateTime')->convertSystemDate($value, 'YYYY');
|
||||
}
|
||||
|
||||
return intval($resultString);
|
||||
}
|
||||
}
|
||||
54
application/Espo/Core/Formula/Functions/ListType.php
Normal file
54
application/Espo/Core/Formula/Functions/ListType.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions;
|
||||
|
||||
use \Espo\ORM\Entity;
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class ListType extends Base
|
||||
{
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($item->value as $item) {
|
||||
$result[] = $this->evaluate($item);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\NumberGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class AbsType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 1) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return abs($value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Formula\Functions\NumberGroup;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class RoundType extends \Espo\Core\Formula\Functions\Base
|
||||
{
|
||||
public function process(\StdClass $item)
|
||||
{
|
||||
if (!property_exists($item, 'value')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_array($item->value)) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if (count($item->value) < 1) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
$value = $this->evaluate($item->value[0]);
|
||||
|
||||
$precision = 0;
|
||||
if (count($item->value) > 1) {
|
||||
$precision = $this->evaluate($item->value[1]);
|
||||
}
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return round($value, $precision);
|
||||
}
|
||||
}
|
||||
@@ -219,6 +219,11 @@ class Parser
|
||||
$firstOperator = null;
|
||||
$minIndex = null;
|
||||
|
||||
if ($expression === '') return (object) [
|
||||
'type' => 'value',
|
||||
'value' => null
|
||||
];
|
||||
|
||||
foreach ($this->priorityList as $operationList) {
|
||||
foreach ($operationList as $operator) {
|
||||
$index = strpos($expression, $operator, 1);
|
||||
@@ -229,7 +234,23 @@ class Parser
|
||||
$possibleRightOperator = trim($operator . $expression[$index + 1]);
|
||||
}
|
||||
}
|
||||
if ($possibleRightOperator && $possibleRightOperator != $operator && $this->operatorMap[$possibleRightOperator]) continue;
|
||||
if (
|
||||
$possibleRightOperator &&
|
||||
$possibleRightOperator != $operator &&
|
||||
!empty($this->operatorMap[$possibleRightOperator])
|
||||
) continue;
|
||||
|
||||
$possibleLeftOperator = null;
|
||||
if (strlen($operator) === 1) {
|
||||
if ($index > 0) {
|
||||
$possibleLeftOperator = trim($expression[$index - 1] . $operator);
|
||||
}
|
||||
}
|
||||
if (
|
||||
$possibleLeftOperator &&
|
||||
$possibleLeftOperator != $operator &&
|
||||
!empty($this->operatorMap[$possibleLeftOperator])
|
||||
) continue;
|
||||
|
||||
$firstPart = substr($expression, 0, $index);
|
||||
$secondPart = substr($expression, $index + strlen($operator));
|
||||
|
||||
@@ -42,17 +42,14 @@ class HookManager
|
||||
protected $cacheFile = 'data/cache/application/hooks.php';
|
||||
|
||||
/**
|
||||
* List of defined hooks
|
||||
* List of ignored hook methods
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hookList = array(
|
||||
'beforeSave',
|
||||
'afterSave',
|
||||
'beforeRemove',
|
||||
'afterRemove',
|
||||
'afterRelate',
|
||||
'afterUnrelate'
|
||||
protected $ignoredMethodList = array(
|
||||
'__construct',
|
||||
'getDependencyList',
|
||||
'inject'
|
||||
);
|
||||
|
||||
protected $paths = array(
|
||||
@@ -170,9 +167,12 @@ class HookManager
|
||||
$hookFilePath = Util::concatPath($hookScopeDirPath, $hookFile);
|
||||
$className = Util::getClassName($hookFilePath);
|
||||
|
||||
foreach($this->hookList as $hookName) {
|
||||
$classMethods = get_class_methods($className);
|
||||
$hookMethods = array_diff($classMethods, $this->ignoredMethodList);
|
||||
|
||||
foreach($hookMethods as $hookName) {
|
||||
$entityHookData = isset($hookData[$scopeName][$hookName]) ? $hookData[$scopeName][$hookName] : array();
|
||||
if (method_exists($className, $hookName) && !$this->isHookExists($className, $entityHookData)) {
|
||||
if (!$this->isHookExists($className, $entityHookData)) {
|
||||
$hookData[$normalizedScopeName][$hookName][$className::$order][] = $className;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,12 +48,15 @@ class Htmlizer
|
||||
|
||||
protected $acl;
|
||||
|
||||
public function __construct(FileManager $fileManager, DateTime $dateTime, NumberUtil $number, $acl = null)
|
||||
protected $entityManager;
|
||||
|
||||
public function __construct(FileManager $fileManager, DateTime $dateTime, NumberUtil $number, $acl = null, $entityManager = null)
|
||||
{
|
||||
$this->fileManager = $fileManager;
|
||||
$this->dateTime = $dateTime;
|
||||
$this->number = $number;
|
||||
$this->acl = $acl;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
protected function getAcl()
|
||||
@@ -61,6 +64,11 @@ class Htmlizer
|
||||
return $this->acl;
|
||||
}
|
||||
|
||||
protected function getEntityManager()
|
||||
{
|
||||
return $this->entityManager;
|
||||
}
|
||||
|
||||
protected function format($value)
|
||||
{
|
||||
if (is_float($value)) {
|
||||
@@ -109,6 +117,9 @@ class Htmlizer
|
||||
if ($item instanceof \StdClass) {
|
||||
$v = get_object_vars($v);
|
||||
}
|
||||
if (!is_array($v)) {
|
||||
$v = [];
|
||||
}
|
||||
foreach ($v as $k => $w) {
|
||||
$v[$k] = $this->format($v[$k]);
|
||||
}
|
||||
@@ -163,7 +174,8 @@ class Htmlizer
|
||||
'helpers' => [
|
||||
'file' => function ($context, $options) {
|
||||
if (count($context) && $context[0]) {
|
||||
return 'data/upload/'.$context[0];
|
||||
$id = $context[0];
|
||||
return "?entryPoint=attachment&id=" . $id;
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -192,8 +204,20 @@ class Htmlizer
|
||||
|
||||
$html = $renderer($data);
|
||||
|
||||
|
||||
$html = str_replace('?entryPoint=attachment&', '?entryPoint=attachment&', $html);
|
||||
$html = preg_replace('/\?entryPoint=attachment\&id=(.*)/', 'data/upload/$1', $html);
|
||||
|
||||
if ($this->getEntityManager()) {
|
||||
$html = preg_replace_callback('/\?entryPoint=attachment\&id=([A-Za-z0-9]*)/', function ($matches) {
|
||||
$id = $matches[1];
|
||||
$attachment = $this->getEntityManager()->getEntity('Attachment', $id);
|
||||
|
||||
if ($attachment) {
|
||||
$filePath = $this->getEntityManager()->getRepository('Attachment')->getFilePath($attachment);
|
||||
return $filePath;
|
||||
}
|
||||
}, $html);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
74
application/Espo/Core/Injectable.php
Normal file
74
application/Espo/Core/Injectable.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core;
|
||||
|
||||
abstract class Injectable implements \Espo\Core\Interfaces\Injectable
|
||||
{
|
||||
protected $dependencyList = array();
|
||||
|
||||
protected $injections = array();
|
||||
|
||||
public function inject($name, $object)
|
||||
{
|
||||
$this->injections[$name] = $object;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->init();
|
||||
}
|
||||
|
||||
protected function init()
|
||||
{
|
||||
}
|
||||
|
||||
protected function getInjection($name)
|
||||
{
|
||||
return $this->injections[$name];
|
||||
}
|
||||
|
||||
protected function addDependency($name)
|
||||
{
|
||||
if (in_array($name, $this->dependencyList)) return;
|
||||
$this->dependencyList[] = $name;
|
||||
}
|
||||
|
||||
protected function addDependencyList(array $list)
|
||||
{
|
||||
foreach ($list as $item) {
|
||||
$this->addDependency($item);
|
||||
}
|
||||
}
|
||||
|
||||
public function getDependencyList()
|
||||
{
|
||||
return $this->dependencyList;
|
||||
}
|
||||
}
|
||||
58
application/Espo/Core/InjectableFactory.php
Normal file
58
application/Espo/Core/InjectableFactory.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core;
|
||||
|
||||
use \Espo\Core\Exceptions\Error;
|
||||
|
||||
class InjectableFactory
|
||||
{
|
||||
private $container;
|
||||
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function createByClassName($className)
|
||||
{
|
||||
if (class_exists($className)) {
|
||||
$service = new $className();
|
||||
if (!($service instanceof \Espo\Core\Interfaces\Injectable)) {
|
||||
throw new Error("Class '$className' is not instance of Injectable interface");
|
||||
}
|
||||
$dependencyList = $service->getDependencyList();
|
||||
foreach ($dependencyList as $name) {
|
||||
$service->inject($name, $this->container->get($name));
|
||||
}
|
||||
return $service;
|
||||
}
|
||||
throw new Error("Class '$className' does not exist");
|
||||
}
|
||||
}
|
||||
@@ -104,12 +104,16 @@ class Importer
|
||||
}
|
||||
}
|
||||
|
||||
if ($parser->checkMessageAttribute($message, 'from')) {
|
||||
$email->set('fromString', $parser->getMessageAttribute($message, 'from'));
|
||||
$fromAddressData = $parser->getAddressDataFromMessage($message, 'from');
|
||||
if ($fromAddressData) {
|
||||
$fromString = ($fromAddressData['name'] ? ($fromAddressData['name'] . ' ') : '') . '<' . $fromAddressData['address'] .'>';
|
||||
$email->set('fromString', $fromString);
|
||||
}
|
||||
|
||||
if ($parser->checkMessageAttribute($message, 'reply-To')) {
|
||||
$email->set('replyToString', $parser->getMessageAttribute($message, 'reply-To'));
|
||||
$replyToData = $parser->getAddressDataFromMessage($message, 'reply-To');
|
||||
if ($replyToData) {
|
||||
$replyToString = ($replyToData['name'] ? ($replyToData['name'] . ' ') : '') . '<' . $replyToData['address'] .'>';
|
||||
$email->set('replyToString', $replyToString);
|
||||
}
|
||||
|
||||
$fromArr = $parser->getAddressListFromMessage($message, 'from');
|
||||
@@ -124,6 +128,9 @@ class Importer
|
||||
$email->set('cc', implode(';', $ccArr));
|
||||
$email->set('replyTo', implode(';', $replyToArr));
|
||||
|
||||
$addressNameMap = $parser->getAddressNameMap($message);
|
||||
$email->set('addressNameMap', $addressNameMap);
|
||||
|
||||
if ($folderData) {
|
||||
foreach ($folderData as $uId => $folderId) {
|
||||
$email->setLinkMultipleColumn('users', 'folderId', $uId, $folderId);
|
||||
|
||||
222
application/Espo/Core/Mail/Parsers/MailMimeParser.php
Normal file
222
application/Espo/Core/Mail/Parsers/MailMimeParser.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Mail\Parsers;
|
||||
|
||||
class MailMimeParser
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $parser = array();
|
||||
|
||||
protected $messageHash = array();
|
||||
|
||||
public function __construct($entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
protected function getEntityManager()
|
||||
{
|
||||
return $this->entityManager;
|
||||
}
|
||||
|
||||
protected function getParser()
|
||||
{
|
||||
if (!$this->parser) {
|
||||
$this->parser = new \ZBateson\MailMimeParser\MailMimeParser();
|
||||
}
|
||||
|
||||
return $this->parser;
|
||||
}
|
||||
|
||||
protected function loadContent($message)
|
||||
{
|
||||
$raw = $message->getFullRawContent();
|
||||
$key = spl_object_hash($message);
|
||||
$this->messageHash[$key] = $this->getParser()->parse($raw);
|
||||
}
|
||||
|
||||
protected function getMessage($message)
|
||||
{
|
||||
$key = spl_object_hash($message);
|
||||
if (!array_key_exists($key, $this->messageHash)) {
|
||||
$raw = $message->getRawHeader();
|
||||
if (!$raw) {
|
||||
$raw = $message->getFullRawContent();
|
||||
}
|
||||
$this->messageHash[$key] = $this->getParser()->parse($raw);
|
||||
}
|
||||
|
||||
return $this->messageHash[$key];
|
||||
}
|
||||
|
||||
public function checkMessageAttribute($message, $attribute)
|
||||
{
|
||||
return $this->getMessage($message)->getHeaderValue($attribute) !== null;
|
||||
}
|
||||
|
||||
public function getMessageAttribute($message, $attribute)
|
||||
{
|
||||
if (!$this->checkMessageAttribute($message, $attribute)) return null;
|
||||
|
||||
return $this->getMessage($message)->getHeaderValue($attribute);
|
||||
}
|
||||
|
||||
public function getMessageMessageId($message)
|
||||
{
|
||||
return $this->getMessageAttribute($message, 'Message-ID');
|
||||
}
|
||||
|
||||
public function getAddressNameMap($message)
|
||||
{
|
||||
$map = (object) [];
|
||||
|
||||
foreach (['from', 'to', 'cc', 'reply-To'] as $type) {
|
||||
$header = $this->getMessage($message)->getHeader($type);
|
||||
if ($header) {
|
||||
$list = $header->getAddresses();
|
||||
foreach ($list as $item) {
|
||||
$address = $item->getEmail();
|
||||
$name = $item->getName();
|
||||
if ($name && $address) {
|
||||
$map->$address = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
public function getAddressDataFromMessage($message, $type)
|
||||
{
|
||||
$addressList = [];
|
||||
$header = $this->getMessage($message)->getHeader($type);
|
||||
if ($header) {
|
||||
foreach ($header->getAddresses() as $item) {
|
||||
return [
|
||||
'address' => $item->getEmail(),
|
||||
'name' => $item->getName()
|
||||
];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAddressListFromMessage($message, $type)
|
||||
{
|
||||
$addressList = [];
|
||||
$header = $this->getMessage($message)->getHeader($type);
|
||||
if ($header) {
|
||||
$list = $header->getAddresses();
|
||||
foreach ($list as $address) {
|
||||
$addressList[] = $address->getEmail();
|
||||
}
|
||||
}
|
||||
return $addressList;
|
||||
}
|
||||
|
||||
public function fetchContentParts(\Espo\Entities\Email $email, $message)
|
||||
{
|
||||
$this->loadContent($message);
|
||||
|
||||
$bodyPlain = $this->getMessage($message)->getTextContent();
|
||||
$bodyHtml = $this->getMessage($message)->getHtmlContent();
|
||||
|
||||
if ($bodyHtml) {
|
||||
$email->set('isHtml', true);
|
||||
$email->set('body', $bodyHtml);
|
||||
$email->set('bodyPlain', $bodyPlain);
|
||||
} else {
|
||||
$email->set('isHtml', false);
|
||||
$email->set('body', $bodyPlain);
|
||||
}
|
||||
|
||||
if (!$email->get('body') && $email->get('bodyPlain')) {
|
||||
$email->set('body', $email->get('bodyPlain'));
|
||||
}
|
||||
|
||||
$attachmentObjList = $this->getMessage($message)->getAllAttachmentParts();
|
||||
$inlineIds = array();
|
||||
|
||||
foreach ($attachmentObjList as $attachmentObj) {
|
||||
$attachment = $this->getEntityManager()->getEntity('Attachment');
|
||||
|
||||
$content = $attachmentObj->getContent();
|
||||
|
||||
$disposition = $attachmentObj->getHeaderValue('Content-Disposition');
|
||||
|
||||
$attachment = $this->getEntityManager()->getEntity('Attachment');
|
||||
$attachment->set('name', $attachmentObj->getHeaderParameter('Content-Disposition', 'filename', 'unnamed'));
|
||||
$attachment->set('type', $attachmentObj->getHeaderValue('Content-Type'));
|
||||
|
||||
$contentId = $attachmentObj->getHeaderValue('Content-ID');
|
||||
|
||||
if ($contentId) {
|
||||
$contentId = trim($contentId, '<>');
|
||||
}
|
||||
|
||||
if ($disposition == 'inline') {
|
||||
$attachment->set('role', 'Inline Attachment');
|
||||
} else {
|
||||
$attachment->set('role', 'Attachment');
|
||||
}
|
||||
|
||||
$attachment->set('contents', $content);
|
||||
|
||||
$this->getEntityManager()->saveEntity($attachment);
|
||||
|
||||
if ($disposition == 'attachment') {
|
||||
$email->addLinkMultipleId('attachments', $attachment->id);
|
||||
if ($contentId) {
|
||||
$inlineIds[$contentId] = $attachment->id;
|
||||
}
|
||||
} else if ($disposition == 'inline') {
|
||||
if ($contentId) {
|
||||
$inlineIds[$contentId] = $attachment->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$body = $email->get('body');
|
||||
|
||||
if (!empty($body)) {
|
||||
foreach ($inlineIds as $cid => $attachmentId) {
|
||||
if (strpos($body, 'cid:' . $cid) !== false) {
|
||||
$body = str_replace('cid:' . $cid, '?entryPoint=attachment&id=' . $attachmentId, $body);
|
||||
} else {
|
||||
$email->addLinkMultipleId('attachments', $attachmentId);
|
||||
}
|
||||
}
|
||||
$email->set('body', $body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,42 @@ class PhpMimeMailParser
|
||||
return $this->getMessageAttribute($message, 'Message-ID');
|
||||
}
|
||||
|
||||
public function getAddressNameMap($message)
|
||||
{
|
||||
$map = (object) [];
|
||||
|
||||
foreach (['from', 'to', 'cc', 'reply-To'] as $type) {
|
||||
if ($this->checkMessageAttribute($message, $type)) {
|
||||
$list = $this->getParser($message)->getAddresses($type);
|
||||
foreach ($list as $item) {
|
||||
$name = $list[0]['display'];
|
||||
$address = $list[0]['address'];
|
||||
if ($name && $address && $name !== $address) {
|
||||
$map->$address = $name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
public function getAddressDataFromMessage($message, $type)
|
||||
{
|
||||
$addressList = [];
|
||||
if ($this->checkMessageAttribute($message, $type)) {
|
||||
$list = $this->getParser($message)->getAddresses($type);
|
||||
if (count($list)) {
|
||||
return [
|
||||
'address' => $list[0]['address'],
|
||||
'name' => $list[0]['display'],
|
||||
];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAddressListFromMessage($message, $type)
|
||||
{
|
||||
$addressList = [];
|
||||
@@ -130,9 +166,10 @@ class PhpMimeMailParser
|
||||
$attachment->set('name', $attachmentObj->getFileName());
|
||||
$attachment->set('type', $attachmentObj->getContentType());
|
||||
|
||||
$contentId = $attachmentObj->getContentID();
|
||||
|
||||
if ($disposition == 'inline') {
|
||||
$attachment->set('role', 'Inline Attachment');
|
||||
$contentId = $attachmentObj->getContentID();
|
||||
} else {
|
||||
$attachment->set('role', 'Attachment');
|
||||
}
|
||||
@@ -142,11 +179,14 @@ class PhpMimeMailParser
|
||||
$this->getEntityManager()->saveEntity($attachment);
|
||||
|
||||
if ($disposition == 'attachment') {
|
||||
$attachmentsIds = $email->get('attachmentsIds');
|
||||
$attachmentsIds[] = $attachment->id;
|
||||
$email->set('attachmentsIds', $attachmentsIds);
|
||||
$email->addLinkMultipleId('attachments', $attachment->id);
|
||||
if ($contentId) {
|
||||
$inlineIds[$contentId] = $attachment->id;
|
||||
}
|
||||
} else if ($disposition == 'inline') {
|
||||
$inlineIds[$contentId] = $attachment->id;
|
||||
if ($contentId) {
|
||||
$inlineIds[$contentId] = $attachment->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,9 @@ class Parser extends \PhpMimeMailParser\Parser
|
||||
&& substr($part['content-type'], 0, 10) !== 'multipart/'
|
||||
) {
|
||||
// if we cannot get it by getMessageBody(), we assume it is an attachment
|
||||
$disposition = 'attachment';
|
||||
if ($disposition !== 'inline') {
|
||||
$disposition = 'attachment';
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array($disposition, $dispositions) === true && isset($filename) === true) {
|
||||
|
||||
@@ -72,6 +72,45 @@ class ZendMail
|
||||
return $messageId;
|
||||
}
|
||||
|
||||
public function getAddressNameMap($message)
|
||||
{
|
||||
$map = (object) [];
|
||||
|
||||
$zendMessage = $message->getZendMessage();
|
||||
|
||||
foreach (['from', 'to', 'cc', 'reply-To'] as $type) {
|
||||
if (isset($zendMessage->$type)) {
|
||||
$list = $this->normilizeHeader($zendMessage->getHeader($type))->getAddressList();
|
||||
foreach ($list as $item) {
|
||||
$name = $item->getName();
|
||||
$address = $item->getEmail();
|
||||
if ($name && $address && $name !== $address) {
|
||||
$map->$address = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
public function getAddressDataFromMessage($message, $type)
|
||||
{
|
||||
$zendMessage = $message->getZendMessage();
|
||||
|
||||
$addressList = array();
|
||||
if (isset($zendMessage->$type)) {
|
||||
$list = $this->normilizeHeader($zendMessage->getHeader($type))->getAddressList();
|
||||
foreach ($list as $address) {
|
||||
return [
|
||||
'address' => $address->getEmail(),
|
||||
'name' => $address->getName()
|
||||
];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAddressListFromMessage($message, $type)
|
||||
{
|
||||
$zendMessage = $message->getZendMessage();
|
||||
@@ -227,6 +266,13 @@ class ZendMail
|
||||
$attachmentsIds = $email->get('attachmentsIds');
|
||||
$attachmentsIds[] = $attachment->id;
|
||||
$email->set('attachmentsIds', $attachmentsIds);
|
||||
|
||||
if (isset($part->contentID)) {
|
||||
$contentId = trim($part->contentID, '<>');
|
||||
if ($contentId) {
|
||||
$inlineIds[$contentId] = $attachment->id;
|
||||
}
|
||||
}
|
||||
} else if ($disposition == 'inline') {
|
||||
$inlineIds[$contentId] = $attachment->id;
|
||||
}
|
||||
|
||||
@@ -189,6 +189,16 @@ class RDB extends \Espo\ORM\Repositories\RDB implements Injectable
|
||||
$this->getEntityManager()->getHookManager()->process($this->entityType, 'afterRemove', $entity, $options);
|
||||
}
|
||||
|
||||
protected function afterMassRelate(Entity $entity, $relationName, array $params = array(), array $options = array())
|
||||
{
|
||||
$hookData = array(
|
||||
'relationName' => $relationName,
|
||||
'relationParams' => $params
|
||||
);
|
||||
|
||||
$this->getEntityManager()->getHookManager()->process($this->entityType, 'afterMassRelate', $entity, $options, $hookData);
|
||||
}
|
||||
|
||||
public function remove(Entity $entity, array $options = array())
|
||||
{
|
||||
$result = parent::remove($entity, $options);
|
||||
@@ -269,18 +279,22 @@ class RDB extends \Espo\ORM\Repositories\RDB implements Injectable
|
||||
$entity->set('modifiedAt', $nowString);
|
||||
}
|
||||
if ($entity->hasAttribute('createdById')) {
|
||||
if (empty($options['import']) || !$entity->has('createdById')) {
|
||||
$entity->set('createdById', $this->getEntityManager()->getUser()->id);
|
||||
if (empty($options['skipCreatedBy']) && (empty($options['import']) || !$entity->has('createdById'))) {
|
||||
if ($this->getEntityManager()->getUser()) {
|
||||
$entity->set('createdById', $this->getEntityManager()->getUser()->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (empty($options['silent'])) {
|
||||
if (empty($options['silent']) && empty($options['skipModifiedBy'])) {
|
||||
if ($entity->hasAttribute('modifiedAt')) {
|
||||
$entity->set('modifiedAt', $nowString);
|
||||
}
|
||||
if ($entity->hasAttribute('modifiedById')) {
|
||||
$entity->set('modifiedById', $this->getEntityManager()->getUser()->id);
|
||||
$entity->set('modifiedByName', $this->getEntityManager()->getUser()->get('name'));
|
||||
if ($this->getEntityManager()->getUser()) {
|
||||
$entity->set('modifiedById', $this->getEntityManager()->getUser()->id);
|
||||
$entity->set('modifiedByName', $this->getEntityManager()->getUser()->get('name'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ class AclManager extends \Espo\Core\AclManager
|
||||
$config = $this->getContainer()->get('config');
|
||||
$fileManager = $this->getContainer()->get('fileManager');
|
||||
$metadata = $this->getContainer()->get('metadata');
|
||||
$fieldManager = $this->getContainer()->get('fieldManager');
|
||||
$fieldManager = $this->getContainer()->get('fieldManagerUtil');
|
||||
$portal = $this->getPortal();
|
||||
|
||||
$this->tableHashMap[$key] = new $this->tableClassName($user, $portal, $config, $fileManager, $metadata, $fieldManager);
|
||||
@@ -178,6 +178,15 @@ class AclManager extends \Espo\Core\AclManager
|
||||
return parent::checkReadOnlyTeam($user, $scope);
|
||||
}
|
||||
|
||||
public function checkReadNo(User $user, $scope)
|
||||
{
|
||||
if ($this->checkUserIsNotPortal($user)) {
|
||||
$data = $this->getTable($user)->getScopeData($scope);
|
||||
return $this->getMainManager()->checkReadNo($user, $data);
|
||||
}
|
||||
return parent::checkReadNo($user, $scope);
|
||||
}
|
||||
|
||||
public function checkReadOnlyOwn(User $user, $scope)
|
||||
{
|
||||
if ($this->checkUserIsNotPortal($user)) {
|
||||
|
||||
@@ -35,11 +35,6 @@ class Language extends \Espo\Core\Utils\Language
|
||||
{
|
||||
public function setPortal($portal)
|
||||
{
|
||||
if ($portal->get('language') !== '' && $portal->get('language')) {
|
||||
if (!$this->getPreferences()->get('language')) {
|
||||
$this->setLanguage($portal->get('language'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class ThemeManager extends \Espo\Core\Utils\ThemeManager
|
||||
{
|
||||
$theme = $this->portal->get('theme');
|
||||
if (!$theme) {
|
||||
$theme = $this->defaultName;
|
||||
$theme = $this->config->get('theme', $this->defaultName);
|
||||
}
|
||||
return $theme;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,9 @@ class Base
|
||||
|
||||
private $userTimeZone = null;
|
||||
|
||||
protected $additionalFilterTypeList = ['linkedWith', 'inCategory', 'isUserFromTeams'];
|
||||
protected $additionalFilterTypeList = ['inCategory', 'isUserFromTeams'];
|
||||
|
||||
protected $textFilterUseContainsAttributeList = [];
|
||||
|
||||
const MIN_LENGTH_FOR_CONTENT_SEARCH = 4;
|
||||
|
||||
@@ -128,7 +130,7 @@ class Base
|
||||
|
||||
$result['orderBy'] = $sortBy;
|
||||
$type = $this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'fields', $sortBy, 'type']);
|
||||
if ($type === 'link') {
|
||||
if (in_array($type, ['link', 'file', 'image'])) {
|
||||
$result['orderBy'] .= 'Name';
|
||||
} else if ($type === 'linkParent') {
|
||||
$result['orderBy'] .= 'Type';
|
||||
@@ -144,7 +146,7 @@ class Base
|
||||
$list = $this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'fields', $sortBy, 'options']);
|
||||
if ($list && is_array($list) && count($list)) {
|
||||
if ($this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'fields', $sortBy, 'isSorted'])) {
|
||||
$list = asort($list);
|
||||
asort($list);
|
||||
}
|
||||
if ($desc) {
|
||||
$list = array_reverse($list);
|
||||
@@ -210,7 +212,7 @@ class Base
|
||||
foreach ($where as $item) {
|
||||
$type = $item['type'];
|
||||
if (!in_array($type, $ignoreTypeList)) {
|
||||
$part = $this->getWherePart($item);
|
||||
$part = $this->getWherePart($item, $result);
|
||||
if (!empty($part)) {
|
||||
$whereClause[] = $part;
|
||||
}
|
||||
@@ -257,13 +259,18 @@ class Base
|
||||
|
||||
$defs = $relDefs[$link];
|
||||
if ($relationType == 'manyMany') {
|
||||
$this->addJoin([$link, $link . 'Filter'], $result);
|
||||
$this->addLeftJoin([$link, $link . 'Filter'], $result);
|
||||
$midKeys = $seed->getRelationParam($link, 'midKeys');
|
||||
|
||||
if (!empty($midKeys)) {
|
||||
$key = $midKeys[1];
|
||||
$part[$link . 'Filter' . 'Middle.' . $key] = $idsValue;
|
||||
}
|
||||
} else if ($relationType == 'hasMany') {
|
||||
$alias = $link . 'Filter';
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
|
||||
$part[$alias . '.id'] = $idsValue;
|
||||
} else if ($relationType == 'belongsTo') {
|
||||
$key = $seed->getRelationParam($link, 'key');
|
||||
if (!empty($key)) {
|
||||
@@ -428,6 +435,8 @@ class Base
|
||||
if (!$this->getUser()->isAdmin()) {
|
||||
if ($this->getAcl()->checkReadOnlyTeam($this->getEntityType())) {
|
||||
$this->accessOnlyTeam($result);
|
||||
} else if ($this->getAcl()->checkReadNo($this->getEntityType())) {
|
||||
$this->accessNo($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,12 +449,21 @@ class Base
|
||||
} else {
|
||||
if ($this->getAcl()->checkReadOnlyContact($this->getEntityType())) {
|
||||
$this->accessPortalOnlyContact($result);
|
||||
} else if ($this->getAcl()->checkReadNo($this->getEntityType())) {
|
||||
$this->accessNo($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function accessNo(&$result)
|
||||
{
|
||||
$result['whereClause'][] = array(
|
||||
'id' => null
|
||||
);
|
||||
}
|
||||
|
||||
protected function accessOnlyOwn(&$result)
|
||||
{
|
||||
if ($this->hasAssignedUsersField()) {
|
||||
@@ -724,7 +742,7 @@ class Base
|
||||
$attribute = $w['attribute'];
|
||||
}
|
||||
if ($attribute) {
|
||||
if (isset($w['type']) && $w['type'] === 'linkedWith') {
|
||||
if (isset($w['type']) && in_array($w['type'], ['isLinked', 'isNotLinked', 'linkedWith', 'notLinkedWith', 'isUserFromTeams'])) {
|
||||
if (in_array($attribute, $this->getAcl()->getScopeForbiddenFieldList($this->getEntityType()))) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
@@ -928,7 +946,7 @@ class Base
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getWherePart($item)
|
||||
protected function getWherePart($item, &$result = null)
|
||||
{
|
||||
$part = array();
|
||||
|
||||
@@ -940,30 +958,38 @@ class Base
|
||||
$attribute = $item['attribute'];
|
||||
}
|
||||
|
||||
if (!is_null($attribute) && !is_string($attribute)) {
|
||||
throw new Error('Bad attribute in where statement');
|
||||
}
|
||||
|
||||
if (!empty($attribute) && !empty($item['type'])) {
|
||||
$methodName = 'getWherePart' . ucfirst($attribute) . ucfirst($item['type']);
|
||||
if (method_exists($this, $methodName)) {
|
||||
$value = null;
|
||||
if (!empty($item['value'])) {
|
||||
if (array_key_exists('value', $item)) {
|
||||
$value = $item['value'];
|
||||
}
|
||||
return $this->$methodName($value);
|
||||
return $this->$methodName($value, $result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!empty($item['dateTime'])) {
|
||||
return $this->convertDateTimeWhere($item);
|
||||
}
|
||||
|
||||
if (!array_key_exists('value', $item)) {
|
||||
$item['value'] = null;
|
||||
}
|
||||
|
||||
if (!empty($item['type'])) {
|
||||
switch ($item['type']) {
|
||||
case 'or':
|
||||
case 'and':
|
||||
case 'not':
|
||||
if (is_array($item['value'])) {
|
||||
$arr = array();
|
||||
foreach ($item['value'] as $i) {
|
||||
$a = $this->getWherePart($i);
|
||||
$a = $this->getWherePart($i, $result);
|
||||
foreach ($a as $left => $right) {
|
||||
if (!empty($right) || is_null($right) || $right === '') {
|
||||
$arr[] = array($left => $right);
|
||||
@@ -1107,7 +1133,7 @@ class Base
|
||||
$quarter--;
|
||||
if ($quarter == 0) {
|
||||
$quarter = 4;
|
||||
$dt->sub('P1Y');
|
||||
$dt->modify('-1 year');
|
||||
}
|
||||
$part['AND'] = array(
|
||||
$attribute . '>=' => $dt->add(new \DateInterval('P'.(($quarter - 1) * 3).'M'))->format('Y-m-d'),
|
||||
@@ -1136,6 +1162,96 @@ class Base
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'isNotLinked':
|
||||
if (!$result) break;
|
||||
$alias = $attribute . 'IsNotLinkedFilter' . strval(rand(10000, 99999));;
|
||||
$part[$alias . '.id'] = null;
|
||||
$this->setDistinct(true, $result);
|
||||
$this->addLeftJoin([$attribute, $alias], $result);
|
||||
break;
|
||||
case 'isLinked':
|
||||
if (!$result) break;
|
||||
$alias = $attribute . 'IsLinkedFilter' . strval(rand(10000, 99999));;
|
||||
$part[$alias . '.id!='] = null;
|
||||
$this->setDistinct(true, $result);
|
||||
$this->addLeftJoin([$attribute, $alias], $result);
|
||||
break;
|
||||
case 'linkedWith':
|
||||
$seed = $this->getSeed();
|
||||
$link = $attribute;
|
||||
if (!$seed->hasRelation($link)) break;
|
||||
|
||||
$alias = $link . 'Filter' . strval(rand(10000, 99999));
|
||||
|
||||
$value = $item['value'];
|
||||
|
||||
if (is_null($value)) break;
|
||||
|
||||
$relationType = $seed->getRelationType($link);
|
||||
|
||||
if ($relationType == 'manyMany') {
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
$midKeys = $seed->getRelationParam($link, 'midKeys');
|
||||
|
||||
if (!empty($midKeys)) {
|
||||
$key = $midKeys[1];
|
||||
$part[$alias . 'Middle.' . $key] = $value;
|
||||
}
|
||||
} else if ($relationType == 'hasMany') {
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
|
||||
$part[$alias . '.id'] = $value;
|
||||
} else if ($relationType == 'belongsTo') {
|
||||
$key = $seed->getRelationParam($link, 'key');
|
||||
if (!empty($key)) {
|
||||
$part[$key] = $value;
|
||||
}
|
||||
} else if ($relationType == 'hasOne') {
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
$part[$alias . '.id'] = $value;
|
||||
} else {
|
||||
break;;
|
||||
}
|
||||
$this->setDistinct(true, $result);
|
||||
break;
|
||||
case 'notLinkedWith':
|
||||
$seed = $this->getSeed();
|
||||
$link = $attribute;
|
||||
if (!$seed->hasRelation($link)) break;
|
||||
|
||||
$value = $item['value'];
|
||||
|
||||
if (is_null($value)) break;
|
||||
|
||||
$relationType = $seed->getRelationType($link);
|
||||
|
||||
$alias = $link . 'NotLinkedFilter' . strval(rand(10000, 99999));
|
||||
|
||||
if ($relationType == 'manyMany') {
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
$midKeys = $seed->getRelationParam($link, 'midKeys');
|
||||
|
||||
if (!empty($midKeys)) {
|
||||
$key = $midKeys[1];
|
||||
$result['joinConditions'][$alias] = [$key => $value];
|
||||
$part[$alias . 'Middle.' . $key] = null;
|
||||
}
|
||||
} else if ($relationType == 'hasMany') {
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
$result['joinConditions'][$alias] = ['id' => $value];
|
||||
$part[$alias . '.id'] = null;
|
||||
} else if ($relationType == 'belongsTo') {
|
||||
$key = $seed->getRelationParam($link, 'key');
|
||||
if (!empty($key)) {
|
||||
$part[$key . '!='] = $value;
|
||||
}
|
||||
} else if ($relationType == 'hasOne') {
|
||||
$this->addLeftJoin([$link, alias], $result);
|
||||
$part[$alias . '.id!='] = $value;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
$this->setDistinct(true, $result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1322,6 +1438,9 @@ class Base
|
||||
(
|
||||
!empty($fieldDefs[$field]['type']) && $fieldDefs[$field]['type'] == 'text'
|
||||
||
|
||||
!empty($this->textFilterUseContainsAttributeList[$field])
|
||||
||
|
||||
!empty($fieldDefs[$field]['type']) && $fieldDefs[$field]['type'] == 'varchar' &&
|
||||
$this->getConfig()->get('textFilterUseContainsForVarchar')
|
||||
)
|
||||
) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"tab": true,
|
||||
"acl": true,
|
||||
"aclPortal": true,
|
||||
"aclPortalLevelList": ["all", "account", "own", "no"],
|
||||
"aclPortalLevelList": ["all", "account", "contact", "own", "no"],
|
||||
"customizable": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"tab": true,
|
||||
"acl": true,
|
||||
"aclPortal": true,
|
||||
"aclPortalLevelList": ["all", "account", "own", "no"],
|
||||
"aclPortalLevelList": ["all", "account", "contact", "own", "no"],
|
||||
"customizable": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"tab": true,
|
||||
"acl": true,
|
||||
"aclPortal": true,
|
||||
"aclPortalLevelList": ["all", "account", "own", "no"],
|
||||
"aclPortalLevelList": ["all", "account", "contact", "own", "no"],
|
||||
"customizable": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"controller": "controllers/record",
|
||||
"boolFilterList": ["onlyMy"],
|
||||
"recordViews": {
|
||||
"detail": "views/templates/event/record/detail"
|
||||
},
|
||||
"activityDefs": {
|
||||
"activitiesCreate": true,
|
||||
"historyCreate": true
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
"options": [300, 600, 900, 1800, 2700, 3600, 7200],
|
||||
"default": 300,
|
||||
"notStorable": true,
|
||||
"select": "TIMESTAMPDIFF(SECOND, date_start, date_end)",
|
||||
"select": "TIMESTAMPDIFF(SECOND, {tableName}.date_start, {tableName}.date_end)",
|
||||
"orderBy": "duration {direction}"
|
||||
},
|
||||
"parent": {
|
||||
"type": "linkParent",
|
||||
"entityList": ["Account", "Lead"]
|
||||
"entityList": ["Account", "Lead", "Contact"]
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
@@ -46,7 +46,8 @@
|
||||
"reminders": {
|
||||
"type": "jsonArray",
|
||||
"notStorable": true,
|
||||
"view": "crm:views/meeting/fields/reminders"
|
||||
"view": "crm:views/meeting/fields/reminders",
|
||||
"layoutListDisabled": true
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "datetime",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"tab": true,
|
||||
"acl": true,
|
||||
"aclPortal": true,
|
||||
"aclPortalLevelList": ["all", "account", "own", "no"],
|
||||
"aclPortalLevelList": ["all", "account", "contact", "own", "no"],
|
||||
"customizable": true,
|
||||
"importable": true,
|
||||
"notifications": true
|
||||
|
||||
5
application/Espo/Core/Templates/i18n/da_DK/Base.json
Normal file
5
application/Espo/Core/Templates/i18n/da_DK/Base.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Opret {entityTypeTranslated} "
|
||||
}
|
||||
}
|
||||
10
application/Espo/Core/Templates/i18n/da_DK/BasePlus.json
Normal file
10
application/Espo/Core/Templates/i18n/da_DK/BasePlus.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"links": {
|
||||
"meetings": "Møder",
|
||||
"calls": "Opkald",
|
||||
"tasks": "Opgaver"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Opret {entityTypeTranslated} "
|
||||
}
|
||||
}
|
||||
15
application/Espo/Core/Templates/i18n/da_DK/Company.json
Normal file
15
application/Espo/Core/Templates/i18n/da_DK/Company.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"fields": {
|
||||
"billingAddress": "Betalingsadresse",
|
||||
"shippingAddress": "Leveringsadresse",
|
||||
"website": "Website"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Møder",
|
||||
"calls": "Opkald",
|
||||
"tasks": "Opgaver"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Opret {entityTypeTranslated} "
|
||||
}
|
||||
}
|
||||
36
application/Espo/Core/Templates/i18n/da_DK/Event.json
Normal file
36
application/Espo/Core/Templates/i18n/da_DK/Event.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"fields": {
|
||||
"parent": "Henviser til",
|
||||
"dateStart": "Startdato",
|
||||
"dateEnd": "Slutdato",
|
||||
"duration": "Varighed",
|
||||
"status": "Status",
|
||||
"reminders": "Underretninger"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Henviser til"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "Planlagt",
|
||||
"Held": "Gennemført",
|
||||
"Not Held": "Ikke Gennemført"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Opret {entityTypeTranslated}",
|
||||
"Schedule {entityType}": "Planlæg {entityTypeTranslated}",
|
||||
"Log {entityType}": "Log {entityTypeTranslated}",
|
||||
"Set Held": "Marker som Gennemført",
|
||||
"Set Not Held": "Marker som Ikke Gennemført"
|
||||
},
|
||||
"massActions": {
|
||||
"setHeld": "Marker som Gennemført",
|
||||
"setNotHeld": "Marker som Ikke Gennemført"
|
||||
},
|
||||
"presetFilters": {
|
||||
"planned": "Planlagt",
|
||||
"held": "Gennemført",
|
||||
"todays": "Dagens"
|
||||
}
|
||||
}
|
||||
13
application/Espo/Core/Templates/i18n/da_DK/Person.json
Normal file
13
application/Espo/Core/Templates/i18n/da_DK/Person.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"fields": {
|
||||
"address": "Adresse"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Møder",
|
||||
"calls": "Opkald",
|
||||
"tasks": "Opgaver"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Opret {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,8 @@
|
||||
"dateStart": "Startdatum",
|
||||
"dateEnd": "Enddatum",
|
||||
"duration": "Dauer",
|
||||
"status": "Status"
|
||||
"status": "Status",
|
||||
"reminders": "Erinnerungen"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Bezieht sich auf"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"links": {
|
||||
"meetings": "Meetings",
|
||||
"calls": "Calls",
|
||||
"tasks": "Tasks"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,15 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"fields": {
|
||||
"billingAddress": "Billing Address",
|
||||
"shippingAddress": "Shipping Address",
|
||||
"website": "Website"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Meetings",
|
||||
"calls": "Calls",
|
||||
"tasks": "Tasks"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,36 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
"fields": {
|
||||
"parent": "Parent",
|
||||
"dateStart": "Date de début",
|
||||
"dateEnd": "Date End",
|
||||
"duration": "Duration",
|
||||
"status": "Status",
|
||||
"reminders": "Reminders"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Parent"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "Planned",
|
||||
"Held": "Held",
|
||||
"Not Held": "Not Held"
|
||||
}
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}",
|
||||
"Schedule {entityType}": "Schedule {entityTypeTranslated}",
|
||||
"Log {entityType}": "Log {entityTypeTranslated}",
|
||||
"Set Held": "Set Held",
|
||||
"Set Not Held": "Set Not Held"
|
||||
},
|
||||
"massActions": {
|
||||
"setHeld": "Set Held",
|
||||
"setNotHeld": "Set Not Held"
|
||||
},
|
||||
"presetFilters": {
|
||||
"planned": "Planned",
|
||||
"held": "Held",
|
||||
"todays": "Today's"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"fields": {
|
||||
"address": "Address"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Meetings",
|
||||
"calls": "Calls",
|
||||
"tasks": "Tasks"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Créer un {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
5
application/Espo/Core/Templates/i18n/nb_NO/Base.json
Normal file
5
application/Espo/Core/Templates/i18n/nb_NO/Base.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Opprett {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
10
application/Espo/Core/Templates/i18n/nb_NO/BasePlus.json
Normal file
10
application/Espo/Core/Templates/i18n/nb_NO/BasePlus.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"links": {
|
||||
"meetings": "Møter",
|
||||
"calls": "Samtaler",
|
||||
"tasks": "Oppgaver"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Opprett {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
15
application/Espo/Core/Templates/i18n/nb_NO/Company.json
Normal file
15
application/Espo/Core/Templates/i18n/nb_NO/Company.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"fields": {
|
||||
"billingAddress": "Faktureringsadresse",
|
||||
"shippingAddress": "Leveringsadresse",
|
||||
"website": "Nettside"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Møter",
|
||||
"calls": "Samtaler",
|
||||
"tasks": "Oppgaver"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Opprett {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
36
application/Espo/Core/Templates/i18n/nb_NO/Event.json
Normal file
36
application/Espo/Core/Templates/i18n/nb_NO/Event.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"fields": {
|
||||
"parent": "Forelder",
|
||||
"dateStart": "Startdato",
|
||||
"dateEnd": "Sluttdato",
|
||||
"duration": "Varighet",
|
||||
"status": "Status",
|
||||
"reminders": "Påminnelser"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Forelder"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "Planlagt",
|
||||
"Held": "Gjennomført",
|
||||
"Not Held": "Ikke gjennomført"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Opprett {entityTypeTranslated}",
|
||||
"Schedule {entityType}": "Planlegg {entityTypeTranslated}",
|
||||
"Log {entityType}": "Logg {entityTypeTranslated}",
|
||||
"Set Held": "Merk som gjennomført",
|
||||
"Set Not Held": "Merk som ikke gjennomført"
|
||||
},
|
||||
"massActions": {
|
||||
"setHeld": "Merk som gjennomført",
|
||||
"setNotHeld": "Merk som ikke gjennomført"
|
||||
},
|
||||
"presetFilters": {
|
||||
"planned": "Planlagt",
|
||||
"held": "Gjennomført",
|
||||
"todays": "Dagens"
|
||||
}
|
||||
}
|
||||
13
application/Espo/Core/Templates/i18n/nb_NO/Person.json
Normal file
13
application/Espo/Core/Templates/i18n/nb_NO/Person.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"fields": {
|
||||
"address": "Adresse"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Møter",
|
||||
"calls": "Samtaler",
|
||||
"tasks": "Oppgaver"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Opprett {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"links": {
|
||||
"meetings": "Meetings",
|
||||
"calls": "Calls",
|
||||
"tasks": "Tasks"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,15 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"fields": {
|
||||
"billingAddress": "Платежный адрес",
|
||||
"shippingAddress": "Адрес доставки",
|
||||
"website": "Website"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Meetings",
|
||||
"calls": "Calls",
|
||||
"tasks": "Tasks"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,36 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
"fields": {
|
||||
"parent": "Parent",
|
||||
"dateStart": "Date Start",
|
||||
"dateEnd": "Date End",
|
||||
"duration": "Duration",
|
||||
"status": "Status",
|
||||
"reminders": "Reminders"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Parent"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "Planned",
|
||||
"Held": "Held",
|
||||
"Not Held": "Not Held"
|
||||
}
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}",
|
||||
"Schedule {entityType}": "Schedule {entityTypeTranslated}",
|
||||
"Log {entityType}": "Log {entityTypeTranslated}",
|
||||
"Set Held": "Set Held",
|
||||
"Set Not Held": "Set Not Held"
|
||||
},
|
||||
"massActions": {
|
||||
"setHeld": "Set Held",
|
||||
"setNotHeld": "Set Not Held"
|
||||
},
|
||||
"presetFilters": {
|
||||
"planned": "Запланировано",
|
||||
"held": "Held",
|
||||
"todays": "Сегодняшние"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"fields": {
|
||||
"address": "Адрес"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Meetings",
|
||||
"calls": "Calls",
|
||||
"tasks": "Tasks"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Создать {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} Oluştur"
|
||||
}
|
||||
}
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} oluştur"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} Oluştur"
|
||||
}
|
||||
}
|
||||
"links": {
|
||||
"meetings": "Toplantılar",
|
||||
"calls": "(Seslenme)",
|
||||
"tasks": "Görevler"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} oluştur"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,15 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} Oluştur"
|
||||
}
|
||||
}
|
||||
"fields": {
|
||||
"billingAddress": "Fatura Adresi",
|
||||
"shippingAddress": "Teslimat Adresi",
|
||||
"website": "Web sitesi "
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Toplantılar",
|
||||
"calls": "(Seslenme)",
|
||||
"tasks": "Görevler"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} oluştur"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,36 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} Oluştur"
|
||||
"fields": {
|
||||
"parent": "Üst",
|
||||
"dateStart": "Başlangıç Tarihi",
|
||||
"dateEnd": "Son Tarih",
|
||||
"duration": "Süre ",
|
||||
"status": "Durum ",
|
||||
"reminders": "Hatırlatıcılar"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Üst"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "Planlandı",
|
||||
"Held": "Düzenlenen",
|
||||
"Not Held": "Düzenlenmedi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} oluştur",
|
||||
"Schedule {entityType}": "Zamanlama {entityTypeTranslated}",
|
||||
"Log {entityType}": "{entityTypeTranslated} günlüğünü kaydet",
|
||||
"Set Held": "Düzenlendi",
|
||||
"Set Not Held": "Düzenlenmedi olarak ayarla"
|
||||
},
|
||||
"massActions": {
|
||||
"setHeld": "Düzenlendi",
|
||||
"setNotHeld": "Düzenlenmedi olarak ayarla"
|
||||
},
|
||||
"presetFilters": {
|
||||
"planned": "Planlandı",
|
||||
"held": "Düzenlenen",
|
||||
"todays": "Bugünün"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} Oluştur"
|
||||
}
|
||||
}
|
||||
"fields": {
|
||||
"address": "Adres "
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Toplantılar",
|
||||
"calls": "(Seslenme)",
|
||||
"tasks": "Görevler"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "{entityTypeTranslated} oluştur"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"links": {
|
||||
"meetings": "Зустрічі",
|
||||
"calls": "Дзвінки",
|
||||
"tasks": "Завдання"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,15 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"fields": {
|
||||
"billingAddress": "Адреса виставлення рахунку",
|
||||
"shippingAddress": "Адреса доставки",
|
||||
"website": "Вебсайт"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Зустрічі",
|
||||
"calls": "Дзвінки",
|
||||
"tasks": "Завдання"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,36 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
"fields": {
|
||||
"parent": "Батько",
|
||||
"dateStart": "Дата початку",
|
||||
"dateEnd": "Дата завершення",
|
||||
"duration": "Тривалість",
|
||||
"status": "Статус",
|
||||
"reminders": "Нагадування"
|
||||
},
|
||||
"links": {
|
||||
"parent": "Батько"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "Плановий",
|
||||
"Held": "Виконано",
|
||||
"Not Held": "Не вміщений"
|
||||
}
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}",
|
||||
"Schedule {entityType}": "Розклад {entityTypeTranslated} ",
|
||||
"Log {entityType}": "Лог {entityTypeTranslated}",
|
||||
"Set Held": "Позначити виконаним",
|
||||
"Set Not Held": "Позначити невиконаним"
|
||||
},
|
||||
"massActions": {
|
||||
"setHeld": "Позначити виконаними",
|
||||
"setNotHeld": "Позначити невиконаними"
|
||||
},
|
||||
"presetFilters": {
|
||||
"planned": "Планований",
|
||||
"held": "Виконані",
|
||||
"todays": "Сьогоднішні"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
"fields": {
|
||||
"address": "Адреса"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "Зустрічі",
|
||||
"calls": "Дзвінки",
|
||||
"tasks": "Завдання"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "Створити {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
5
application/Espo/Core/Templates/i18n/zh_CN/Base.json
Normal file
5
application/Espo/Core/Templates/i18n/zh_CN/Base.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"labels": {
|
||||
"Create {entityType}": "创建 {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
10
application/Espo/Core/Templates/i18n/zh_CN/BasePlus.json
Normal file
10
application/Espo/Core/Templates/i18n/zh_CN/BasePlus.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"links": {
|
||||
"meetings": "会晤",
|
||||
"calls": "通话",
|
||||
"tasks": "任务"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "创建 {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
15
application/Espo/Core/Templates/i18n/zh_CN/Company.json
Normal file
15
application/Espo/Core/Templates/i18n/zh_CN/Company.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"fields": {
|
||||
"billingAddress": "账单地址",
|
||||
"shippingAddress": "邮寄地址",
|
||||
"website": "网站"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "会晤",
|
||||
"calls": "通话",
|
||||
"tasks": "任务"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "创建 {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
36
application/Espo/Core/Templates/i18n/zh_CN/Event.json
Normal file
36
application/Espo/Core/Templates/i18n/zh_CN/Event.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"fields": {
|
||||
"parent": "关联",
|
||||
"dateStart": "开始日期",
|
||||
"dateEnd": "结束日期",
|
||||
"duration": "持续时间",
|
||||
"status": "状态",
|
||||
"reminders": "提醒"
|
||||
},
|
||||
"links": {
|
||||
"parent": "关联"
|
||||
},
|
||||
"options": {
|
||||
"status": {
|
||||
"Planned": "已计划",
|
||||
"Held": "已举行",
|
||||
"Not Held": "未举行"
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "创建 {entityTypeTranslated}",
|
||||
"Schedule {entityType}": "计划 {entityTypeTranslated}",
|
||||
"Log {entityType}": "记录 {entityTypeTranslated} ",
|
||||
"Set Held": "设为已举行",
|
||||
"Set Not Held": "设为未举行"
|
||||
},
|
||||
"massActions": {
|
||||
"setHeld": "设为已举行",
|
||||
"setNotHeld": "设为未举行"
|
||||
},
|
||||
"presetFilters": {
|
||||
"planned": "已计划",
|
||||
"held": "已举行",
|
||||
"todays": "今天的"
|
||||
}
|
||||
}
|
||||
13
application/Espo/Core/Templates/i18n/zh_CN/Person.json
Normal file
13
application/Espo/Core/Templates/i18n/zh_CN/Person.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"fields": {
|
||||
"address": "地址"
|
||||
},
|
||||
"links": {
|
||||
"meetings": "会晤",
|
||||
"calls": "通话",
|
||||
"tasks": "任务"
|
||||
},
|
||||
"labels": {
|
||||
"Create {entityType}": "创建 {entityTypeTranslated}"
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,13 @@ class Auth extends \Slim\Middleware
|
||||
list($authUsername, $authPassword) = explode(':', base64_decode($espoAuth));
|
||||
}
|
||||
|
||||
if (!isset($authUsername)) {
|
||||
if (!empty($_COOKIE['auth-username']) && !empty($_COOKIE['auth-token'])) {
|
||||
$authUsername = $_COOKIE['auth-username'];
|
||||
$authPassword = $_COOKIE['auth-token'];
|
||||
}
|
||||
}
|
||||
|
||||
$espoCgiAuth = $req->headers('HTTP_ESPO_CGI_AUTH');
|
||||
if (empty($espoCgiAuth)) {
|
||||
$espoCgiAuth = $req->headers('REDIRECT_HTTP_ESPO_CGI_AUTH');
|
||||
|
||||
@@ -31,6 +31,89 @@ namespace Espo\Core\Utils\Api;
|
||||
|
||||
class Slim extends \Slim\Slim
|
||||
{
|
||||
public function __construct(array $userSettings = array())
|
||||
{
|
||||
// Setup IoC container
|
||||
$this->container = new \Slim\Helper\Set();
|
||||
$this->container['settings'] = array_merge(static::getDefaultSettings(), $userSettings);
|
||||
|
||||
// Default environment
|
||||
$this->container->singleton('environment', function ($c) {
|
||||
/* ESPOCRM: change Environment class */
|
||||
//return \Slim\Environment::getInstance();
|
||||
return \Espo\Core\Utils\Api\Slim\Environment::getInstance();
|
||||
/* ESPOCRM: end */
|
||||
});
|
||||
|
||||
// Default request
|
||||
$this->container->singleton('request', function ($c) {
|
||||
return new \Slim\Http\Request($c['environment']);
|
||||
});
|
||||
|
||||
// Default response
|
||||
$this->container->singleton('response', function ($c) {
|
||||
return new \Slim\Http\Response();
|
||||
});
|
||||
|
||||
// Default router
|
||||
$this->container->singleton('router', function ($c) {
|
||||
return new \Slim\Router();
|
||||
});
|
||||
|
||||
// Default view
|
||||
$this->container->singleton('view', function ($c) {
|
||||
$viewClass = $c['settings']['view'];
|
||||
$templatesPath = $c['settings']['templates.path'];
|
||||
|
||||
$view = ($viewClass instanceOf \Slim\View) ? $viewClass : new $viewClass;
|
||||
$view->setTemplatesDirectory($templatesPath);
|
||||
return $view;
|
||||
});
|
||||
|
||||
// Default log writer
|
||||
$this->container->singleton('logWriter', function ($c) {
|
||||
$logWriter = $c['settings']['log.writer'];
|
||||
|
||||
return is_object($logWriter) ? $logWriter : new \Slim\LogWriter($c['environment']['slim.errors']);
|
||||
});
|
||||
|
||||
// Default log
|
||||
$this->container->singleton('log', function ($c) {
|
||||
$log = new \Slim\Log($c['logWriter']);
|
||||
$log->setEnabled($c['settings']['log.enabled']);
|
||||
$log->setLevel($c['settings']['log.level']);
|
||||
$env = $c['environment'];
|
||||
$env['slim.log'] = $log;
|
||||
|
||||
return $log;
|
||||
});
|
||||
|
||||
// Default mode
|
||||
$this->container['mode'] = function ($c) {
|
||||
$mode = $c['settings']['mode'];
|
||||
|
||||
if (isset($_ENV['SLIM_MODE'])) {
|
||||
$mode = $_ENV['SLIM_MODE'];
|
||||
} else {
|
||||
$envMode = getenv('SLIM_MODE');
|
||||
if ($envMode !== false) {
|
||||
$mode = $envMode;
|
||||
}
|
||||
}
|
||||
|
||||
return $mode;
|
||||
};
|
||||
|
||||
// Define default middleware stack
|
||||
$this->middleware = array($this);
|
||||
$this->add(new \Slim\Middleware\Flash());
|
||||
$this->add(new \Slim\Middleware\MethodOverride());
|
||||
|
||||
// Make default if first instance
|
||||
if (is_null(static::getInstance())) {
|
||||
$this->setName('default');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redefine the run method
|
||||
|
||||
60
application/Espo/Core/Utils/Api/Slim/Environment.php
Normal file
60
application/Espo/Core/Utils/Api/Slim/Environment.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2017 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
|
||||
* Website: http://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Utils\Api\Slim;
|
||||
|
||||
class Environment extends \Slim\Environment
|
||||
{
|
||||
/**
|
||||
* Define undefined $_SERVER variables
|
||||
*/
|
||||
private static function setUndefinedVariables()
|
||||
{
|
||||
$list = array(
|
||||
'REQUEST_METHOD',
|
||||
'REMOTE_ADDR',
|
||||
'SERVER_NAME',
|
||||
'SERVER_PORT',
|
||||
'REQUEST_URI',
|
||||
);
|
||||
|
||||
foreach ($list as $name) {
|
||||
if (!array_key_exists($name, $_SERVER)) {
|
||||
$_SERVER[$name] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getInstance($refresh = false)
|
||||
{
|
||||
static::setUndefinedVariables();
|
||||
|
||||
return parent::getInstance($refresh);
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,7 @@ class Auth
|
||||
}
|
||||
|
||||
$user->set('isAdmin', $isAdmin);
|
||||
$user->set('ipAddress', $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
$entityManager->setUser($user);
|
||||
$this->getContainer()->setUser($user);
|
||||
@@ -116,7 +117,10 @@ class Auth
|
||||
|
||||
public function login($username, $password)
|
||||
{
|
||||
$authToken = $this->getEntityManager()->getRepository('AuthToken')->where(array('token' => $password))->findOne();
|
||||
$authToken = $this->getEntityManager()->getRepository('AuthToken')->where(array(
|
||||
'token' => $password,
|
||||
'isActive' => true
|
||||
))->findOne();
|
||||
|
||||
if ($authToken) {
|
||||
if (!$this->allowAnyAccess) {
|
||||
@@ -167,6 +171,8 @@ class Auth
|
||||
$user->loadLinkMultipleField('teams');
|
||||
}
|
||||
|
||||
$user->set('ipAddress', $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
$this->getEntityManager()->setUser($user);
|
||||
$this->getContainer()->setUser($user);
|
||||
|
||||
@@ -186,6 +192,7 @@ class Auth
|
||||
|
||||
$this->getEntityManager()->saveEntity($authToken);
|
||||
$user->set('token', $authToken->get('token'));
|
||||
$user->set('authTokenId', $authToken->id);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -201,7 +208,8 @@ class Auth
|
||||
{
|
||||
$authToken = $this->getEntityManager()->getRepository('AuthToken')->where(array('token' => $token))->findOne();
|
||||
if ($authToken) {
|
||||
$this->getEntityManager()->removeEntity($authToken);
|
||||
$authToken->set('isActive', false);
|
||||
$this->getEntityManager()->saveEntity($authToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user