diff options
Diffstat (limited to 'application')
-rw-r--r-- | application/ApplicationUtils.php | 104 | ||||
-rw-r--r-- | application/LinkDB.php | 20 | ||||
-rw-r--r-- | application/Utils.php | 53 |
3 files changed, 174 insertions, 3 deletions
diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php index b0e94e24..274331e1 100644 --- a/application/ApplicationUtils.php +++ b/application/ApplicationUtils.php | |||
@@ -4,6 +4,110 @@ | |||
4 | */ | 4 | */ |
5 | class ApplicationUtils | 5 | class ApplicationUtils |
6 | { | 6 | { |
7 | private static $GIT_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli'; | ||
8 | private static $GIT_BRANCHES = array('master', 'stable'); | ||
9 | private static $VERSION_FILE = 'shaarli_version.php'; | ||
10 | private static $VERSION_START_TAG = '<?php /* '; | ||
11 | private static $VERSION_END_TAG = ' */ ?>'; | ||
12 | |||
13 | /** | ||
14 | * Gets the latest version code from the Git repository | ||
15 | * | ||
16 | * The code is read from the raw content of the version file on the Git server. | ||
17 | * | ||
18 | * @return mixed the version code from the repository if available, else 'false' | ||
19 | */ | ||
20 | public static function getLatestGitVersionCode($url, $timeout=2) | ||
21 | { | ||
22 | list($headers, $data) = get_http_url($url, $timeout); | ||
23 | |||
24 | if (strpos($headers[0], '200 OK') === false) { | ||
25 | error_log('Failed to retrieve ' . $url); | ||
26 | return false; | ||
27 | } | ||
28 | |||
29 | return str_replace( | ||
30 | array(self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL), | ||
31 | array('', '', ''), | ||
32 | $data | ||
33 | ); | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * Checks if a new Shaarli version has been published on the Git repository | ||
38 | * | ||
39 | * Updates checks are run periodically, according to the following criteria: | ||
40 | * - the update checks are enabled (install, global config); | ||
41 | * - the user is logged in (or this is an open instance); | ||
42 | * - the last check is older than a given interval; | ||
43 | * - the check is non-blocking if the HTTPS connection to Git fails; | ||
44 | * - in case of failure, the update file's modification date is updated, | ||
45 | * to avoid intempestive connection attempts. | ||
46 | * | ||
47 | * @param string $currentVersion the current version code | ||
48 | * @param string $updateFile the file where to store the latest version code | ||
49 | * @param int $checkInterval the minimum interval between update checks (in seconds | ||
50 | * @param bool $enableCheck whether to check for new versions | ||
51 | * @param bool $isLoggedIn whether the user is logged in | ||
52 | * | ||
53 | * @throws Exception an invalid branch has been set for update checks | ||
54 | * | ||
55 | * @return mixed the new version code if available and greater, else 'false' | ||
56 | */ | ||
57 | public static function checkUpdate($currentVersion, | ||
58 | $updateFile, | ||
59 | $checkInterval, | ||
60 | $enableCheck, | ||
61 | $isLoggedIn, | ||
62 | $branch='stable') | ||
63 | { | ||
64 | if (! $isLoggedIn) { | ||
65 | // Do not check versions for visitors | ||
66 | return false; | ||
67 | } | ||
68 | |||
69 | if (empty($enableCheck)) { | ||
70 | // Do not check if the user doesn't want to | ||
71 | return false; | ||
72 | } | ||
73 | |||
74 | if (is_file($updateFile) && (filemtime($updateFile) > time() - $checkInterval)) { | ||
75 | // Shaarli has checked for updates recently - skip HTTP query | ||
76 | $latestKnownVersion = file_get_contents($updateFile); | ||
77 | |||
78 | if (version_compare($latestKnownVersion, $currentVersion) == 1) { | ||
79 | return $latestKnownVersion; | ||
80 | } | ||
81 | return false; | ||
82 | } | ||
83 | |||
84 | if (! in_array($branch, self::$GIT_BRANCHES)) { | ||
85 | throw new Exception( | ||
86 | 'Invalid branch selected for updates: "' . $branch . '"' | ||
87 | ); | ||
88 | } | ||
89 | |||
90 | // Late Static Binding allows overriding within tests | ||
91 | // See http://php.net/manual/en/language.oop5.late-static-bindings.php | ||
92 | $latestVersion = static::getLatestGitVersionCode( | ||
93 | self::$GIT_URL . '/' . $branch . '/' . self::$VERSION_FILE | ||
94 | ); | ||
95 | |||
96 | if (! $latestVersion) { | ||
97 | // Only update the file's modification date | ||
98 | file_put_contents($updateFile, $currentVersion); | ||
99 | return false; | ||
100 | } | ||
101 | |||
102 | // Update the file's content and modification date | ||
103 | file_put_contents($updateFile, $latestVersion); | ||
104 | |||
105 | if (version_compare($latestVersion, $currentVersion) == 1) { | ||
106 | return $latestVersion; | ||
107 | } | ||
108 | |||
109 | return false; | ||
110 | } | ||
7 | 111 | ||
8 | /** | 112 | /** |
9 | * Checks the PHP version to ensure Shaarli can run | 113 | * Checks the PHP version to ensure Shaarli can run |
diff --git a/application/LinkDB.php b/application/LinkDB.php index 15fadbc3..f771ac8b 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php | |||
@@ -57,18 +57,25 @@ class LinkDB implements Iterator, Countable, ArrayAccess | |||
57 | // Hide public links | 57 | // Hide public links |
58 | private $_hidePublicLinks; | 58 | private $_hidePublicLinks; |
59 | 59 | ||
60 | // link redirector set in user settings. | ||
61 | private $_redirector; | ||
62 | |||
60 | /** | 63 | /** |
61 | * Creates a new LinkDB | 64 | * Creates a new LinkDB |
62 | * | 65 | * |
63 | * Checks if the datastore exists; else, attempts to create a dummy one. | 66 | * Checks if the datastore exists; else, attempts to create a dummy one. |
64 | * | 67 | * |
65 | * @param $isLoggedIn is the user logged in? | 68 | * @param string $datastore datastore file path. |
69 | * @param boolean $isLoggedIn is the user logged in? | ||
70 | * @param boolean $hidePublicLinks if true all links are private. | ||
71 | * @param string $redirector link redirector set in user settings. | ||
66 | */ | 72 | */ |
67 | function __construct($datastore, $isLoggedIn, $hidePublicLinks) | 73 | function __construct($datastore, $isLoggedIn, $hidePublicLinks, $redirector = '') |
68 | { | 74 | { |
69 | $this->_datastore = $datastore; | 75 | $this->_datastore = $datastore; |
70 | $this->_loggedIn = $isLoggedIn; | 76 | $this->_loggedIn = $isLoggedIn; |
71 | $this->_hidePublicLinks = $hidePublicLinks; | 77 | $this->_hidePublicLinks = $hidePublicLinks; |
78 | $this->_redirector = $redirector; | ||
72 | $this->_checkDB(); | 79 | $this->_checkDB(); |
73 | $this->_readDB(); | 80 | $this->_readDB(); |
74 | } | 81 | } |
@@ -259,7 +266,14 @@ You use the community supported version of the original Shaarli project, by Seba | |||
259 | 266 | ||
260 | // Escape links data | 267 | // Escape links data |
261 | foreach($this->_links as &$link) { | 268 | foreach($this->_links as &$link) { |
262 | sanitizeLink($link); | 269 | sanitizeLink($link); |
270 | // Do not use the redirector for internal links (Shaarli note URL starting with a '?'). | ||
271 | if (!empty($this->_redirector) && !startsWith($link['url'], '?')) { | ||
272 | $link['real_url'] = $this->_redirector . urlencode($link['url']); | ||
273 | } | ||
274 | else { | ||
275 | $link['real_url'] = $link['url']; | ||
276 | } | ||
263 | } | 277 | } |
264 | } | 278 | } |
265 | 279 | ||
diff --git a/application/Utils.php b/application/Utils.php index b8579b48..f84f70e4 100644 --- a/application/Utils.php +++ b/application/Utils.php | |||
@@ -148,3 +148,56 @@ function is_session_id_valid($sessionId) | |||
148 | 148 | ||
149 | return true; | 149 | return true; |
150 | } | 150 | } |
151 | |||
152 | /** | ||
153 | * In a string, converts URLs to clickable links. | ||
154 | * | ||
155 | * @param string $text input string. | ||
156 | * @param string $redirector if a redirector is set, use it to gerenate links. | ||
157 | * | ||
158 | * @return string returns $text with all links converted to HTML links. | ||
159 | * | ||
160 | * @see Function inspired from http://www.php.net/manual/en/function.preg-replace.php#85722 | ||
161 | */ | ||
162 | function text2clickable($text, $redirector) | ||
163 | { | ||
164 | $regex = '!(((?:https?|ftp|file)://|apt:|magnet:)\S+[[:alnum:]]/?)!si'; | ||
165 | |||
166 | if (empty($redirector)) { | ||
167 | return preg_replace($regex, '<a href="$1">$1</a>', $text); | ||
168 | } | ||
169 | // Redirector is set, urlencode the final URL. | ||
170 | return preg_replace_callback( | ||
171 | $regex, | ||
172 | function ($matches) use ($redirector) { | ||
173 | return '<a href="' . $redirector . urlencode($matches[1]) .'">'. $matches[1] .'</a>'; | ||
174 | }, | ||
175 | $text | ||
176 | ); | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * This function inserts where relevant so that multiple spaces are properly displayed in HTML | ||
181 | * even in the absence of <pre> (This is used in description to keep text formatting). | ||
182 | * | ||
183 | * @param string $text input text. | ||
184 | * | ||
185 | * @return string formatted text. | ||
186 | */ | ||
187 | function space2nbsp($text) | ||
188 | { | ||
189 | return preg_replace('/(^| ) /m', '$1 ', $text); | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * Format Shaarli's description | ||
194 | * TODO: Move me to ApplicationUtils when it's ready. | ||
195 | * | ||
196 | * @param string $description shaare's description. | ||
197 | * @param string $redirector if a redirector is set, use it to gerenate links. | ||
198 | * | ||
199 | * @return string formatted description. | ||
200 | */ | ||
201 | function format_description($description, $redirector) { | ||
202 | return nl2br(space2nbsp(text2clickable($description, $redirector))); | ||
203 | } | ||