aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--application/bookmark/BookmarkInitializer.php4
-rw-r--r--application/bookmark/LinkUtils.php8
-rw-r--r--application/front/controller/visitor/ErrorController.php11
-rw-r--r--assets/default/scss/shaarli.scss6
-rw-r--r--inc/languages/fr/LC_MESSAGES/shaarli.po14
-rw-r--r--tests/bookmark/LinkUtilsTest.php30
-rw-r--r--tests/front/controller/visitor/ErrorControllerTest.php29
-rw-r--r--tpl/default/error.html8
8 files changed, 94 insertions, 16 deletions
diff --git a/application/bookmark/BookmarkInitializer.php b/application/bookmark/BookmarkInitializer.php
index 04b996f3..98dd3f1c 100644
--- a/application/bookmark/BookmarkInitializer.php
+++ b/application/bookmark/BookmarkInitializer.php
@@ -36,8 +36,8 @@ class BookmarkInitializer
36 public function initialize(): void 36 public function initialize(): void
37 { 37 {
38 $bookmark = new Bookmark(); 38 $bookmark = new Bookmark();
39 $bookmark->setTitle('quicksilver (loop) on Vimeo ' . t('(private bookmark with thumbnail demo)')); 39 $bookmark->setTitle('Calm Jazz Music - YouTube ' . t('(private bookmark with thumbnail demo)'));
40 $bookmark->setUrl('https://vimeo.com/153493904'); 40 $bookmark->setUrl('https://www.youtube.com/watch?v=DVEUcbPkb-c');
41 $bookmark->setDescription(t( 41 $bookmark->setDescription(t(
42'Shaarli will automatically pick up the thumbnail for links to a variety of websites. 42'Shaarli will automatically pick up the thumbnail for links to a variety of websites.
43 43
diff --git a/application/bookmark/LinkUtils.php b/application/bookmark/LinkUtils.php
index 9493b0aa..cf97e3b0 100644
--- a/application/bookmark/LinkUtils.php
+++ b/application/bookmark/LinkUtils.php
@@ -68,16 +68,16 @@ function html_extract_tag($tag, $html)
68 $properties = implode('|', $propertiesKey); 68 $properties = implode('|', $propertiesKey);
69 // We need a OR here to accept either 'property=og:noquote' or 'property="og:unrelated og:my-tag"' 69 // We need a OR here to accept either 'property=og:noquote' or 'property="og:unrelated og:my-tag"'
70 $orCondition = '["\']?(?:og:)?'. $tag .'["\']?|["\'][^\'"]*?(?:og:)?' . $tag . '[^\'"]*?[\'"]'; 70 $orCondition = '["\']?(?:og:)?'. $tag .'["\']?|["\'][^\'"]*?(?:og:)?' . $tag . '[^\'"]*?[\'"]';
71 // Try to retrieve OpenGraph image. 71 // Try to retrieve OpenGraph tag.
72 $ogRegex = '#<meta[^>]+(?:'. $properties .')=(?:'. $orCondition .')[^>]*content=["\'](.*?)["\'].*?>#'; 72 $ogRegex = '#<meta[^>]+(?:'. $properties .')=(?:'. $orCondition .')[^>]*content=(["\'])([^\1]*?)\1.*?>#';
73 // If the attributes are not in the order property => content (e.g. Github) 73 // If the attributes are not in the order property => content (e.g. Github)
74 // New regex to keep this readable... more or less. 74 // New regex to keep this readable... more or less.
75 $ogRegexReverse = '#<meta[^>]+content=["\'](.*?)["\'][^>]+(?:'. $properties .')=(?:'. $orCondition .').*?>#'; 75 $ogRegexReverse = '#<meta[^>]+content=(["\'])([^\1]*?)\1[^>]+(?:'. $properties .')=(?:'. $orCondition .').*?>#';
76 76
77 if (preg_match($ogRegex, $html, $matches) > 0 77 if (preg_match($ogRegex, $html, $matches) > 0
78 || preg_match($ogRegexReverse, $html, $matches) > 0 78 || preg_match($ogRegexReverse, $html, $matches) > 0
79 ) { 79 ) {
80 return $matches[1]; 80 return $matches[2];
81 } 81 }
82 82
83 return false; 83 return false;
diff --git a/application/front/controller/visitor/ErrorController.php b/application/front/controller/visitor/ErrorController.php
index 8da11172..428e8254 100644
--- a/application/front/controller/visitor/ErrorController.php
+++ b/application/front/controller/visitor/ErrorController.php
@@ -26,8 +26,14 @@ class ErrorController extends ShaarliVisitorController
26 $response = $response->withStatus($throwable->getCode()); 26 $response = $response->withStatus($throwable->getCode());
27 } else { 27 } else {
28 // Internal error (any other Throwable) 28 // Internal error (any other Throwable)
29 if ($this->container->conf->get('dev.debug', false)) { 29 if ($this->container->conf->get('dev.debug', false) || $this->container->loginManager->isLoggedIn()) {
30 $this->assignView('message', $throwable->getMessage()); 30 $this->assignView('message', t('Error: ') . $throwable->getMessage());
31 $this->assignView(
32 'text',
33 '<a href="https://github.com/shaarli/Shaarli/issues/new">'
34 . t('Please report it on Github.')
35 . '</a>'
36 );
31 $this->assignView('stacktrace', exception2text($throwable)); 37 $this->assignView('stacktrace', exception2text($throwable));
32 } else { 38 } else {
33 $this->assignView('message', t('An unexpected error occurred.')); 39 $this->assignView('message', t('An unexpected error occurred.'));
@@ -36,7 +42,6 @@ class ErrorController extends ShaarliVisitorController
36 $response = $response->withStatus(500); 42 $response = $response->withStatus(500);
37 } 43 }
38 44
39
40 return $response->write($this->render('error')); 45 return $response->write($this->render('error'));
41 } 46 }
42} 47}
diff --git a/assets/default/scss/shaarli.scss b/assets/default/scss/shaarli.scss
index ed774a9d..cc8ccc1e 100644
--- a/assets/default/scss/shaarli.scss
+++ b/assets/default/scss/shaarli.scss
@@ -1276,11 +1276,15 @@ form {
1276 margin: 70px 0 25px; 1276 margin: 70px 0 25px;
1277 } 1277 }
1278 1278
1279 a {
1280 color: var(--main-color);
1281 }
1282
1279 pre { 1283 pre {
1280 margin: 0 20%; 1284 margin: 0 20%;
1281 padding: 20px 0; 1285 padding: 20px 0;
1282 text-align: left; 1286 text-align: left;
1283 line-height: .7em; 1287 line-height: 1em;
1284 } 1288 }
1285} 1289}
1286 1290
diff --git a/inc/languages/fr/LC_MESSAGES/shaarli.po b/inc/languages/fr/LC_MESSAGES/shaarli.po
index 4c363fa8..51bef6c7 100644
--- a/inc/languages/fr/LC_MESSAGES/shaarli.po
+++ b/inc/languages/fr/LC_MESSAGES/shaarli.po
@@ -1,8 +1,8 @@
1msgid "" 1msgid ""
2msgstr "" 2msgstr ""
3"Project-Id-Version: Shaarli\n" 3"Project-Id-Version: Shaarli\n"
4"POT-Creation-Date: 2020-11-05 16:47+0100\n" 4"POT-Creation-Date: 2020-11-05 19:43+0100\n"
5"PO-Revision-Date: 2020-11-05 16:48+0100\n" 5"PO-Revision-Date: 2020-11-05 19:44+0100\n"
6"Last-Translator: \n" 6"Last-Translator: \n"
7"Language-Team: Shaarli\n" 7"Language-Team: Shaarli\n"
8"Language: fr_FR\n" 8"Language: fr_FR\n"
@@ -501,7 +501,15 @@ msgstr "mois"
501msgid "Monthly" 501msgid "Monthly"
502msgstr "Mensuel" 502msgstr "Mensuel"
503 503
504#: application/front/controller/visitor/ErrorController.php:33 504#: application/front/controller/visitor/ErrorController.php:30
505msgid "Error: "
506msgstr "Erreur : "
507
508#: application/front/controller/visitor/ErrorController.php:34
509msgid "Please report it on Github."
510msgstr "Merci de la rapporter sur Github."
511
512#: application/front/controller/visitor/ErrorController.php:39
505msgid "An unexpected error occurred." 513msgid "An unexpected error occurred."
506msgstr "Une erreur inattendue s'est produite." 514msgstr "Une erreur inattendue s'est produite."
507 515
diff --git a/tests/bookmark/LinkUtilsTest.php b/tests/bookmark/LinkUtilsTest.php
index c2f9f930..ddab4e3c 100644
--- a/tests/bookmark/LinkUtilsTest.php
+++ b/tests/bookmark/LinkUtilsTest.php
@@ -169,6 +169,36 @@ class LinkUtilsTest extends TestCase
169 } 169 }
170 170
171 /** 171 /**
172 * Test html_extract_tag() with double quoted content containing single quote, and the opposite.
173 */
174 public function testHtmlExtractExistentNameTagWithMixedQuotes(): void
175 {
176 $description = 'Bob and Alice share M&M\'s.';
177
178 $html = '<meta property="og:description" content="' . $description . '">';
179 $this->assertEquals($description, html_extract_tag('description', $html));
180
181 $html = '<meta tag1="content1" property="og:unrelated1 og:description og:unrelated2" '.
182 'tag2="content2" content="' . $description . '" tag3="content3">';
183 $this->assertEquals($description, html_extract_tag('description', $html));
184
185 $html = '<meta property="og:description" name="description" content="' . $description . '">';
186 $this->assertEquals($description, html_extract_tag('description', $html));
187
188 $description = 'Bob and Alice share "cookies".';
189
190 $html = '<meta property="og:description" content=\'' . $description . '\'>';
191 $this->assertEquals($description, html_extract_tag('description', $html));
192
193 $html = '<meta tag1="content1" property="og:unrelated1 og:description og:unrelated2" '.
194 'tag2="content2" content=\'' . $description . '\' tag3="content3">';
195 $this->assertEquals($description, html_extract_tag('description', $html));
196
197 $html = '<meta property="og:description" name="description" content=\'' . $description . '\'>';
198 $this->assertEquals($description, html_extract_tag('description', $html));
199 }
200
201 /**
172 * Test html_extract_tag() when the tag <meta name= is not found. 202 * Test html_extract_tag() when the tag <meta name= is not found.
173 */ 203 */
174 public function testHtmlExtractNonExistentNameTag() 204 public function testHtmlExtractNonExistentNameTag()
diff --git a/tests/front/controller/visitor/ErrorControllerTest.php b/tests/front/controller/visitor/ErrorControllerTest.php
index 75408cf4..e18a6fa2 100644
--- a/tests/front/controller/visitor/ErrorControllerTest.php
+++ b/tests/front/controller/visitor/ErrorControllerTest.php
@@ -50,7 +50,31 @@ class ErrorControllerTest extends TestCase
50 } 50 }
51 51
52 /** 52 /**
53 * Test displaying error with any exception (no debug): only display an error occurred with HTTP 500. 53 * Test displaying error with any exception (no debug) while logged in:
54 * display full error details
55 */
56 public function testDisplayAnyExceptionErrorNoDebugLoggedIn(): void
57 {
58 $request = $this->createMock(Request::class);
59 $response = new Response();
60
61 // Save RainTPL assigned variables
62 $assignedVariables = [];
63 $this->assignTemplateVars($assignedVariables);
64
65 $this->container->loginManager->method('isLoggedIn')->willReturn(true);
66
67 $result = ($this->controller)($request, $response, new \Exception('abc'));
68
69 static::assertSame(500, $result->getStatusCode());
70 static::assertSame('Error: abc', $assignedVariables['message']);
71 static::assertContainsPolyfill('Please report it on Github', $assignedVariables['text']);
72 static::assertArrayHasKey('stacktrace', $assignedVariables);
73 }
74
75 /**
76 * Test displaying error with any exception (no debug) while logged out:
77 * display standard error without detail
54 */ 78 */
55 public function testDisplayAnyExceptionErrorNoDebug(): void 79 public function testDisplayAnyExceptionErrorNoDebug(): void
56 { 80 {
@@ -61,10 +85,13 @@ class ErrorControllerTest extends TestCase
61 $assignedVariables = []; 85 $assignedVariables = [];
62 $this->assignTemplateVars($assignedVariables); 86 $this->assignTemplateVars($assignedVariables);
63 87
88 $this->container->loginManager->method('isLoggedIn')->willReturn(false);
89
64 $result = ($this->controller)($request, $response, new \Exception('abc')); 90 $result = ($this->controller)($request, $response, new \Exception('abc'));
65 91
66 static::assertSame(500, $result->getStatusCode()); 92 static::assertSame(500, $result->getStatusCode());
67 static::assertSame('An unexpected error occurred.', $assignedVariables['message']); 93 static::assertSame('An unexpected error occurred.', $assignedVariables['message']);
94 static::assertArrayNotHasKey('text', $assignedVariables);
68 static::assertArrayNotHasKey('stacktrace', $assignedVariables); 95 static::assertArrayNotHasKey('stacktrace', $assignedVariables);
69 } 96 }
70} 97}
diff --git a/tpl/default/error.html b/tpl/default/error.html
index c3e0c3c1..34f9707d 100644
--- a/tpl/default/error.html
+++ b/tpl/default/error.html
@@ -9,13 +9,17 @@
9<div id="pageError" class="page-error-container center"> 9<div id="pageError" class="page-error-container center">
10 <h2>{$message}</h2> 10 <h2>{$message}</h2>
11 11
12 <img src="{$asset_path}/img/sad_star.png#" alt="">
13
14 {if="!empty($text)"}
15 <p>{$text}</p>
16 {/if}
17
12 {if="!empty($stacktrace)"} 18 {if="!empty($stacktrace)"}
13 <pre> 19 <pre>
14 {$stacktrace} 20 {$stacktrace}
15 </pre> 21 </pre>
16 {/if} 22 {/if}
17
18 <img src="{$asset_path}/img/sad_star.png#" alt="">
19</div> 23</div>
20{include="page.footer"} 24{include="page.footer"}
21</body> 25</body>