Skip to content

Commit aa0751c

Browse files
author
billy clark
authored
Release 1.9.2
2 parents 581aa52 + 805aded commit aa0751c

16 files changed

+184
-127
lines changed

docker/app/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ COPY docker/app/entrypoint.sh /
125125

126126
COPY --from=composer-builder /composer/vendor /var/www/html/vendor
127127

128+
# patch exception handling from Symfony to actually show exceptions instead of swallowing them
129+
COPY docker/app/symfony-exceptions.patch /
130+
RUN patch -p4 -i /symfony-exceptions.patch
131+
128132
RUN echo "${BUILD_VERSION}" > /var/www/html/build-version.txt \
129133
&& sed -i /var/www/html/version.php -e "s/^\\(define('VERSION', '\\).*;\$/\\1${BUILD_VERSION}'\\);/"
130134

docker/app/customizations.php.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
memory_limit = 256M
22
post_max_size = 60M
33
upload_max_filesize = 60M
4+
xdebug.log_level = 0

docker/app/symfony-exceptions.patch

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
--- a/var/www/html/vendor/symfony/debug/ExceptionHandler.php 2019-07-23 15:39:19.000000000 +0700
2+
+++ b/var/www/html/vendor/symfony/debug/ExceptionHandler.php 2021-09-27 15:08:37.000000000 +0700
3+
@@ -103,7 +103,7 @@
4+
* The latter takes precedence and any output from the former is cancelled,
5+
* if and only if nothing bad happens in this handling path.
6+
*/
7+
- public function handle(\Exception $exception)
8+
+ public function handle(\Error $exception)
9+
{
10+
if (null === $this->handler || $exception instanceof OutOfMemoryException) {
11+
$this->sendPhpResponse($exception);
12+
@@ -144,7 +144,7 @@
13+
try {
14+
\call_user_func($this->handler, $exception);
15+
$this->caughtLength = $caughtLength;
16+
- } catch (\Exception $e) {
17+
+ } catch (\Error $e) {
18+
if (!$caughtLength) {
19+
// All handlers failed. Let PHP handle that now.
20+
throw $exception;
21+
@@ -158,7 +158,7 @@
22+
* This method uses plain PHP functions like header() and echo to output
23+
* the response.
24+
*
25+
- * @param \Exception|FlattenException $exception An \Exception or FlattenException instance
26+
+ * @param \Error|FlattenException $exception An \Error or FlattenException instance
27+
*/
28+
public function sendPhpResponse($exception)
29+
{
30+
@@ -180,7 +180,7 @@
31+
/**
32+
* Gets the full HTML content associated with the given exception.
33+
*
34+
- * @param \Exception|FlattenException $exception An \Exception or FlattenException instance
35+
+ * @param \Error|FlattenException $exception An \Error or FlattenException instance
36+
*
37+
* @return string The HTML content as a string
38+
*/
39+
@@ -250,7 +250,7 @@
40+
41+
$content .= "</tbody>\n</table>\n</div>\n";
42+
}
43+
- } catch (\Exception $e) {
44+
+ } catch (\Error $e) {
45+
// something nasty happened and we cannot throw an exception anymore
46+
if ($this->debug) {
47+
$title = sprintf('Exception thrown when handling an exception (%s: %s)', \get_class($e), $this->escapeHtml($e->getMessage()));
48+
@@ -390,7 +390,7 @@
49+
} else {
50+
try {
51+
$link = $fmt->format($path, $line);
52+
- } catch (\Exception $e) {
53+
+ } catch (\Error $e) {
54+
return sprintf('<span class="block trace-file-path">in <span title="%s%3$s"><strong>%s</strong>%s</span></span>', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');
55+
}
56+
}
57+
--- a/var/www/html/vendor/symfony/debug/Exception/FlattenException.php 2019-07-23 15:39:19.000000000 +0700
58+
+++ b/var/www/html/vendor/symfony/debug/Exception/FlattenException.php 2021-09-27 15:09:06.000000000 +0700
59+
@@ -33,7 +33,7 @@
60+
private $file;
61+
private $line;
62+
63+
- public static function create(\Exception $exception, $statusCode = null, array $headers = [])
64+
+ public static function create(\Error $exception, $statusCode = null, array $headers = [])
65+
{
66+
$e = new static();
67+
$e->setMessage($exception->getMessage());
68+
@@ -59,7 +59,7 @@
69+
70+
$previous = $exception->getPrevious();
71+
72+
- if ($previous instanceof \Exception) {
73+
+ if ($previous instanceof \Error) {
74+
$e->setPrevious(static::create($previous));
75+
} elseif ($previous instanceof \Throwable) {
76+
$e->setPrevious(static::create(new FatalThrowableError($previous)));
77+
@@ -178,7 +178,7 @@
78+
return $this->trace;
79+
}
80+
81+
- public function setTraceFromException(\Exception $exception)
82+
+ public function setTraceFromException(\Error $exception)
83+
{
84+
$this->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine());
85+
}

src/Site/OAuth/OAuthBase.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,14 @@ public function findUserModelByOAuthId(string $oauthId)
156156
return $userModel;
157157
}
158158

159-
public static function setSilexAuthToken(UserModel $userModel, Application $app): string
159+
public static function doSilexLogin(UserModel $userModel, Application $app): string
160160
{
161161
$roles = AuthUserProvider::getSiteRoles($userModel, $app['website']);
162162
$oauthUser = new UserWithId($userModel->username, '', $userModel->username, $roles);
163163
$oauthToken = new UsernamePasswordToken($oauthUser, '', 'site', $oauthUser->getRoles());
164164
$tokenStorage = $app['security.token_storage'];
165+
$userModel->last_login = time();
166+
$userModel->write();
165167
if (!is_null($tokenStorage) && $tokenStorage instanceof TokenStorageInterface) {
166168
$tokenStorage->setToken($oauthToken);
167169
return true;
@@ -277,7 +279,7 @@ protected function loginWithOAuthToken(Application $app, AbstractProvider $provi
277279
// so that any changes made by Validate::check won't be overwritten by our write() call
278280
Validate::check($app, $userModel->validationKey);
279281
}
280-
$success = $this->setSilexAuthToken($userModel, $app);
282+
$success = $this->doSilexLogin($userModel, $app);
281283
if (! $success) {
282284
$this->addErrorMessage($app, 'Sorry, we couldn\'t process the ' . ucwords($this->getProviderName()) . ' login data. This may be a temporary failure, so please try again. If the problem persists, try logging in with a username and password instead.');
283285
}
@@ -286,7 +288,7 @@ protected function loginWithOAuthToken(Application $app, AbstractProvider $provi
286288
}
287289
} else {
288290
// OAuth ID found in our user model
289-
$success = $this->setSilexAuthToken($userModel, $app);
291+
$success = $this->doSilexLogin($userModel, $app);
290292
if (! $success) {
291293
$this->addErrorMessage($app, 'Sorry, we couldn\'t process the ' . ucwords($this->getProviderName()) . ' login data. This may be a temporary failure, so please try again. If the problem persists, try logging in with a username and password instead.');
292294
}

src/Site/views/languageforge/container/languageforge.html.twig

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<div id="primary-navigation" class="fixed-nav-bar" data-ng-cloak data-ng-controller="navbarController as $ctrl">
1212
<nav class="navbar navbar-expand navbar-dark align-items-stretch">
1313
<span class="navbar-brand d-md-inline-block mr-auto">
14-
<img class="navbar-logo" src="/Site/views/languageforge/theme/default/image/lf_logo_medium.png">
14+
<img class="navbar-logo" title="v{{ version }}" src="/Site/views/languageforge/theme/default/image/lf_logo_medium.png">
1515
<a class="website-title" href="/">{{ app.website.name }}</a>
1616
</span>
1717
<ul class="nav navbar-nav">
@@ -127,7 +127,7 @@
127127
<div id="primary-navigation" class="logged-out" data-ng-cloak data-ng-controller="navbarController as $ctrl">
128128
<nav class="fixed-nav-bar navbar navbar-expand navbar-dark align-items-stretch logged-out">
129129
<span class="navbar-brand d-md-inline-block mr-auto">
130-
<img class="navbar-logo" src="/Site/views/languageforge/theme/default/image/lf_logo_medium.png">
130+
<img class="navbar-logo" title="v{{ version }}" src="/Site/views/languageforge/theme/default/image/lf_logo_medium.png">
131131
<a class="" href="/">{{ app.website.name }}</a>
132132
</span>
133133
<ul class="nav navbar-nav">
@@ -151,28 +151,6 @@
151151
{% endif %}
152152
{% endblock %}
153153

154-
{% block footer %}
155-
<footer class="footer">
156-
<div class="d-flex">
157-
<div class="d-none d-sm-flex align-items-end">
158-
<div>
159-
<a href="https://inter.payap.ac.th/"><img src="/Site/views/shared/image/payap_logo.png"
160-
alt="Payap University Logo" width="85" height="25" /></a>
161-
<a href="http://www.sil.org"><img src="/Site/views/shared/image/sil_logo_small.png"
162-
alt="SIL International Logo" width="25" height="30" /></a>
163-
</div>
164-
</div>
165-
<div class="d-flex flex-grow justify-content-end align-items-end">
166-
<small>
167-
v {{ version }}.
168-
Copyright <span class="notranslate">{{ "now"|date("Y") }}</span> <a href="http://www.sil.org" class="links">SIL International</a>.
169-
<a href="/terms_and_conditions" class="links">Terms and conditions</a>.
170-
</small>
171-
</div>
172-
</div>
173-
</footer>
174-
{% endblock %}
175-
176154
{% block analytics %}
177155
{% if 'languageforge.org' in http_host %}
178156
<script>

src/Site/views/shared/_global.scss

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -173,27 +173,6 @@ nav {
173173
@include button-variant(white, #ADADAD, #E6E6E6);
174174
}
175175

176-
.footer{
177-
background-color: $theme-primary;
178-
color: white;
179-
padding: 0.5em;
180-
margin-top: 0.5em;
181-
182-
.links{
183-
color: white;
184-
border-bottom: 1px dotted white;
185-
text-decoration: none;
186-
}
187-
188-
.footerimages {
189-
padding-bottom: 10px;
190-
}
191-
192-
img {
193-
margin-right: 5px;
194-
}
195-
}
196-
197176
// TODO: Remove hack for modal box issue as a result of ui.bootstrap
198177
.modal-select-language {
199178

src/angular-app/languageforge/lexicon/editor/_editor.scss

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,12 @@ dc-entry .card {
293293
}
294294
}
295295
.lexiconItemListContainer {
296-
@include media-breakpoint-up(sm) {
296+
@include media-breakpoint-up(md) {
297297
margin-bottom: 5px;
298-
height: calc(100vh - 310px);
298+
height: calc(100vh - 260px);
299299
}
300300
@include media-breakpoint-down(sm) {
301-
height: calc(100vh - 260px);
301+
height: calc(100vh - 220px);
302302
}
303303
overflow: auto;
304304
}
@@ -321,8 +321,12 @@ dc-entry .card {
321321

322322
#lexAppEditView {
323323
#compactEntryListContainer {
324-
height: calc(100vh - 400px);
324+
height: calc(100vh - 325px);
325325
overflow: auto;
326+
327+
.list-group-item {
328+
padding: .25rem 1.25rem;
329+
}
326330
}
327331
.word-definition-title {
328332
margin-bottom: 5px;
@@ -721,7 +725,7 @@ dc-entry .card {
721725
position: relative;
722726
overflow-y: hidden;
723727
min-height: 40px;
724-
height: 55px;
728+
height: 50px;
725729
border-bottom: solid 1px darkgrey;
726730
width: 100%;
727731
line-height: 1.2em;
@@ -736,10 +740,8 @@ dc-entry .card {
736740
}
737741

738742
.entryItemView {
739-
/* TODO: review this in light of animation and the footer staying at the bottom. IJH 2014-09
740-
The view is used in edit and comment view */
743+
min-height: 580px;
741744

742-
min-height: 580px;
743745
.field-container {
744746
position: relative;
745747
.comment-bubble-group {
@@ -782,13 +784,16 @@ dc-entry .card {
782784
}
783785

784786
.entryItemView {
785-
i.fa-times {
786-
cursor: pointer;
787-
color: #888;
788-
}
789-
button i.fa-times {
790-
color: inherit;
791-
}
787+
.form-group {
788+
margin-bottom: 5px;
789+
}
790+
i.fa-times {
791+
cursor: pointer;
792+
color: #888;
793+
}
794+
button i.fa-times {
795+
color: inherit;
796+
}
792797
}
793798

794799
#lexAppCommentView .commentCount {

src/angular-app/languageforge/lexicon/editor/comment/lex-comments-view.scss

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
@import '../../../../../Site/views/languageforge/theme/default/sass/variables';
2+
@import '../../../../../../node_modules/bootstrap/scss/functions';
3+
@import '../../../../../../node_modules/bootstrap/scss/variables';
4+
@import '../../../../../../node_modules/bootstrap/scss/mixins';
25

36
#lexAppEditView {
47
display: flex;
@@ -19,11 +22,12 @@
1922
overflow-y: scroll;
2023
overflow-x: hidden;
2124

22-
@include media-breakpoint-up(sm) {
23-
height: calc(100vh - 296px);
25+
@include media-breakpoint-up(md) {
26+
height: calc(100vh - 230px);
2427
}
28+
2529
@include media-breakpoint-down(sm) {
26-
height: calc(100vh - 270px);
30+
height: calc(100vh - 215px);
2731
}
2832
}
2933

src/angular-app/languageforge/lexicon/editor/editor.component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ export class LexiconEditorController implements angular.IController {
147147
if (this.hasUnsavedChanges()) {
148148
this.saveCurrentEntry();
149149
}
150+
// destroy listeners when leaving editor page
151+
angular.element(window).unbind('keyup', (e: Event) => {});
150152
};
151153

152154
this.show.entryListModifiers = !(this.$window.localStorage.getItem('viewFilter') == null ||

src/angular-app/languageforge/lexicon/shared/share-with-others/invite-member-form.component.html

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
<b>Invite a new member</b>
33
<div class="inline-invite-form" style="margin-top: 8px;">
44
<label>via: </label>
5-
<input type="email" class="form-control" placeholder="Email" ng-model="$ctrl.inviteEmail">
6-
<button type="button" class="btn btn-primary"
7-
ng-click="$ctrl.sendEmailInvite()" data-ng-disabled="$ctrl.inviteEmailDisabled()">
8-
<i class="fa fa-paper-plane"></i>
9-
</button>
5+
<input type="email" ng-form="email" class="form-control" placeholder="Email" ng-model="$ctrl.inviteEmail">
106
<role-dropdown class="sm-no-margin"
117
ng-if="$ctrl.currentUserIsManager"
128
target="'email_invite'"
139
roles="$ctrl.emailInviteRoles"
1410
selected-role="$ctrl.emailInviteRole"
1511
on-role-changed="$ctrl.onRoleChanged($event)"></role-dropdown>
12+
<button type="button" class="btn btn-primary"
13+
ng-click="$ctrl.sendEmailInvite()" data-ng-disabled="! ($ctrl.inviteEmail && email.$valid)">
14+
<i class="fa fa-paper-plane pr-1"></i> Send
15+
</button>
1616
</div>
1717

1818
<div ng-if="$ctrl.currentUserIsManager || !$ctrl.inviteLink">
@@ -33,6 +33,10 @@
3333
roles="$ctrl.reusableInviteLinkRoles"
3434
selected-role="$ctrl.getInviteRole()"
3535
on-role-changed="$ctrl.onRoleChanged($event)"></role-dropdown>
36+
<button type="button" class="btn btn-primary"
37+
ng-click="$ctrl.copy()" data-ng-disabled="! $ctrl.inviteLink">
38+
<i class="fa fa-clipboard pr-1"></i> Copy
39+
</button>
3640
</div>
3741
</div>
3842
</div>

0 commit comments

Comments
 (0)