Compare commits

...

817 commits

Author SHA1 Message Date
59416eec4d Merge remote-tracking branch 'github/v0.13' into myShaarli_commu 2024-06-20 17:25:16 +02:00
ArthurHoaro
df121586c1
Bump Shaarli version to v0.13.0
Signed-off-by: ArthurHoaro <arthur@hoa.ro>
2023-11-22 10:53:18 -05:00
ArthurHoaro
00a9ddd013
Changelog v0.13.0 + authors (#2040) 2023-11-22 10:47:58 -05:00
ArthurHoaro
326870f216
Fix XSS vulnerability in tag search (#2039)
It affect the title tag of the bookmark list page.
Fixes shaarli/Shaarli#2038
2023-11-22 10:29:30 -05:00
nodiscc
ca07f265f1
Merge pull request #2037 from nodiscc/doc-title-retrieval-limitations
doc: troubleshooting: automatic title retrieval fails when it is set by javascript
2023-11-15 15:52:26 +00:00
nodiscc
4557abb981
Merge pull request #2036 from nodiscc/doc-general-download-timeout-max-size
doc: document general.download_max_size/timeout configuration settings
2023-11-15 15:51:58 +00:00
nodiscc
c88bc1d760
Merge pull request #2035 from nodiscc/doc-rm-bountysource
doc: remove bountysource badge
2023-11-15 15:51:33 +00:00
nodiscc
bd3e71cacb
doc: automatic title retrieval fails when it is set by javascript
- related https://github.com/shaarli/Shaarli/issues/531
- fixes https://github.com/shaarli/Shaarli/issues/989
2023-11-15 16:04:39 +01:00
nodiscc
1697e7a4bd
doc: document general.download_max_size/timeout configuration settings
- fixes https://github.com/shaarli/Shaarli/issues/2034
2023-11-15 15:56:30 +01:00
nodiscc
db71d2fcd4
doc: remove bountysource badge
- fixes https://github.com/shaarli/Shaarli/issues/2033
2023-11-15 15:50:33 +01:00
nodiscc
2caa586a4d
Merge pull request #2030 from nodiscc/doc-cleanup-3rdparty
doc: themes: remove unmaintained themes
2023-11-04 14:31:49 +00:00
nodiscc
c60a42890b
doc: themes: remove unmaintained theme shaarli-blocks
- Attention: This theme will no longer be updated
- unmaintained since 2015
2023-11-02 16:40:51 +01:00
nodiscc
beb683e463
doc: themes: remove unmaintained theme dhoko/ShaarliTemplate
- unmaintained since 2014, shaarli 0.0.45
2023-11-02 16:40:10 +01:00
nodiscc
408b7e7d0a
doc: themes: remove unmaintained theme shaarli-launch
-  This repository has been archived by the owner on Aug 16, 2018. It is now read-only.
- This theme is no longer maintained and won't get any support or update.
2023-11-02 16:38:40 +01:00
nodiscc
646f63e413
doc: themes: remove incompatible albinomouse theme
- not compatible with shaarli >=0.9 https://github.com/alexisju/albinomouse-template/issues/9
2023-11-02 16:37:57 +01:00
nodiscc
a98553b601
doc: themes: remove unmaintained superhero theme
-  This repository has been archived by the owner on Oct 28, 2019. It is now read-only.
2023-11-02 16:36:46 +01:00
nodiscc
2ef90ec791
Merge pull request #2028 from dajare/add-stack-theme
Add shaarli-stack theme to Community-and-related-software.md
2023-11-01 17:33:17 +00:00
David
0222e62ea4
Add shaarli-stack theme to Community-and-related-software.md 2023-11-01 15:02:47 +00:00
nodiscc
5b21103d76
Merge pull request #2027 from shaarli/dependabot/npm_and_yarn/browserify-sign-4.2.2
build(deps): bump browserify-sign from 4.2.1 to 4.2.2
2023-10-27 14:03:16 +00:00
dependabot[bot]
728169f185
build(deps): bump browserify-sign from 4.2.1 to 4.2.2
Bumps [browserify-sign](https://github.com/crypto-browserify/browserify-sign) from 4.2.1 to 4.2.2.
- [Changelog](https://github.com/browserify/browserify-sign/blob/main/CHANGELOG.md)
- [Commits](https://github.com/crypto-browserify/browserify-sign/compare/v4.2.1...v4.2.2)

---
updated-dependencies:
- dependency-name: browserify-sign
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-27 13:31:57 +00:00
nodiscc
78f7a338c1
Merge pull request #2026 from shaarli/dependabot/npm_and_yarn/babel/traverse-7.23.2
build(deps): bump @babel/traverse from 7.14.0 to 7.23.2
2023-10-17 09:48:01 +00:00
dependabot[bot]
bfdbb62cd1
build(deps): bump @babel/traverse from 7.14.0 to 7.23.2
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.14.0 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 03:49:22 +00:00
nodiscc
ba21aa60d9
Merge pull request #2025 from nodiscc/doc-sphinx
replace mkdocs with sphinx/myst-parser for HTML documentation generation, documentation improvements
2023-10-15 16:16:49 +00:00
nodiscc
484ee2bbb0
tool/.gitattributes: exclude doc/html/.doctrees/ from zip exports
- https://www.sphinx-doc.org/en/master/man/sphinx-build.html#cmdoption-sphinx-build-d
- https://stackoverflow.com/questions/33904042/is-doctrees-folder-required-for-displaying-html-docs-with-sphinx
2023-10-06 12:33:01 +02:00
nodiscc
e5545436b0
doc: development/release procedure: version number must be bumped in doc/conf.py and README.mdn as well 2023-10-05 15:28:22 +02:00
nodiscc
00db4f6bcc
doc: update external links based on redirects, fix/remove dead links
- checked with python -m sphinx -b linkcheck -c doc doc/md doc/linkcheck
2023-10-05 15:02:00 +02:00
nodiscc
e7a2d06a63
doc: server configuration: standardize whitespace/newlines 2023-10-05 15:01:56 +02:00
nodiscc
00ccae495c
doc: server configuration: update apache configuration, use php-fpm
- remove apache 2.2 configuration (2.4 was released in 2012)
2023-10-05 15:01:56 +02:00
nodiscc
1e7419eca9
doc: server configuration: replace fireHOL (unmaintained) with firewalld 2023-10-05 15:01:50 +02:00
nodiscc
2a88f7a526
doc: index: remove inline icon 2023-10-05 15:01:50 +02:00
nodiscc
8d3e224936
doc: index: remove a screenshot thumbnail so that all thumbnails fit on one line 2023-10-05 15:01:43 +02:00
nodiscc
4e653e1e97
tools/github actions: use makefile/sphinx instead of mkdocs to build HTML documentation 2023-10-05 15:01:43 +02:00
nodiscc
00264cb4a1
doc: community & related software: remove unmaintained shaarli forks (since 2014/2015) 2023-10-05 15:01:43 +02:00
nodiscc
ee5ee294b2
doc: server configuration: remove outdated screencast
- ref. https://github.com/shaarli/Shaarli/issues/2002
- uses old instructions/mod-php instead of the now recommended php-fpm
- server configuration may not be the ideal page for this, installation would be more suitable
2023-10-05 15:01:43 +02:00
nodiscc
81cfed8be4
doc: use relative links when possible 2023-10-05 15:01:42 +02:00
nodiscc
0992c86f16
doc: add missing h1 heading to Usage.md 2023-10-05 15:01:42 +02:00
nodiscc
256cffb289
doc: fix typo 2023-10-05 15:01:42 +02:00
nodiscc
62552cc413
doc: development: standardize hooks documentation, use less headings 2023-10-05 15:01:42 +02:00
nodiscc
a4b3430078
doc: fix link to translations documentation 2023-10-05 15:01:42 +02:00
nodiscc
5dd9bc93e1
doc: fix syntax highlighting in code blocks
- remove json syntax highlighting from invalid json block
- fix warning about unknown lexer `conf`
- fix syntax highlighting for example htaccess
2023-10-05 15:01:42 +02:00
nodiscc
9230af464d
doc: group all development-releated documentation under a single Development page
- add the Development page to the main TOC
2023-10-05 15:01:42 +02:00
nodiscc
b7719cdf0a
doc: plugin system: fix links to anchors 2023-10-05 15:01:41 +02:00
nodiscc
db1532214e
replace mkdocs with sphinx/myst-parser for HTML documentation generation
- fixes https://github.com/shaarli/Shaarli/issues/1451
- tools/.gitattributes: exclude doc/conf.py and doc/requirements.txt from zip exports
- tools/doc/sphinx: suppress myst.xref_missing warnings caused by https://github.com/executablebooks/MyST-Parser/issues/564
- dockerfile: use makefile/sphinx instead of mkdocs to build HTML documentation
- dockerfile: add bash to the docs build container (make: bash: No such file or directory)
- tools/doc/readthedocs: force use of python 3.11 (readthedocs ERROR: No matching distribution found for sphinx==7.1.0)
- tools/doc/readthedocs: add all required configuration variables https://docs.readthedocs.io/en/latest/config-file/v2.html#build-os
- tools/doc/readthedocs: override build commands to allow the source directory to be different from the conf.py directory (https://docs.readthedocs.io/en/stable/config-file/v2.html#build-commands, https://github.com/readthedocs/readthedocs.org/issues/1543)
- tools/doc/readthedocs: manually set output directory (readthedocs ERROR: No _readthedocs/html folder was created during this build.)
- doc: replace all references to mkdocs with sphinx
2023-10-05 15:01:34 +02:00
nodiscc
c4d3e2d7ec
Merge pull request #2024 from nodiscc/update-alpine-3.16
docker: update base alpine docker image to 3.16.7
2023-10-03 16:46:44 +00:00
nodiscc
5db074fdef
docker: update base alpine docker image to 3.16.7
- the previous (0.12.2) release image was based on 3.16.4 since the .patch version was not specified, which shows vulnerabilities when scanned with trivy (https://github.com/shaarli/Shaarli/pull/2019)
2023-10-03 18:43:25 +02:00
nodiscc
ea3cda543c
Merge pull request #2021 from shaarli/doc-php8.2-compat
doc: server configuration: add PHP 8.2 to PHP compatibility table
2023-09-25 15:06:08 +00:00
nodiscc
280e6138fc
Merge pull request #2003 from nodiscc/doc-hyphens
correct usage of hyphens in all occurences of 'super fast, database-free'
2023-09-25 14:57:55 +00:00
nodiscc
4b94854200
doc: server configuration: add PHP 8.2 to PHP compatibility table
- Tested with php-fpm 8.2.7-1~deb12u1 on Debian 12
- ref. https://github.com/shaarli/Shaarli/issues/2020
2023-09-21 12:48:23 +00:00
nodiscc
775fcb44f9
Merge pull request #2018 from nodiscc/doc-debian-package
doc: community/related software/integration with other platforms: add link to shaarli debian package
2023-09-08 19:43:19 +00:00
nodiscc
25d2a9b744
doc: community/related software/integration with other platforms: add link to shaarli debian package
- fixes https://github.com/shaarli/shaarli-pkg-debian/issues/8
- https://github.com/shaarli/shaarli-pkg-debian is unmaintained, please use downstream packaging repo at https://salsa.debian.org/php-team/pear/shaarli
- https://github.com/shaarli/shaarli-pkg-debian will be archived after this PR is merged
2023-08-27 15:59:39 +02:00
nodiscc
572c55f0b1
Merge pull request #2015 from nodiscc/doc-fix-mkdocs-warnings
doc: fix mkdocs build warnings/relative links
2023-08-20 21:18:28 +00:00
nodiscc
add670b8ab
doc: fix mkdocs build warnings/relative links
INFO    -  Cleaning site directory
INFO    -  Building documentation to directory: /home/live/GIT/Shaarli/doc/html
INFO    -  Doc file 'index.md' contains an unrecognized relative link 'Usage#tag-cloud', it was left
           as is. Did you mean 'Usage.md#tag-cloud'?
INFO    -  Doc file 'index.md' contains an unrecognized relative link 'Usage#picture-wall', it was
           left as is. Did you mean 'Usage.md#picture-wall'?
INFO    -  Doc file 'index.md' contains an unrecognized relative link 'Usage#import-export', it was
           left as is. Did you mean 'Usage.md#import-export'?
INFO    -  Doc file 'Community-and-related-software.md' contains an unrecognized relative link
           'REST-API', it was left as is. Did you mean 'REST-API.md'?
INFO    -  Doc file 'Community-and-related-software.md' contains an unrecognized relative link
           'Theming', it was left as is.
INFO    -  Doc file 'Installation.md' contains an unrecognized relative link
           'dev/Development#third-party-libraries', it was left as is. Did you mean
           'dev/Development.md#third-party-libraries'?
INFO    -  Doc file 'Installation.md' contains an unrecognized relative link
           'Upgrade-and-migration', it was left as is. Did you mean 'Upgrade-and-migration.md'?
INFO    -  Doc file 'Plugins.md' contains an unrecognized relative link 'Shaarli-configuration', it
           was left as is. Did you mean 'Shaarli-configuration.md'?
INFO    -  Doc file 'REST-API.md' contains an unrecognized relative link 'Server-configuration', it
           was left as is. Did you mean 'Server-configuration.md'?
INFO    -  Doc file 'Reverse-proxy.md' contains an unrecognized relative link
           'Shaarli-configuration', it was left as is. Did you mean 'Shaarli-configuration.md'?
INFO    -  Doc file 'Server-configuration.md' contains an unrecognized relative link
           'Directory-structure', it was left as is.
INFO    -  Doc file 'Shaarli-configuration.md' contains an unrecognized relative link
           'Translations', it was left as is.
INFO    -  Doc file 'dev/Development.md' contains an unrecognized relative link 'Unit-tests', it was
           left as is. Did you mean 'Unit-tests.md'?
INFO    -  Doc file 'dev/Development.md' contains an unrecognized relative link 'GnuPG-signature',
           it was left as is. Did you mean 'GnuPG-signature.md'?
INFO    -  Doc file 'dev/GnuPG-signature.md' contains an unrecognized relative link 'Release
           Shaarli', it was left as is.
INFO    -  Doc file 'dev/Theming.md' contains an unrecognized relative link 'Shaarli-configuration',
           it was left as is.
INFO    -  Doc file 'dev/Translations.md' contains an unrecognized relative link 'Theming', it was
           left as is. Did you mean 'Theming.md'?
INFO    -  Documentation built in 0.40 seconds
2023-08-20 23:13:59 +02:00
nodiscc
5a6515c988
Merge pull request #2014 from nodiscc/build-docker-pr
tools: github actions: build docker images on pull requests
2023-08-19 11:48:29 +00:00
nodiscc
ea57088177
tools: github actions: build docker images on pull requests
- fixes https://github.com/shaarli/Shaarli/issues/1800
- do not push, only check that the image builds correctly
- tag the image as :pr-PR_NUMBER
2023-08-19 13:44:58 +02:00
nodiscc
638a7c5141
Merge pull request #2012 from nodiscc/update-trivy
tools/tests: update trivy to v0.44.0
2023-08-01 13:22:05 +00:00
nodiscc
c937d3e184
tools/tests: update trivy to v0.44.0
- https://github.com/aquasecurity/trivy/releases/tag/v0.44.0
2023-08-01 15:10:57 +02:00
nodiscc
4cbba2fe64
Merge pull request #2010 from shaarli/dependabot/npm_and_yarn/word-wrap-1.2.4
build(deps): bump word-wrap from 1.2.3 to 1.2.4
2023-07-19 13:47:28 +00:00
dependabot[bot]
949e03ca1f
build(deps): bump word-wrap from 1.2.3 to 1.2.4
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-19 00:03:56 +00:00
nodiscc
e91984b507
Merge pull request #2008 from clach04/patch-1
Doc update, WebSub (formerly PubSubHubbub) plugin
2023-07-15 12:31:18 +00:00
clach04
f812581234
Doc update, WebSub (formerly PubSubHubbub) plugin
Clarify old and new name along with Wikipedia link.
2023-07-15 02:11:57 -07:00
nodiscc
5af1c9dbae
Merge pull request #2006 from shaarli/dependabot/npm_and_yarn/semver-5.7.2
build(deps): bump semver from 5.7.1 to 5.7.2
2023-07-11 11:00:35 +00:00
nodiscc
e7ff18c864
Merge pull request #2005 from nodiscc/update-trivy
tools/Makefile: update trivy to v0.43.1
2023-07-11 10:53:05 +00:00
dependabot[bot]
66982b6f79
build(deps): bump semver from 5.7.1 to 5.7.2
Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-11 03:32:45 +00:00
nodiscc
6d16b6c8a8
tools/Makefile: update trivy to v0.43.1
è https://github.com/aquasecurity/trivy/releases/tag/v0.43.1
2023-07-08 21:18:37 +02:00
nodiscc
910b695d4d
correct usage of hyphens in all occurences of 'super fast, database-free'
- fixes https://github.com/shaarli/Shaarli/issues/1758
2023-07-06 18:57:22 +02:00
nodiscc
d24fc65695
Merge pull request #1998 from nodiscc/trivy-repo-scan
tools/CI: scan repository with trivy security scanner (yarn.lock, composer.lock)
2023-07-06 16:37:13 +00:00
Amadeous
c44a0d200d
Expose tags_separator config through /info API (#1997) 2023-06-30 22:15:41 +00:00
Alistair Young
9fd6739a1f
docker: nginx: listen on IPv6 in addition to IPv4 (#1983) 2023-06-30 22:08:02 +00:00
nodiscc
3b5923b7e1
tools/CI: scan repository with trivy security scanner (yarn.lock, composer.lock)
- run scan on each push/pull request update
- can be run locally using make test_trivy_repo
- exit with error code 0/success when vulnerabilities are found,  as not to make the workflow fail, a separate periodic run that exits with code 1 should be added in parallel
- update trivy to v0.43.0
- https://github.com/aquasecurity/trivy/releases/tag/v0.43.0
- also consider TRIVY_EXIT_CODE when running trivy on the latest docker image
- ref. https://github.com/shaarli/Shaarli/issues/1531
2023-06-30 23:56:09 +02:00
nodiscc
467b28c237
Merge pull request #1989 from nodiscc/trivy-fix-target-docker-image
gihub actions: fix value of TRIVY_TARGET_DOCKER_IMAGE
2023-05-21 19:10:36 +00:00
nodiscc
0eee6a2ba1
gihub actions: fix value of TRIVY_TARGET_DOCKER_IMAGE
- fixes Error response from daemon: no such image: ghcr.io/***:trivy: No such image: ghcr.io/***:trivy
- introduced in https://github.com/shaarli/Shaarli/pull/1980 but the test target branch/tag was never reverted to 'latest'
2023-05-21 21:08:36 +02:00
nodiscc
27db81ab07
Merge pull request #1987 from nodiscc/doc-or-operator
doc: improve docs on usage of OR operator in tags search
2023-05-21 18:30:57 +00:00
nodiscc
f64b4666ea
Merge pull request #1980 from nodiscc/trivy
tools: run trivy vulnerability scanner on the 'latest' docker image
2023-05-21 18:29:11 +00:00
nodiscc
a1c6460077
doc: improve docs on usage of OR operator in tags search
- fixes https://github.com/shaarli/Shaarli/issues/1982
2023-05-21 20:27:12 +02:00
nodiscc
a8c7c5c4bf
Merge pull request #1984 from nlegaillart/patch-1
Update Community-and-related-software.md
2023-05-21 18:24:44 +00:00
Nicolas Le Gaillart
eb340c7eb6
Update Community-and-related-software.md
Hi, here are my two little plugins for Shaarli.
2023-05-17 22:33:36 +02:00
nodiscc
22b4044986
tools/github actions: revert temporary changes used for trivy tests on fork/branch 2023-05-02 12:27:49 +02:00
nodiscc
d48e06f438
run trivy vulnerability scanner on the 'latest' docker image
- run trivy from makefile so that it can be run both locally and through github actions
- usage: make test_trivy TRIVY_TARGET_DOCKER_IMAGE=regist.ry/user/image:tag
- tested by downgrading the base image to alpine 3.15.7 and verifying that vulnerabilities are reported (https://github.com/nodiscc/Shaarli/actions/runs/4860040980/jobs/8663400103)
- TEMP/TESTING only push image to ghcr.io, run trivy on trivy branch/docker tag as well as master
- ref. https://github.com/shaarli/Shaarli/issues/1531
2023-05-02 12:24:50 +02:00
ArthurHoaro
88b76c44f7
Fix autofocus: load bulk action input on linklist only (#1976) 2023-04-15 12:46:09 -04:00
ArthurHoaro
1cd642619f
Documentation: fix broken link to 3rd party plugins (#1975) 2023-04-15 12:01:50 -04:00
Gregory
5f69e17310
Update Server-configuration.md (#1973) 2023-04-15 09:02:48 -04:00
ArthurHoaro
e0a8f961ba
Support: ignore disk_free_space if the function is unavailable (#1970) 2023-04-08 10:10:29 -04:00
bschwede
739776a754
Update german translation (#1969) 2023-04-08 15:26:27 +02:00
nodiscc
08d9347e9a
Merge pull request #1958 from ArthurHoaro/php-drop-7.3-and-less
Drop support for PHP 7.1, 7.2 and 7.3
2023-04-03 15:43:07 +00:00
ArthurHoaro
050bb50cdf
Update compatibility matrix 2023-03-25 09:42:42 -04:00
ArthurHoaro
ef9d019ccd
Docker build: add ARM64 platform and bump Github action version (#1965) 2023-03-25 09:35:58 -04:00
nodiscc
a7e361e22a
Merge pull request #1962 from nodiscc/docker-armv7
github actions: build OCI images that contain both amd64 and armv7
2023-03-21 17:22:24 +00:00
nodiscc
9a1ad45e90
remove ununsed Dockerfile.armhf 2023-03-21 18:18:12 +01:00
nodiscc
fd4379992d
github actions: build OCI images that contin both amd64 and armv7
- ref. https://docs.docker.com/engine/reference/commandline/buildx_build/#platform
- ref. https://docs.docker.com/build/ci/github-actions/multi-platform/
- replaces https://github.com/shaarli/Shaarli/pull/1496
- make docker image name configurable through CI variables for easier testing
2023-03-21 18:10:37 +01:00
nodiscc
9c9d6298bf
Merge pull request #1960 from nodiscc/doc-updte-release-branch
doc: update release procedure (merge the latest release to the release branch) + use the release branch for latest release version detection
2023-03-20 17:23:34 +00:00
nodiscc
625235787e
admin/server: use the 'release' branch as reference for latest release version number detection
- ref. https://github.com/shaarli/Shaarli/issues/1961
2023-03-20 18:17:13 +01:00
nodiscc
062698c123
doc: update release procedure (merge the latest release to the release branch)
- ref. https://github.com/shaarli/Shaarli/pull/1959
2023-03-20 18:08:02 +01:00
ArthurHoaro
0a47d89193 Drop support for PHP 7.1, 7.2 and 7.3
This commit doesn't yet enforce the new requirement since previous version will continue to work for a short while.
2023-03-18 14:27:41 -04:00
ArthurHoaro
6624f00c05
Makefile: Use GNU tar if available (#1957) 2023-03-18 14:03:34 -04:00
ArthurHoaro
c0c743f9c6 Bump badge version 2023-03-18 13:41:03 -04:00
ArthurHoaro
9e24bb317c
Changelog v0.12.2 (#1956) 2023-03-18 13:24:16 -04:00
ArthurHoaro
ebe9417981
Rename authors makefile target to avoid conflicts with filename (#1955) 2023-03-18 13:19:37 -04:00
ArthurHoaro
8cd369aee7
Fix Logger exception: gracefully handle permission issue (#1954) 2023-03-18 12:13:48 -04:00
ArthurHoaro
b858332f9f
Fix a bug when using '/' as a tag separator (#1953) 2023-03-18 11:59:00 -04:00
ArthurHoaro
8457001294
Do not display deprecated warnings by default (#1952) 2023-03-18 11:01:33 -04:00
nodiscc
f15ac5957a
Merge pull request #1951 from nodiscc/doc-ghcrio
doc: move OCI images hosting to ghcr.io
2023-03-18 14:10:28 +00:00
nodiscc
721c090198
doc: move OCI images hosting to ghcr.io
- dockerhub free team accounts will be deleted in < 30 days (https://www.docker.com/blog/we-apologize-we-did-a-terrible-job-announcing-the-end-of-docker-free-teams/), this affects the Shaarli team account
- automated builds will keep pushing latest builds to dockerhub in addition to gchr.io, until the account is deleted
- **users relying on `shaarli/shaarli` OCI images are advised to migrate to `ghcr.io/shaarli/shaarli` as soon as possible**
- existing tagged images have been copied from https://hub.docker.com/r/shaarli/shaarli/ to https://github.com/shaarli/Shaarli/pkgs/container/shaarli/versions?filters%5Bversion_type%5D=tagged
- prepend `ghcr.io/` to all references to OCI images
- update all references to dockerhub -> github packages registry, update developer documentation, cleanup dead links
- ref. https://github.com/shaarli/Shaarli/issues/1948
2023-03-17 16:17:37 +01:00
nodiscc
9195ce0378
Merge pull request #1950 from nodiscc/tests-php-8.2
github actions: add tests for PHP 8.2
2023-03-17 14:37:26 +00:00
nodiscc
4b88cbb56c
Merge pull request #1945 from nodiscc/docker-latest-replace-dev-with-hash
docker: latest: replace dev in shaarli_version.php with the latest commit hash
2023-03-17 14:20:58 +00:00
nodiscc
e4ee672404
github actions: add tests for PHP 8.2
- ref. https://github.com/shaarli/Shaarli/pull/1928
2023-03-17 15:11:08 +01:00
nodiscc
169755c6a9
docker: latest: replace dev in shaarli_version.php with the latest commit hash
- fixes https://github.com/shaarli/Shaarli/issues/1676
- testing was successful using docker run --entrypoint /bin/cat nodiscc/shaarli:latest shaarli/shaarli_version.php (returns <?php /* c4a5ef5 */ ?>)
2023-03-17 15:04:38 +01:00
Denis Renning
4c76d4eea9
Github actions: update node (#1928)
* update Node dependent actions
* doc: update compatibility table

Co-authored-by: William Desportes <williamdes@wdes.fr>
Co-authored-by: nodiscc <nodiscc@gmail.com>
2023-03-17 01:22:20 +00:00
nodiscc
99485504d0
Merge pull request #1949 from hydrargyrum/master
ci: push container images to github registry in addition to dockerhub
2023-03-17 01:15:26 +00:00
Hg
cc2ea94d06 ci: push container images to github registry in addition to dockerhub
it's good to have multiple container registries, in case one decides to not
be welcoming anymore to open-source projects
2023-03-16 21:30:43 +01:00
nodiscc
1222aa62c5
Merge pull request #1947 from shaarli/fix-vintage-visibility-link
template/vintage: fix typo in visibility selection link
2023-03-15 01:31:30 +00:00
nodiscc
50c27108c7
template/vintage: fix typo in visibility selection link
- fixes https://github.com/shaarli/Shaarli/issues/1946
2023-03-15 01:29:23 +00:00
nodiscc
0d70e5e44f
Merge pull request #1938 from nodiscc/doc-proxy-timeout
doc: troubleshooting: add note to adjust proxy timeouts or PHP max execution time if encountering timeouts
2023-03-01 14:15:41 +00:00
nodiscc
a9acad9e1a
doc: troubleshooting: add note to adjust proxy timeouts or PHP max execution time if encountering timeouts
- fixes https://github.com/shaarli/Shaarli/issues/1910
- fixes https://github.com/shaarli/Shaarli/issues/1854
2023-02-19 15:29:56 +01:00
nodiscc
f3316d707a
Merge pull request #1939 from nodiscc/fix-php8-tests
tools: github actions: fix PHP 8.0 tests
2023-02-19 15:28:51 +01:00
nodiscc
b9938cf084
tools: github actions: fix PHP 8.0 tests
- `--ignore-platform-req=php` is no longer needed
- fixes https://github.com/shaarli/Shaarli/issues/1933
2023-01-31 14:39:30 +01:00
nodiscc
8226308d67
Merge pull request #1936 from kcaran/upstream
1932: Fixed Roboto-Regular and Roboto-Bold font declarations
2023-01-29 23:26:22 +00:00
nodiscc
1ba35135a1
Merge pull request #1937 from shaarli/doc-file-uris
doc: shaarli configuration: mention file:/// URIs
2023-01-29 23:26:04 +00:00
nodiscc
de895c73b7
doc: shaarli configuration: mention file:/// URIs
fixes https://github.com/shaarli/Shaarli/issues/1906
2023-01-29 23:17:48 +00:00
Keith Carangelo
3c39cea735 1932: Fixed Roboto-Regular and Roboto-Bold font declarations 2023-01-25 09:30:28 -05:00
nodiscc
ab16f6a826
Merge pull request #1931 from shaarli/dependabot/npm_and_yarn/json5-1.0.2
build(deps): bump json5 from 1.0.1 to 1.0.2
2023-01-20 20:15:05 +00:00
dependabot[bot]
c0ace02c3a
build(deps): bump json5 from 1.0.1 to 1.0.2
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-07 04:07:05 +00:00
Sebastien Wains
6d4e397805
Add mention to Shaarli Archiver (#1926) 2022-12-24 07:23:54 -05:00
locness3
965f8948ee
Fix formatting of v0.9.0 changelog (#1927) 2022-12-24 07:21:59 -05:00
nodiscc
bc470ef8c7
doc: PHP extensions are also required for development (#1922) 2022-12-24 07:21:11 -05:00
dependabot[bot]
ff4d8b5198
build(deps): bump decode-uri-component from 0.2.0 to 0.2.2 (#1920)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-24 07:20:02 -05:00
nodiscc
8f8abf2025
Merge pull request #1921 from shaarli/doc-bulk-creation
doc: usage.md: add note about batch/bulk creation operation
2022-12-04 12:06:10 +00:00
nodiscc
7bcf4255a7
doc: usage.md: add note about batch/bulk creation operation
added in https://github.com/shaarli/Shaarli/pull/1587
2022-12-04 13:02:07 +01:00
Keith Carangelo
733b40446e
Ensure tags are unique when adding and deleting them from bookmarks. (#1918)
* Ensure tags are unique when adding and deleting them from bookmarks.

* Fixed PHPCS issues with test script
2022-12-01 02:47:10 +01:00
ArthurHoaro
e957f8fb23
fix: bulk tag action - wrong controller name (#1917) 2022-11-30 12:49:28 -05:00
ArthurHoaro
c971344ddb
Fix ReadItLater checkbox label on bulk add (#1916)
* Fix ReadItLater checkbox label on bulk add

Adds a random string to the HTML ID so it can be unique in batch more,
where there are multiple checkboxes.

* Fix PHPUnit compatibility polyfill
2022-11-26 10:39:35 -05:00
nodiscc
f28b9d550e
docker: install php8-ldap in Docker images (#1914)
- fixes #1890
2022-11-26 08:58:21 -05:00
ArthurHoaro
00cce1f8c7
Bulk action: add or delete tag to multiple bookmarks (#1898) 2022-11-26 08:58:12 -05:00
ArthurHoaro
cd618bd8be
PubSubHub Plugin: make 1 external call per request (#1877)
On bulk operations, this plugin heavily impacts performances because it make 1 external request
per link saved. Add a simple limit to only make one call per request.
2022-11-26 08:57:59 -05:00
ArthurHoaro
84b37c7baa
Add an additional free disk space check before saving the datastore (#1913)
Fixes https://github.com/shaarli/Shaarli/issues/1810
2022-11-25 17:23:43 +01:00
ArthurHoaro
4242f6955a
Fix PHP 8 incompatibility with debug mode enabled (#1915) 2022-11-25 17:16:09 +01:00
nodiscc
611b794034
Merge pull request #1909 from heimpogo/patch-1
Fix mishandling of Shaare term
2022-11-20 15:13:10 +00:00
nodiscc
5abf19faf2
Merge pull request #1905 from philipp-r/autocapitalize
autocapitalize off for the username input
2022-11-20 15:12:55 +00:00
nodiscc
ac8966566e
Merge pull request #1912 from shaarli/dependabot/npm_and_yarn/minimatch-3.1.2
build(deps): bump minimatch from 3.0.4 to 3.1.2
2022-11-17 17:31:58 +00:00
dependabot[bot]
0a058bba45
build(deps): bump minimatch from 3.0.4 to 3.1.2
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-17 15:49:49 +00:00
nodiscc
864e0bf775
Merge pull request #1908 from shaarli/dependabot/npm_and_yarn/loader-utils-1.4.2
build(deps): bump loader-utils from 1.4.1 to 1.4.2
2022-11-17 15:48:39 +00:00
heimpogo
75e659e3a2
Fix mishandling of Shaare term
"Shaare" is used as a verb and as a noun. In the "shaare"/"shaares"-Keys this was mixed up. The Share term *is* used in the Translation. So there is no need to work around it.
2022-11-16 10:40:12 +01:00
dependabot[bot]
15fb1bdeef
build(deps): bump loader-utils from 1.4.1 to 1.4.2
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.2/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-15 22:18:07 +00:00
nodiscc
89a945a1c9
Merge pull request #1907 from shaarli/dependabot/npm_and_yarn/loader-utils-1.4.1
build(deps): bump loader-utils from 1.4.0 to 1.4.1
2022-11-08 23:00:00 +00:00
dependabot[bot]
bd0d639c60
build(deps): bump loader-utils from 1.4.0 to 1.4.1
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.1/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.1)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-08 00:46:52 +00:00
philipp
75fe26dbdb autocapitalize off for username input 2022-11-06 18:24:40 +01:00
nodiscc
a54795f8eb
Merge pull request #1876 from ArthurHoaro/doc/apache-docs
doc(apache2): allow access to local docs folder
2022-10-14 15:52:37 +00:00
nodiscc
6775e2a2af
Merge pull request #1896 from ArthurHoaro/fix/translate-test
Fix translate Makefile target
2022-10-09 19:08:19 +00:00
ArthurHoaro
a265865124 Fix translate Makefile target
The syntax was invalid and this target was not actually doing anything
(it probably worked at some point in another context).

This change make sure that the .mo files are properly generated, even in
unit tests context and fixes #1893
2022-10-08 08:02:02 -04:00
nodiscc
ea1810d4da
Merge pull request #1895 from reinboldg/patch-1
Update shaarli.po/fix typo in french translation
2022-10-05 16:26:21 +00:00
Gregory
a66f036ece
Update shaarli.po
Fix typo
2022-10-05 10:10:41 +02:00
nodiscc
288b25ae61
Merge pull request #1891 from shaarli/github-actions-no-fail-fast
tools/github actions: do not cancel all PHP jobs when a single one fails
2022-09-24 16:10:01 +00:00
nodiscc
93a826f0a4
tools/github actions: do not cancel all PHP jobs when a single one fails
- https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#handling-failures
2022-09-24 18:07:54 +02:00
nodiscc
dc589b7490
Merge pull request #1869 from shaarli/docker-alpine-php8
update docker images to use PHP 8
2022-09-24 15:58:23 +00:00
nodiscc
5177e036fa
tests/docker: alpine316: add php8-gettext package 2022-09-24 17:55:16 +02:00
nodiscc
74883e373e
docker: Dockerfile: add php8-gettext package 2022-09-24 17:55:16 +02:00
nodiscc
8b1f9115ad
tests/docker: add php8-xmlwriter packate to alpine316 test image
- squizlabs/php_codesniffer[3.0.0, ..., 3.7.1] require ext-xmlwriter * -> it is missing from your system. Install or enable PHP's xmlwriter extension.
2022-09-24 17:55:16 +02:00
nodiscc
e0a9d66d99
tests/makefile: rewrite translate target to be compatible with busybox find
- https://manpages.debian.org/bullseye/busybox-static/busybox.1.en.html#find
2022-09-24 17:55:15 +02:00
nodiscc
bd81f94287
tests: update alpine316 test image to use php8 2022-09-24 17:55:15 +02:00
nodiscc
b5988ce296
docker: update s6 service definition to use php-fpm8 2022-09-24 17:55:15 +02:00
nodiscc
1da6caedfb
Dockerfile.armhf: upgrade python2 -> python3
- python2 no longer available in alpine 3.16
- ref. https://github.com/shaarli/Shaarli/issues/1048
2022-09-24 17:55:14 +02:00
nodiscc
db33cd79b5
update docker images to use PHP 8
- fixes https://github.com/shaarli/Shaarli/issues/1868
2022-09-24 17:55:14 +02:00
Aurélien Tamisier
6180c859d3
Merge pull request #1857 from virtualtam/export
Improve bookmark metadata formatting for Netscape exports
2022-09-24 15:00:02 +02:00
Hazhar Galeh
dbd99f310f
Resolve PHP 8.1 deprecations (#1866)
Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com>
Co-authored-by: ArthurHoaro <arthur@hoa.ro>
2022-09-14 08:17:07 +02:00
nodiscc
221a2534b2
Merge pull request #1858 from nodiscc/doc-thumbnailer-mode
doc: shaarli configuration: fixes/improvements to thumbnails settings documentation
2022-09-12 23:13:41 +00:00
nodiscc
8c4c408072
doc: shaarli configuration: update thumbnails-related configuration settings/examples
- remove obsolete config keys
2022-09-04 12:23:08 +02:00
ArthurHoaro
51603fe265
Merge pull request #1878 from ArthurHoaro/fix/github-assets-429 2022-08-20 22:58:36 +02:00
ArthurHoaro
0f896033fa Github Action: fix failing pipeline due to rate limit on githubassets.com
Quick and easy solution: try to reach GitLab instead.
2022-08-20 22:55:28 +02:00
ArthurHoaro
dc08e17996 doc(apache2): allow access to local docs folder 2022-08-20 10:46:53 +02:00
ArthurHoaro
7c6df1c80f
Merge pull request #1872 from ArthurHoaro/feature/shaarli-netscape-upgrade 2022-08-20 08:52:59 +02:00
nodiscc
3665594d36
Merge pull request #1727 from ArthurHoaro/feature/readit
New Core Plugin: ReadItLater
2022-08-16 10:42:20 +02:00
ArthurHoaro
8a7a09df90
Merge pull request #1787 from yfdyh000/software.md 2022-08-13 16:12:59 +02:00
ArthurHoaro
bde1fdcb48 Netscape bookmark parser: bump to new major version
Apply breaking changes of the new version:
  - parsed bookmarks have different field names
  - default values (private and tags) are no longer handled by the library
  - constructor signature has been updated
2022-08-13 16:08:23 +02:00
YFdyh000
10b460fbd2 refine Community-and-related-software.md and tools page
- tpl/default/tools.html: simplify Third-party resources section
 - doc: community & related software: add AddToShaarli source code link
 - fix addtoshaarli source link
 - improve shields.io badges/formatting
 - use shields.io for cloudron/yunohost links
 - use a generic-looking icon

Worked on by @yfdyh000 and @nodiscc
2022-08-13 10:25:52 +02:00
ArthurHoaro
130008da03
Merge pull request #1792 from yfdyh000/sitetitle 2022-08-13 10:21:48 +02:00
ArthurHoaro
b59cdb3871 ArthurHoaro code review: use Shared Bookmark as default title instead of My links 2022-08-13 10:19:15 +02:00
YFdyh000
d5b218eed4 Simple and uniform localized website title 2022-08-13 10:19:15 +02:00
ArthurHoaro
22d43c303b
Merge pull request #1788 from yfdyh000/messages_210822 2022-08-13 10:11:21 +02:00
ArthurHoaro
8b10110c2b ArthurHoaro code review: typo 2022-08-13 10:07:21 +02:00
ArthurHoaro
32777d9fd2
Merge pull request #1871 from ArthurHoaro/chore/bump-dependencies 2022-08-13 10:03:20 +02:00
ArthurHoaro
46a104e433 chore: bump minor composer dependencies
Especially for latest Slim minor which fix a few PHP 8.1 warnings
2022-08-13 09:54:06 +02:00
ArthurHoaro
11cf6e9b49 Fix PHPCS rules 2022-08-12 19:58:07 +02:00
ArthurHoaro
39c89d84f5 Update official plugin list in the documentation 2022-08-12 19:58:07 +02:00
ArthurHoaro
bf8bec322b New Core Plugin: ReadItLater
Create a new core plugin allowing to mark bookmarks to read them later.
When enabled:

  * checkbox is displayed in editlink view for new bookmarks
  * a plugin setting is available to check it or not it by default
  * in bookmark list:
    * new global filter to display only bookmark flagged as read it
      later
    * for each bookmarks, new action icon to toggle read it later status
    * for each « readitlater » bookmark, red label « To Read » added,
      and red line on the right of the bookmark added (default template)

Fixes #143

Signed-off-by: ArthurHoaro <arthur@hoa.ro>
2022-08-12 19:58:07 +02:00
nodiscc
91dbe63e00
Merge pull request #1867 from shaarli/docker-update-alpine
Dockerfile/Dockerfile.armhf: update base alpine image to v3.16
2022-08-10 20:23:49 +02:00
nodiscc
fdfc09f73f
tests: update base alpine image to v3.16 in test Dockerfiles 2022-08-10 20:15:21 +02:00
nodiscc
0abe2f0dcc
Dockerfile/Dockerfile.armhf: update base alpine image to v3.16
- https://hub.docker.com/_/alpine
- https://hub.docker.com/r/arm32v6/alpine/
- related https://github.com/shaarli/Shaarli/issues/1757
- related https://github.com/shaarli/Shaarli/issues/1855
2022-08-10 20:10:52 +02:00
nodiscc
40a26241de
Merge pull request #1864 from shaarli/dependabot/npm_and_yarn/terser-4.8.1
build(deps): bump terser from 4.8.0 to 4.8.1
2022-07-26 13:17:59 +00:00
dependabot[bot]
e22c550cca
build(deps): bump terser from 4.8.0 to 4.8.1
Bumps [terser](https://github.com/terser/terser) from 4.8.0 to 4.8.1.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-20 02:01:01 +00:00
VirtualTam
3813b39a4c Export: set a bookmark's PRIVATE attribute using an integer value
Signed-off-by: VirtualTam <virtualtam@flibidi.net>
2022-06-03 13:29:19 +02:00
VirtualTam
21af53f795 Export: set a bookmark's LAST_MODIFIED attribute to its update timestamp
Signed-off-by: VirtualTam <virtualtam@flibidi.net>
2022-06-03 13:28:08 +02:00
nodiscc
026ed40d90
Merge pull request #1848 from nodiscc/build-yarnpkg
build: use the yarnpkg command instead of yarn
2022-04-06 17:38:24 +00:00
nodiscc
7e39b5ee36
Merge pull request #1849 from nodiscc/doc-dev-install-deps
doc: installation/tests: clarify build tools installation procedure
2022-04-06 17:36:02 +00:00
nodiscc
febe0a6487 doc: installation/tests: clarify build tools installation procedure
- don't repeat link to getcomposer.org
- add an example of installing build dependencies on Debian
2022-04-06 19:29:35 +02:00
nodiscc
803f6a7e36 build: use the yarnpkg command instead of yarn
- yarnpkg is always aliased to the proper yarn binary on all distributions
- yarn command does not always point to yarn package managed (Debian)
2022-04-06 19:26:01 +02:00
nodiscc
1387e059eb
Merge pull request #1845 from kcaran/month_end
#1844 - Month end issues with the Daily Shaarli, updates to date processing
2022-04-06 17:21:28 +00:00
Keith Carangelo
9d99925615 Updated to pass codesniffer 2022-03-31 16:01:55 -04:00
Keith Carangelo
6ecc4745f4 Fix Github #1844 - Monthly views previous/next month links during month
end. Avoid deprecated strftime function. Got tests to pass in PHP 8.1.
2022-03-31 15:42:25 -04:00
nodiscc
f6076a9275
Merge pull request #1843 from shaarli/dependabot/npm_and_yarn/ansi-regex-4.1.1
Bump ansi-regex from 4.1.0 to 4.1.1
2022-03-29 18:01:51 +00:00
dependabot[bot]
abf5a0fb9f
Bump ansi-regex from 4.1.0 to 4.1.1
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/chalk/ansi-regex/releases)
- [Commits](https://github.com/chalk/ansi-regex/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: ansi-regex
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-29 16:09:51 +00:00
nodiscc
c2c8990f23
Merge pull request #1842 from shaarli/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-03-29 16:09:21 +00:00
nodiscc
f2cd2215f0
Merge pull request #1837 from nfriedli/master
Correction: pubsubhubbub hub link in RSS / Atom.
The hub link variable is wrong in default template (this correction) but OK in the vintage one.
2022-03-29 16:08:57 +00:00
dependabot[bot]
441b755712
Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-29 15:32:20 +00:00
Nicolas Friedli
cbb140a9af Correction: pubsubhubbub hub link in RSS / Atom. 2022-03-14 14:21:29 +01:00
nodiscc
30cf6bf92e
Merge pull request #1826 from nodiscc/dockerfile-alpine-3.15
dockerfile: update base image to alpine 3.15
2022-01-14 13:38:10 +00:00
nodiscc
6067508bb1 dockerfile: update base image to alpine 3.15
- fixes https://github.com/shaarli/Shaarli/issues/1655
2022-01-14 14:23:23 +01:00
nodiscc
39a3749f3b
Merge pull request #1825 from nodiscc/fix-phpcs-blank-lines-after-brace
tests: phpcs: fix 'Opening brace must not be followed by a blank line' error
2022-01-13 19:54:45 +00:00
nodiscc
cf9031da22 tests: phpcs: fix 'Opening brace must not be followed by a blank line' error
- fixes https://github.com/shaarli/Shaarli/issues/1818
2022-01-13 20:50:39 +01:00
nodiscc
aeda845b3c
Merge pull request #1806 from nodiscc/doc-fix-example-config-json
doc: add "formatter" setting to example.json.php, remove duplicate "general" key
fixes https://github.com/shaarli/Shaarli/issues/1680
2021-12-17 14:35:14 +00:00
nodiscc
7ae4b2f8b0
doc: add "formatter" key to example config.json.php
- fixes https://github.com/shaarli/Shaarli/issues/1680
2021-10-10 15:11:38 +02:00
nodiscc
df0ca43873
doc: remove duplicate "general" key in example config.php.json
- ref. https://github.com/shaarli/Shaarli/issues/1680
2021-10-10 15:09:57 +02:00
nodiscc
21550cda7d
Merge pull request #1804 from nodiscc/doc-fix-icon
doc: fix homepage title/icon rendering
2021-10-02 11:25:16 +00:00
nodiscc
e0f4fd4537
doc: fix homepage title/icon rendering
- fixes https://github.com/shaarli/Shaarli/issues/1774
2021-09-26 21:53:41 +02:00
ArthurHoaro
163cd8ce2d
Merge pull request #1798 from kcaran/or-tag-search 2021-09-23 08:32:40 +02:00
Keith Carangelo
d2019d3a09 Fixed issue with suggestions on multiple terms 2021-09-08 20:45:56 -04:00
Keith Carangelo
c6f27b1ade Fixed issues after running make code_sniffer 2021-09-08 15:46:51 -04:00
Keith Carangelo
6202038c65 Updated to pass eslint 2021-09-08 15:40:05 -04:00
Keith Carangelo
a7d43caccb Added support for OR (~) and optional AND (+) operators for tag searches. 2021-09-08 15:26:58 -04:00
Keith Carangelo
6e0f92acb4 Merge branch 'master' of github.com:Shaarli/Shaarli into upstream 2021-09-07 13:41:59 -04:00
ArthurHoaro
6ca3980812
Merge pull request #1795 from shaarli/dependabot/npm_and_yarn/tar-6.1.11
Bump tar from 6.1.3 to 6.1.11
2021-09-05 10:22:10 +02:00
ArthurHoaro
a276e0c4e6
Merge pull request #1786 from yfdyh000/remove_travis.org
remove travis from README.md
2021-09-05 09:28:46 +02:00
ArthurHoaro
b1f026b674
Merge pull request #1791 from yfdyh000/plugin_enabled
Intuitive checkbox for Enabled Plugins
2021-09-05 09:27:55 +02:00
dependabot[bot]
a908ed6866
Bump tar from 6.1.3 to 6.1.11
Bumps [tar](https://github.com/npm/node-tar) from 6.1.3 to 6.1.11.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v6.1.3...v6.1.11)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-31 16:51:51 +00:00
Keith Carangelo
6ca8ab31b2 Merge branch 'master' of github.com:Shaarli/Shaarli into upstream 2021-08-26 14:17:37 -04:00
YFdyh000
f33af48b59 Intuitive checkbox for Enabled Plugins 2021-08-22 22:34:28 +08:00
YFdyh000
dea58d5abd trivial refine for messages 2021-08-22 21:58:52 +08:00
YFdyh000
36e16b3d17 remove travis from README.md 2021-08-22 21:44:39 +08:00
ArthurHoaro
3b1818dfa6
Merge pull request #1781 from yfdyh000/zh_CN 2021-08-14 10:52:58 +02:00
ArthurHoaro
9a62827452 UT: bump number of languages 2021-08-14 10:44:40 +02:00
nodiscc
dba8975f85
Merge pull request #1784 from shaarli/dependabot/npm_and_yarn/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7
2021-08-14 00:21:20 +00:00
nodiscc
4dfabbf8a7
Merge pull request #1780 from shaarli/dependabot/npm_and_yarn/tar-6.1.3
Bump tar from 6.1.0 to 6.1.3
2021-08-14 00:21:01 +00:00
dependabot[bot]
65d9afa9b8
Bump path-parse from 1.0.6 to 1.0.7
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-10 22:52:25 +00:00
YFdyh000
142370f0a1 Add Chinese (Simplified) translation 2021-08-10 07:23:42 +08:00
dependabot[bot]
a0eed0546b
Bump tar from 6.1.0 to 6.1.3
Bumps [tar](https://github.com/npm/node-tar) from 6.1.0 to 6.1.3.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v6.1.0...v6.1.3)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-03 19:55:31 +00:00
nodiscc
ab6a4c9f7b
Merge pull request #1779 from letompouce/doc-rm-markdown-plugin
doc: remove the markdown plugin from the plugins list
2021-08-02 13:52:02 +00:00
ToM
63fe4881cc doc: remove the markdown plugin from the plugins list
The plugin is now part of core since v0.12.0
2021-08-01 16:44:31 +02:00
nodiscc
a79707258f
Merge pull request #1768 from nodiscc/doc-proxy-subdirectory
doc: add notice about nginx location directive when shaarli is installed in a subdirectory
2021-07-19 17:02:29 +00:00
nodiscc
1a36e314ba
Merge pull request #1769 from nodiscc/doc-php-ldap
doc: LDAP login support, update php requirements list
2021-07-19 17:02:14 +00:00
nodiscc
4cfaa67e07
Merge pull request #1767 from nodiscc/doc-bookmarklet
doc: bookmarklet is now working on github.com
2021-07-19 17:02:05 +00:00
nodiscc
338648093f
Merge pull request #1765 from nodiscc/github-actions-docker-build
build and push docker images using Github Actions
2021-07-19 16:58:34 +00:00
nodiscc
d1fed70609
Merge pull request #1766 from shaarli/dependabot/npm_and_yarn/postcss-7.0.36
Bump postcss from 7.0.35 to 7.0.36
2021-06-18 15:47:38 +00:00
nodiscc
4a63c2bbb4
doc: LDAP login support, update php requirements list
- fixes https://github.com/shaarli/Shaarli/issues/1677
2021-06-17 17:57:07 +02:00
nodiscc
f841121a6e
doc: add notice about nginx location directive when shaarli is installed in a subdirectory
- fixes https://github.com/shaarli/Shaarli/issues/1679
2021-06-17 17:50:56 +02:00
nodiscc
2a569f1e93
doc: bookmarklet is now working on github.com
- left generic paragraph about this problem in place, since the problem may still be present on other sites
- closes https://github.com/shaarli/Shaarli/issues/1730
2021-06-17 17:46:00 +02:00
dependabot[bot]
bf63992617
Bump postcss from 7.0.35 to 7.0.36
Bumps [postcss](https://github.com/postcss/postcss) from 7.0.35 to 7.0.36.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/7.0.35...7.0.36)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-15 20:38:40 +00:00
nodiscc
eeaabc05a7
build and push docker images using github actions
- push images to https://hub.docker.com/r/shaarli/shaarli/tags using a personal access token (access tokens are not available for organizations)
- push an image tagged :latest for builds on master
- push an image with the same tag as the git tag for v*.*.* tags, and for the "release" branch
- update documentation (remove references to Travis/Drone CI
- deprecate stable and master Docker tags (ref. https://github.com/shaarli/Shaarli/issues/1453)
- add deprecation notices to CHANGELOG.md
2021-06-15 20:35:36 +02:00
nodiscc
11c6fc418d
Merge pull request #1763 from shaarli/dependabot/npm_and_yarn/trim-newlines-3.0.1
Bump trim-newlines from 3.0.0 to 3.0.1
2021-06-14 12:20:54 +00:00
dependabot[bot]
4f6a4f6107
Bump trim-newlines from 3.0.0 to 3.0.1
Bumps [trim-newlines](https://github.com/sindresorhus/trim-newlines) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/sindresorhus/trim-newlines/releases)
- [Commits](https://github.com/sindresorhus/trim-newlines/commits)

---
updated-dependencies:
- dependency-name: trim-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-08 18:23:13 +00:00
ArthurHoaro
a047b62c2b
Merge pull request #1760 from qbi/patch-1
Change Zeichen to Token
2021-05-28 08:19:27 +02:00
nodiscc
fbedbd8ee2
Merge pull request #1759 from ArthurHoaro/feat/github-actions
Setup Github Actions for Shaarli
2021-05-25 15:49:56 +00:00
Jens Kubieziel
0b97c4279e
Change Zeichen to Token
I'd recommend to change the German translation. The word "Zeichen" is misleading in this case. It means something like string or character. The word "Token" fits better. In general I'd change the message to "Wrong XSRF token". This makes it more clear what happens here.
2021-05-25 09:58:46 +00:00
ArthurHoaro
8887f9826a
Merge pull request #1752 from oblab/patch-3
Update includes.html
2021-05-23 11:43:24 +02:00
ArthurHoaro
2ce2ef3708 Setup Github Actions for Shaarli
This is kind of a quick & dirty setup in order to fix our non-CI current status.
We can later decide to either improve it or fix Drone CI.

Related to #1754
2021-05-23 11:36:24 +02:00
nodiscc
d8fe0e7276
Merge pull request #1741 from nodiscc/drone-ci
switch continuous integration system to Drone CI
2021-05-16 17:32:42 +00:00
Olivier
3d27ecbb37
Update includes.html
change permalink '<meta property="og:url" content="{$index_url}?{$link.shorturl}" />' by '<meta property="og:url" content="{$index_url}shaare/{$link.shorturl}" />'
2021-05-15 10:50:13 +02:00
ArthurHoaro
fbb33c723e
Merge pull request #1750 from oblab/patch-1
Update includes.html
2021-05-15 10:47:53 +02:00
ArthurHoaro
bbb2dd30ac
Merge pull request #1751 from oblab/patch-2 2021-05-15 10:47:37 +02:00
Olivier
62c9b3a6d9
Update daily.html
Change permalink in daily.html file : <a href="{$base_path}/?{$link.shorturl}" title="{'Permalink'|t}">
by : <a href="{$base_path}/shaare/{$link.shorturl}" title="{'Permalink'|t}">
2021-05-15 10:42:59 +02:00
Olivier
bbcb18931c
Update includes.html
Change the permalink in meta property : <meta property="og:url" content="{$index_url}?{$link.shorturl}" />
by : <meta property="og:url" content="{$index_url}shaare/{$link.shorturl}" /> ?
2021-05-15 10:40:29 +02:00
nodiscc
d4da270289
doc: update CI documentation
- use cloud.drone.io badges for builds on the master branch
- stable/0.x badges will need to be updated when the next stable/0.x release is published
2021-05-13 14:28:25 +02:00
nodiscc
832739e58f
switch continuous integration system to Drone CI:
- add .drone.yml, reimplement tasks from .travis.yml (php/node/python test suites)
- ref. https://github.com/shaarli/Shaarli/issues/1649
- https://www.drone.io/enterprise/opensource/
- https://cloud.drone.io/shaarli/Shaarli/settings
- https://docs.drone.io/pipeline/docker/syntax/steps/
- https://docs.drone.io/pipeline/docker/syntax/cloning/
- https://docs.drone.io/pipeline/environment/reference/
- https://docs.drone.io/pipeline/configuration/
- https://docs.drone.io/pipeline/overview/
- https://docs.drone.io/pipeline/docker/syntax/volumes/
- https://docs.drone.io/pipeline/docker/syntax/volumes/temporary/
- php: use custom php base images with prebuilt PHP extensions and composer (speed up build process) (https://hub.docker.com/r/shaarli/drone-ci-base, https://www.github.com/shaarli/drone-ci-base, https://hub.docker.com/repository/docker/shaarli/drone-ci-base/builds)
- no need to port $PATH update command, the default node:10 image already has the correct $PATH
- don't force pull of latest images to speed up builds
- the default is to use a local/cached image when the image is not tagged :latest
- https://docs.drone.io/pipeline/docker/syntax/parallelism/
- https://docs.drone.io/pipeline/environment/reference/drone-git-http-url/
- ignore PHP version requirements for https://packagist.org/packages/pubsubhubbub/publisher, pending merge of https://github.com/pubsubhubbub/php-publisher/pull/11
- closes https://github.com/shaarli/Shaarli/issues/1649
2021-05-13 14:28:11 +02:00
ArthurHoaro
0f4cd55599
Merge pull request #1748 from ArthurHoaro/fix/mkdocs
Fix documentation build
2021-05-13 11:43:43 +02:00
ArthurHoaro
e660450a2b Fix documentation build
- pages parameters has been deprecated and renamed by nav
  - the build fails with an empty extra_css array
2021-05-13 11:36:37 +02:00
ArthurHoaro
45b3c7cb7a
Merge pull request #1747 from ArthurHoaro/chore/bump-front-deps
Bump dependency versions
2021-05-08 14:18:56 +02:00
ArthurHoaro
723e93f439 Bump dependency versions 2021-05-08 13:40:20 +02:00
ArthurHoaro
6225cc9c86
Merge pull request #1746 from shaarli/dependabot/npm_and_yarn/lodash-4.17.21
Bump lodash from 4.17.20 to 4.17.21
2021-05-08 12:54:27 +02:00
dependabot[bot]
824f3c6dff
Bump lodash from 4.17.20 to 4.17.21
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-08 10:38:45 +00:00
ArthurHoaro
4ca1b33b0e
Merge pull request #1743 from shaarli/dependabot/npm_and_yarn/ssri-6.0.2
Bump ssri from 6.0.1 to 6.0.2
2021-04-20 08:11:16 +02:00
dependabot[bot]
c273f511aa
Bump ssri from 6.0.1 to 6.0.2
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-20 02:24:55 +00:00
nodiscc
a5482cf9af
Merge pull request #1739 from ralienpp/master
Add '406 not acceptable' to the Troubleshooting section
2021-04-14 15:53:13 +00:00
Alexander Railean
060e6d9498 Correct HTTP status code 206->406 2021-04-12 21:05:21 +02:00
Alexander Railean
e00b9dc099 Add '206 not acceptable' to the Troubleshooting section 2021-04-12 21:03:43 +02:00
nodiscc
0ed6614981
Merge pull request #1738 from shaarli/doc-fix-casing
doc: plugins.md: fix link casing
2021-04-12 18:28:08 +00:00
nodiscc
9700d9ea3e
doc: plugins.md: fix link casing
fixes https://github.com/shaarli/Shaarli/issues/1737
2021-04-12 18:15:58 +00:00
nodiscc
9f87e82cdb
Merge pull request #1734 from ArthurHoaro/doc/php-extensions
Documentation: include all PHP extensions installed in our official Docker image
2021-04-05 10:52:37 +00:00
ArthurHoaro
5bf3deb815
Merge pull request #1733 from ArthurHoaro/feature/phpcs-tests 2021-04-05 11:34:03 +02:00
ArthurHoaro
ba4fa9460a Documentation: include all PHP extensions installed in our official Docker image
Fixes #1700
2021-04-05 11:27:45 +02:00
ArthurHoaro
8b428dabea
Merge pull request #1732 from ArthurHoaro/fix/legacy-bookmarklet-url
Change legacy URL route for Add Note bookmarklet
2021-04-05 11:10:54 +02:00
ArthurHoaro
af764dfd4e
Merge pull request #1731 from ArthurHoaro/fix/search-highlight-table
Search highlight: do not use special characters for tokens
2021-04-05 11:10:43 +02:00
ArthurHoaro
44b0825860 Coding style: update documentation (static analysis section)
Related to #95
2021-04-05 11:08:02 +02:00
ArthurHoaro
830a73dcf6 Coding style: manually fix remaining errors in tests after PHPCBF
Related to #95
2021-04-05 11:00:28 +02:00
ArthurHoaro
0681511699 Coding style: Apply automatic PHPCBF to tests forlder (PSR12)
Related to #95
2021-04-05 09:39:34 +02:00
ArthurHoaro
9665870b39 Change legacy URL route for Add Note bookmarklet 2021-04-05 09:29:44 +02:00
ArthurHoaro
b2a43bc861 Search highlight: do not use special characters for tokens
It messes with Markdown syntax (tables in this case).

Fixes #1729
2021-04-05 09:15:25 +02:00
ArthurHoaro
bd7ed438fa
Merge pull request #1728 from yude/master 2021-04-04 11:52:09 +02:00
yudejp
b29f14d67e
Update Japanese translation 2021-04-04 13:20:25 +09:00
yude
0a47426f88
Merge pull request #3 from shaarli/master
Merge upstream
2021-04-04 11:25:48 +09:00
ArthurHoaro
2c2c349e8a
Merge pull request #1725 from ajabep/patch-1
Fix a crash when generating an atom feed with no bookmarks
2021-04-03 13:16:54 +02:00
Ajabep
2ea2c99dcb
Fix a bug
When we try to access the atom feed and have no bookmarks, it raised the following exception :

```
Call to a member function reorder() on array /webroot/application/bookmark/BookmarkFileService.php:143
#0 /webroot/application/feed/FeedBuilder.php(106): Shaarli\Bookmark\BookmarkFileService->search(Array, 'public', false, false, true)
#1 /webroot/application/front/controller/visitor/FeedController.php(47): Shaarli\Feed\FeedBuilder->buildData('atom', Array)
#2 /webroot/application/front/controller/visitor/FeedController.php(20): Shaarli\Front\Controller\Visitor\FeedController->processRequest('atom', Object(Slim\Http\Request), Object(Slim\Http\Response))
#3 [internal function]: Shaarli\Front\Controller\Visitor\FeedController->atom(Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#4 /webroot/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php(40): call_user_func(Array, Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#5 /webroot/vendor/slim/slim/Slim/Route.php(281): Slim\Handlers\Strategies\RequestResponse->__invoke(Array, Object(Slim\Http\Request), Object(Slim\Http\Response), Array)
#6 /webroot/application/front/ShaarliMiddleware.php(55): Slim\Route->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response))
#7 [internal function]: Shaarli\Front\ShaarliMiddleware->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\Route))
#8 /webroot/vendor/slim/slim/Slim/DeferredCallable.php(57): call_user_func_array(Array, Array)
#9 [internal function]: Slim\DeferredCallable->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\Route))
#10 /webroot/vendor/slim/slim/Slim/MiddlewareAwareTrait.php(70): call_user_func(Object(Slim\DeferredCallable), Object(Slim\Http\Request), Object(Slim\Http\Response), Object(Slim\Route))
#11 /webroot/vendor/slim/slim/Slim/MiddlewareAwareTrait.php(117): Slim\Route->Slim\{closure}(Object(Slim\Http\Request), Object(Slim\Http\Response))
#12 /webroot/vendor/slim/slim/Slim/Route.php(268): Slim\Route->callMiddlewareStack(Object(Slim\Http\Request), Object(Slim\Http\Response))
#13 /webroot/vendor/slim/slim/Slim/App.php(503): Slim\Route->run(Object(Slim\Http\Request), Object(Slim\Http\Response))
#14 /webroot/vendor/slim/slim/Slim/MiddlewareAwareTrait.php(117): Slim\App->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response))
#15 /webroot/vendor/slim/slim/Slim/App.php(392): Slim\App->callMiddlewareStack(Object(Slim\Http\Request), Object(Slim\Http\Response))
#16 /webroot/vendor/slim/slim/Slim/App.php(297): Slim\App->process(Object(Slim\Http\Request), Object(Slim\Http\Response))
#17 /webroot/index.php(177): Slim\App->run(true)
#18 {main}
```
2021-04-02 21:14:09 +02:00
ArthurHoaro
4543717881
Merge pull request #1724 from shaarli/dependabot/npm_and_yarn/y18n-4.0.1
Bump y18n from 4.0.0 to 4.0.1
2021-03-30 17:11:08 +02:00
dependabot[bot]
fe170cb571
Bump y18n from 4.0.0 to 4.0.1
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-30 14:59:13 +00:00
Keith Carangelo
755c094bdd Merge branch 'master' of github.com:Shaarli/Shaarli into upstream 2021-03-29 11:27:32 -04:00
nodiscc
8b8ed23ae1
Merge pull request #1718 from shaarli/doc-apache-directoryindex
doc: apache: explicitly set index.php as DirectoryIndex
2021-03-27 14:17:40 +00:00
ArthurHoaro
28123e7283
Merge pull request #1722 from ArthurHoaro/feature/bump-thumbnailer
Bump WebThumbnailer version to fix Instagram issue
2021-03-27 13:26:34 +01:00
ArthurHoaro
546c776acd Bump WebThumbnailer version to fix Instagram issue
Related to #1711
2021-03-27 13:22:55 +01:00
ArthurHoaro
e1847ae5a7
Merge pull request #1719 from shaarli/dependabot/npm_and_yarn/elliptic-6.5.4
Bump elliptic from 6.5.3 to 6.5.4
2021-03-27 12:20:28 +01:00
dependabot[bot]
fb0d610c80
Bump elliptic from 6.5.3 to 6.5.4
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-09 01:59:38 +00:00
nodiscc
c5cd2f16f4
Merge pull request #1717 from jalr/patch-1
Fix typo in documentation
2021-03-07 15:06:33 +00:00
nodiscc
3bb6205e7f
doc: apache: explicitely ste index.php as DirectoryIndex
WIthout this directive apache will try other default/global DirectoryIndex files resulting in useless file access/error messages in logs

```
[Sun Mar 07 14:04:25.383960 2021] [authz_core:error] [pid 946:tid 139985284290304] [client 10.0.0.1:42616] AH01630: client denied by server configuration: /var/www/links.example.org/index.html
[Sun Mar 07 14:04:25.384293 2021] [authz_core:error] [pid 946:tid 139985284290304] [client 10.0.0.1:42616] AH01630: client denied by server configuration: /var/www/links.example.org/index.cgi
[Sun Mar 07 14:04:25.384465 2021] [authz_core:error] [pid 946:tid 139985284290304] [client 10.0.0.1:42616] AH01630: client denied by server configuration: /var/www/links.example.org/index.pl
```
2021-03-07 13:08:31 +00:00
jalr
94dadd85a0
Fix typo 2021-03-07 10:58:15 +00:00
ArthurHoaro
9db1ccdf2c
Merge pull request #1698 from ArthurHoaro/feature/plugins-search-filter
New plugin hook: ability to add custom filters to Shaarli search engine
2021-02-04 11:11:33 +01:00
ArthurHoaro
bcba6bd353 New plugin hook: ability to add custom filters to Shaarli search engine
A new plugin hook has been added: hook_test_filter_search_entry
This hook allows to filter out bookmark with custom plugin code when a search is performed.

Related to #143
2021-02-04 11:02:50 +01:00
ArthurHoaro
8997ae6c8e
Merge pull request #1697 from ArthurHoaro/feature/pagination
Handle pagination through BookmarkService
2021-02-04 10:57:44 +01:00
ArthurHoaro
11edc143b4
Merge pull request #1696 from ArthurHoaro/fix/search-highlight-url 2021-02-04 10:57:12 +01:00
ArthurHoaro
a1cd7a3b2f ShaarliParsedown: add PHPDoc/comments 2021-02-04 10:53:23 +01:00
ArthurHoaro
83b4eb1795
Merge pull request #1694 from ArthurHoaro/fix/bulk-add-redirect-token
Fix: bulk add redirection with ending slash
2021-01-26 16:25:09 +01:00
ArthurHoaro
d496fd857d
Merge pull request #1699 from bschwede/master
Update German translations, added new strings to server.html
2021-01-26 16:23:44 +01:00
bschwede
e570cc8b1a Update German translations, added new strings to server.html 2021-01-25 00:51:36 +01:00
ArthurHoaro
9b8c0a4560 Handle pagination through BookmarkService
Handle all search results through SearchResult object.
This is a required step toward implementing a BookmarkService based on SQL database.

Related to #953
2021-01-20 15:01:29 +01:00
ArthurHoaro
055d97f9a9
Merge pull request #1695 from ArthurHoaro/fix/ut-curl 2021-01-20 11:31:35 +01:00
ArthurHoaro
9ef8555ad2 Support search highlights when matching URL content
DefaultFormatter:
  - format 'a' tag content and not href attribute
  - format hashtags properly
Markdown(Extra)Formatter:
  - Extend Parsedown to format highlight properly: https://github.com/erusev/parsedown/wiki/Tutorial:-Create-Extensions

Fixes #1681
2021-01-19 17:49:19 +01:00
ArthurHoaro
dafd3f081a format_date: include timezone in IntlDateFormatter object
@see https://www.php.net/manual/en/intldateformatter.format.php

> If a DateTime or an IntlCalendar object is passed, its timezone is not considered. The object will be formatted using the formaterʼs configured timezone. If one wants to use the timezone of the object to be formatted, IntlDateFormatter::setTimeZone() must be called before with the objectʼs timezone.
2021-01-19 15:03:28 +01:00
ArthurHoaro
6b76ce6f62 curl usage: support HTTP/2 response code header 2021-01-19 15:03:18 +01:00
ArthurHoaro
baac4388b1
Merge pull request #1693 from ArthurHoaro/fix/bulk-add-delete
Fix: bulk add - delete existing link
2021-01-19 14:31:15 +01:00
ArthurHoaro
5b5d22a3df
Merge pull request #1691 from ArthurHoaro/fix/bulk-add-js-checkboxes
Fix: bulk add - private status
2021-01-19 14:30:40 +01:00
ArthurHoaro
3d6278e86f Fix: bulk add redirection with ending slash
Otherwise cookie may not be store under the right subfolder, thus generating tokens in the wrong session file.

Fixes #1690
2021-01-19 14:26:04 +01:00
ArthurHoaro
93175b6e9d Fix: bulk add - delete existing link
Do not send redirect response in bookmark delete controller if the request comes from bulk creation page.

Fixes #1683
2021-01-19 12:54:34 +01:00
ArthurHoaro
47ac77adbb Fix: bulk add - private status
Use 'checked' attribute instead of 'value' for checkboxes. 'value' always returns 'on'.

Fixes #1684
2021-01-19 11:55:50 +01:00
ArthurHoaro
ffa39719a1
Merge pull request #1689 from ArthurHoaro/fix/bulk-add-html-label
Fix: bulk add - use unique HTML ID
2021-01-19 11:48:38 +01:00
ArthurHoaro
31c4be2b60
Merge pull request #1688 from ArthurHoaro/fix/bulk-single-url 2021-01-19 11:48:29 +01:00
ArthurHoaro
2fbdb7d657
Merge pull request #1687 from ArthurHoaro/feature/template-name
Inject current template name in templates
2021-01-19 11:48:18 +01:00
ArthurHoaro
8fbc29de02 Fix: bulk add - use unique HTML ID
Use links loop ID to make ID unique and fix browser labels behaviour.

Fixes #1685
2021-01-19 11:35:42 +01:00
ArthurHoaro
9e55beebfd Fix: error when using bulk shaare with a single URL
Make sure that header metadata associated with permalink is only used in linklist template.

Fixes #1686
2021-01-19 11:18:56 +01:00
ArthurHoaro
ccd1862d5f Inject current template name in templates
Use either legacy key _PAGE_ or new 'template' one.

Related to https://github.com/kalvn/Shaarli-Material/issues/118
2021-01-19 10:34:11 +01:00
nodiscc
544bbdaf83
Merge pull request #1675 from yudete/master
Update Japanese translations
2021-01-04 17:51:05 +00:00
yudete
bf02f8ba8e Update Japanese translations 2021-01-04 18:55:03 +09:00
yude
e6754f2154
Merge pull request #2 from shaarli/master
Merge fork source
2021-01-04 18:51:10 +09:00
ArthurHoaro
ed4ee8f029
Merge pull request #1671 from ArthurHoaro/fix/plugin-colors-update
Fix default_colors plugin: update CSS file on color change
2021-01-03 11:43:54 +01:00
ArthurHoaro
20ba77a2dc
Merge pull request #1672 from ArthurHoaro/feature/api-parse-tags-string 2021-01-03 11:43:31 +01:00
ArthurHoaro
0640c1a6db API: POST/PUT Link - properly parse tags string
Even though the documentation specify that tags should be passed as an array, tags string is actually allowed. So this adds a proper parsing with configured separator.

Related to #1651
2020-12-29 13:01:04 +01:00
ArthurHoaro
035a002edc Fix default_colors plugin: update CSS file on color change
Last update of this plugin remove the save_plugin_parameters hook.

Fixes #1657
2020-12-29 11:59:14 +01:00
ArthurHoaro
fe58bdcd9e
Merge pull request #1664 from ArthurHoaro/fix/metadata-sync
Fix: synchronous metadata retrieval is failing in strict mode
2020-12-29 11:44:10 +01:00
ArthurHoaro
8ed5fbef8f
Merge pull request #1665 from ArthurHoaro/fix/metadata-regexes-2
Fix metadata extract regex (2)
2020-12-29 11:43:39 +01:00
ArthurHoaro
b01b3b83a7
Merge pull request #1666 from ArthurHoaro/feature/daily-rss-cache
Daily RSS Cache: invalidate cache base on the date
2020-12-29 11:43:00 +01:00
ArthurHoaro
f2e309b67d
Merge pull request #1669 from leyrer/master
Typo fix line 76 'Authentication' -> Authorization
2020-12-29 00:36:22 +01:00
leyrer
151fa1e450 Typo fix line 76 'Authentication' -> Authorization 2020-12-26 13:45:01 +01:00
ArthurHoaro
f00600a283 Daily RSS Cache: invalidate cache base on the date
Currently the cache is only invalidated when the datastore changes, while it should rely on selected period of time.

Fixes #1659
2020-12-17 15:48:03 +01:00
ArthurHoaro
88a8e284b2 Fix metadata extract regex (2)
Reference: https://stackoverflow.com/questions/8055727/negating-a-backreference-in-regular-expressions

Fixes #1656
2020-12-17 13:56:24 +01:00
ArthurHoaro
ab4c170672
Merge pull request #1644 from ArthurHoaro/fix/daily-rss
Daily RSS - Remove relative description (today, yesterday)
2020-12-16 16:04:53 +01:00
ArthurHoaro
bd11879018
Merge pull request #1645 from ArthurHoaro/feature/plugin-register-route
Plugin system: allow plugins to provide custom routes
2020-12-16 16:04:15 +01:00
ArthurHoaro
8f423eb11c
Merge pull request #1658 from dougbreaux/master
newer alpine (for newer PHP) and apk upgrade #1655
2020-12-16 16:02:14 +01:00
ArthurHoaro
b1d78519a8
Merge pull request #1652 from ArthurHoaro/fix/failing-mutex
Fix: soft fail if the mutex is not working
2020-12-16 16:01:32 +01:00
ArthurHoaro
3d5f05052f
Merge pull request #1661 from shaarli/dependabot/npm_and_yarn/ini-1.3.7 2020-12-16 16:00:35 +01:00
ArthurHoaro
51dea3b87e
Merge pull request #1660 from e2jk/patch-1
Upgrade alpine from 3.8 to 3.10 in armhf Dockerfile
2020-12-16 15:59:46 +01:00
ArthurHoaro
6a3a78d023 Fix: synchronous metadata retrieval is failing in strict mode
Metadata can now only be string or null.

Fixes #1653
2020-12-16 14:04:32 +01:00
dependabot[bot]
5b74c67461
Bump ini from 1.3.5 to 1.3.7
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-11 03:39:18 +00:00
Doug Breaux
2a20e67f76 remove apk upgrade #1655 2020-12-06 22:02:34 -06:00
Emilien Klein
ee07df357b
Upgrade alpine from 3.8 to 3.10 in armhf Dockerfile
The Docker for armhf doesn't build anymore on Alpine 3.8, upgrading to 3.10.
Building works fine on a Rapsberry Pi 4 running Raspbian GNU/Linux 10 (buster)



This is the error with 3.8:
```
[2/4] Fetching packages...
error css-loader@4.3.0: The engine "node" is incompatible with this module. Expected version ">= 10.13.0".
error Found incompatible module
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
The command '/bin/sh -c apk --update --no-cache add yarn nodejs-current python2 build-base     && cd /shaarli     && yarn install     && yarn run build     && rm -rf node_modules' returned a non-zero code: 1
```


Not upgrading to 3.11, due to this error:
```
2/4] Fetching packages...
error browserslist@4.14.3: The engine "node" is incompatible with this module. Expected version "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7". Got "13.1.0"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

The command '/bin/sh -c apk --update --no-cache add yarn nodejs-current python2 build-base     && cd /shaarli     && yarn install     && yarn run build     && rm -rf node_modules' returned a non-zero code: 1
```


Not upgrading to 3.12 either, due to this error:
```
ERROR: unsatisfiable constraints:
  py2-pip (missing):
    required by: world[py2-pip]
The command '/bin/sh -c apk --update --no-cache add py2-pip     && cd /usr/src/app/shaarli     && pip install --no-cache-dir mkdocs     && mkdocs build --clean' returned a non-zero code: 1
```
There's probably a way to have Python2 pip installed on 3.12, but I suppose other issues would arise (such as the one happening with 3.11), so only proposing to upgrade to 3.10 now. This would probably be looked at more in detail when merging the amd64 and arm/v7 Docker builds, see #1496.
2020-12-06 21:02:39 +01:00
Doug Breaux
495545f2f0 newer alpine (for newer PHP) and apk upgrade #1655 2020-12-04 16:12:39 -06:00
ArthurHoaro
8a6b7e96b7 Fix: soft fail if the mutex is not working
And display the error in server admin page

Fixes #1650
2020-11-24 13:39:35 +01:00
ArthurHoaro
e4b8330e45
Merge pull request #1648 from nodiscc/fix-ConfigureControllerTest
ConfigureControllerTest.php: update expected languages number to 6
2020-11-24 13:39:09 +01:00
ArthurHoaro
05c616f7a0 chmod -x russian translation file 2020-11-24 13:35:37 +01:00
nodiscc
70507b8603
ConfigureControllerTest.php: update expected languages number to 6
Following the addition of russian translations in #1642
Fixes https://github.com/shaarli/Shaarli/issues/1647
2020-11-22 11:06:14 +00:00
Keith Carangelo
b2eb77e1f7 Merge branch 'master' of github.com:Shaarli/Shaarli 2020-11-17 09:31:12 -05:00
ArthurHoaro
51580efbff
Merge pull request #1642 from prog-it/master 2020-11-17 13:13:49 +01:00
ArthurHoaro
da950241f3
Merge pull request #1639 from ArthurHoaro/doc/fix-release
Doc: fix missing merge on Release page
2020-11-15 12:48:16 +01:00
ArthurHoaro
a6e9c08499 Plugin system: allow plugins to provide custom routes
- each route will be prefixed by `/plugin/<plugin_name>`
  - add a new template for plugins rendering
  - add a live example in the demo_plugin

Check out the "Plugin System" documentation for more detail.

Related to #143
2020-11-15 12:41:43 +01:00
ArthurHoaro
2883c6d0a7 Daily RSS - Remove relative description (today, yesterday)
It is not useful for the RSS feed, as every new entry will be 'yesterday', and it requires an update the next day.
2020-11-15 12:05:08 +01:00
prog-it
1595d0e2b3 Add russian language file 2020-11-15 06:16:55 +05:00
prog-it
150f2a0f24 Add russian language selection 2020-11-14 07:45:10 +05:00
ArthurHoaro
831e974ea5 Doc: fix missing merge on Release page 2020-11-12 13:16:20 +01:00
ArthurHoaro
6f9e0609f4 Update badge versions 2020-11-12 13:05:19 +01:00
ArthurHoaro
a6935feb22
Merge pull request #1638 from ArthurHoaro/changelog/v0.12.1
CHANGELOG v0.12.1
2020-11-12 13:00:45 +01:00
ArthurHoaro
5a09b5fffd CHANGELOG v0.12.1 2020-11-12 12:56:22 +01:00
ArthurHoaro
302662797c
Merge pull request #1635 from ArthurHoaro/feature/phpcs 2020-11-10 10:46:04 +01:00
ArthurHoaro
c94c32d1a3
Merge pull request #1637 from ArthurHoaro/fix/server-admin-update-check
Server admin: do not retrieve latest version without update_check
2020-11-10 10:45:50 +01:00
ArthurHoaro
39b75ea983
Merge pull request #1636 from ArthurHoaro/fix/vintage-async-metadata 2020-11-10 10:45:22 +01:00
ArthurHoaro
7e78237fc9
Merge pull request #1630 from ArthurHoaro/fix/apache-config
Reviewed Apache configuration
2020-11-10 10:45:05 +01:00
ArthurHoaro
325cc8adad
Merge pull request #1634 from ArthurHoaro/fix/docker-compose
Docker-compose: fix SSL certificate + add parameter for Docker tag
2020-11-10 10:44:50 +01:00
ArthurHoaro
8affa22431
Merge pull request #1628 from ArthurHoaro/fix/nginx-config
Reviewed nginx configuration
2020-11-10 10:44:29 +01:00
ArthurHoaro
80c8889bfe Server admin: do not retrieve latest version without update_check
If the setting 'updates.check_updates' is disabled, do not retrieve the latest version on server administration page.

Additionally, updated default values for

  - updates.check_updates from false to true
  - updates.check_updates_branch from stable to latest
2020-11-09 14:42:30 +01:00
ArthurHoaro
85c09fe379 Vintage theme: fix routes in daily page 2020-11-09 12:46:43 +01:00
ArthurHoaro
336f15e8ba Vintage theme: display global messages 2020-11-09 12:46:24 +01:00
ArthurHoaro
1e49a65a2a Vintage theme: support async metadata retrieval 2020-11-09 12:36:04 +01:00
ArthurHoaro
2f4df75304 Update Static Analysis documentation 2020-11-09 12:17:40 +01:00
ArthurHoaro
5c856a6923 Run PHPCS during Travis CI checks + disable xdebug 2020-11-09 10:56:49 +01:00
ArthurHoaro
b99e00f7cd Manually fix remaining PHPCS errors 2020-11-09 10:56:49 +01:00
ArthurHoaro
53054b2bf6 Apply PHP Code Beautifier on source code for linter automatic fixes 2020-11-09 10:56:24 +01:00
ArthurHoaro
b7c50a58de Docker-compose: fix SSL certificate + add parameter for Docker tag
Use envvar SHAARLI_VIRTUAL_HOST for Traefik's docker.domain parameter instead of localhost (I'm not sure if did work at some point).

Add an environment variable to choose which Docker tag to use instead of using master by default.

Fixes #1632
2020-11-09 10:36:13 +01:00
ArthurHoaro
e09bb93e18 Coding style: switch PHPCS to PSR12
Also temporarily ignore test code (one step at a time).

Reference: https://www.php-fig.org/psr/psr-12/

Related to #95
2020-11-08 14:09:15 +01:00
ArthurHoaro
d9d71b10c3
Merge pull request #1621 from ArthurHoaro/feature/tag-separators 2020-11-08 14:07:33 +01:00
ArthurHoaro
c51d65238b
Merge pull request #1629 from ArthurHoaro/fix/demo-vimeo
Replace vimeo link in demo bookmarks due to IP ban on the demo instance
2020-11-08 14:06:45 +01:00
ArthurHoaro
8d8fa898ab
Merge pull request #1631 from ArthurHoaro/fix/html-extract-quote-fix
Fix an issue truncating extracted metadata content
2020-11-08 14:06:38 +01:00
ArthurHoaro
00d3dd91ef Fix an issue truncating extracted metadata content
Previous regex forced the selection to stop at either the first single or double quote found, regardless of the opening quote. Using '\1', we're sure to wait for the proper quote before stopping the capture.
2020-11-08 13:54:39 +01:00
ArthurHoaro
8a9796014c Reviewed Apache configuration
(in documentation)

For security purpose, block access to any static file not matching the list of allowed extensions.
It allows us to remove the specific retriction on dotfiles, and fix Apache part of #1608.
2020-11-08 13:13:13 +01:00
ArthurHoaro
9952de2fe0 Replace vimeo link in demo bookmarks due to IP ban on the demo instance
Fixes #1148
2020-11-08 11:58:17 +01:00
ArthurHoaro
ce901a5828 Reviewed nginx configuration
Both in documentation and Docker image.

For security purpose, it no longer allow to access static files through
the main nginx *location*. Static files are served if their extension
matches the whitelist.

As a side effect, we no longer need specific restrictions, and
therefore it fixes the nginx part of #1608.
2020-11-07 14:27:49 +01:00
ArthurHoaro
8c5f6c786d
Merge pull request #1627 from ArthurHoaro/fix/unexpected-error
Display error details even with dev.debug set to false
2020-11-06 10:00:03 +01:00
ArthurHoaro
cfdd209440 Display error details even with dev.debug set to false
It makes more sense to display the error even if it's unexpected.
Only for logged in users.

Fixes #1606
2020-11-05 19:55:17 +01:00
ArthurHoaro
8a1ce1da15 ESLint 2020-11-05 19:14:17 +01:00
ArthurHoaro
df9aac5b64 Tags separator: vintage theme compatibility 2020-11-05 18:16:52 +01:00
ArthurHoaro
67339338af Bump shaarli/netscape-bookmark-parser dependency version 2020-11-05 17:54:42 +01:00
ArthurHoaro
b3bd8c3e8d Feature: support any tag separator
So it allows to have multiple words tags.

Breaking change: commas ',' are no longer a default separator.

Fixes #594
2020-11-05 17:54:42 +01:00
ArthurHoaro
48df9f45b8
Merge pull request #1626 from ArthurHoaro/fix/vintage-webpack
Webpack: fix vintage theme images include
2020-11-05 17:54:14 +01:00
ArthurHoaro
c61d8a85b7 Webpack: fix vintage theme images include 2020-11-05 17:44:33 +01:00
ArthurHoaro
a5a4fb1793
Merge pull request #1625 from ArthurHoaro/fix/delete-confirm-popup
Fix confirm popup before bookmark deletion
2020-11-05 16:58:24 +01:00
ArthurHoaro
5f987a64d8 Fix confirm popup before bookmark deletion
Regression introduced by #1596

Fixes #1623
2020-11-05 16:49:00 +01:00
ArthurHoaro
8bbf57a2d0
Merge pull request #1620 from ArthurHoaro/feature/no-auto-link
Default formatter: add a setting to disable auto-linkification
2020-11-05 16:47:17 +01:00
ArthurHoaro
47d1581850
Merge pull request #1624 from ArthurHoaro/fix/delete-redirect
Fix: redirect to referrer after bookmark deletion
2020-11-05 16:36:34 +01:00
ArthurHoaro
a4a59e183e
Merge pull request #1619 from ArthurHoaro/fix/translations
Fix French translation
2020-11-05 16:36:04 +01:00
ArthurHoaro
330ac859fb Fix: redirect to referrer after bookmark deletion
Except if the referer points to a permalink (which has been deleted).

Fixes #1622
2020-11-05 16:14:27 +01:00
ArthurHoaro
740b32b520 Default formatter: add a setting to disable auto-linkification
+ update documentation
  + single parameter for both URL and hashtags

Fixes #1094
2020-11-03 12:43:35 +01:00
ArthurHoaro
1a94978e44 Fix French translation
2 missing key + 1 wrong translation

Fixes  #1571
2020-11-03 11:58:02 +01:00
ArthurHoaro
38b55fbf3d
Merge pull request #1610 from ArthurHoaro/fix/wallabag
Plugin wallabag: minor improvements
2020-11-03 11:46:54 +01:00
ArthurHoaro
b7ec15790e
Merge pull request #1618 from ArthurHoaro/fix/ut-daily-date-1-digit
UT: fix formatting issue when the current day has a single digit
2020-11-02 19:42:20 +01:00
ArthurHoaro
b862705947 UT: fix formatting issue when the current day has a single digit 2020-11-02 19:32:48 +01:00
ArthurHoaro
dff039092d
Merge pull request #1616 from dimtion/fix-api-redirect
API postLink: change relative path to absolute path
2020-10-29 16:03:07 +01:00
Loïc Carr
b37ca79072 postLink: change relative path to absolute path 2020-10-28 20:08:18 -07:00
ArthurHoaro
14c9370b4f
Merge pull request #1615 from ArthurHoaro/hotfix/save-redirect
Remove unnecessary escape of referer
2020-10-28 14:18:25 +01:00
ArthurHoaro
114a43b20e Remove unnecessary escape of referer
Fixes #1611
2020-10-28 14:13:50 +01:00
ArthurHoaro
1ca7ddd76b
Merge pull request #1614 from ArthurHoaro/hotfix/php71-compat-login
Fix compatiliby issue on login with PHP 7.1
2020-10-28 14:08:08 +01:00
ArthurHoaro
d3f6d52525 Fix compatiliby issue on login with PHP 7.1
session_set_cookie_params does not return any value in PHP 7.1
2020-10-28 14:02:08 +01:00
ArthurHoaro
d2bb40cc7c
Merge pull request #1613 from ArthurHoaro/hotfix/404-not-authorized
Raise 404 error instead of 500 if permalink access is denied
2020-10-28 13:22:40 +01:00
ArthurHoaro
156061d445 Raise 404 error instead of 500 if permalink access is denied 2020-10-28 13:16:18 +01:00
ArthurHoaro
06734af130
Merge pull request #1612 from ArthurHoaro/hotfix/simplexml
Include php-simplexml in Docker image
2020-10-28 12:30:19 +01:00
ArthurHoaro
ff9686066e Include php-simplexml in Docker image
Composer 2.0 is now blocking everything if requirements are not met
2020-10-28 12:25:52 +01:00
ArthurHoaro
358cb20bcb Plugin wallabag: minor improvements
- hide the wallabag icon for logged out users
  - set API V2 as default parameter
  - fix URL encoding issue with special chars

Fixes #1147
2020-10-27 21:03:29 +01:00
ArthurHoaro
b2b5ef3122
Merge pull request #1587 from ArthurHoaro/feature/batch-bookmark-creation 2020-10-27 20:18:18 +01:00
ArthurHoaro
34c8f558e5 Bulk creation: ignore blank lines 2020-10-27 20:11:30 +01:00
ArthurHoaro
6a71675887 Bulk creation: displays a progress bar when saving all displayed forms 2020-10-27 20:11:30 +01:00
ArthurHoaro
c609944cb9 Bulk creation: improve performances using memoization
Reduced additional processing time per links from ~40ms to ~5ms
2020-10-27 20:11:30 +01:00
ArthurHoaro
25e90d8d75 Bulk creation: fix private status based on the first form 2020-10-27 20:11:30 +01:00
ArthurHoaro
5d8de7587d Feature: bulk creation of bookmarks
This changes creates a new form in addlink page allowing to create
multiple bookmarks at once more easily. It focuses on re-using as much
existing code and template component as  possible.

These changes includes:
  - a new form in addlink (hidden behind a button by default),
containing a text area for URL, and tags/private status to apply to
created links
  - this form displays a new template called editlink.batch, itself
including editlink template multiple times
  - User interation in this new templates are handle by a new JS script
(shaare-batch.js) making AJAX requests, and therefore does not need page
reloading
  - ManageShaareController has been split into 3 distinct controllers:
    + ShaareAdd: displays addlink template
    + ShaareManage: various operation applied on existing shaares
(change visibility, pin, deletion, etc.)
    + ShaarePublish: handles creation/edit forms and saving Shaare's
form
  - Updated translations

Fixes #137
2020-10-27 20:11:30 +01:00
ArthurHoaro
b8e5a253ab
Merge pull request #1595 from ArthurHoaro/feature/daily-period 2020-10-27 19:59:28 +01:00
ArthurHoaro
54afb1d6f6 Fix rebase issue 2020-10-27 19:55:29 +01:00
ArthurHoaro
36e6d88dbf Feature: add weekly and monthly view/RSS feed for daily page
- Heavy refactoring of DailyController
  - Add a banner like in tag cloud to display monthly and weekly links
  - Translations: t() now supports variables with optional first letter
uppercase

Fixes #160
2020-10-27 19:45:02 +01:00
ArthurHoaro
c2cd15dac2 Move utils classes to Shaarli\Helper namespace and folder 2020-10-27 19:41:38 +01:00
ArthurHoaro
977db7eabc
Merge pull request #1597 from ArthurHoaro/feature/share-private-bookmark
Feature: Share private bookmarks using a URL containing a private key
2020-10-27 19:40:57 +01:00
ArthurHoaro
9c04921a8c Feature: Share private bookmarks using a URL containing a private key
- Add a share link next to « Permalink » in linklist (using share icon
from fork awesome)
  - This link generates a private key associated to the bookmark
  - Accessing the bookmark while logged out with the proper key will
display it

Fixes #475
2020-10-27 19:32:57 +01:00
ArthurHoaro
e6215a2ad9
Merge pull request #1604 from ArthurHoaro/feature/server-admin-page
Feature: add a Server administration page
2020-10-27 19:29:43 +01:00
ArthurHoaro
034c1ce526
Merge pull request #1609 from GaneshKandu/patch-1 2020-10-27 19:27:06 +01:00
Ganesh Kandu
e69e3fef7b
Removed PHP_EOL
just replace "*/ ?>" and "<?php /*" with '' and "Trim" output whatever is EOF will trimmed out.
2020-10-27 18:08:14 +05:30
Ganesh Kandu
42a72c02fa
Replaced PHP_EOL to "\n"
i was getting error 

```
An error occurred while parsing JSON configuration file (data/config.json.php): error code #4
➜ Syntax error
Please check your JSON syntax (without PHP comment tags) using a JSON lint tool such as jsonlint.com.
```
after debug i found 
```php
        $data = str_replace(self::getPhpHeaders(), '', $data);
        $data = str_replace(self::getPhpSuffix(), '', $data);
```
doesn't removing php header and php suffix

cause of this issue was PHP_EOL represents the endline character for the current system. if my  ```config.json.php```  was encoded with unix ( LF ) and php running on windows windows encoding ( CR LF ) is not same as unix encoding ( LF ) so ```str_replace``` doesn't replace strin  then it causes issue.
2020-10-27 17:42:35 +05:30
ArthurHoaro
820cae27cf
Merge pull request #1601 from ArthurHoaro/feature/psr3 2020-10-24 11:37:29 +02:00
Keith Carangelo
49da2ffbce Ignore plugins except for those installed by default 2020-10-23 09:49:40 -04:00
ArthurHoaro
8f6e3d51cc
Merge pull request #1605 from ArthurHoaro/fix/nginx-doc-rule
Fix: nginx - add rule to disable url-rewriting for the docs
2020-10-21 15:55:39 +02:00
ArthurHoaro
2f87bfdc69 Fix: nginx - add rule to disable url-rewriting for the docs
Related to #1603
2020-10-21 15:23:30 +02:00
ArthurHoaro
0cf76ccb47 Feature: add a Server administration page
It contains mostly read only information about the current Shaarli instance,
PHP version, extensions, file and folder permissions, etc.
Also action buttons to clear the cache or sync thumbnails.

Part of the content of this page is also displayed on the install page,
to check server requirement before installing Shaarli config file.

Fixes #40
Fixes #185
2020-10-21 15:06:47 +02:00
ArthurHoaro
3445443349
Merge pull request #1602 from ArthurHoaro/fix/root-exceptions
Dislay an error if an exception occurs in the error handler
2020-10-20 21:37:20 +02:00
ArthurHoaro
5c06c0870f Dislay an error if an exception occurs in the error handler
Related to #1598
2020-10-20 18:32:46 +02:00
ArthurHoaro
b38a1b0209 Use PSR-3 logger for login attempts
Fixes #1122
2020-10-20 11:47:07 +02:00
ArthurHoaro
ca5e98da48 Composer: explicitly import katzgrau/klogger (already included in netscape-bookmark-parser) 2020-10-20 10:39:58 +02:00
ArthurHoaro
d8030c8155
Merge pull request #1584 from ArthurHoaro/feature/async-thumbnail-retrieval
Asynchronous retrieval of bookmark's thumbnails
2020-10-20 10:30:02 +02:00
ArthurHoaro
21e72da9ee Asynchronous retrieval of bookmark's thumbnails
This feature is based general.enable_async_metadata setting and works with existing metadata.js file.
The script is compatible with any template:
   - the thumbnail div bloc must have  attribute
   - the bookmark bloc must have  attribute with the bookmark ID as value

Fixes #1564
2020-10-20 10:15:18 +02:00
ArthurHoaro
9b3c1270bc
Merge pull request #1567 from ArthurHoaro/feature/async-title-retrieval 2020-10-20 10:14:28 +02:00
ArthurHoaro
552c3b942a
Merge pull request #1600 from yudete/master 2020-10-20 10:08:03 +02:00
yudete
5256b42870 Update translations (Japanese) 2020-10-19 10:25:51 +09:00
yudete
52e27a96a4 Update translations (Japanese) 2020-10-19 10:17:35 +09:00
ArthurHoaro
6866ed766f
Merge pull request #1588 from ArthurHoaro/feature/search-highlight 2020-10-16 20:40:49 +02:00
ArthurHoaro
f1a148ab92 add search highlight unit tests 2020-10-16 20:31:49 +02:00
ArthurHoaro
4e3875c0ce Feature: highlight fulltext search results
How it works:

  1. when a fulltext search is made, Shaarli looks for the first
occurence position of every term matching the search. No change here,
but we store these positions in an array, in Bookmark's additionalContent.
  2. when formatting bookmarks (through BookmarkFormatter
implementation):
    1. first we insert specific tokens at every search result positions
    2. we format the content (escape HTML, apply markdown, etc.)
    3. as a last step, we replace our token with displayable span
elements

Cons: this tightens coupling between search filters and formatters
Pros: it was absolutely necessary not to perform the
search twice. this solution has close to no impact on performances.

Fixes #205
2020-10-16 20:31:12 +02:00
ArthurHoaro
64cac25626
Merge pull request #1596 from ArthurHoaro/feature/better-rename-tag
Improve Manage tags page
2020-10-16 20:15:19 +02:00
ArthurHoaro
3cb4e8a44c Improve Manage tags page
Fixes #1125
2020-10-16 20:03:25 +02:00
ArthurHoaro
81c9df1363
Merge pull request #1593 from ArthurHoaro/fix/no-url-rewriting 2020-10-16 19:26:03 +02:00
ArthurHoaro
7836ed9b2e Doc: typo 2020-10-16 19:20:45 +02:00
ArthurHoaro
3adbdc2a83 Inject ROOT_PATH in plugin instead of regenerating it everywhere 2020-10-16 13:06:06 +02:00
ArthurHoaro
7f5250421b Support using Shaarli without URL rewriting
- Shaarli can be fully used by prefixing any URL with /index.php/
   - {$base_path} used in templates already works with this configuration
   - Assets path (outside of theme's assets) must be prefixed with {$root_url}/
   - Documentation section in « Server configuration »

Fixes #1590
2020-10-16 12:47:11 +02:00
ArthurHoaro
cd2878edee
Merge pull request #1592 from ArthurHoaro/fix/strict-type-daily
Strict types: fix an issue in daily where the date could be an int
2020-10-16 12:16:54 +02:00
ArthurHoaro
4b3aca6623 Strict types: fix an issue in daily where the date could be an int 2020-10-16 12:04:46 +02:00
ArthurHoaro
5334090be0 Improve metadata retrieval (performances and accuracy)
- Use dedicated function to download headers to avoid apply multiple regexps on headers
  - Also try to extract title from meta tags
2020-10-15 11:36:56 +02:00
ArthurHoaro
4cf3564d28 Add a setting to retrieve bookmark metadata asynchrounously
- There is a new standalone script (metadata.js) which requests
    a new controller to get bookmark metadata and fill the form async
  - This feature is enabled with the new setting: general.enable_async_metadata
    (enabled by default)
  - general.retrieve_description is now enabled by default
  - A small rotating loader animation has a been added to bookmark inputs
    when metadata is being retrieved (default template)
  - Custom JS htmlentities has been removed and  mathiasbynens/he
    library is used instead

Fixes #1563
2020-10-15 09:08:46 +02:00
ArthurHoaro
f34554c6c2
Merge pull request #1591 from ArthurHoaro/doc/server-conf-php-v
Doc: add PHP 7.4 and 8.0 as supported version
2020-10-15 09:06:27 +02:00
ArthurHoaro
ec45749187 Doc: add PHP 7.4 and 8.0 as supported version 2020-10-15 09:01:41 +02:00
ArthurHoaro
4a26974a4b
Merge pull request #1583 from ArthurHoaro/feature/bookmark-strict-types
Add strict types for bookmarks management
2020-10-13 13:56:07 +02:00
ArthurHoaro
efb7d21b52 Add strict types for bookmarks management
Parameters typing and using strict types overall increase the codebase
quality by enforcing the a given parameter will have the expected type.

It also removes the need to unnecessary unit tests checking methods
behavior with invalid input.
2020-10-13 13:50:11 +02:00
ArthurHoaro
29c31b7ec6
Merge pull request #1570 from ArthurHoaro/feature/datastore-mutex
Add mutex on datastore I/O operations
2020-10-13 13:30:37 +02:00
ArthurHoaro
fd1ddad98d Add mutex on datastore I/O operations
To make sure that there is no concurrent operation on the datastore file.

Fixes #1132
2020-10-13 12:38:19 +02:00
ArthurHoaro
458b6b9918
Merge pull request #1540 from ArthurHoaro/fix/metadata-regexes
Improve regex to extract HTML metadata (title, description, etc.)
2020-10-13 12:26:55 +02:00
ArthurHoaro
543b16b4f4
Merge pull request #1525 from ArthurHoaro/feature/rest-api-bookmark-dates
REST API: allow override of creation and update dates
2020-10-13 12:26:01 +02:00
ArthurHoaro
8f269b49d7
Merge pull request #1521 from ArthurHoaro/feature/markdown-extra
Add Markdown Extra formatter
2020-10-13 12:25:12 +02:00
ArthurHoaro
8fabcd0224 Add Markdown Extra formatter
Library: [Parsedown Extra](https://github.com/erusev/parsedown-extra)

Also sort dependencies alphabetically.

Fixes #1169
2020-10-13 12:20:34 +02:00
ArthurHoaro
84045ffbb1 Update badge versions 2020-10-13 12:01:19 +02:00
ArthurHoaro
64152387d6
Merge pull request #1589 from ArthurHoaro/changelog/v0.12.0
CHANGELOG and AUTHORS for v0.12.0
2020-10-13 11:49:07 +02:00
ArthurHoaro
2d015d79b7 CHANGELOG and AUTHORS for v0.12.0 2020-10-13 11:44:31 +02:00
ArthurHoaro
3020310dd0
Merge pull request #1586 from ArthurHoaro/changelog/v0.12.0-beta-2
CHANGELOG and AUTHORS for v0.12.0-beta-2
2020-10-08 08:54:19 +02:00
ArthurHoaro
b028f0869f CHANGELOG and AUTHORS for v0.12.0-beta-2 2020-10-08 08:41:30 +02:00
ArthurHoaro
7f1bb5553b
Merge pull request #1585 from ArthurHoaro/fix/xss-and-tag-search
Security: fix multiple XSS vulnerabilities + fix search tags with special chars
2020-10-08 08:19:06 +02:00
ArthurHoaro
72fbbcd679 Security: fix multiple XSS vulnerabilities + fix search tags with special chars
XSS vulnerabilities fixed in editlink, linklist, tag.cloud and tag.list.

Also fixed tag search with special characters: urlencode function needs to be applied on raw data, before espaping, otherwise the rendered URL is wrong.
2020-10-06 17:30:18 +02:00
nodiscc
df25b28dcd
Merge pull request #1579 from sprak3000/issue-1437-tag-sort-buttons-ui
Fix #1437 - Make tag cloud/list views buttons more obvious
2020-10-04 11:45:24 +00:00
nodiscc
fc4d1b6796
Merge pull request #1581 from nodiscc/compose-traefik-version
docker-compose.yml: pin traefik image to 1.7-alpine
2020-10-04 11:33:57 +00:00
nodiscc
bb176441cb docker-compose.yml: pin traefik image to 1.7-alpine
- fixes https://github.com/shaarli/Shaarli/issues/1493
- https://hub.docker.com/_/traefik/
2020-10-03 14:35:06 +02:00
ArthurHoaro
7b18876361
Merge pull request #1575 from ArthurHoaro/feature/php8 2020-10-03 12:59:16 +02:00
ArthurHoaro
ee07b7283f
Merge pull request #1574 from stoeps13/hosting-fix 2020-10-03 12:59:01 +02:00
sprak3000
f4ea7cd563 Issue #1437 - Make tag cloud/list views buttons more obvious
This work alters the markup and CSS for the tag sort UI to match the button feel filters and links per page uses.
2020-10-02 14:06:02 -04:00
ArthurHoaro
1db2ebbd79
Merge pull request #1577 from ArthurHoaro/fix/edit-zero
Fix a bug preventing to edit bookmark with ID #0
2020-10-02 14:24:07 +02:00
ArthurHoaro
255b2264a1 Revert unrelated changes and add unit tests 2020-09-30 15:57:57 +02:00
ArthurHoaro
80a3efe116 Fix a bug preventing to edit bookmark with ID #0 2020-09-30 15:31:34 +02:00
Christoph Stoettner
25cb75552b Fix identation 2020-09-30 12:29:54 +02:00
Christoph Stoettner
d8ef4a893f Change to ->container->environment 2020-09-30 12:27:44 +02:00
ArthurHoaro
95158e7565
Merge pull request #1576 from ArthurHoaro/release/v0.12.0-beta-1/changelog
Update CHANGELOG and AUTHOR
2020-09-30 11:59:42 +02:00
ArthurHoaro
22e75f062d Update CHANGELOG and AUTHOR 2020-09-30 11:55:51 +02:00
ArthurHoaro
c3fca560b6
Merge pull request #1569 from ArthurHoaro/fix/bad-encoding
Fix warning if the encoding retrieved from external headers is invalid
2020-09-30 11:35:57 +02:00
ArthurHoaro
769a28833b
Merge pull request #1566 from nodiscc/makefile-composer-install
doc/Makefile: remove references to composer update
2020-09-30 11:12:17 +02:00
ArthurHoaro
1ea09a1b8b Fix warning if the encoding retrieved from external headers is invalid
Also fixed the regex to support this failing header: charset="utf-8"\r\n"
2020-09-30 11:11:19 +02:00
ArthurHoaro
d246e2c512 Use assertRegExp polyfill instead of regexMatches 2020-09-29 18:57:25 +02:00
ArthurHoaro
3a49307c3d Ignore PHP deps when removing phpunit in PHP 8.0 environment 2020-09-29 18:57:25 +02:00
ArthurHoaro
d018755b45 Update composer dependencies from PHP 7.1 2020-09-29 18:57:25 +02:00
ArthurHoaro
f447edb73b Fix missing @expectedException convertion 2020-09-29 18:57:25 +02:00
ArthurHoaro
ab58f25420 Compatibility with PHP 8 2020-09-29 18:57:22 +02:00
ArthurHoaro
a5a9cf23ac Compatibility with PHPUnit 9 2020-09-29 18:57:20 +02:00
ArthurHoaro
2b7a7bc928 Run CI against PHP 8.0 2020-09-29 18:57:17 +02:00
Christoph Stoettner
676571dab9 Workaround for hoster (ionos)
The hoster writes the environment variable with bearer token to
REDIRECT_HTTP_AUTHORIZATION and needs to provide RewriteBase / to
.htaccess
2020-09-29 12:15:04 +02:00
ArthurHoaro
6cdca9562c
Merge pull request #1572 from ArthurHoaro/feature/php8 2020-09-29 11:36:27 +02:00
ArthurHoaro
b1baca99f2 Convert legacy PHPUnit @expected* to new ->expect*
Converted automatically using https://github.com/ArthurHoaro/convert-legacy-phpunit-expect
2020-09-27 14:09:55 +02:00
ArthurHoaro
8f60e1206e Comply with PHPUnit V8: setup/teardown functions must return void 2020-09-26 15:08:39 +02:00
ArthurHoaro
24225f6332 tmp 2020-09-26 14:43:21 +02:00
ArthurHoaro
e011be0170 Travis CI: run composer update instead of install
And ignore PHP 7.1 platform requirement, in order to get matching version of PHPUnit
2020-09-26 14:33:27 +02:00
ArthurHoaro
d0ae1ba273
Merge pull request #1568 from ArthurHoaro/fix/vintage-linkdate
Fix undefined linkdate variable in vintage theme
2020-09-26 11:58:32 +02:00
ArthurHoaro
1cb5be5d0c Fix undefined linkdate variable in vintage theme
Fixes #1371
2020-09-25 18:24:53 +02:00
ArthurHoaro
585fc700fa
Merge pull request #1560 from ArthurHoaro/fix/redirect-wrong-path
Fix invalid redirection using the path of an external domain
2020-09-25 10:59:51 +02:00
ArthurHoaro
85b972baf6
Merge pull request #1558 from ArthurHoaro/fix/plugins-base-path
Fix plugin base path in core plugins
2020-09-25 10:59:40 +02:00
ArthurHoaro
71eb87353c
Merge pull request #1565 from nodiscc/rm-makefile-summary
Makefile: remove static_analysis_summary from all: target
2020-09-25 10:57:25 +02:00
nodiscc
0f686afe11 doc/Makefile: remove references to composer update
- add make composer_dependencies_dev Makefile target and use this instead
- fix composer initial installation procedure
- fix php-xdebug install instructions
2020-09-24 21:51:28 +02:00
nodiscc
6ec24b3605 Makefile: remove static_analysis_summary from all: target
static_analysis_summary was removed in 37c9c6b#diff-b67911656ef5d18c4ae36cb6741b7965 but not from the all: target dependencies. Therefore running make all always fails.
fixes https://github.com/shaarli/Shaarli/issues/1459
2020-09-24 21:45:17 +02:00
ArthurHoaro
cdb96276c1
Merge pull request #1561 from ArthurHoaro/feature/front-deps-upgrade 2020-09-23 15:50:23 +02:00
ArthurHoaro
9192a48be3 Fix ESLint after dependency upgrade 2020-09-22 18:14:18 +02:00
ArthurHoaro
98325d646e Bump NodeJS version on travis build 2020-09-22 17:57:54 +02:00
ArthurHoaro
96746d7165 Upgrade front end dependencies
Mostly in order to get rid of deprecated deps, and upgrade vulnerable ones.

  - Upgrade webpack from 3.x to 4.x
  - Moved babel package to main repo
  - Replaced deprecated extract-text-webpack-plugin with extract-text-webpack-plugin
  - Replaced deprecated babel-minify-webpack-plugin with terser-webpack-plugin
  - Replaced deprecated node-sass with (dart) sass package
  - Replaced deprecated sass-lint with stylelint (the rules might be a bit different

Related to #1531: trivy doesn't raise any more issue
2020-09-22 17:51:42 +02:00
ArthurHoaro
abe033be85 Fix invalid redirection using the path of an external domain
Fixes #1554
2020-09-22 15:37:26 +02:00
ArthurHoaro
5baafe5001
Merge pull request #1559 from ArthurHoaro/fix/edit-redirect
Fix redirection to referer after editing a link
2020-09-22 14:15:13 +02:00
ArthurHoaro
98e7a59ca2
Merge pull request #1539 from ArthurHoaro/feature/manual-root-url 2020-09-22 14:08:54 +02:00
ArthurHoaro
2785d85e0a Fix redirection to referer after editing a link
Fixes #1545
2020-09-22 14:04:10 +02:00
ArthurHoaro
76fe68d924 Fix plugin base path in core plugins
Also fix note check in archiveorg plugin, and regression on vintage template.
Documentation regarding relative path has been added.

Fixes #1548
2020-09-22 13:50:19 +02:00
ArthurHoaro
6f199ee489
Merge pull request #1556 from kcaran/apache_methods 2020-09-22 11:45:58 +02:00
Keith Carangelo
4488ea4bb9 Added PATCH to the allowed Apache request methods. 2020-09-14 15:32:51 -04:00
ArthurHoaro
0d930454a2
Merge pull request #1553 from ArthurHoaro/fix/404-page
Properly handle 404 errors
2020-09-12 21:41:58 +02:00
ArthurHoaro
4af591ff3c
Merge pull request #1551 from ArthurHoaro/fix/plugin-save-metadata
Plugins: do not save metadata along plugin parameters
2020-09-12 21:41:24 +02:00
ArthurHoaro
b93cfeba7b Fix subfolder configuration in unit tests 2020-09-12 21:39:01 +02:00
ArthurHoaro
650a5f09cb Add manual configuration for root URL
This new setting under 'general.root_url' allows to override automatic discovery of Shaarli instance's URL.

Fixes #1339
2020-09-12 21:39:01 +02:00
nodiscc
e809908f9e
Merge pull request #1389 from shaarli/doc-rework-setup
doc: rework installation/setup guides, general refactoring
2020-09-12 12:38:05 +00:00
ArthurHoaro
97870f3512 doc: Docker minor improvements 2020-09-12 14:31:45 +02:00
Immánuel!
68855686db Add 2 plugins to the 3rd party plugin list
Besides adding 2 new plugins, also reordered the list by ABC and fixed some discrepancies in the details to restore balance in the force
2020-09-12 14:31:45 +02:00
nodiscc
a5e9f2d6c9 doc: nginx config: document ipv4 and ipv6 listen directives 2020-09-12 14:31:45 +02:00
nodiscc
61f0c4b679 doc: apache config: remove useless documentroot directive in HTTP-only virtualhost (only used for redirects) 2020-09-12 14:31:45 +02:00
nodiscc
f682f1b899 doc: serve configuration/reverse proxy: fix apache mod_md configuration, move reference links to their respective sections, shorten 2020-09-12 14:31:45 +02:00
nodiscc
083b28021a doc: server configuration: fix apache restart command 2020-09-12 14:31:45 +02:00
nodiscc
19489e92d7 doc: server configuration: enable mod_headers 2020-09-12 14:31:45 +02:00
nodiscc
5eece37b0a doc: server configuration: fix apache site config file name 2020-09-12 14:31:45 +02:00
nodiscc
d8847936d4 doc: server configuration: add reminder to change the example domain name 2020-09-12 14:31:45 +02:00
nodiscc
9417f1337e doc: server configuration: add asciicast of server configuration procedure (asciinema) 2020-09-12 14:31:45 +02:00
nodiscc
1a19c921a9 doc: updagrde/migration: simplify permissions setup 2020-09-12 14:31:45 +02:00
nodiscc
78b5b44d8f doc: installation: simplify permissions setup 2020-09-12 14:31:45 +02:00
nodiscc
ff2b5f5bd8 doc: docker: update docker-compose to 1.26.2 2020-09-12 14:31:45 +02:00
nodiscc
48b19a7014 doc: installation: bump version to 0.11.1 2020-09-12 14:31:45 +02:00
nodiscc
02117f7ea3 doc: reverse proxy: update HTTP->HTTPS redirect configuration, remove logging options 2020-09-12 14:31:45 +02:00
nodiscc
e21df1e729 doc: fail2Ban: add note about restarting fail2ban 2020-09-12 14:31:45 +02:00
nodiscc
f3ab261631 doc: apache: add example configuration for mod_md 2020-09-12 14:31:45 +02:00
nodiscc
38d66e1a40 doc: server configuration: apache: add note about mod_md 2020-09-12 14:31:45 +02:00
nodiscc
ecdae2237f doc: server configuration: update apache configuration 2.2 -> 2.4
https://httpd.apache.org/docs/current/upgrading.html
2020-09-12 14:31:45 +02:00
nodiscc
45203c0bca doc: Community-and-related-software.md: order plugins alphabetically 2020-09-12 14:31:45 +02:00
nodiscc
46e019a132 doc: plugins: remove doc about deprecated $GLOBALS['config']['ENABLED_PLUGINS'] array 2020-09-12 14:31:45 +02:00
nodiscc
78f319fa6b doc: troubleshooting: add procedure to clear shaarli caches 2020-09-12 14:31:45 +02:00
nodiscc
6c4cae378e doc: server configuration: remove apache logging options
see https://github.com/nodiscc/xsrv/blob/master/roles/apache/templates/etc_apache2_conf-available_logging.conf.j2 for an example server-wide logging configuration
2020-09-12 14:31:45 +02:00
nodiscc
1aeefe1088 doc: server configuration: formatting/add comment 2020-09-12 14:31:45 +02:00
nodiscc
e0fe33f90b doc: server configuration: add note on required firewall/NAT for Let's Encrypt certificates 2020-09-12 14:31:45 +02:00
Lucas Cimon
b6c9a2db30 Removing dead link in doc
As it currently redirects to https://www.lgblog.fr
2020-09-12 14:31:45 +02:00
nodiscc
5cacf290f0 doc: document dev.debug configuration etting
ref. https://github.com/shaarli/Shaarli/pull/779
2020-09-12 14:31:45 +02:00
owen bell
56ae25f11f add shaarli-default-dark to the themes list 2020-09-12 14:31:45 +02:00
Lucas Cimon
f5afa87c38 Added links to doc section "Articles and social media discussions" 2020-09-12 14:31:45 +02:00
nodiscc
dfe14f264b doc: server configuration: php requirements: add php-simplexml
ref. https://github.com/shaarli/Shaarli/pull/1476
2020-09-12 14:31:45 +02:00
nodiscc
74c2ae4088 doc: Community-and-related-software: add shaarli-webhooks plugin 2020-09-12 14:31:45 +02:00
nodiscc
328c215a8a doc: add note about importing browser bookmarks folder structure to shaarli tags
ref. https://github.com/shaarli/Shaarli/issues/1449
2020-09-12 14:31:45 +02:00
nodiscc
dfed9b2dd5 doc: troubleshooting: improve compatibility with PHP 5.6/FTP upload limits
ref. https://github.com/shaarli/Shaarli/issues/1469
2020-09-12 14:31:45 +02:00
nodiscc
881bd96f15 doc: usage: active filters/clear search filters 2020-09-12 14:31:45 +02:00
nodiscc
778add2c9c doc: nginx: add let's encrypt ssl configuration 2020-09-12 14:31:45 +02:00
nodiscc
538fb324a8 doc: nginx: reorder 2020-09-12 14:31:45 +02:00
nodiscc
c84d143047 apache: fix let's encrypt configuration , copy it directly from reference file
including options-ssl-apache.conf requires python3-certbot-apache which pulls a lot of dependencies
2020-09-12 14:31:45 +02:00
nodiscc
30255b794a doc: php compatibility: add php 7.3 2020-09-12 14:31:45 +02:00
nodiscc
41b93897f3 server-configuration: move firewall/NAT requirements to Network section 2020-09-12 14:31:45 +02:00
nodiscc
6384447d1d fix markdown syntax 2020-09-12 14:31:45 +02:00
nodiscc
a32e6665d0 formatting/emphasis 2020-09-12 14:31:45 +02:00
nodiscc
fe007f94e4 doc: docker.md: fix stray code block 2020-09-12 14:31:45 +02:00
nodiscc
91a21c2729 **General rewording, proof-reading, deduplication, shortening, reordering, simplification, cleanup/formatting/standardization**
- standardize page names, rework documentation structure, update TOC
- use same example paths everywhere
- level 1 titles on all pages
- fix broken links
- .md suffix on all page links (works both from readthedocs and github repository views)

**Server:**

A full and concise installation guide with examples is a frequent request. The documentation should provide such a guide for basic installation needs, while explaining alternative/advanced configuration at the end. Links to reference guides and documentation should be used more frequently to avoid recommending an outdated or excessively complex configuration.

- server: move most server-related info to server-configuration.md, cleanup/shorten
- server: update list of php dependencies/libraries, link to composer.json
- server: installation: support 3 install methods (from release zip, from sources, using docker)
- server: installation: use rsync instead of mv as mv results will change depending of taget directory already existing or not
- server: add example/basic usage of certbot
- server, upgrade, installation: update file permissions setup, use sudo for upgrade operations in webserver document root
- server: apache: add comments to configuration, fix and factorize file permissions setup, set cache-control header, deny access to dotfiles, add missing apache config steps, add http->https redirect example
- server: nginx: refactor nginx configuration, add comments, DO log access to denied/protected files
- server: add links to MDN for x-forwarded-* http headers explanation, cleanup/clarify robots.txt and crawlers section
- server: bump file upload size limit to 100MB we have reports of bookmark exports weighing +40MB - i have a 13MB one here
- server: simplify phpinfo documentation
- server: move backup and restore information to dedicated page
- docker: move all docker docs to Docker.md, simplify/ docker setup, add docker-compose.yml example, replace docker-101 with docker cheatsheet
- troubleshooting: move all troubleshooting documentation to troubleshooting.md

**Usage:**

- index: add getting started section on index page
- features/usage: move all usage-related documentation to usage.md, add links from the main feature list to corresponding usage docs, clarify/reword features list
- shaarli configuration: add note about configuring from web interface

**Removed:**

- remove obsolete/orphan images
- remove obsolete shaarchiver example
- remove outdated "decode datastore content" snippet

**Development:**

- development: move development-related docs (static analysis, CI, unit tests, 3rd party libs, link structure/directory, guidelines, security....) to dev/ directory
- development: Merge several pages to development.md
- **Breaking change?:** remove mentions of 'stable' branch, switch to new branch/release model (master=latest commit, release=latest tag)
- **Breaking change?:** refer to base sharing unit as "Shaare" everywhere (TODO: reflect changes in the code?) doc: update featues list/link to usage.md for details
- development: directory structure: add note about required file permissions
- .travis-ci.yml: add comments
- .htaccess: add comment
2020-09-12 14:31:45 +02:00
ArthurHoaro
4ff703e369 Plugins: do not save metadata along plugin parameters
Also prevent the token to be saved.

Fixes #1550
2020-09-12 13:29:34 +02:00
ArthurHoaro
d52ab0b1e9 Properly handle 404 errors
Use 404 template instead of default Slim error page if the route is not found.

Fixes #827
2020-09-12 12:42:19 +02:00
ArthurHoaro
6128ab6a55
Merge pull request #1552 from ArthurHoaro/feature/better-initializer 2020-09-12 12:14:18 +02:00
ArthurHoaro
da7acb9830 Improve default bookmarks after install
Used @nodiscc suggestion in #1148 (slightly edited).
It provides a description of what Shaarli does, Markdown rendering demo, and a thumbnail link.

Fixes #1148
2020-09-10 16:29:17 +02:00
ArthurHoaro
e2dff28b44
Merge pull request #1547 from ArthurHoaro/fix/daily-visibility
Fix visibility issue on daily page
2020-09-06 14:16:08 +02:00
ArthurHoaro
949a095310
Merge pull request #1538 from ArthurHoaro/feature/plugins-bookmark-service
Inject BookmarkServiceInterface in plugins data
2020-09-06 14:13:16 +02:00
ArthurHoaro
27ddfec3c3 Fix visibility issue on daily page
This filter (links by day) didn't apply any visibility parameter.

Fixes #1543
2020-09-06 14:11:02 +02:00
ArthurHoaro
a5dd7d58d2
Merge pull request #1546 from immanuelfodor/patch-2
Fix broken css/js files on individual shaare pages
2020-09-06 13:38:31 +02:00
Immánuel!
707a1d237a
Fix broken css/js files on individual shaare pages 2020-09-06 13:29:38 +02:00
ArthurHoaro
a3cb851d0c
Merge pull request #1542 from shaarli/dependabot/npm_and_yarn/node-sass-4.13.1
Bump node-sass from 4.12.0 to 4.13.1
2020-09-06 13:24:09 +02:00
dependabot[bot]
7b05dd71f3
Bump node-sass from 4.12.0 to 4.13.1
Bumps [node-sass](https://github.com/sass/node-sass) from 4.12.0 to 4.13.1.
- [Release notes](https://github.com/sass/node-sass/releases)
- [Changelog](https://github.com/sass/node-sass/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sass/node-sass/compare/v4.12.0...v4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-04 09:54:32 +00:00
Keith Carangelo
e2a2441d3b Merge branch 'links_per_page' 2020-09-03 15:39:31 -04:00
ArthurHoaro
2ba51040c7
Merge pull request #1541 from ArthurHoaro/fix/legacy-login-encoding 2020-09-03 18:54:45 +02:00
ArthurHoaro
d33cffdb2e Fix: encoding in legacy route login redirection to post bookmark
When a bookmark is post from a logged out user, he is first redirected to the login page with 'returnurl' containing the link, then redirected again when the login is processed.
We need to reencode the posted URL, otherwise the browser does not handle the fragment as a part of the posted parameter.
2020-09-03 18:46:10 +02:00
ArthurHoaro
2cd0509b50 Improve regex to extract HTML metadata (title, description, etc.)
Also added a bunch of tests to cover more use cases.

Fixes #1375
2020-09-03 17:46:26 +02:00
ArthurHoaro
80b708a878 Inject BookmarkServiceInterface in plugins data
Related discussion: ilesinge/shaarli-related#7
2020-09-03 15:08:08 +02:00
ArthurHoaro
46d3f8162b
Merge pull request #1537 from ArthurHoaro/fix/back-compatible-targets 2020-09-03 14:57:24 +02:00
ArthurHoaro
0386a84d82 Fix feed target in UT 2020-09-03 10:18:04 +02:00
ArthurHoaro
ce7918386a Improve backward compatibility for LegacyRouter
LegacyRouter is no longer used for routing, only in existing plugins to match the _PAGE_ parameter.
So we change a few of its values there, to match the new ones defined in TemplatePage.

@see discussion in shaarli/Shaarli#1537
2020-09-03 10:09:36 +02:00
ArthurHoaro
21163a3329
Merge pull request #1519 from ArthurHoaro/fix/mobile-pin-link
Default template: display pin button in mobile view
2020-09-03 08:49:20 +02:00
ArthurHoaro
865f0a0e01
Merge pull request #1523 from ArthurHoaro/fix/default-colors-generation
Default colors plugin: generate CSS file during initialization
2020-09-03 08:48:51 +02:00
ArthurHoaro
9e6371a6fd
Merge pull request #1520 from ArthurHoaro/fix/jp-language 2020-09-03 08:46:47 +02:00
ArthurHoaro
0a286f6946
Merge pull request #1526 from kcaran/links_per_page 2020-09-03 08:45:48 +02:00
ArthurHoaro
2835ac7cbe
Merge pull request #1524 from ArthurHoaro/fix/rss-sticky
Fixed: Pinned bookmarks are displayed first in ATOM/RSS feeds
2020-09-03 08:45:12 +02:00
ArthurHoaro
ca636b898c
Merge pull request #1536 from ArthurHoaro/fix/login-private-shaarli
Fix login loop for private instances
2020-09-03 08:35:18 +02:00
ArthurHoaro
d95624add4
Merge pull request #1534 from ArthurHoaro/fix/legacy-route-post 2020-09-03 08:35:05 +02:00
ArthurHoaro
43582975dc
Merge pull request #1535 from ArthurHoaro/fix/export-token
Export: refresh CRSF token after submit
2020-09-03 08:34:57 +02:00
Keith Carangelo
82fcace8fc Merge branch 'master' of https://github.com/shaarli/Shaarli into links_per_page 2020-09-02 11:38:56 -04:00
ArthurHoaro
14fcfb5213 Fix login loop for private instances
GET /login and POST /login have 2 distinct route name.

Fixes #1533
2020-09-01 11:26:24 +02:00
ArthurHoaro
cd10bc23e7 Export: refresh CRSF token after submit
This allow users to submit the form multiple times, because there is no actual browser redirection to the page.

Fixes #1532
2020-09-01 11:01:21 +02:00
ArthurHoaro
11aa4a7a29 Support redirection of legacy route 'do=configure' 2020-09-01 10:40:35 +02:00
ArthurHoaro
9e2d47e519 Fix legacy redirection when Shaarli instance is under a subfolder 2020-09-01 10:40:18 +02:00
ArthurHoaro
aca995e09c Fix support for legacy route login redirection
Makes sure that the user is properly redirected to the bookmark form after login, even with legacy routes
2020-09-01 10:12:54 +02:00
ArthurHoaro
0e60b7f174
Merge pull request #1530 from ArthurHoaro/fix/untagged-only-broken
Fix broken route to filter not tagged bookmarks
2020-09-01 09:37:01 +02:00
Keith Carangelo
4479aff18f
Avoid using global variables
Co-authored-by: ArthurHoaro <arthur@hoa.ro>
2020-08-31 09:20:03 -04:00
ArthurHoaro
63b0059ed5 Fix broken route to filter not tagged bookmarks
Also display the filter for visitors.

Fixes #1529
2020-08-31 14:09:27 +02:00
ArthurHoaro
06f05c923a
Merge pull request #1512 from shaarli/dependabot/npm_and_yarn/elliptic-6.5.3
Bump elliptic from 6.4.1 to 6.5.3
2020-08-31 14:06:32 +02:00
ArthurHoaro
a975d97a8d
Merge pull request #1505 from shaarli/dependabot/npm_and_yarn/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19
2020-08-31 14:03:58 +02:00
Keith Carangelo
e813934ae1 Moved definition of a.selected to pass sasslint test 2020-08-30 07:26:21 -04:00
Keith Carangelo
816ffba74b Added $links_per_page variable to template and display on default 2020-08-29 11:02:59 -04:00
ArthurHoaro
b06fc28aa3 REST API: allow override of creation and update dates
Note that if they're not provided, default behaviour will apply:
creation and update dates will be autogenerated, and not empty.

Fixes #1223
2020-08-29 11:45:08 +02:00
ArthurHoaro
a8e210faa6 Fixed: Pinned bookmarks are displayed first in ATOM/RSS feeds
Fixes #1485
2020-08-29 10:06:40 +02:00
ArthurHoaro
972daa4513 Default colors plugin: generate CSS file during initialization
Current behaviour only generate the custom CSS file when the plugin settings are saved, which can be annoying if the file is deleted but the settings are set.
Most common use case is Docker deployment, because the plugin directory is not mounted as a volume.
2020-08-29 09:38:30 +02:00
ArthurHoaro
8af1d2da60 Fix UT 2020-08-27 15:26:52 +02:00
ArthurHoaro
ebc027ec0a Japanese translation: add language to admin configuration page
Also use ISO country code (JP) instead of JA.
2020-08-27 15:00:48 +02:00
ArthurHoaro
3eba6bd318 Default template: display pin button in mobile view
Fixes #1347
2020-08-27 14:48:07 +02:00
ArthurHoaro
bea062149e
Merge pull request #1518 from ArthurHoaro/authors/v0.12.0-beta
Update authors for v0.12.0-beta
2020-08-27 13:56:36 +02:00
ArthurHoaro
2d8a0a71a8 Update authors for v0.12.0-beta 2020-08-27 13:52:18 +02:00
ArthurHoaro
46237c9788
Merge pull request #1517 from ArthurHoaro/changelog/v0.12.0-beta
Changelog for v0.12.0-beta
2020-08-27 13:44:18 +02:00
ArthurHoaro
6152a26790 Changelog for v0.12.0-beta 2020-08-27 13:39:49 +02:00
ArthurHoaro
109ebf318f
Merge pull request #1516 from ArthurHoaro/feature/plugin-incompatibility
Better handling of plugin incompatibility
2020-08-27 12:10:16 +02:00
ArthurHoaro
7e3dc0ba98 Better handling of plugin incompatibility
If a PHP is raised while executing plugin hook, Shaarli will display an error instead of rendering the error page (or just ending in fatal error for default hooks).
Also added phpErrorHandler which is handled differently that regular errorHandler by Slim.:
2020-08-27 12:04:36 +02:00
ArthurHoaro
af41d5ab5d
Merge pull request #1511 from ArthurHoaro/wip-slim-routing 2020-08-27 10:27:34 +02:00
ArthurHoaro
0c6fdbe12b Move error handling to dedicated controller instead of middleware 2020-08-21 10:50:44 +02:00
ArthurHoaro
bedbb845ee Move all admin controller into a dedicated group
Also handle authentication check in a new middleware for the admin group.
2020-08-13 11:08:13 +02:00
ArthurHoaro
1a68ae5a29 Bookmark's thumbnails PHPDoc improvement 2020-08-01 11:14:03 +02:00
ArthurHoaro
d6e5f04d39 Remove anonymous permission and initialize bookmarks on login 2020-08-01 11:10:57 +02:00
dependabot[bot]
af074f9030
Bump elliptic from 6.4.1 to 6.5.3
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.4.1 to 6.5.3.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.4.1...v6.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-30 13:43:35 +00:00
ArthurHoaro
f7f08ceec1 Fix basePath in unit tests reference DB 2020-07-28 22:34:45 +02:00
ArthurHoaro
624123177f Include empty basePath in formatting 2020-07-28 21:09:22 +02:00
ArthurHoaro
301c7ab1a0 Better support for notes permalink 2020-07-28 20:46:11 +02:00
ArthurHoaro
b725eb047d Fix links per page controller path 2020-07-27 12:56:59 +02:00
ArthurHoaro
a285668ec4 Fix redirection after post install login 2020-07-27 12:34:17 +02:00
ArthurHoaro
9fbc42294e New basePath: fix officiel plugin paths and vintage template 2020-07-26 14:43:10 +02:00
ArthurHoaro
bc583903ad Fix: header search action should be on linklist 2020-07-24 12:49:50 +02:00
ArthurHoaro
204035bd3c Fix: visitor are allowed to chose nb of links per page 2020-07-24 12:48:53 +02:00
ArthurHoaro
87ae3c4f08 Fix default link and redirection in install controller 2020-07-24 10:30:47 +02:00
ArthurHoaro
8e9169ceba Update French translation 2020-07-23 21:19:21 +02:00
ArthurHoaro
3ee8351e43 Multiple small fixes 2020-07-23 21:19:21 +02:00
ArthurHoaro
fabff3835d Move PHP and config init to dedicated file
in order to keep index.php as minimal as possible
2020-07-23 21:19:21 +02:00
ArthurHoaro
a8c11451e8 Process login through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
c4ad3d4f06 Process Shaarli install through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
1a8ac737e5 Process main page (linklist) through Slim controller
Including a bunch of improvements on the container,
and helper used across new controllers.
2020-07-23 21:19:21 +02:00
ArthurHoaro
6132d64748 Process thumbnail synchronize page through Slim controllers 2020-07-23 21:19:21 +02:00
ArthurHoaro
764d34a7d3 Process token retrieve through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
1b8620b1ad Process plugins administration page through Slim controllers 2020-07-23 21:19:21 +02:00
ArthurHoaro
78657347c5 Process bookmarks import through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
c70ff64a61 Process bookmark exports through Slim controllers 2020-07-23 21:19:21 +02:00
ArthurHoaro
e8a10f312a Use NetscapeBookmarkUtils object instance instead of static calls 2020-07-23 21:19:21 +02:00
ArthurHoaro
3447d888d7 Pin bookmarks through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
7b8a6f2858 Process change visibility action through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
1ab675445e Fix bookmarklet with new routes
* Use the new shaare route
   * Add source hidden input in editlink template to close the popup after saving
2020-07-23 21:19:21 +02:00
ArthurHoaro
baa6979194 Improve ManageTagController coverage and error handling 2020-07-23 21:19:21 +02:00
ArthurHoaro
9c75f87793 Use multi-level routes for existing controllers instead of 1 level everywhere
Also prefix most admin routes with /admin/
2020-07-23 21:19:21 +02:00
ArthurHoaro
818b3193ff Explicitly define base and asset path in templates
With the new routes, all pages are not all at the same folder level anymore
(e.g. /shaare and /shaare/123), so we can't just use './' everywhere.
The most consistent way to handle this is to prefix all path with the proper variable,
and handle the actual path in controllers.
2020-07-23 21:19:21 +02:00
ArthurHoaro
c22fa57a55 Handle shaare creation/edition/deletion through Slim controllers 2020-07-23 21:19:21 +02:00
ArthurHoaro
8eac2e5488 Process manage tags page through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
66063ed1a1 Process configure page through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
465033230d Password change: UT use case with open shaarli 2020-07-23 21:19:21 +02:00
ArthurHoaro
fdedbfd4a7 Test ShaarliAdminController 2020-07-23 21:19:21 +02:00
ArthurHoaro
ef00f9d203 Process password change controller through Slim 2020-07-23 21:19:21 +02:00
ArthurHoaro
ba43064ddb Process tools page through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
2899ebb5b5 Initialize admin Slim controllers
- Reorganize visitor controllers
  - Fix redirection with Slim's requests base path
  - Fix daily links
2020-07-23 21:19:21 +02:00
ArthurHoaro
af290059d1 Process session filters through Slim controllers
Including:
  - visibility
  - links per page
  - untagged only
2020-07-23 21:19:21 +02:00
ArthurHoaro
893f5159c6 Process remove tag endpoint through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
dd09ec52b2 Refactor front controller tests to create container mock using a trait 2020-07-23 21:19:21 +02:00
ArthurHoaro
5ec4708ced Process OpenSearch controller through Slim
Also it was missing on the default template feeds
2020-07-23 21:19:21 +02:00
ArthurHoaro
7b2ba6ef82 RSS/ATOM feeds: process through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
f4929b1188 Make FeedBuilder instance creation independant of the request stack 2020-07-23 21:19:21 +02:00
ArthurHoaro
c56a540c6e Remove legacy handling of /add-tag route 2020-07-23 21:19:21 +02:00
ArthurHoaro
029ada5a07 PHP 7.1 compatibility 2020-07-23 21:19:21 +02:00
ArthurHoaro
c4d5be53c2 Process Daily RSS feed through Slim controller
The daily RSS template has been entirely rewritten to handle the whole feed through the template engine.
2020-07-23 21:19:21 +02:00
ArthurHoaro
e3d28be967 Slim daily: minor bugfix with empty data 2020-07-23 21:19:21 +02:00
ArthurHoaro
07f99432b7 Slim daily: support legacy query parameter 2020-07-23 21:19:21 +02:00
ArthurHoaro
69e29ff65e Process daily page through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
60ae241251 Process tag list page through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
3772298ee7 Few optimizations and code readability for tag cloud controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
c79473bd84 Handle tag filtering in the Bookmark service 2020-07-23 21:19:21 +02:00
ArthurHoaro
72caf4e84c Working version before optimization 2020-07-23 21:19:21 +02:00
ArthurHoaro
c266a89d0f Process tag cloud page through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
03340c18ea Slim router: handle add tag route 2020-07-23 21:19:21 +02:00
ArthurHoaro
8e47af2b36 Process logout through Slim controller 2020-07-23 21:19:21 +02:00
ArthurHoaro
b0428aa9b0 Migrate cache purge function to a proper class
And update dependencies and tests.

Note that SESSION['tags'] has been removed a log ago
2020-07-23 21:19:21 +02:00
ArthurHoaro
485b168a96 Process picwall rendering through Slim controller + UT 2020-07-23 21:19:21 +02:00
ArthurHoaro
bee33239ed Fix all relative link to work with new URL 2020-07-23 21:19:21 +02:00
ArthurHoaro
b8e3630f2e
Merge pull request #1508 from ArthurHoaro/fix/docker-build-gcc
Fix Docker build: gcc is no longer included in python alpine image
2020-07-23 21:10:47 +02:00
ArthurHoaro
c909f5d5cc Fix Docker build: gcc is no longer included in python alpine image 2020-07-23 21:05:10 +02:00
ArthurHoaro
2a891ca6b1
Merge pull request #1499 from ArthurHoaro/fix/travis-74-build
Travis CI: upgrade distribution and remove deprecated sudo
2020-07-20 18:16:55 +02:00
dependabot[bot]
df46c28208
Bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-16 21:04:59 +00:00
ArthurHoaro
7e884740f1 Travis CI: upgrade distribution and remove deprecated sudo
This upgrade fixes PHP 7.4 fatal error builds, because dist < xenial do
not include php-gd with PHP 7.4.
2020-07-06 09:28:50 +02:00
ArthurHoaro
78c2f122e0
Merge pull request #1428 from pipoprods/feat/ldap-auth 2020-06-25 16:53:18 +02:00
ArthurHoaro
8694e8411b LDAP - Force protocol LDAPv3
On Linux, php-ldap seems to rely on a library which still uses deprecated LDAPv2 as default version,
causing authentication issues.

See: https://stackoverflow.com/a/48238224/1484919
2020-06-25 16:18:25 +02:00
ArthurHoaro
e1231265bc
Merge pull request #1476 from tyjak/master
Fix missing php7-simplexml plugin for Dockerfile.armhf
2020-06-25 13:58:32 +02:00
Sébastien NOBILI
a69cfe0dd2
Update application/security/LoginManager.php
Co-authored-by: ArthurHoaro <arthur@hoa.ro>
2020-06-03 10:36:04 +02:00
Sébastien NOBILI
9ba6982ea3
Update application/security/LoginManager.php
Co-authored-by: ArthurHoaro <arthur@hoa.ro>
2020-06-03 10:35:41 +02:00
Sébastien NOBILI
21e5df5ee8
Update application/security/LoginManager.php
Co-authored-by: ArthurHoaro <arthur@hoa.ro>
2020-06-03 10:34:32 +02:00
David Foucher
c0d750b9e5 Fix missing php7-simplexml plugin
This is to fix this error I got:

  Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for slim/slim 3.12.3 -> satisfiable by slim/slim[3.12.3].
    - slim/slim 3.12.3 requires ext-simplexml * -> the requested PHP extension simplexml is missing from your system.

  To enable extensions, verify that they are enabled in your .ini files:
    - /etc/php7/php.ini
    - /etc/php7/conf.d/00_curl.ini
    - /etc/php7/conf.d/00_iconv.ini
    - /etc/php7/conf.d/00_json.ini
    - /etc/php7/conf.d/00_mbstring.ini
    - /etc/php7/conf.d/00_openssl.ini
    - /etc/php7/conf.d/01_phar.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.
2020-05-23 14:26:04 +02:00
ArthurHoaro
8f80821820
Merge pull request #1461 from flowgunso/documentation_how_create_plugin 2020-05-16 11:35:49 +02:00
flow.gunso
50c9543f7b Add an example for the description variable to the meta file 2020-05-15 22:47:19 +02:00
flow.gunso
8f6202deb0 Document about the .meta file at the plugin creation/initialization 2020-05-15 22:17:48 +02:00
ArthurHoaro
cf01113cad
Merge pull request #1424 from aguytech/master 2020-05-12 09:46:12 +02:00
nodiscc
752bc4c5e6
Merge pull request #1403 from shaarli/doc-composer
doc: simplify composer installation procedure, merge Unit tests related pages, reword/shorten, fix references to old php versions
2020-04-11 13:06:30 +00:00
nodiscc
2dd6ecb126 doc: composer update should actually be removed as it alters the Composer lock file 2020-04-11 13:53:15 +02:00
nodiscc
dbbcb0c6cf
doc: use <PHP_VERSION>, fix php.ini path
Co-Authored-By: Aurélien Tamisier <virtualtam+github@flibidi.net>
2020-03-09 17:44:12 +00:00
nodiscc
273453900a
doc: use obvious <PHP_VERSION> placeholder
Co-Authored-By: Aurélien Tamisier <virtualtam+github@flibidi.net>
2020-03-09 17:43:45 +00:00
nodiscc
1ea8aeef76
doc: fix php.ini path
Co-Authored-By: Aurélien Tamisier <virtualtam+github@flibidi.net>
2020-03-09 17:43:09 +00:00
Sébastien NOBILI
46846fd4fc fixed typo 2020-03-02 18:23:55 +01:00
Sébastien NOBILI
cc2ded54e1 ldap authentication, fixes shaarli/Shaarli#1343 2020-03-02 17:13:18 +01:00
aguy
424530d9af
Add an exception to method 'whitelist_protocols' for url which started with '#'
This is to allow local link for markdown, actually a local link write with this syntax : '[anchor](#local_link)' produce this html code: http://#local_link
2020-02-28 15:14:22 +00:00
ArthurHoaro
810f0f6c96
Merge pull request #1421 from yudete/master
Add Japanese translation
2020-02-17 22:10:57 +01:00
ArthurHoaro
df7c286d91
Merge pull request #1417 from bmsleight/master
Update Makefile
2020-02-17 18:14:47 +01:00
yude
db206aaaca
Update Japanese translations 2020-02-11 10:55:10 +09:00
yude
1f02ae8076
Japanese translation 2020-02-11 09:33:38 +09:00
ArthurHoaro
922341aaa7
Merge pull request #1420 from oktomus/master
Add autofocus on tag cloud filter input
2020-02-10 21:04:42 +01:00
Kevin Masson
82e7b56f29 Add autofocus on tag cloud filter input
Fix #1413
2020-02-10 13:53:44 +01:00
Brendan M. Sleight
52964ec873
Update Makefile
Solve make htmldoc error on python3 ubuntu
2020-02-05 20:07:47 +00:00
ArthurHoaro
f6637392a9
Fix division by zero in tagcloud (#1411)
Fix division by zero in tagcloud
2020-01-26 14:55:07 +01:00
ArthurHoaro
b495d5c92a Fix division by zero in tagcloud
It happens if we have a maximum of 1 occurrence in tags (log(1) = 0)
2020-01-26 14:52:10 +01:00
ArthurHoaro
c653ae3bfb
Render login page through Slim controller (#1401)
Render login page through Slim controller
2020-01-26 11:41:10 +01:00
ArthurHoaro
27ceea2aee Rename ci attribute to container 2020-01-26 11:34:29 +01:00
ArthurHoaro
0498b209b5 Execute common plugin hooks before rendering login page 2020-01-26 11:34:14 +01:00
ArthurHoaro
9e4cc28e29 Fix all existing links and redirection to ?do=login 2020-01-26 11:34:14 +01:00
ArthurHoaro
dd51f653d0 Fix SASS Lint 2020-01-26 11:34:14 +01:00
ArthurHoaro
6c50a6ccce Render login page through Slim controller 2020-01-26 11:34:14 +01:00
ArthurHoaro
1410dce2db
Rollback breaking change in REST API routes (#1410)
Rollback breaking change in REST API routes
2020-01-26 11:33:22 +01:00
ArthurHoaro
20433ea72b Rollback breaking change in REST API routes 2020-01-26 11:30:25 +01:00
ArthurHoaro
529fc750b3
Session cookie setting being set while session is active (#1406)
Session cookie setting being set while session is active
2020-01-26 09:12:44 +01:00
ArthurHoaro
0d42b21200
Fix deprecated use of implode (#1408)
Fix deprecated use of implode
2020-01-23 22:36:00 +01:00
ArthurHoaro
fc6c701774 Fix deprecated use of implode 2020-01-23 22:31:51 +01:00
ArthurHoaro
09390a50cd Session cookie setting being set while session is active
Trying to do will raise a warning since PHP 7.2, and it never worked as intented.
See: https://bugs.php.net/bug.php\?id\=75650
2020-01-23 19:51:14 +01:00
nodiscc
04a816f648 doc: fix references to php5, use new directory structure 2020-01-19 13:52:03 +01:00
nodiscc
3b04d19a62 doc: fix reference to old version of php-xdebug package 2020-01-19 13:49:48 +01:00
nodiscc
54ab5636e3 doc: merge unit tests/docker unit tests pages, simplfy, reword 2020-01-19 13:18:29 +01:00
nodiscc
a8a38401f0 doc: reword simplify xdebug installation/unit tests 2020-01-19 13:11:11 +01:00
nodiscc
7a7a523782 doc: simplify unit tests documentation 2020-01-19 13:09:23 +01:00
nodiscc
6fa3c87d32 doc: simplify composer installation procedure 2020-01-19 13:05:21 +01:00
nodiscc
57bd9780c8
Merge pull request #1402 from shaarli/fix-makefile
fix directory creation in makefile
2020-01-19 12:03:24 +00:00
nodiscc
dd452c5691 fix directory creation in makefile
the syntax {doc,venor} is only supported in bash and make uses /bin/sh as default shell
2020-01-19 12:35:19 +01:00
ArthurHoaro
1001cc108f
Fix an issue with private tags and fix nomarkdown tag (#1399)
Fix an issue with private tags and fix nomarkdown tag
2020-01-18 17:59:37 +01:00
ArthurHoaro
12523aea34
Ulauncher Extension (#1400)
Ulauncher Extension
2020-01-18 15:27:37 +01:00
Sebastien Wains
fecfc73b3f
Ulauncher Extension 2020-01-18 15:22:49 +01:00
ArthurHoaro
a39acb2518 Fix an issue with private tags and fix nomarkdown tag
The new bookmark service wasn't handling private tags properly.

nomarkdown tag is now shown only for logged in user in bookmarks, and hidden for everyone in tag clouds/lists.

Fixes #726
2020-01-18 11:39:26 +01:00
ArthurHoaro
7e3648ad87
Fix an issue with bookmark visibility filter (#1398)
Fix an issue with bookmark visibility filter
2020-01-18 10:52:08 +01:00
ArthurHoaro
4869d535b5 Fix an issue with bookmark visibility filter 2020-01-18 10:49:30 +01:00
ArthurHoaro
3fb29fdda0
Store bookmarks as PHP objects and add a service layer to retri… (#1307)
Store bookmarks as PHP objects and add a service layer to retrieve them
2020-01-18 10:01:06 +01:00
ArthurHoaro
e26e2060f5 Add and update unit test for the new system (Bookmark + Service)
See #1307
2020-01-18 09:56:32 +01:00
ArthurHoaro
cf92b4dd15 Apply the new system (Bookmark + Service) to the whole code base
See https://github.com/shaarli/Shaarli/issues/1307
2020-01-18 09:55:59 +01:00
ArthurHoaro
336a28fa4a Introduce Bookmark object and Service layer to retrieve them
See https://github.com/shaarli/Shaarli/issues/1307 for details
2020-01-17 18:42:11 +01:00
ArthurHoaro
796c4c57d0
Run Unit Tests against PHP 7.4 (#1353)
Run Unit Tests against PHP 7.4
2020-01-17 18:39:56 +01:00
ArthurHoaro
def39d0dd7 Run Unit Tests against PHP 7.4
Bump PHPUnit version and fix unit test

  - Globals are handled differently and are persistent through tests
  - Tests without assertions are marked as risky: some of them are just
meant to check that no error is raised.
2020-01-17 18:34:37 +01:00
ArthurHoaro
ef02885753
Merge pull request #1358 from shaarli/doc-add-screenshots
Doc: add screenshots of all pages
2020-01-17 18:27:42 +01:00
ArthurHoaro
7d0db8b567
Avoiding warning 'PHP Notice: Undefined index: updated' (#1392)
Avoiding warning 'PHP Notice: Undefined index: updated'
2020-01-12 15:22:02 +01:00
Lucas Cimon
d9bfceaddf Avoiding warning 'PHP Notice: Undefined index: updated' 2020-01-12 14:55:37 +01:00
nodiscc
74c1d02079 doc: siplify troubleshooting, link to reference docs, reorder 2020-01-04 00:28:04 +01:00
nodiscc
5256f83d02 doc: troubleshooting: add note about error 500/internal server error caused by apache 2.2 and no mod_version 2020-01-04 00:19:25 +01:00
nodiscc
eb0a0f77cc
doc: remove obsolete link 2019-11-27 19:28:26 +00:00
nodiscc
af8a03d1ab
doc: remove obsolete link 2019-11-27 19:28:06 +00:00
Aurélien Tamisier
ac2214bdb5
Merge pull request #1383 from doc75/doc_docker
Fix #1382 - update documentation related to docker images
2019-11-26 23:46:39 +01:00
Guillaume Virlet
72539044fb Fix #1382 - update documentation related to docker images base image and PHP version used 2019-11-26 22:12:34 +01:00
nodiscc
99c7d66384
Merge pull request #1379 from rfolo9li/patch-1
Add php-json as required PHP module
2019-11-09 15:45:09 +00:00
nodiscc
3575fe5bcf
doc: add explanation of php-json requirement 2019-11-09 15:40:53 +00:00
rfolo9li
54b065c253
Added php-json as required PHP module
Without php-json the installation stops with a white screen and the following error:
> 09-Nov-2019 14:05:46 UTC] PHP Fatal error:  Uncaught Error: Call to undefined function Shaarli\Config\json_encode() in /var/www/html/shaarli/application/config/ConfigJson.php:48
> Stack trace:
> #0 /var/www/html/shaarli/application/config/ConfigManager.php(239): Shaarli\Config\ConfigJson->write('data/config.jso...', Array)
> #1 /var/www/html/shaarli/index.php(1835): Shaarli\Config\ConfigManager->write(false)
> #2 /var/www/html/shaarli/index.php(178): install(Object(Shaarli\Config\ConfigManager), Object(Shaarli\Security\SessionManager), Object(Shaarli\Security\LoginManager))
> #3 {main}
>   thrown in /var/www/html/shaarli/application/config/ConfigJson.php on line 48

Tested with Shaarli 0.10.4 on CentOS 8 with Httpd 2.4.37 and PHP 7.2.11.
2019-11-09 15:24:10 +01:00
nodiscc
4b15c49198
Merge pull request #1374 from paulvandenburg/demo-plugin-typos
Fix some typos and remove a few unnecessary comments in demo plugin
2019-10-27 09:55:57 +00:00
Paul van den Burg
83ef0ff176 Fix some typos and remove a few unnecessary comments in demo plugin 2019-10-26 21:35:05 +02:00
nodiscc
f4c6625962
Merge pull request #1366 from shaarli/doc-setuptools-mkdocs
doc: CI/dev tools: add paragraph about documentation/mkdocs
2019-10-02 19:57:59 +00:00
nodiscc
b4665de89b
fix typo 2019-10-02 19:57:40 +00:00
nodiscc
5ed0d9f54d
Merge pull request #1368 from NerosTie/patch-1
emojione & twemoji removed
2019-09-28 11:16:02 +00:00
Neros
bda0d35a51
emojione & twemoji removed
Since emojis are in every web browsers now, these plugins have no purpose anymore. And they are very outdated.
2019-09-25 20:03:58 +02:00
nodiscc
31d691649a
Merge pull request #1367 from shaarli/thumbnailer-soundcloud
thumbnailer: add soundcloud.com to list of common media domains
2019-09-21 17:41:32 +00:00
nodiscc
0b631e69d1
thumbnailer: add soundcloud.com to list of common media domains
OpenGraph thumbnails are well supported on soundcloud.com, displaying an album/track/artist cover image
2019-09-21 16:48:24 +00:00
nodiscc
954b3c81ce
doc: CI/dev tools: add paragraph about documentation/mkdocs
Fixes https://github.com/shaarli/Shaarli/issues/1335
2019-09-19 19:04:05 +00:00
nodiscc
1df5e9ca86
Merge pull request #1361 from Lucas-C/patch-1
Add pelican shaarli_poster plugin to list of integrations
2019-09-19 18:49:18 +00:00
nodiscc
c139a6e9ed
doc: update shaarli_poster pelican plugin url 2019-09-19 18:49:03 +00:00
nodiscc
b04ff6cf16
Merge pull request #1365 from shaarli/dependabot/npm_and_yarn/mixin-deep-1.3.2
Bump mixin-deep from 1.3.1 to 1.3.2
2019-09-19 18:44:56 +00:00
dependabot[bot]
7eb196723e
Bump mixin-deep from 1.3.1 to 1.3.2
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-09-19 18:26:32 +00:00
nodiscc
fc66e61ca9
Merge pull request #1364 from ArthurHoaro/hotfix/md-rss-permalink
Fix RSS permalink included in Markdown bloc
2019-09-14 14:39:49 +00:00
ArthurHoaro
0baa658130 Fix RSS permalink included in Markdown bloc
Adds another line break before inserting RSS permalink to avoid including it in markdown blocs, such as blockquote.
2019-09-12 19:38:37 +02:00
ArthurHoaro
51837fe8ba
Fix undefined thumbnail in OpenGraph headers (#1363)
Fix undefined thumbnail in OpenGraph headers
2019-09-10 20:25:19 +02:00
ArthurHoaro
e0e24335f7 Fix undefined thumbnail on OpenGraph headers
Fixes #1362
2019-09-10 18:40:07 +02:00
Lucas Cimon
3b0f03770b
Add pelican shaarli_poster plugin to list of integrations 2019-09-04 10:00:22 +02:00
ArthurHoaro
90ea2cb62e
Merge pull request #1359 from shaarli/dependabot/npm_and_yarn/lodash-4.17.15
Bump lodash from 4.17.11 to 4.17.15
2019-08-27 22:33:49 +02:00
dependabot[bot]
8d4cada793
Bump lodash from 4.17.11 to 4.17.15
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.15.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.15)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-27 17:33:59 +00:00
nodiscc
424ae4b001
Doc: add screenshots of all pages
Fixes https://github.com/shaarli/Shaarli/issues/598
2019-08-27 17:10:37 +00:00
ArthurHoaro
188a99db99
Merge pull request #1355 from ArthurHoaro/hotfix/feed-md-directlink
Markdown plugin: fix RSS feed direct link reverse
2019-08-15 12:59:57 +02:00
ArthurHoaro
354fb98cc9 Markdown plugin: fix RSS feed direct link reverse
The plugin was only reversing permalinks and failed with setting rss_permalinks set to false
2019-08-15 12:56:32 +02:00
ArthurHoaro
5669f474f3
Merge pull request #1354 from ArthurHoaro/hotfix/img-lazy-loading
Fix image lazy loading issues
2019-08-15 11:51:37 +02:00
ArthurHoaro
b5e2b23c99 Fix image lazy loading issues
For some reason, bLazy won't load the image if the img block has
either 0 height or width.
2019-08-15 11:41:50 +02:00
nodiscc
0a4bc5a17d
Merge pull request #1351 from ArthurHoaro/hotfix/index-php-version
Bump PHP version check in index.php
2019-08-10 11:30:16 +00:00
ArthurHoaro
b405a44f29 Bump PHP version check in index.php
Fixes #1249
2019-08-10 12:47:58 +02:00
ArthurHoaro
5f1617a480
Merge pull request #1352 from ArthurHoaro/hotfix/ut-error
Fix UT: LinkDBTest - make each tests independant
2019-08-10 12:46:41 +02:00
ArthurHoaro
bd1adc8df6 Fix UT: LinkDBTest - make each tests independant
Otherwise the datastore is empty in the last test, making it
inconsistent due to dates issues.
2019-08-10 12:42:53 +02:00
ArthurHoaro
7ff3ed1d63
Merge pull request #1336 from ArthurHoaro/hotfix/atom-author
ATOM Feed: use instance name as author name instead of URL
2019-08-10 12:08:22 +02:00
ArthurHoaro
14a7d73c2d
Merge pull request #1350 from ArthurHoaro/hotfix/sort-consistency
Make sure that bookmark sort is consistent, even with equal timestamps
2019-08-10 12:07:55 +02:00
ArthurHoaro
edcfe54c45
Merge pull request #1346 from kalvn/fixdailynotice
Fixes a Undefined index: thumbnail in daily page.
2019-08-10 12:07:20 +02:00
ArthurHoaro
9f9627059a Make sure that bookmark sort is consistent, even with equal timestamps
Fixes #1348
2019-08-07 13:18:02 +02:00
kalvn
8ba951640c Fixes a Undefined index: thumbnail in daily page. 2019-08-04 22:02:18 +02:00
ArthurHoaro
1a6d61766a Bump badge version 2019-08-03 09:57:17 +02:00
ArthurHoaro
3a52dfcc5c
Merge pull request #1345 from ArthurHoaro/changelog-v0.11.1
Changelog v0.11.1
2019-08-03 09:53:28 +02:00
ArthurHoaro
f400ba291d Changelog v0.11.1 2019-08-03 09:49:48 +02:00
ArthurHoaro
31c788ddcf
Merge pull request #1344 from agentcobra/agentcobra-patch-1
little fix template
2019-08-03 09:40:17 +02:00
ArthurHoaro
e29a9a73b4
Merge pull request #1342 from ArthurHoaro/hotfix/composer-php71
Upgrade composer dependencies from PHP 7.1
2019-08-01 19:57:53 +02:00
ArthurHoaro
df40879739 Upgrade composer dependencies from PHP 7.1 2019-08-01 19:55:24 +02:00
ArthurHoaro
91af3e6b19
Merge pull request #1341 from ArthurHoaro/hotfix/travis-eol
Remove Travis unit tests against PHP 5.6 and 7.0
2019-08-01 19:46:08 +02:00
ArthurHoaro
5e61546a32 Remove Travis unit tests against PHP 5.6 and 7.0 2019-08-01 19:39:56 +02:00
nodiscc
211d93307b
Merge pull request #1340 from shaarli/fix-doc-links
doc: fix broken markdown link
2019-08-01 17:17:03 +00:00
nodiscc
58c2701e54 doc: fix broken markdown link
fixes https://github.com/shaarli/Shaarli/issues/1330
2019-08-01 19:09:05 +02:00
agentcobra
419eef1f56
little fix template
fix link between label and checkbox (updateCheck)
2019-08-01 12:33:25 +02:00
ArthurHoaro
fa7625219d
Merge pull request #1337 from ArthurHoaro/hotfix/docker-build
Docker: Bump NodeJS version to prevent an issue with node-sass
2019-07-29 20:08:00 +02:00
ArthurHoaro
67d4029fee Docker: Bump NodeJS version to prevent an issue with node-sass 2019-07-29 20:01:14 +02:00
ArthurHoaro
9f3bdf5895
Merge pull request #1327 from llune/master
a11y fixes
2019-07-29 19:39:50 +02:00
ArthurHoaro
f9b99c7217 ATOM Feed: use instance name as author name instead of URL
Related FreshRSS/FreshRSS#2466
2019-07-29 19:37:51 +02:00
Luce Carević
06a8992737
maj linklist
put back the link on the thumbmail and fix a11y
2019-07-28 12:33:06 +02:00
ArthurHoaro
ad8099a7af Bump badges version 2019-07-27 11:58:19 +02:00
Luce Carević
d1bcf28db3 fix a11y 2019-07-13 18:56:43 +02:00
Luce Carević
719ef8e896 fix a11y 2019-07-13 18:26:31 +02:00
258 changed files with 23723 additions and 10214 deletions

View file

@ -1,17 +0,0 @@
options:
max-warnings: 0
rules:
property-sort-order:
- 0
# Sort order rule does not work with CSS variables: https://github.com/sasstools/sass-lint/issues/1161
# - 1
# -
# order: 'concentric'
no-important:
- 0
no-vendor-prefixes:
- 0 # this will be fixed with v2: see https://github.com/sasstools/sass-lint/pull/1137
nesting-depth:
- 1
-
max-depth: 4

15
.dev/.stylelintrc.js Normal file
View file

@ -0,0 +1,15 @@
module.exports = {
extends: 'stylelint-config-standard',
plugins: [
"stylelint-scss"
],
rules: {
"indentation": [2],
"number-leading-zero": null,
// Replace CSS @ with SASS ones
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true,
// not compatible with SASS apparently
"no-descending-specificity": null
},
}

View file

@ -17,27 +17,14 @@ http {
index index.html index.php;
server {
listen 80;
root /var/www/shaarli;
listen 80;
listen [::]:80;
root /var/www/shaarli;
access_log /var/log/nginx/shaarli.access.log;
error_log /var/log/nginx/shaarli.error.log;
location ~ /\. {
# deny access to dotfiles
access_log off;
log_not_found off;
deny all;
}
location ~ ~$ {
# deny access to temp editor files, e.g. "script.php~"
access_log off;
log_not_found off;
deny all;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
location ~* \.(?:ico|css|js|gif|jpe?g|png|ttf|oet|woff2?)$ {
# cache static assets
expires max;
add_header Pragma public;
@ -49,25 +36,25 @@ http {
alias /var/www/shaarli/images/favicon.ico;
}
location / {
# Slim - rewrite URLs
try_files $uri /index.php$is_args$args;
location /doc/html/ {
default_type "text/html";
try_files $uri $uri/ $uri.html =404;
}
location ~ (index)\.php$ {
location / {
# Slim - rewrite URLs & do NOT serve static files through this location
try_files _ /index.php$is_args$args;
}
location ~ index\.php$ {
# Slim - split URL path into (script_filename, path_info)
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_split_path_info ^(index.php)(/.+)$;
# filter and proxy PHP requests to PHP-FPM
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
location ~ \.php$ {
# deny access to all other PHP scripts
deny all;
}
}
}

View file

@ -1,2 +1,2 @@
#!/bin/execlineb -P
php-fpm7 -F
php-fpm8 -F

View file

@ -2,8 +2,15 @@
.dev
.git
.github
.gitattributes
.gitignore
tests
# Docker related resources are not needed inside the container
.dockerignore
Dockerfile
Dockerfile.armhf
# Docker Compose resources
docker-compose.yml
@ -13,6 +20,9 @@ data/*
pagecache/*
tmp/*
# Shaarli's docs are created during the build
doc/html/
# Eclipse project files
.settings
.buildpath

View file

@ -14,7 +14,7 @@ indent_size = 4
indent_size = 2
[*.php]
max_line_length = 100
max_line_length = 120
[Dockerfile]
max_line_length = 80

4
.gitattributes vendored
View file

@ -40,6 +40,8 @@ Dockerfile* export-ignore
Doxyfile export-ignore
Makefile export-ignore
node_modules/ export-ignore
mkdocs.yml export-ignore
doc/conf.py export-ignore
doc/requirements.txt export-ignore
doc/html/.doctrees/ export-ignore
phpunit.xml export-ignore
tests/ export-ignore

7
.github/mailmap vendored
View file

@ -1,13 +1,18 @@
ArthurHoaro <arthur@hoa.ro>
ArthurHoaro <arthur@hoa.ro> <arthur.hoareau@wizacha.com>
ArthurHoaro <arthur@hoa.ro> Arthur
Florian Eula <eula.florian@gmail.com> feula
Florian Eula <eula.florian@gmail.com> <mr.pikzen@gmail.com>
Immánuel Fodor <immanuelfactor+github@gmail.com>
Immánuel Fodor <immanuelfactor+github@gmail.com> Immánuel! <21174107+immanuelfodor@users.noreply.github.com>
kalvn <kalvnthereal@gmail.com> <kalvn@users.noreply.github.com>
kalvn <kalvnthereal@gmail.com> <kalvn@pm.me>
Neros <contact@neros.fr> <NerosTie@users.noreply.github.com>
Nicolas Danelon <hi@nicolasmd.com.ar> nicolasm
Nicolas Danelon <hi@nicolasmd.com.ar> <nda@3818.com.ar>
Nicolas Danelon <hi@nicolasmd.com.ar> <nicolasdanelon@gmail.com>
Nicolas Danelon <hi@nicolasmd.com.ar> <nicolasdanelon@users.noreply.github.com>
Sébastien Sauvage <sebsauvage@sebsauvage.net>
Sébastien NOBILI <code@pipoprods.org> <s-code-github@pipoprods.org>
Timo Van Neerden <fire@lehollandaisvolant.net>
Timo Van Neerden <fire@lehollandaisvolant.net> lehollandaisvolant <levoltigeurhollandais@gmail.com>
VirtualTam <virtualtam@flibidi.net> <tamisier.aurelien@gmail.com>

106
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,106 @@
name: Shaarli CI
on: [push, pull_request]
jobs:
php:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-versions: ['7.4', '8.0', '8.1', '8.2']
name: PHP ${{ matrix.php-versions }}
steps:
- name: Set locales
run: |
sudo locale-gen de_DE.utf8 && \
sudo locale-gen en_US.utf8 && \
sudo locale-gen fr_FR.utf8 && \
sudo dpkg-reconfigure --frontend=noninteractive locales
- name: Install Gettext
run: sudo apt-get install gettext
- name: Checkout
uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: gd, xml, curl, mbstring, intl, gettext
tools: composer:v2
- name: Check PHP version
run: php -v
- name: Setup Composer from PHP version + update
run: composer config --unset platform && composer config platform.php ${{ matrix.php-versions }}
- name: Update dependencies for PHP 8.x
if: ${{ matrix.php-versions == '8.0' || matrix.php-versions == '8.1' }}
run: |
composer update && \
composer remove --dev phpunit/phpunit && \
composer require --dev phpunit/php-text-template ^2.0 && \
composer require --dev phpunit/phpunit ^9.0
- name: Update dependencies for PHP 7.x
if: ${{ matrix.php-versions != '8.0' && matrix.php-versions != '8.1' }}
run: composer update
- name: Clean up
run: make clean
- name: Check permissions
run: make check_permissions
- name: Run PHPCS
run: make code_sniffer
- name: Run tests
run: make all_tests
node:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '14.x'
- name: Yarn install
run: yarnpkg install
- name: Verify successful frontend builds
run: yarnpkg run build
- name: JS static analysis
run: make eslint
- name: Linter for SASS syntax
run: make sasslint
python:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Build documentation
run: make htmldoc
trivy-repo:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Run trivy scanner on repository (non-blocking)
run: make test_trivy_repo TRIVY_EXIT_CODE=0

45
.github/workflows/docker-latest.yml vendored Normal file
View file

@ -0,0 +1,45 @@
name: Build/push Docker image (master/latest)
on:
push:
branches: [ master ]
jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout
uses: actions/checkout@v3
- name: Set shaarli version to the latest commit hash
run: sed -i "s/dev/$(git rev-parse --short HEAD)/" shaarli_version.php
- name: Build and push
id: docker_build
uses: docker/build-push-action@v4
with:
context: .
push: true
platforms: linux/amd64,linux/arm64,linux/arm/v7
tags: |
${{ secrets.DOCKER_IMAGE }}:latest
ghcr.io/${{ secrets.DOCKER_IMAGE }}:latest
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
- name: Run trivy scanner on latest docker image
run: make test_trivy_docker TRIVY_TARGET_DOCKER_IMAGE=ghcr.io/${{ secrets.DOCKER_IMAGE }}:latest

21
.github/workflows/docker-pr.yml vendored Normal file
View file

@ -0,0 +1,21 @@
name: Build Docker image (Pull Request)
on:
pull_request:
branches: [ master ]
jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build Docker image
id: docker_build
uses: docker/build-push-action@v2
with:
push: false
tags: shaarli/shaarli:pr-${{ github.event.number }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

43
.github/workflows/docker-tags.yml vendored Normal file
View file

@ -0,0 +1,43 @@
name: Build/push Docker image (tags/releases)
on:
push:
tags:
- "v*.*.*"
branches:
- "v*.*"
- release
jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- name: Get the tag name
run: echo "REF=${GITHUB_REF##*/}" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v3
with:
push: true
platforms: linux/amd64,linux/arm/v7
tags: |
${{ secrets.DOCKER_IMAGE }}:${{ env.REF }}
ghcr.io/${{ secrets.DOCKER_IMAGE }}:${{ env.REF }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

13
.gitignore vendored
View file

@ -25,8 +25,21 @@ coverage
sandbox
phpmd.html
phpdoc.xml
.phpunit.result.cache
trivy
# User plugin configuration
plugins/*
!addlink_toolbar
!archiveorg
!default_colors
!demo_plugin
!isso
!piwik
!playvideos
!pubsubhubbub
!qrcode
!wallabag
plugins/*/config.php
plugins/default_colors/default_colors.css

View file

@ -5,11 +5,19 @@
# Required
version: 2
# Build documentation with MkDocs
mkdocs:
configuration: mkdocs.yml
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: doc/conf.py
builder: html
build:
os: ubuntu-22.04
tools:
python: "3.11"
commands:
- pip install sphinx==7.1.0 furo==2023.7.26 myst-parser sphinx-design
- sphinx-build -b html -c doc/ doc/md/ _readthedocs/html/
# Optionally set the version of Python and requirements required to build your docs
# https://github.com/rtfd/readthedocs.org/issues/5250
python:
version: 3.5
install:
- requirements: doc/requirements.txt

View file

@ -1,56 +0,0 @@
sudo: false
dist: trusty
matrix:
include:
- language: php
php: 7.3
- language: php
php: 7.2
- language: php
php: 7.1
- language: php
php: 7.0
- language: php
php: 5.6
- language: node_js
node_js: 8
cache:
yarn: true
directories:
- $HOME/.cache/yarn
install:
- yarn install
before_script:
- PATH=${PATH//:\.\/node_modules\/\.bin/}
script:
- yarn run build # Just to be sure that the build isn't broken
- make eslint
- make sasslint
- language: python
python: 3.6
cache:
directories:
- $HOME/.cache/pip
install:
- pip install mkdocs
script:
- mkdocs build --clean
cache:
directories:
- $HOME/.composer/cache
install:
- composer install --prefer-dist
before_script:
- PATH=${PATH//:\.\/node_modules\/\.bin/}
script:
- make clean
- make check_permissions
- make all_tests

46
AUTHORS
View file

@ -1,8 +1,8 @@
1206 ArthurHoaro <arthur@hoa.ro>
1216 ArthurHoaro <arthur@hoa.ro>
456 nodiscc <nodiscc@gmail.com>
405 VirtualTam <virtualtam@flibidi.net>
384 nodiscc <nodiscc@gmail.com>
56 Sébastien Sauvage <sebsauvage@sebsauvage.net>
23 dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
27 dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
19 Keith Carangelo <mail@kcaran.com>
16 Luce Carević <lcarevic@access42.net>
15 Florian Eula <eula.florian@gmail.com>
@ -15,32 +15,38 @@
6 YFdyh000 <yfdyh000@gmail.com>
6 kalvn <kalvnthereal@gmail.com>
6 B. van Berkum <dev@dotmpe.com>
6 Immánuel Fodor <immanuelfactor+github@gmail.com>
6 YFdyh000 <yfdyh000@gmail.com>
6 kalvn <kalvnthereal@gmail.com>
6 llune <llune@users.noreply.github.com>
5 Mark Schmitz <kramred@gmail.com>
5 Sébastien NOBILI <code@pipoprods.org>
4 Alexandre Alapetite <alexandre@alapetite.fr>
4 yude <yudesleepy@gmail.com>
4 David Sferruzza <david.sferruzza@gmail.com>
4 yude <yudesleepy@gmail.com>
3 Agurato <mail.vmonot@gmail.com>
3 Christoph Stoettner <christoph.stoettner@stoeps.de>
3 Olivier <bourreauolivier@gmail.com>
3 Teromene <teromene@teromene.fr>
3 yudete <yu@yude.moe>
3 Agurato <mail.vmonot@gmail.com>
3 Olivier <bourreauolivier@gmail.com>
3 Christoph Stoettner <christoph.stoettner@stoeps.de>
2 Alexander Railean <alexandr.railean@arculus.de>
2 Alexandre G.-Raymond <alex@ndre.gr>
2 Chris Kuethe <chris.kuethe@gmail.com>
2 Doug Breaux <25640850+dougbreaux@users.noreply.github.com>
2 Felix Bartels <felix@host-consultants.de>
2 Ganesh Kandu <kanduganesh@gmail.com>
2 Gregory <gregory@nosheep.fr>
2 Guillaume Virlet <github@virlet.org>
2 Knah Tsaeb <Knah-Tsaeb@knah-tsaeb.org>
2 Mathieu Chabanon <git@matchab.fr>
2 Miloš Jovanović <mjovanovic@gmail.com>
2 Neros <contact@neros.fr>
2 Alexandre G.-Raymond <alex@ndre.gr>
2 Qwerty <champlywood@free.fr>
2 Guillaume Virlet <github@virlet.org>
2 Sebastien Wains <sebw@users.noreply.github.com>
2 Stephen Muth <smuth4@gmail.com>
2 Timo Van Neerden <fire@lehollandaisvolant.net>
2 Alexander Railean <alexandr.railean@arculus.de>
2 Doug Breaux <25640850+dougbreaux@users.noreply.github.com>
2 flow.gunso <flow.gunso@gmail.com>
2 Chris Kuethe <chris.kuethe@gmail.com>
2 Ganesh Kandu <kanduganesh@gmail.com>
2 julienCXX <software@chmodplusx.eu>
2 Knah Tsaeb <Knah-Tsaeb@knah-tsaeb.org>
2 philipp-r <philipp-r@users.noreply.github.com>
@ -58,6 +64,8 @@
1 Adrien le Maire <adrien@alemaire.be>
1 Ajabep <ajabep@users.noreply.github.com>
1 Alexis J <alexis@effingo.be>
1 Alistair Young <avatar@arkane-systems.net>
1 Amadeous <amadeous@users.noreply.github.com>
1 Angristan <angristan@users.noreply.github.com>
1 Bish Erbas <42714627+bisherbas@users.noreply.github.com>
1 BoboTiG <bobotig@gmail.com>
@ -66,6 +74,7 @@
1 Buster One <37770318+buster-one@users.noreply.github.com>
1 D Low <daniellowtw@gmail.com>
1 Daniel Jakots <vigdis@chown.me>
1 David <dajare@gmail.com>
1 David Foucher <dev@tyjak.net>
1 Denis Renning <denis@devtty.de>
1 Dennis Verspuij <dennisverspuij@users.noreply.github.com>
@ -75,7 +84,6 @@
1 Florian Voigt <flvoigt@me.com>
1 Franck Kerbiriou <FranckKe@users.noreply.github.com>
1 Gary Marigliano <gmarigliano93@gmail.com>
1 Gregory <gregory@nosheep.fr>
1 Hazhar Galeh <78073762+hazhargaleh@users.noreply.github.com>
1 Hg <dev@indigo.re>
1 Jens Kubieziel <github@kubieziel.de>
@ -90,16 +98,26 @@
1 Mark Gerarts <mark.gerarts@gmail.com>
1 Marsup <marsup@gmail.com>
1 Nicolas Friedli <nicolas@theologique.ch>
1 Nicolas Le Gaillart <nicolas@legaillart.fr>
1 Paul van den Burg <github@paulvandenburg.nl>
1 Adrien Oliva <adrien.oliva@yapbreak.fr>
1 Rajat Hans <rajathans9@gmail.com>
1 Sbgodin <Sbgodin@users.noreply.github.com>
1 ToM <tom@leloop.org>
1 TsT <tst2005@gmail.com>
1 agentcobra <agentcobra@free.fr>
1 aguy <aguytech@users.noreply.github.com>
1 bschwede <bschwede@users.noreply.github.com>
1 bschwede <gummibando@gmx.net>
1 clach04 <clach04@gmail.com>
1 dimtion <zizou.xena@gmail.com>
1 durcheinandr <jochen@durcheinandr.de>
1 heimpogo <hypertexthome@googlemail.com>
1 jalr <mail@jalr.de>
1 lapineige <lapineige@users.noreply.github.com>
1 leyrer <gitlab@leyrer.priv.at>
1 locness3 <37651007+locness3@users.noreply.github.com>
1 owen bell <66233223+xfnw@users.noreply.github.com>
1 philipp <philipp@philipp.PC.Ubuntu>
1 rfolo9li <50079896+rfolo9li@users.noreply.github.com>
1 sprak3000 <sprak3000+github@gmail.com>
1 yudejp <i@yude.jp>

View file

@ -4,6 +4,57 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [v0.13.0](https://github.com/shaarli/Shaarli/releases/tag/v0.12.3) - 2023-11-22
> Major changes:
> - Security: Fix XSS vulnerability in tag search
> - Drop support for PHP 7.1, 7.2 and 7.3
### Added
* Docker build: add ARM64 platform and bump Github action version by @ArthurHoaro in https://github.com/shaarli/Shaarli/pull/1965
* github actions: build OCI images that contain both amd64 and armv7 by @nodiscc in https://github.com/shaarli/Shaarli/pull/1962
* Expose tags_separator config through /info API by @amadeous in https://github.com/shaarli/Shaarli/pull/1997
* tools: github actions: build docker images on pull requests by @nodiscc in https://github.com/shaarli/Shaarli/pull/2014
* doc: server configuration: add PHP 8.2 to PHP compatibility table by @nodiscc in https://github.com/shaarli/Shaarli/pull/2021
* Add shaarli-stack theme to Community-and-related-software.md by @dajare in https://github.com/shaarli/Shaarli/pull/2028
* doc: document general.download_max_size/timeout configuration settings by @nodiscc in https://github.com/shaarli/Shaarli/pull/2036
* doc: troubleshooting: automatic title retrieval fails when it is set by javascript by @nodiscc in https://github.com/shaarli/Shaarli/pull/2037
### Changed
* doc: update release procedure (merge the latest release to the release branch) + use the release branch for latest release version detection by @nodiscc in https://github.com/shaarli/Shaarli/pull/1960
* Update german translation by @bschwede in https://github.com/shaarli/Shaarli/pull/1969
* Update Server-configuration.md by @reinboldg in https://github.com/shaarli/Shaarli/pull/1973
* Update Community-and-related-software.md by @nlegaillart in https://github.com/shaarli/Shaarli/pull/1984
* doc: improve docs on usage of OR operator in tags search by @nodiscc in https://github.com/shaarli/Shaarli/pull/1987
* docker: nginx: listen on IPv6 in addition to IPv4 by @cerebrate in https://github.com/shaarli/Shaarli/pull/1983
* Doc update, WebSub (formerly PubSubHubbub) plugin by @clach04 in https://github.com/shaarli/Shaarli/pull/2008
* doc: community/related software/integration with other platforms: add link to shaarli debian package by @nodiscc in https://github.com/shaarli/Shaarli/pull/2018
* replace mkdocs with sphinx/myst-parser for HTML documentation generation, documentation improvements by @nodiscc in https://github.com/shaarli/Shaarli/pull/2025
### Fixed
* Makefile: Use GNU tar if available by @ArthurHoaro in https://github.com/shaarli/Shaarli/pull/1957
* Support: ignore disk_free_space if the function is unavailable by @ArthurHoaro in https://github.com/shaarli/Shaarli/pull/1970
* Documentation: fix broken link to 3rd party plugins by @ArthurHoaro in https://github.com/shaarli/Shaarli/pull/1975
* Fix autofocus: load bulk action input on linklist only by @ArthurHoaro in https://github.com/shaarli/Shaarli/pull/1976
* doc: fix mkdocs build warnings/relative links by @nodiscc in https://github.com/shaarli/Shaarli/pull/2015
* correct usage of hyphens in all occurences of 'super fast, database-free' by @nodiscc in https://github.com/shaarli/Shaarli/pull/2003
### Removed
* Drop support for PHP 7.1, 7.2 and 7.3 by @ArthurHoaro in https://github.com/shaarli/Shaarli/pull/1958
* doc: themes: remove unmaintained themes by @nodiscc in https://github.com/shaarli/Shaarli/pull/2030
* doc: remove bountysource badge by @nodiscc in https://github.com/shaarli/Shaarli/pull/2035
### Security
* Fix XSS vulnerability in tag search by @ArthurHoaro in https://github.com/shaarli/Shaarli/pull/2039
* tools: run trivy vulnerability scanner on the 'latest' docker image by @nodiscc in https://github.com/shaarli/Shaarli/pull/1980
* github actions: fix value of TRIVY_TARGET_DOCKER_IMAGE by @nodiscc in https://github.com/shaarli/Shaarli/pull/1989
* tools/CI: scan repository with trivy security scanner (yarn.lock, composer.lock) by @nodiscc in https://github.com/shaarli/Shaarli/pull/1998
* tools/tests: update trivy to v0.44.0 by @nodiscc in https://github.com/shaarli/Shaarli/pull/2012
* docker: update base alpine docker image to 3.16.7 by @nodiscc in https://github.com/shaarli/Shaarli/pull/2024
**Full Changelog**: https://github.com/shaarli/Shaarli/compare/v0.12.2...v0.12.3
## [v0.12.2](https://github.com/shaarli/Shaarli/releases/tag/v0.12.2) - 2023-03-18
> Docker: use `ghcr.io/shaarli/shaarli` as Docker image instead of `shaarli/shaarli`.

View file

@ -4,8 +4,8 @@
FROM python:3-alpine as docs
ADD . /usr/src/app/shaarli
RUN cd /usr/src/app/shaarli \
&& pip install --no-cache-dir mkdocs \
&& mkdocs build --clean
&& apk add --no-cache gcc musl-dev make bash \
&& make htmldoc
# Stage 2:
# - Resolve PHP dependencies with Composer
@ -16,43 +16,46 @@ RUN cd shaarli \
# Stage 3:
# - Frontend dependencies
FROM node:9.9-alpine as node
FROM node:12-alpine as node
COPY --from=composer /app/shaarli shaarli
RUN cd shaarli \
&& yarn install \
&& yarn run build \
&& yarnpkg install \
&& yarnpkg run build \
&& rm -rf node_modules
# Stage 4:
# - Shaarli image
FROM alpine:3.8
FROM alpine:3.16.7
LABEL maintainer="Shaarli Community"
RUN apk --update --no-cache add \
ca-certificates \
nginx \
php7 \
php7-ctype \
php7-curl \
php7-fpm \
php7-gd \
php7-iconv \
php7-intl \
php7-json \
php7-mbstring \
php7-openssl \
php7-session \
php7-xml \
php7-zlib \
php8 \
php8-ctype \
php8-curl \
php8-fpm \
php8-gd \
php8-gettext \
php8-iconv \
php8-intl \
php8-json \
php8-ldap \
php8-mbstring \
php8-openssl \
php8-session \
php8-xml \
php8-simplexml \
php8-zlib \
s6
COPY .docker/nginx.conf /etc/nginx/nginx.conf
COPY .docker/php-fpm.conf /etc/php7/php-fpm.conf
COPY .docker/php-fpm.conf /etc/php8/php-fpm.conf
COPY .docker/services.d /etc/services.d
RUN rm -rf /etc/php7/php-fpm.d/www.conf \
&& sed -i 's/post_max_size.*/post_max_size = 10M/' /etc/php7/php.ini \
&& sed -i 's/upload_max_filesize.*/upload_max_filesize = 10M/' /etc/php7/php.ini
RUN rm -rf /etc/php8/php-fpm.d/www.conf \
&& sed -i 's/post_max_size.*/post_max_size = 10M/' /etc/php8/php.ini \
&& sed -i 's/upload_max_filesize.*/upload_max_filesize = 10M/' /etc/php8/php.ini
WORKDIR /var/www

View file

@ -1,80 +0,0 @@
# Stage 1:
# - Copy Shaarli sources
# - Build documentation
FROM arm32v6/alpine:3.8 as docs
ADD . /usr/src/app/shaarli
RUN apk --update --no-cache add py2-pip \
&& cd /usr/src/app/shaarli \
&& pip install --no-cache-dir mkdocs \
&& mkdocs build --clean
# Stage 2:
# - Resolve PHP dependencies with Composer
FROM arm32v6/alpine:3.8 as composer
COPY --from=docs /usr/src/app/shaarli /app/shaarli
RUN apk --update --no-cache add php7-curl php7-mbstring composer \
&& cd /app/shaarli \
&& composer --prefer-dist --no-dev install
# Stage 3:
# - Frontend dependencies
FROM arm32v6/alpine:3.8 as node
COPY --from=composer /app/shaarli /shaarli
RUN apk --update --no-cache add yarn nodejs-current python2 build-base \
&& cd /shaarli \
&& yarn install \
&& yarn run build \
&& rm -rf node_modules
# Stage 4:
# - Shaarli image
FROM arm32v6/alpine:3.8
LABEL maintainer="Shaarli Community"
MAINTAINER Shaarli Community
RUN apk --update --no-cache add \
ca-certificates \
curl \
nginx \
php7 \
php7-ctype \
php7-curl \
php7-fpm \
php7-gd \
php7-iconv \
php7-intl \
php7-json \
php7-mbstring \
php7-openssl \
php7-phar \
php7-session \
php7-xml \
php7-zlib \
s6
COPY .docker/nginx.conf /etc/nginx/nginx.conf
COPY .docker/php-fpm.conf /etc/php7/php-fpm.conf
COPY .docker/services.d /etc/services.d
RUN curl -sS https://getcomposer.org/installer | php7 -- --install-dir=/usr/local/bin --filename=composer \
&& rm -rf /etc/php7/php-fpm.d/www.conf \
&& sed -i 's/post_max_size.*/post_max_size = 10M/' /etc/php7/php.ini \
&& sed -i 's/upload_max_filesize.*/upload_max_filesize = 10M/' /etc/php7/php.ini
WORKDIR /var/www
RUN curl -L https://github.com/shaarli/Shaarli/archive/latest.tar.gz | tar xzf - \
&& mv Shaarli-latest shaarli \
&& cd shaarli \
&& composer --prefer-dist --no-dev install \
&& rm -rf ~/.composer \
&& chown -R nginx:nginx . \
&& ln -sf /dev/stdout /var/log/nginx/shaarli.access.log \
&& ln -sf /dev/stderr /var/log/nginx/shaarli.error.log
VOLUME /var/www/shaarli/data
EXPOSE 80
ENTRYPOINT ["/bin/s6-svscan", "/etc/services.d"]
CMD []

View file

@ -1,9 +1,9 @@
# The personal, minimalist, super-fast, database free, bookmarking service.
# The personal, minimalist, super fast, database-free, bookmarking service.
# Makefile for PHP code analysis & testing, documentation and release generation
BIN = vendor/bin
all: static_analysis_summary check_permissions test
all: check_permissions test
##
# Docker test adapter
@ -24,13 +24,16 @@ docker_%:
##
PHPCS := $(BIN)/phpcs
# Use GNU Tar where available
ifneq (, $(shell which gtar))
TAR := gtar
else
TAR := tar
endif
code_sniffer:
@$(PHPCS)
### - errors filtered by coding standard: PEAR, PSR1, PSR2, Zend...
PHPCS_%:
@$(PHPCS) --report-full --report-width=200 --standard=$*
### - errors by Git author
code_sniffer_blame:
@$(PHPCS) --report-gitblame
@ -80,10 +83,15 @@ locale_test_%:
--testsuite language-$(firstword $(subst _, ,$*))
all_tests: test locale_test_de_DE locale_test_en_US locale_test_fr_FR
@$(BIN)/phpcov merge --html coverage coverage
@# --The current version is not compatible with PHP 7.2
@#$(BIN)/phpcov merge --html coverage coverage
@# --text doesn't work with phpunit 4.* (v5 requires PHP 5.6)
@#$(BIN)/phpcov merge --text coverage/txt coverage
### download 3rd-party PHP libraries, including dev dependencies
composer_dependencies_dev: clean
composer install --prefer-dist
##
# Custom release archive generation
#
@ -105,24 +113,25 @@ composer_dependencies: clean
### download 3rd-party frontend libraries
frontend_dependencies:
yarn install
yarnpkg install
### Build frontend dependencies
build_frontend: frontend_dependencies
yarn run build
yarnpkg run build
### generate a release tarball and include 3rd-party dependencies and translations
release_tar: composer_dependencies htmldoc translate build_frontend
git archive --prefix=$(ARCHIVE_PREFIX) -o $(ARCHIVE_VERSION).tar HEAD
tar rvf $(ARCHIVE_VERSION).tar --transform "s|^vendor|$(ARCHIVE_PREFIX)vendor|" vendor/
tar rvf $(ARCHIVE_VERSION).tar --transform "s|^doc/html|$(ARCHIVE_PREFIX)doc/html|" doc/html/
tar rvf $(ARCHIVE_VERSION).tar --transform "s|^tpl|$(ARCHIVE_PREFIX)tpl|" tpl/
$(TAR) rvf $(ARCHIVE_VERSION).tar --transform "s|^vendor|$(ARCHIVE_PREFIX)vendor|" vendor/
$(TAR) rvf $(ARCHIVE_VERSION).tar --transform "s|^doc/html|$(ARCHIVE_PREFIX)doc/html|" doc/html/
$(TAR) rvf $(ARCHIVE_VERSION).tar --transform "s|^tpl|$(ARCHIVE_PREFIX)tpl|" tpl/
gzip $(ARCHIVE_VERSION).tar
### generate a release zip and include 3rd-party dependencies and translations
release_zip: composer_dependencies htmldoc translate build_frontend
git archive --prefix=$(ARCHIVE_PREFIX) -o $(ARCHIVE_VERSION).zip -9 HEAD
mkdir -p $(ARCHIVE_PREFIX)/{doc,vendor}
mkdir -p $(ARCHIVE_PREFIX)/doc
mkdir -p $(ARCHIVE_PREFIX)/vendor
rsync -a doc/html/ $(ARCHIVE_PREFIX)doc/html/
zip -r $(ARCHIVE_VERSION).zip $(ARCHIVE_PREFIX)doc/
rsync -a vendor/ $(ARCHIVE_PREFIX)vendor/
@ -138,10 +147,10 @@ release_zip: composer_dependencies htmldoc translate build_frontend
### remove all unversioned files
clean:
@git clean -df
@rm -rf sandbox
@rm -rf sandbox trivy*
### generate the AUTHORS file from Git commit information
authors:
generate_authors:
@cp .github/mailmap .mailmap
@git shortlog -sne > AUTHORS
@rm .mailmap
@ -150,25 +159,57 @@ authors:
phpdoc: clean
@docker run --rm -v $(PWD):/data -u `id -u`:`id -g` phpdoc/phpdoc
### generate HTML documentation from Markdown pages with MkDocs
### generate HTML documentation from Markdown pages with Sphinx
htmldoc:
python3 -m venv venv/
bash -c 'source venv/bin/activate; \
pip install mkdocs; \
mkdocs build --clean'
pip install wheel; \
pip install sphinx==7.1.0 furo==2023.7.26 myst-parser sphinx-design; \
sphinx-build -b html -c doc/ doc/md/ doc/html/'
find doc/html/ -type f -exec chmod a-x '{}' \;
rm -r venv
### Generate Shaarli's translation compiled file (.mo)
translate:
@find inc/languages/ -name shaarli.po -execdir msgfmt shaarli.po -o shaarli.mo \;
@echo "----------------------"
@echo "Compile translation files"
@echo "----------------------"
@for pofile in `find inc/languages/ -name shaarli.po`; do \
echo "Compiling $$pofile"; \
msgfmt -v "$$pofile" -o "`dirname "$$pofile"`/`basename "$$pofile" .po`.mo"; \
done;
### Run ESLint check against Shaarli's JS files
eslint:
@yarn run eslint -c .dev/.eslintrc.js assets/vintage/js/
@yarn run eslint -c .dev/.eslintrc.js assets/default/js/
@yarnpkg run eslint -c .dev/.eslintrc.js assets/vintage/js/
@yarnpkg run eslint -c .dev/.eslintrc.js assets/default/js/
@yarnpkg run eslint -c .dev/.eslintrc.js assets/common/js/
### Run CSSLint check against Shaarli's SCSS files
sasslint:
@yarn run sass-lint -c .dev/.sasslintrc 'assets/default/scss/*.scss' -v -q
@yarnpkg run stylelint --config .dev/.stylelintrc.js 'assets/default/scss/*.scss'
##
# Security scans
##
# trivy version (https://github.com/aquasecurity/trivy/releases)
TRIVY_VERSION=0.44.0
# default trivy exit code when vulnerabilities are found
TRIVY_EXIT_CODE=1
# default docker image to scan with trivy
TRIVY_TARGET_DOCKER_IMAGE=ghcr.io/shaarli/shaarli:latest
### download trivy vulneravbility scanner
download_trivy:
wget --quiet --continue -O trivy_$(TRIVY_VERSION)_Linux-64bit.tar.gz https://github.com/aquasecurity/trivy/releases/download/v$(TRIVY_VERSION)/trivy_$(TRIVY_VERSION)_Linux-64bit.tar.gz
tar -z -x trivy -f trivy_$(TRIVY_VERSION)_Linux-64bit.tar.gz
### run trivy vulnerability scanner on docker image
test_trivy_docker: download_trivy
./trivy --exit-code $(TRIVY_EXIT_CODE) image $(TRIVY_TARGET_DOCKER_IMAGE)
### run trivy vulnerability scanner on composer/yarn dependency trees
test_trivy_repo: download_trivy
./trivy --exit-code $(TRIVY_EXIT_CODE) fs composer.lock
./trivy --exit-code $(TRIVY_EXIT_CODE) fs yarn.lock

View file

@ -1,17 +1,16 @@
![Shaarli logo](doc/md/images/doc-logo.png)
The personal, minimalist, super-fast, database free, bookmarking service.
The personal, minimalist, super fast, database-free, bookmarking service.
_Do you want to share the links you discover?_
_Shaarli is a minimalist link sharing service that you can install on your own server._
_It is designed to be personal (single-user), fast and handy._
[![](https://img.shields.io/badge/stable-v0.11.1-blue.svg)](https://github.com/shaarli/Shaarli/releases/tag/v0.11.1)
[![](https://img.shields.io/badge/latest-v0.12.1-blue.svg)](https://github.com/shaarli/Shaarli/releases/tag/v0.12.1)
[![](https://img.shields.io/badge/master-v0.12.x-blue.svg)](https://github.com/shaarli/Shaarli)
[![](https://img.shields.io/badge/stable-v0.12.2-blue.svg)](https://github.com/shaarli/Shaarli/releases/tag/v0.11.1)
[![](https://img.shields.io/badge/latest-v0.13.0-blue.svg)](https://github.com/shaarli/Shaarli/releases/tag/v0.12.2)
[![](https://img.shields.io/badge/master-v0.13.x-blue.svg)](https://github.com/shaarli/Shaarli)
[![](https://github.com/shaarli/Shaarli/actions/workflows/ci.yml/badge.svg)](https://github.com/shaarli/Shaarli/actions)
[![Join the chat at https://gitter.im/shaarli/Shaarli](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/shaarli/Shaarli)
[![Bountysource](https://www.bountysource.com/badge/team?team_id=19583&style=bounties_received)](https://www.bountysource.com/teams/shaarli/issues)
[![Docker repository](https://img.shields.io/docker/pulls/shaarli/shaarli.svg)](https://github.com/shaarli/Shaarli/pkgs/container/shaarli)
## Quickstart

View file

@ -1,246 +0,0 @@
<?php
namespace Shaarli;
use Exception;
use Shaarli\Config\ConfigManager;
/**
* Shaarli (application) utilities
*/
class ApplicationUtils
{
/**
* @var string File containing the current version
*/
public static $VERSION_FILE = 'shaarli_version.php';
private static $GIT_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli';
private static $GIT_BRANCHES = array('latest', 'stable');
private static $VERSION_START_TAG = '<?php /* ';
private static $VERSION_END_TAG = ' */ ?>';
/**
* Gets the latest version code from the Git repository
*
* The code is read from the raw content of the version file on the Git server.
*
* @param string $url URL to reach to get the latest version.
* @param int $timeout Timeout to check the URL (in seconds).
*
* @return mixed the version code from the repository if available, else 'false'
*/
public static function getLatestGitVersionCode($url, $timeout = 2)
{
list($headers, $data) = get_http_response($url, $timeout);
if (strpos($headers[0], '200 OK') === false) {
error_log('Failed to retrieve ' . $url);
return false;
}
return $data;
}
/**
* Retrieve the version from a remote URL or a file.
*
* @param string $remote URL or file to fetch.
* @param int $timeout For URLs fetching.
*
* @return bool|string The version or false if it couldn't be retrieved.
*/
public static function getVersion($remote, $timeout = 2)
{
if (startsWith($remote, 'http')) {
if (($data = static::getLatestGitVersionCode($remote, $timeout)) === false) {
return false;
}
} else {
if (!is_file($remote)) {
return false;
}
$data = file_get_contents($remote);
}
return str_replace(
array(self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL),
array('', '', ''),
$data
);
}
/**
* Checks if a new Shaarli version has been published on the Git repository
*
* Updates checks are run periodically, according to the following criteria:
* - the update checks are enabled (install, global config);
* - the user is logged in (or this is an open instance);
* - the last check is older than a given interval;
* - the check is non-blocking if the HTTPS connection to Git fails;
* - in case of failure, the update file's modification date is updated,
* to avoid intempestive connection attempts.
*
* @param string $currentVersion the current version code
* @param string $updateFile the file where to store the latest version code
* @param int $checkInterval the minimum interval between update checks (in seconds
* @param bool $enableCheck whether to check for new versions
* @param bool $isLoggedIn whether the user is logged in
* @param string $branch check update for the given branch
*
* @throws Exception an invalid branch has been set for update checks
*
* @return mixed the new version code if available and greater, else 'false'
*/
public static function checkUpdate(
$currentVersion,
$updateFile,
$checkInterval,
$enableCheck,
$isLoggedIn,
$branch = 'stable'
) {
// Do not check versions for visitors
// Do not check if the user doesn't want to
// Do not check with dev version
if (!$isLoggedIn || empty($enableCheck) || $currentVersion === 'dev') {
return false;
}
if (is_file($updateFile) && (filemtime($updateFile) > time() - $checkInterval)) {
// Shaarli has checked for updates recently - skip HTTP query
$latestKnownVersion = file_get_contents($updateFile);
if (version_compare($latestKnownVersion, $currentVersion) == 1) {
return $latestKnownVersion;
}
return false;
}
if (!in_array($branch, self::$GIT_BRANCHES)) {
throw new Exception(
'Invalid branch selected for updates: "' . $branch . '"'
);
}
// Late Static Binding allows overriding within tests
// See http://php.net/manual/en/language.oop5.late-static-bindings.php
$latestVersion = static::getVersion(
self::$GIT_URL . '/' . $branch . '/' . self::$VERSION_FILE
);
if (!$latestVersion) {
// Only update the file's modification date
file_put_contents($updateFile, $currentVersion);
return false;
}
// Update the file's content and modification date
file_put_contents($updateFile, $latestVersion);
if (version_compare($latestVersion, $currentVersion) == 1) {
return $latestVersion;
}
return false;
}
/**
* Checks the PHP version to ensure Shaarli can run
*
* @param string $minVersion minimum PHP required version
* @param string $curVersion current PHP version (use PHP_VERSION)
*
* @throws Exception the PHP version is not supported
*/
public static function checkPHPVersion($minVersion, $curVersion)
{
if (version_compare($curVersion, $minVersion) < 0) {
$msg = t(
'Your PHP version is obsolete!'
. ' Shaarli requires at least PHP %s, and thus cannot run.'
. ' Your PHP version has known security vulnerabilities and should be'
. ' updated as soon as possible.'
);
throw new Exception(sprintf($msg, $minVersion));
}
}
/**
* Checks Shaarli has the proper access permissions to its resources
*
* @param ConfigManager $conf Configuration Manager instance.
*
* @return array A list of the detected configuration issues
*/
public static function checkResourcePermissions($conf)
{
$errors = array();
$rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/');
// Check script and template directories are readable
foreach (array(
'application',
'inc',
'plugins',
$rainTplDir,
$rainTplDir . '/' . $conf->get('resource.theme'),
) as $path) {
if (!is_readable(realpath($path))) {
$errors[] = '"' . $path . '" ' . t('directory is not readable');
}
}
// Check cache and data directories are readable and writable
foreach (array(
$conf->get('resource.thumbnails_cache'),
$conf->get('resource.data_dir'),
$conf->get('resource.page_cache'),
$conf->get('resource.raintpl_tmp'),
) as $path) {
if (!is_readable(realpath($path))) {
$errors[] = '"' . $path . '" ' . t('directory is not readable');
}
if (!is_writable(realpath($path))) {
$errors[] = '"' . $path . '" ' . t('directory is not writable');
}
}
// Check configuration files are readable and writable
foreach (array(
$conf->getConfigFileExt(),
$conf->get('resource.datastore'),
$conf->get('resource.ban_file'),
$conf->get('resource.log'),
$conf->get('resource.update_check'),
) as $path) {
if (!is_file(realpath($path))) {
# the file may not exist yet
continue;
}
if (!is_readable(realpath($path))) {
$errors[] = '"' . $path . '" ' . t('file is not readable');
}
if (!is_writable(realpath($path))) {
$errors[] = '"' . $path . '" ' . t('file is not writable');
}
}
return $errors;
}
/**
* Returns a salted hash representing the current Shaarli version.
*
* Useful for assets browser cache.
*
* @param string $currentVersion of Shaarli
* @param string $salt User personal salt, also used for the authentication
*
* @return string version hash
*/
public static function getVersionHash($currentVersion, $salt)
{
return hash_hmac('sha256', $currentVersion, $salt);
}
}

View file

@ -1,84 +0,0 @@
<?php
namespace Shaarli;
use Shaarli\Exceptions\IOException;
/**
* Class FileUtils
*
* Utility class for file manipulation.
*/
class FileUtils
{
/**
* @var string
*/
protected static $phpPrefix = '<?php /* ';
/**
* @var string
*/
protected static $phpSuffix = ' */ ?>';
/**
* Write data into a file (Shaarli database format).
* The data is stored in a PHP file, as a comment, in compressed base64 format.
*
* The file will be created if it doesn't exist.
*
* @param string $file File path.
* @param mixed $content Content to write.
*
* @return int|bool Number of bytes written or false if it fails.
*
* @throws IOException The destination file can't be written.
*/
public static function writeFlatDB($file, $content)
{
if (is_file($file) && !is_writeable($file)) {
// The datastore exists but is not writeable
throw new IOException($file);
} elseif (!is_file($file) && !is_writeable(dirname($file))) {
// The datastore does not exist and its parent directory is not writeable
throw new IOException(dirname($file));
}
return file_put_contents(
$file,
self::$phpPrefix . base64_encode(gzdeflate(serialize($content))) . self::$phpSuffix
);
}
/**
* Read data from a file containing Shaarli database format content.
*
* If the file isn't readable or doesn't exist, default data will be returned.
*
* @param string $file File path.
* @param mixed $default The default value to return if the file isn't readable.
*
* @return mixed The content unserialized, or default if the file isn't readable, or false if it fails.
*/
public static function readFlatDB($file, $default = null)
{
// Note that gzinflate is faster than gzuncompress.
// See: http://www.php.net/manual/en/function.gzdeflate.php#96439
if (!is_readable($file)) {
return $default;
}
$data = file_get_contents($file);
if ($data == '') {
return $default;
}
return unserialize(
gzinflate(
base64_decode(
substr($data, strlen(self::$phpPrefix), -strlen(self::$phpSuffix))
)
)
);
}
}

View file

@ -1,184 +0,0 @@
<?php
namespace Shaarli;
/**
* Class Router
*
* (only displayable pages here)
*/
class Router
{
public static $AJAX_THUMB_UPDATE = 'ajax_thumb_update';
public static $PAGE_LOGIN = 'login';
public static $PAGE_PICWALL = 'picwall';
public static $PAGE_TAGCLOUD = 'tagcloud';
public static $PAGE_TAGLIST = 'taglist';
public static $PAGE_DAILY = 'daily';
public static $PAGE_FEED_ATOM = 'atom';
public static $PAGE_FEED_RSS = 'rss';
public static $PAGE_TOOLS = 'tools';
public static $PAGE_CHANGEPASSWORD = 'changepasswd';
public static $PAGE_CONFIGURE = 'configure';
public static $PAGE_CHANGETAG = 'changetag';
public static $PAGE_ADDLINK = 'addlink';
public static $PAGE_EDITLINK = 'edit_link';
public static $PAGE_DELETELINK = 'delete_link';
public static $PAGE_CHANGE_VISIBILITY = 'change_visibility';
public static $PAGE_PINLINK = 'pin';
public static $PAGE_EXPORT = 'export';
public static $PAGE_IMPORT = 'import';
public static $PAGE_OPENSEARCH = 'opensearch';
public static $PAGE_LINKLIST = 'linklist';
public static $PAGE_PLUGINSADMIN = 'pluginadmin';
public static $PAGE_SAVE_PLUGINSADMIN = 'save_pluginadmin';
public static $PAGE_THUMBS_UPDATE = 'thumbs_update';
public static $GET_TOKEN = 'token';
/**
* Reproducing renderPage() if hell, to avoid regression.
*
* This highlights how bad this needs to be rewrite,
* but let's focus on plugins for now.
*
* @param string $query $_SERVER['QUERY_STRING'].
* @param array $get $_SERVER['GET'].
* @param bool $loggedIn true if authenticated user.
*
* @return string page found.
*/
public static function findPage($query, $get, $loggedIn)
{
$loggedIn = ($loggedIn === true) ? true : false;
if (empty($query) && !isset($get['edit_link']) && !isset($get['post'])) {
return self::$PAGE_LINKLIST;
}
if (startsWith($query, 'do=' . self::$PAGE_LOGIN) && $loggedIn === false) {
return self::$PAGE_LOGIN;
}
if (startsWith($query, 'do=' . self::$PAGE_PICWALL)) {
return self::$PAGE_PICWALL;
}
if (startsWith($query, 'do=' . self::$PAGE_TAGCLOUD)) {
return self::$PAGE_TAGCLOUD;
}
if (startsWith($query, 'do=' . self::$PAGE_TAGLIST)) {
return self::$PAGE_TAGLIST;
}
if (startsWith($query, 'do=' . self::$PAGE_OPENSEARCH)) {
return self::$PAGE_OPENSEARCH;
}
if (startsWith($query, 'do=' . self::$PAGE_DAILY)) {
return self::$PAGE_DAILY;
}
if (startsWith($query, 'do=' . self::$PAGE_FEED_ATOM)) {
return self::$PAGE_FEED_ATOM;
}
if (startsWith($query, 'do=' . self::$PAGE_FEED_RSS)) {
return self::$PAGE_FEED_RSS;
}
if (startsWith($query, 'do=' . self::$PAGE_THUMBS_UPDATE)) {
return self::$PAGE_THUMBS_UPDATE;
}
if (startsWith($query, 'do=' . self::$AJAX_THUMB_UPDATE)) {
return self::$AJAX_THUMB_UPDATE;
}
// At this point, only loggedin pages.
if (!$loggedIn) {
return self::$PAGE_LINKLIST;
}
if (startsWith($query, 'do=' . self::$PAGE_TOOLS)) {
return self::$PAGE_TOOLS;
}
if (startsWith($query, 'do=' . self::$PAGE_CHANGEPASSWORD)) {
return self::$PAGE_CHANGEPASSWORD;
}
if (startsWith($query, 'do=' . self::$PAGE_CONFIGURE)) {
return self::$PAGE_CONFIGURE;
}
if (startsWith($query, 'do=' . self::$PAGE_CHANGETAG)) {
return self::$PAGE_CHANGETAG;
}
if (startsWith($query, 'do=' . self::$PAGE_ADDLINK)) {
return self::$PAGE_ADDLINK;
}
if (isset($get['edit_link']) || isset($get['post'])) {
return self::$PAGE_EDITLINK;
}
if (isset($get['delete_link'])) {
return self::$PAGE_DELETELINK;
}
if (isset($get[self::$PAGE_CHANGE_VISIBILITY])) {
return self::$PAGE_CHANGE_VISIBILITY;
}
if (startsWith($query, 'do=' . self::$PAGE_PINLINK)) {
return self::$PAGE_PINLINK;
}
if (startsWith($query, 'do=' . self::$PAGE_EXPORT)) {
return self::$PAGE_EXPORT;
}
if (startsWith($query, 'do=' . self::$PAGE_IMPORT)) {
return self::$PAGE_IMPORT;
}
if (startsWith($query, 'do=' . self::$PAGE_PLUGINSADMIN)) {
return self::$PAGE_PLUGINSADMIN;
}
if (startsWith($query, 'do=' . self::$PAGE_SAVE_PLUGINSADMIN)) {
return self::$PAGE_SAVE_PLUGINSADMIN;
}
if (startsWith($query, 'do=' . self::$GET_TOKEN)) {
return self::$GET_TOKEN;
}
return self::$PAGE_LINKLIST;
}
}

View file

@ -168,6 +168,10 @@ class BookmarkIO
*/
public function checkDiskSpace(string $data): bool
{
if (function_exists('disk_free_space') === false) {
return true;
}
return disk_free_space(dirname($this->datastore)) > (strlen($data) + 1024 * 500);
}
}

View file

@ -91,7 +91,7 @@ Markdown also supports tables:
$bookmark = new Bookmark();
$bookmark->setTitle(
'Shaarli - ' . t('The personal, minimalist, super-fast, database free, bookmarking service')
'Shaarli - ' . t('The personal, minimalist, super fast, database-free, bookmarking service')
);
$bookmark->setDescription(t(
'Welcome to Shaarli!

View file

@ -1,577 +0,0 @@
<?php
namespace Shaarli\Bookmark;
use ArrayAccess;
use Countable;
use DateTime;
use Iterator;
use Shaarli\Bookmark\Exception\LinkNotFoundException;
use Shaarli\Exceptions\IOException;
use Shaarli\FileUtils;
/**
* Data storage for links.
*
* This object behaves like an associative array.
*
* Example:
* $myLinks = new LinkDB();
* echo $myLinks[350]['title'];
* foreach ($myLinks as $link)
* echo $link['title'].' at url '.$link['url'].'; description:'.$link['description'];
*
* Available keys:
* - id: primary key, incremental integer identifier (persistent)
* - description: description of the entry
* - created: creation date of this entry, DateTime object.
* - updated: last modification date of this entry, DateTime object.
* - private: Is this link private? 0=no, other value=yes
* - tags: tags attached to this entry (separated by spaces)
* - title Title of the link
* - url URL of the link. Used for displayable links.
* Can be absolute or relative in the database but the relative links
* will be converted to absolute ones in templates.
* - real_url Raw URL in stored in the DB (absolute or relative).
* - shorturl Permalink smallhash
*
* Implements 3 interfaces:
* - ArrayAccess: behaves like an associative array;
* - Countable: there is a count() method;
* - Iterator: usable in foreach () loops.
*
* ID mechanism:
* ArrayAccess is implemented in a way that will allow to access a link
* with the unique identifier ID directly with $link[ID].
* Note that it's not the real key of the link array attribute.
* This mechanism is in place to have persistent link IDs,
* even though the internal array is reordered by date.
* Example:
* - DB: link #1 (2010-01-01) link #2 (2016-01-01)
* - Order: #2 #1
* - Import links containing: link #3 (2013-01-01)
* - New DB: link #1 (2010-01-01) link #2 (2016-01-01) link #3 (2013-01-01)
* - Real order: #2 #3 #1
*/
class LinkDB implements Iterator, Countable, ArrayAccess
{
// Links are stored as a PHP serialized string
private $datastore;
// Link date storage format
const LINK_DATE_FORMAT = 'Ymd_His';
// List of links (associative array)
// - key: link date (e.g. "20110823_124546"),
// - value: associative array (keys: title, description...)
private $links;
// List of all recorded URLs (key=url, value=link offset)
// for fast reserve search (url-->link offset)
private $urls;
/**
* @var array List of all links IDS mapped with their array offset.
* Map: id->offset.
*/
protected $ids;
// List of offset keys (for the Iterator interface implementation)
private $keys;
// Position in the $this->keys array (for the Iterator interface)
private $position;
// Is the user logged in? (used to filter private links)
private $loggedIn;
// Hide public links
private $hidePublicLinks;
/**
* Creates a new LinkDB
*
* Checks if the datastore exists; else, attempts to create a dummy one.
*
* @param string $datastore datastore file path.
* @param boolean $isLoggedIn is the user logged in?
* @param boolean $hidePublicLinks if true all links are private.
*/
public function __construct(
$datastore,
$isLoggedIn,
$hidePublicLinks
) {
$this->datastore = $datastore;
$this->loggedIn = $isLoggedIn;
$this->hidePublicLinks = $hidePublicLinks;
$this->check();
$this->read();
}
/**
* Countable - Counts elements of an object
*/
public function count()
{
return count($this->links);
}
/**
* ArrayAccess - Assigns a value to the specified offset
*/
public function offsetSet($offset, $value)
{
// TODO: use exceptions instead of "die"
if (!$this->loggedIn) {
die(t('You are not authorized to add a link.'));
}
if (!isset($value['id']) || empty($value['url'])) {
die(t('Internal Error: A link should always have an id and URL.'));
}
if (($offset !== null && !is_int($offset)) || !is_int($value['id'])) {
die(t('You must specify an integer as a key.'));
}
if ($offset !== null && $offset !== $value['id']) {
die(t('Array offset and link ID must be equal.'));
}
// If the link exists, we reuse the real offset, otherwise new entry
$existing = $this->getLinkOffset($offset);
if ($existing !== null) {
$offset = $existing;
} else {
$offset = count($this->links);
}
$this->links[$offset] = $value;
$this->urls[$value['url']] = $offset;
$this->ids[$value['id']] = $offset;
}
/**
* ArrayAccess - Whether or not an offset exists
*/
public function offsetExists($offset)
{
return array_key_exists($this->getLinkOffset($offset), $this->links);
}
/**
* ArrayAccess - Unsets an offset
*/
public function offsetUnset($offset)
{
if (!$this->loggedIn) {
// TODO: raise an exception
die('You are not authorized to delete a link.');
}
$realOffset = $this->getLinkOffset($offset);
$url = $this->links[$realOffset]['url'];
unset($this->urls[$url]);
unset($this->ids[$realOffset]);
unset($this->links[$realOffset]);
}
/**
* ArrayAccess - Returns the value at specified offset
*/
public function offsetGet($offset)
{
$realOffset = $this->getLinkOffset($offset);
return isset($this->links[$realOffset]) ? $this->links[$realOffset] : null;
}
/**
* Iterator - Returns the current element
*/
public function current()
{
return $this[$this->keys[$this->position]];
}
/**
* Iterator - Returns the key of the current element
*/
public function key()
{
return $this->keys[$this->position];
}
/**
* Iterator - Moves forward to next element
*/
public function next()
{
++$this->position;
}
/**
* Iterator - Rewinds the Iterator to the first element
*
* Entries are sorted by date (latest first)
*/
public function rewind()
{
$this->keys = array_keys($this->ids);
$this->position = 0;
}
/**
* Iterator - Checks if current position is valid
*/
public function valid()
{
return isset($this->keys[$this->position]);
}
/**
* Checks if the DB directory and file exist
*
* If no DB file is found, creates a dummy DB.
*/
private function check()
{
if (file_exists($this->datastore)) {
return;
}
// Create a dummy database for example
$this->links = array();
$link = array(
'id' => 1,
'title' => t('The personal, minimalist, super-fast, database free, bookmarking service'),
'url' => 'https://shaarli.readthedocs.io',
'description' => t(
'Welcome to Shaarli! This is your first public bookmark. '
. 'To edit or delete me, you must first login.
To learn how to use Shaarli, consult the link "Documentation" at the bottom of this page.
You use the community supported version of the original Shaarli project, by Sebastien Sauvage.'
),
'private' => 0,
'created' => new DateTime(),
'tags' => 'opensource software',
'sticky' => false,
);
$link['shorturl'] = link_small_hash($link['created'], $link['id']);
$this->links[1] = $link;
$link = array(
'id' => 0,
'title' => t('My secret stuff... - Pastebin.com'),
'url' => 'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=',
'description' => t('Shhhh! I\'m a private link only YOU can see. You can delete me too.'),
'private' => 1,
'created' => new DateTime('1 minute ago'),
'tags' => 'secretstuff',
'sticky' => false,
);
$link['shorturl'] = link_small_hash($link['created'], $link['id']);
$this->links[0] = $link;
// Write database to disk
$this->write();
}
/**
* Reads database from disk to memory
*/
private function read()
{
// Public links are hidden and user not logged in => nothing to show
if ($this->hidePublicLinks && !$this->loggedIn) {
$this->links = array();
return;
}
$this->urls = [];
$this->ids = [];
$this->links = FileUtils::readFlatDB($this->datastore, []);
$toremove = array();
foreach ($this->links as $key => &$link) {
if (!$this->loggedIn && $link['private'] != 0) {
// Transition for not upgraded databases.
unset($this->links[$key]);
continue;
}
// Sanitize data fields.
sanitizeLink($link);
// Remove private tags if the user is not logged in.
if (!$this->loggedIn) {
$link['tags'] = preg_replace('/(^|\s+)\.[^($|\s)]+\s*/', ' ', $link['tags']);
}
$link['real_url'] = $link['url'];
$link['sticky'] = isset($link['sticky']) ? $link['sticky'] : false;
$link['sticky'] = isset($link['sticky']) ? $link['sticky'] : false;
// To be able to load links before running the update, and prepare the update
if (!isset($link['created'])) {
$link['id'] = $link['linkdate'];
$link['created'] = DateTime::createFromFormat(self::LINK_DATE_FORMAT, $link['linkdate']);
if (!empty($link['updated'])) {
$link['updated'] = DateTime::createFromFormat(self::LINK_DATE_FORMAT, $link['updated']);
}
$link['shorturl'] = smallHash($link['linkdate']);
}
$this->urls[$link['url']] = $key;
$this->ids[$link['id']] = $key;
}
}
/**
* Saves the database from memory to disk
*
* @throws IOException the datastore is not writable
*/
private function write()
{
$this->reorder();
FileUtils::writeFlatDB($this->datastore, $this->links);
}
/**
* Saves the database from memory to disk
*
* @param string $pageCacheDir page cache directory
*/
public function save($pageCacheDir)
{
if (!$this->loggedIn) {
// TODO: raise an Exception instead
die('You are not authorized to change the database.');
}
$this->write();
invalidateCaches($pageCacheDir);
}
/**
* Returns the link for a given URL, or False if it does not exist.
*
* @param string $url URL to search for
*
* @return mixed the existing link if it exists, else 'false'
*/
public function getLinkFromUrl($url)
{
if (isset($this->urls[$url])) {
return $this->links[$this->urls[$url]];
}
return false;
}
/**
* Returns the shaare corresponding to a smallHash.
*
* @param string $request QUERY_STRING server parameter.
*
* @return array $filtered array containing permalink data.
*
* @throws LinkNotFoundException if the smallhash is malformed or doesn't match any link.
*/
public function filterHash($request)
{
$request = substr($request, 0, 6);
$linkFilter = new LinkFilter($this->links);
return $linkFilter->filter(LinkFilter::$FILTER_HASH, $request);
}
/**
* Returns the list of articles for a given day.
*
* @param string $request day to filter. Format: YYYYMMDD.
*
* @return array list of shaare found.
*/
public function filterDay($request)
{
$linkFilter = new LinkFilter($this->links);
return $linkFilter->filter(LinkFilter::$FILTER_DAY, $request);
}
/**
* Filter links according to search parameters.
*
* @param array $filterRequest Search request content. Supported keys:
* - searchtags: list of tags
* - searchterm: term search
* @param bool $casesensitive Optional: Perform case sensitive filter
* @param string $visibility return only all/private/public links
* @param bool $untaggedonly return only untagged links
*
* @return array filtered links, all links if no suitable filter was provided.
*/
public function filterSearch(
$filterRequest = array(),
$casesensitive = false,
$visibility = 'all',
$untaggedonly = false
) {
// Filter link database according to parameters.
$searchtags = isset($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : '';
$searchterm = isset($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : '';
// Search tags + fullsearch - blank string parameter will return all links.
$type = LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT; // == "vuotext"
$request = [$searchtags, $searchterm];
$linkFilter = new LinkFilter($this);
return $linkFilter->filter($type, $request, $casesensitive, $visibility, $untaggedonly);
}
/**
* Returns the list tags appearing in the links with the given tags
*
* @param array $filteringTags tags selecting the links to consider
* @param string $visibility process only all/private/public links
*
* @return array tag => linksCount
*/
public function linksCountPerTag($filteringTags = [], $visibility = 'all')
{
$links = $this->filterSearch(['searchtags' => $filteringTags], false, $visibility);
$tags = [];
$caseMapping = [];
foreach ($links as $link) {
foreach (preg_split('/\s+/', $link['tags'], 0, PREG_SPLIT_NO_EMPTY) as $tag) {
if (empty($tag)) {
continue;
}
// The first case found will be displayed.
if (!isset($caseMapping[strtolower($tag)])) {
$caseMapping[strtolower($tag)] = $tag;
$tags[$caseMapping[strtolower($tag)]] = 0;
}
$tags[$caseMapping[strtolower($tag)]]++;
}
}
/*
* Formerly used arsort(), which doesn't define the sort behaviour for equal values.
* Also, this function doesn't produce the same result between PHP 5.6 and 7.
*
* So we now use array_multisort() to sort tags by DESC occurrences,
* then ASC alphabetically for equal values.
*
* @see https://github.com/shaarli/Shaarli/issues/1142
*/
$keys = array_keys($tags);
$tmpTags = array_combine($keys, $keys);
array_multisort($tags, SORT_DESC, $tmpTags, SORT_ASC, $tags);
return $tags;
}
/**
* Rename or delete a tag across all links.
*
* @param string $from Tag to rename
* @param string $to New tag. If none is provided, the from tag will be deleted
*
* @return array|bool List of altered links or false on error
*/
public function renameTag($from, $to)
{
if (empty($from)) {
return false;
}
$delete = empty($to);
// True for case-sensitive tag search.
$linksToAlter = $this->filterSearch(['searchtags' => $from], true);
foreach ($linksToAlter as $key => &$value) {
$tags = preg_split('/\s+/', trim($value['tags']));
if (($pos = array_search($from, $tags)) !== false) {
if ($delete) {
unset($tags[$pos]); // Remove tag.
} else {
$tags[$pos] = trim($to);
}
$value['tags'] = trim(implode(' ', array_unique($tags)));
$this[$value['id']] = $value;
}
}
return $linksToAlter;
}
/**
* Returns the list of days containing articles (oldest first)
* Output: An array containing days (in format YYYYMMDD).
*/
public function days()
{
$linkDays = array();
foreach ($this->links as $link) {
$linkDays[$link['created']->format('Ymd')] = 0;
}
$linkDays = array_keys($linkDays);
sort($linkDays);
return $linkDays;
}
/**
* Reorder links by creation date (newest first).
*
* Also update the urls and ids mapping arrays.
*
* @param string $order ASC|DESC
*/
public function reorder($order = 'DESC')
{
$order = $order === 'ASC' ? -1 : 1;
// Reorder array by dates.
usort($this->links, function ($a, $b) use ($order) {
if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) {
return $a['sticky'] ? -1 : 1;
}
return $a['created'] < $b['created'] ? 1 * $order : -1 * $order;
});
$this->urls = [];
$this->ids = [];
foreach ($this->links as $key => $link) {
$this->urls[$link['url']] = $key;
$this->ids[$link['id']] = $key;
}
}
/**
* Return the next key for link creation.
* E.g. If the last ID is 597, the next will be 598.
*
* @return int next ID.
*/
public function getNextId()
{
if (!empty($this->ids)) {
return max(array_keys($this->ids)) + 1;
}
return 0;
}
/**
* Returns a link offset in links array from its unique ID.
*
* @param int $id Persistent ID of a link.
*
* @return int Real offset in local array, or null if doesn't exist.
*/
protected function getLinkOffset($id)
{
if (isset($this->ids[$id])) {
return $this->ids[$id];
}
return null;
}
}

View file

@ -1,449 +0,0 @@
<?php
namespace Shaarli\Bookmark;
use Exception;
use Shaarli\Bookmark\Exception\LinkNotFoundException;
/**
* Class LinkFilter.
*
* Perform search and filter operation on link data list.
*/
class LinkFilter
{
/**
* @var string permalinks.
*/
public static $FILTER_HASH = 'permalink';
/**
* @var string text search.
*/
public static $FILTER_TEXT = 'fulltext';
/**
* @var string tag filter.
*/
public static $FILTER_TAG = 'tags';
/**
* @var string filter by day.
*/
public static $FILTER_DAY = 'FILTER_DAY';
/**
* @var string Allowed characters for hashtags (regex syntax).
*/
public static $HASHTAG_CHARS = '\p{Pc}\p{N}\p{L}\p{Mn}';
/**
* @var LinkDB all available links.
*/
private $links;
/**
* @param LinkDB $links initialization.
*/
public function __construct($links)
{
$this->links = $links;
}
/**
* Filter links according to parameters.
*
* @param string $type Type of filter (eg. tags, permalink, etc.).
* @param mixed $request Filter content.
* @param bool $casesensitive Optional: Perform case sensitive filter if true.
* @param string $visibility Optional: return only all/private/public links
* @param string $untaggedonly Optional: return only untagged links. Applies only if $type includes FILTER_TAG
*
* @return array filtered link list.
*/
public function filter($type, $request, $casesensitive = false, $visibility = 'all', $untaggedonly = false)
{
if (!in_array($visibility, ['all', 'public', 'private'])) {
$visibility = 'all';
}
switch ($type) {
case self::$FILTER_HASH:
return $this->filterSmallHash($request);
case self::$FILTER_TAG | self::$FILTER_TEXT: // == "vuotext"
$noRequest = empty($request) || (empty($request[0]) && empty($request[1]));
if ($noRequest) {
if ($untaggedonly) {
return $this->filterUntagged($visibility);
}
return $this->noFilter($visibility);
}
if ($untaggedonly) {
$filtered = $this->filterUntagged($visibility);
} else {
$filtered = $this->links;
}
if (!empty($request[0])) {
$filtered = (new LinkFilter($filtered))->filterTags($request[0], $casesensitive, $visibility);
}
if (!empty($request[1])) {
$filtered = (new LinkFilter($filtered))->filterFulltext($request[1], $visibility);
}
return $filtered;
case self::$FILTER_TEXT:
return $this->filterFulltext($request, $visibility);
case self::$FILTER_TAG:
if ($untaggedonly) {
return $this->filterUntagged($visibility);
} else {
return $this->filterTags($request, $casesensitive, $visibility);
}
case self::$FILTER_DAY:
return $this->filterDay($request);
default:
return $this->noFilter($visibility);
}
}
/**
* Unknown filter, but handle private only.
*
* @param string $visibility Optional: return only all/private/public links
*
* @return array filtered links.
*/
private function noFilter($visibility = 'all')
{
if ($visibility === 'all') {
return $this->links;
}
$out = array();
foreach ($this->links as $key => $value) {
if ($value['private'] && $visibility === 'private') {
$out[$key] = $value;
} elseif (!$value['private'] && $visibility === 'public') {
$out[$key] = $value;
}
}
return $out;
}
/**
* Returns the shaare corresponding to a smallHash.
*
* @param string $smallHash permalink hash.
*
* @return array $filtered array containing permalink data.
*
* @throws \Shaarli\Bookmark\Exception\LinkNotFoundException if the smallhash doesn't match any link.
*/
private function filterSmallHash($smallHash)
{
$filtered = array();
foreach ($this->links as $key => $l) {
if ($smallHash == $l['shorturl']) {
// Yes, this is ugly and slow
$filtered[$key] = $l;
return $filtered;
}
}
if (empty($filtered)) {
throw new LinkNotFoundException();
}
return $filtered;
}
/**
* Returns the list of links corresponding to a full-text search
*
* Searches:
* - in the URLs, title and description;
* - are case-insensitive;
* - terms surrounded by quotes " are exact terms search.
* - terms starting with a dash - are excluded (except exact terms).
*
* Example:
* print_r($mydb->filterFulltext('hollandais'));
*
* mb_convert_case($val, MB_CASE_LOWER, 'UTF-8')
* - allows to perform searches on Unicode text
* - see https://github.com/shaarli/Shaarli/issues/75 for examples
*
* @param string $searchterms search query.
* @param string $visibility Optional: return only all/private/public links.
*
* @return array search results.
*/
private function filterFulltext($searchterms, $visibility = 'all')
{
if (empty($searchterms)) {
return $this->noFilter($visibility);
}
$filtered = array();
$search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8');
$exactRegex = '/"([^"]+)"/';
// Retrieve exact search terms.
preg_match_all($exactRegex, $search, $exactSearch);
$exactSearch = array_values(array_filter($exactSearch[1]));
// Remove exact search terms to get AND terms search.
$explodedSearchAnd = explode(' ', trim(preg_replace($exactRegex, '', $search)));
$explodedSearchAnd = array_values(array_filter($explodedSearchAnd));
// Filter excluding terms and update andSearch.
$excludeSearch = array();
$andSearch = array();
foreach ($explodedSearchAnd as $needle) {
if ($needle[0] == '-' && strlen($needle) > 1) {
$excludeSearch[] = substr($needle, 1);
} else {
$andSearch[] = $needle;
}
}
$keys = array('title', 'description', 'url', 'tags');
// Iterate over every stored link.
foreach ($this->links as $id => $link) {
// ignore non private links when 'privatonly' is on.
if ($visibility !== 'all') {
if (!$link['private'] && $visibility === 'private') {
continue;
} elseif ($link['private'] && $visibility === 'public') {
continue;
}
}
// Concatenate link fields to search across fields.
// Adds a '\' separator for exact search terms.
$content = '';
foreach ($keys as $key) {
$content .= mb_convert_case($link[$key], MB_CASE_LOWER, 'UTF-8') . '\\';
}
// Be optimistic
$found = true;
// First, we look for exact term search
for ($i = 0; $i < count($exactSearch) && $found; $i++) {
$found = strpos($content, $exactSearch[$i]) !== false;
}
// Iterate over keywords, if keyword is not found,
// no need to check for the others. We want all or nothing.
for ($i = 0; $i < count($andSearch) && $found; $i++) {
$found = strpos($content, $andSearch[$i]) !== false;
}
// Exclude terms.
for ($i = 0; $i < count($excludeSearch) && $found; $i++) {
$found = strpos($content, $excludeSearch[$i]) === false;
}
if ($found) {
$filtered[$id] = $link;
}
}
return $filtered;
}
/**
* generate a regex fragment out of a tag
*
* @param string $tag to to generate regexs from. may start with '-' to negate, contain '*' as wildcard
*
* @return string generated regex fragment
*/
private static function tag2regex($tag)
{
$len = strlen($tag);
if (!$len || $tag === "-" || $tag === "*") {
// nothing to search, return empty regex
return '';
}
if ($tag[0] === "-") {
// query is negated
$i = 1; // use offset to start after '-' character
$regex = '(?!'; // create negative lookahead
} else {
$i = 0; // start at first character
$regex = '(?='; // use positive lookahead
}
$regex .= '.*(?:^| )'; // before tag may only be a space or the beginning
// iterate over string, separating it into placeholder and content
for (; $i < $len; $i++) {
if ($tag[$i] === '*') {
// placeholder found
$regex .= '[^ ]*?';
} else {
// regular characters
$offset = strpos($tag, '*', $i);
if ($offset === false) {
// no placeholder found, set offset to end of string
$offset = $len;
}
// subtract one, as we want to get before the placeholder or end of string
$offset -= 1;
// we got a tag name that we want to search for. escape any regex characters to prevent conflicts.
$regex .= preg_quote(substr($tag, $i, $offset - $i + 1), '/');
// move $i on
$i = $offset;
}
}
$regex .= '(?:$| ))'; // after the tag may only be a space or the end
return $regex;
}
/**
* Returns the list of links associated with a given list of tags
*
* You can specify one or more tags, separated by space or a comma, e.g.
* print_r($mydb->filterTags('linux programming'));
*
* @param string $tags list of tags separated by commas or blank spaces.
* @param bool $casesensitive ignore case if false.
* @param string $visibility Optional: return only all/private/public links.
*
* @return array filtered links.
*/
public function filterTags($tags, $casesensitive = false, $visibility = 'all')
{
// get single tags (we may get passed an array, even though the docs say different)
$inputTags = $tags;
if (!is_array($tags)) {
// we got an input string, split tags
$inputTags = preg_split('/(?:\s+)|,/', $inputTags, -1, PREG_SPLIT_NO_EMPTY);
}
if (!count($inputTags)) {
// no input tags
return $this->noFilter($visibility);
}
// build regex from all tags
$re = '/^' . implode(array_map("self::tag2regex", $inputTags)) . '.*$/';
if (!$casesensitive) {
// make regex case insensitive
$re .= 'i';
}
// create resulting array
$filtered = array();
// iterate over each link
foreach ($this->links as $key => $link) {
// check level of visibility
// ignore non private links when 'privateonly' is on.
if ($visibility !== 'all') {
if (!$link['private'] && $visibility === 'private') {
continue;
} elseif ($link['private'] && $visibility === 'public') {
continue;
}
}
$search = $link['tags']; // build search string, start with tags of current link
if (strlen(trim($link['description'])) && strpos($link['description'], '#') !== false) {
// description given and at least one possible tag found
$descTags = array();
// find all tags in the form of #tag in the description
preg_match_all(
'/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm',
$link['description'],
$descTags
);
if (count($descTags[1])) {
// there were some tags in the description, add them to the search string
$search .= ' ' . implode(' ', $descTags[1]);
}
};
// match regular expression with search string
if (!preg_match($re, $search)) {
// this entry does _not_ match our regex
continue;
}
$filtered[$key] = $link;
}
return $filtered;
}
/**
* Return only links without any tag.
*
* @param string $visibility return only all/private/public links.
*
* @return array filtered links.
*/
public function filterUntagged($visibility)
{
$filtered = [];
foreach ($this->links as $key => $link) {
if ($visibility !== 'all') {
if (!$link['private'] && $visibility === 'private') {
continue;
} elseif ($link['private'] && $visibility === 'public') {
continue;
}
}
if (empty(trim($link['tags']))) {
$filtered[$key] = $link;
}
}
return $filtered;
}
/**
* Returns the list of articles for a given day, chronologically sorted
*
* Day must be in the form 'YYYYMMDD' (e.g. '20120125'), e.g.
* print_r($mydb->filterDay('20120125'));
*
* @param string $day day to filter.
*
* @return array all link matching given day.
*
* @throws Exception if date format is invalid.
*/
public function filterDay($day)
{
if (!checkDateFormat('Ymd', $day)) {
throw new Exception('Invalid date format');
}
$filtered = array();
foreach ($this->links as $key => $l) {
if ($l['created']->format('Ymd') == $day) {
$filtered[$key] = $l;
}
}
// sort by date ASC
return array_reverse($filtered, true);
}
/**
* Convert a list of tags (str) to an array. Also
* - handle case sensitivity.
* - accepts spaces commas as separator.
*
* @param string $tags string containing a list of tags.
* @param bool $casesensitive will convert everything to lowercase if false.
*
* @return array filtered tags string.
*/
public static function tagsStrToArray($tags, $casesensitive)
{
// We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek)
$tagsOut = $casesensitive ? $tags : mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8');
$tagsOut = str_replace(',', ' ', $tagsOut);
return preg_split('/\s+/', $tagsOut, -1, PREG_SPLIT_NO_EMPTY);
}
}

View file

@ -1,15 +0,0 @@
<?php
namespace Shaarli\Bookmark\Exception;
use Exception;
class LinkNotFoundException extends Exception
{
/**
* LinkNotFoundException constructor.
*/
public function __construct()
{
$this->message = t('The link you are trying to reach does not exist or has been deleted.');
}
}

View file

@ -1,38 +0,0 @@
<?php
/**
* Cache utilities
*/
/**
* Purges all cached pages
*
* @param string $pageCacheDir page cache directory
*
* @return mixed an error string if the directory is missing
*/
function purgeCachedPages($pageCacheDir)
{
if (! is_dir($pageCacheDir)) {
$error = sprintf(t('Cannot purge %s: no directory'), $pageCacheDir);
error_log($error);
return $error;
}
array_map('unlink', glob($pageCacheDir.'/*.cache'));
}
/**
* Invalidates caches when the database is changed or the user logs out.
*
* @param string $pageCacheDir page cache directory
*/
function invalidateCaches($pageCacheDir)
{
// Purge cache attached to session.
if (isset($_SESSION['tags'])) {
unset($_SESSION['tags']);
}
// Purge page cache shared by sessions.
purgeCachedPages($pageCacheDir);
}

View file

@ -28,7 +28,7 @@ class ServerController extends ShaarliAdminController
$releaseUrl = ApplicationUtils::$GITHUB_URL . '/releases/';
if ($this->container->conf->get('updates.check_updates', true)) {
$latestVersion = 'v' . ApplicationUtils::getVersion(
ApplicationUtils::$GIT_RAW_URL . '/latest/' . ApplicationUtils::$VERSION_FILE
ApplicationUtils::$GIT_RAW_URL . '/release/' . ApplicationUtils::$VERSION_FILE
);
$releaseUrl .= 'tag/' . $latestVersion;
} else {

View file

@ -82,6 +82,9 @@ class BookmarkListController extends ShaarliVisitorController
$searchTagsUrlEncoded = array_map('urlencode', tags_str2array($searchTags, $tagsSeparator));
$searchTags = !empty($searchTags) ? trim($searchTags, $tagsSeparator) . $tagsSeparator : '';
$searchTags = !empty($searchTags) ? escape($searchTags) : '';
$searchTerm = !empty($searchTerm) ? escape($searchTerm) : '';
// Fill all template fields.
$data = array_merge(
$this->initializeTemplateVars(),
@ -91,8 +94,8 @@ class BookmarkListController extends ShaarliVisitorController
'page_current' => $page,
'page_max' => $searchResult->getLastPage(),
'result_count' => $searchResult->getTotalCount(),
'search_term' => escape($searchTerm),
'search_tags' => escape($searchTags),
'search_term' => $searchTerm,
'search_tags' => $searchTags,
'search_tags_url' => $searchTagsUrlEncoded,
'visibility' => $visibility,
'links' => $links,

View file

@ -329,7 +329,9 @@ class ApplicationUtils
'7.2' => '2020-11-30',
'7.3' => '2021-12-06',
'7.4' => '2022-11-28',
'8.0' => '2023-12-01',
'8.0' => '2023-11-26',
'8.1' => '2024-11-25',
'8.2' => '2025-12-08',
][$matches[1]] ?? (new \DateTime('+2 year'))->format('Y-m-d');
}
}

View file

@ -1,3 +1,4 @@
<<<<<<< HEAD
<?php
namespace Shaarli\Legacy;
@ -583,3 +584,599 @@ You use the community supported version of the original Shaarli project, by Seba
return null;
}
}
||||||| d7dead56
=======
<?php
namespace Shaarli\Legacy;
use ArrayAccess;
use Countable;
use DateTime;
use Iterator;
use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
use Shaarli\Exceptions\IOException;
use Shaarli\Helper\FileUtils;
use Shaarli\Render\PageCacheManager;
/**
* Data storage for bookmarks.
*
* This object behaves like an associative array.
*
* Example:
* $myLinks = new LinkDB();
* echo $myLinks[350]['title'];
* foreach ($myLinks as $link)
* echo $link['title'].' at url '.$link['url'].'; description:'.$link['description'];
*
* Available keys:
* - id: primary key, incremental integer identifier (persistent)
* - description: description of the entry
* - created: creation date of this entry, DateTime object.
* - updated: last modification date of this entry, DateTime object.
* - private: Is this link private? 0=no, other value=yes
* - tags: tags attached to this entry (separated by spaces)
* - title Title of the link
* - url URL of the link. Used for displayable bookmarks.
* Can be absolute or relative in the database but the relative bookmarks
* will be converted to absolute ones in templates.
* - real_url Raw URL in stored in the DB (absolute or relative).
* - shorturl Permalink smallhash
*
* Implements 3 interfaces:
* - ArrayAccess: behaves like an associative array;
* - Countable: there is a count() method;
* - Iterator: usable in foreach () loops.
*
* ID mechanism:
* ArrayAccess is implemented in a way that will allow to access a link
* with the unique identifier ID directly with $link[ID].
* Note that it's not the real key of the link array attribute.
* This mechanism is in place to have persistent link IDs,
* even though the internal array is reordered by date.
* Example:
* - DB: link #1 (2010-01-01) link #2 (2016-01-01)
* - Order: #2 #1
* - Import bookmarks containing: link #3 (2013-01-01)
* - New DB: link #1 (2010-01-01) link #2 (2016-01-01) link #3 (2013-01-01)
* - Real order: #2 #3 #1
*
* @deprecated
*/
class LegacyLinkDB implements Iterator, Countable, ArrayAccess
{
// Links are stored as a PHP serialized string
private $datastore;
// Link date storage format
public const LINK_DATE_FORMAT = 'Ymd_His';
// List of bookmarks (associative array)
// - key: link date (e.g. "20110823_124546"),
// - value: associative array (keys: title, description...)
private $links;
// List of all recorded URLs (key=url, value=link offset)
// for fast reserve search (url-->link offset)
private $urls;
/**
* @var array List of all bookmarks IDS mapped with their array offset.
* Map: id->offset.
*/
protected $ids;
// List of offset keys (for the Iterator interface implementation)
private $keys;
// Position in the $this->keys array (for the Iterator interface)
private $position;
// Is the user logged in? (used to filter private bookmarks)
private $loggedIn;
// Hide public bookmarks
private $hidePublicLinks;
/**
* Creates a new LinkDB
*
* Checks if the datastore exists; else, attempts to create a dummy one.
*
* @param string $datastore datastore file path.
* @param boolean $isLoggedIn is the user logged in?
* @param boolean $hidePublicLinks if true all bookmarks are private.
*/
public function __construct(
$datastore,
$isLoggedIn,
$hidePublicLinks
) {
$this->datastore = $datastore;
$this->loggedIn = $isLoggedIn;
$this->hidePublicLinks = $hidePublicLinks;
$this->check();
$this->read();
}
/**
* Countable - Counts elements of an object
*/
public function count(): int
{
return count($this->links);
}
/**
* ArrayAccess - Assigns a value to the specified offset
*/
public function offsetSet($offset, $value): void
{
// TODO: use exceptions instead of "die"
if (!$this->loggedIn) {
die(t('You are not authorized to add a link.'));
}
if (!isset($value['id']) || empty($value['url'])) {
die(t('Internal Error: A link should always have an id and URL.'));
}
if (($offset !== null && !is_int($offset)) || !is_int($value['id'])) {
die(t('You must specify an integer as a key.'));
}
if ($offset !== null && $offset !== $value['id']) {
die(t('Array offset and link ID must be equal.'));
}
// If the link exists, we reuse the real offset, otherwise new entry
$existing = $this->getLinkOffset($offset);
if ($existing !== null) {
$offset = $existing;
} else {
$offset = count($this->links);
}
$this->links[$offset] = $value;
$this->urls[$value['url']] = $offset;
$this->ids[$value['id']] = $offset;
}
/**
* ArrayAccess - Whether or not an offset exists
*/
public function offsetExists($offset): bool
{
return array_key_exists($this->getLinkOffset($offset), $this->links);
}
/**
* ArrayAccess - Unsets an offset
*/
public function offsetUnset($offset): void
{
if (!$this->loggedIn) {
// TODO: raise an exception
die('You are not authorized to delete a link.');
}
$realOffset = $this->getLinkOffset($offset);
$url = $this->links[$realOffset]['url'];
unset($this->urls[$url]);
unset($this->ids[$realOffset]);
unset($this->links[$realOffset]);
}
/**
* ArrayAccess - Returns the value at specified offset
*/
public function offsetGet($offset): ?array
{
$realOffset = $this->getLinkOffset($offset);
return isset($this->links[$realOffset]) ? $this->links[$realOffset] : null;
}
/**
* Iterator - Returns the current element
*/
public function current(): array
{
return $this[$this->keys[$this->position]];
}
/**
* Iterator - Returns the key of the current element
*
* @return int|string
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->keys[$this->position];
}
/**
* Iterator - Moves forward to next element
*/
public function next(): void
{
++$this->position;
}
/**
* Iterator - Rewinds the Iterator to the first element
*
* Entries are sorted by date (latest first)
*/
public function rewind(): void
{
$this->keys = array_keys($this->ids);
$this->position = 0;
}
/**
* Iterator - Checks if current position is valid
*/
public function valid(): bool
{
return isset($this->keys[$this->position]);
}
/**
* Checks if the DB directory and file exist
*
* If no DB file is found, creates a dummy DB.
*/
private function check()
{
if (file_exists($this->datastore)) {
return;
}
// Create a dummy database for example
$this->links = [];
$link = [
'id' => 1,
'title' => t('The personal, minimalist, super fast, database-free, bookmarking service'),
'url' => 'https://shaarli.readthedocs.io',
'description' => t(
'Welcome to Shaarli! This is your first public bookmark. '
. 'To edit or delete me, you must first login.
To learn how to use Shaarli, consult the link "Documentation" at the bottom of this page.
You use the community supported version of the original Shaarli project, by Sebastien Sauvage.'
),
'private' => 0,
'created' => new DateTime(),
'tags' => 'opensource software',
'sticky' => false,
];
$link['shorturl'] = link_small_hash($link['created'], $link['id']);
$this->links[1] = $link;
$link = [
'id' => 0,
'title' => t('My secret stuff... - Pastebin.com'),
'url' => 'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=',
'description' => t('Shhhh! I\'m a private link only YOU can see. You can delete me too.'),
'private' => 1,
'created' => new DateTime('1 minute ago'),
'tags' => 'secretstuff',
'sticky' => false,
];
$link['shorturl'] = link_small_hash($link['created'], $link['id']);
$this->links[0] = $link;
// Write database to disk
$this->write();
}
/**
* Reads database from disk to memory
*/
private function read()
{
// Public bookmarks are hidden and user not logged in => nothing to show
if ($this->hidePublicLinks && !$this->loggedIn) {
$this->links = [];
return;
}
$this->urls = [];
$this->ids = [];
$this->links = FileUtils::readFlatDB($this->datastore, []);
$toremove = [];
foreach ($this->links as $key => &$link) {
if (!$this->loggedIn && $link['private'] != 0) {
// Transition for not upgraded databases.
unset($this->links[$key]);
continue;
}
// Sanitize data fields.
sanitizeLink($link);
// Remove private tags if the user is not logged in.
if (!$this->loggedIn) {
$link['tags'] = preg_replace('/(^|\s+)\.[^($|\s)]+\s*/', ' ', $link['tags']);
}
$link['real_url'] = $link['url'];
$link['sticky'] = isset($link['sticky']) ? $link['sticky'] : false;
<<<<<<<< HEAD:application/bookmark/LinkDB.php
$link['sticky'] = isset($link['sticky']) ? $link['sticky'] : false;
// To be able to load links before running the update, and prepare the update
|||||||| d7dead56:application/bookmark/LinkDB.php
// To be able to load links before running the update, and prepare the update
========
// To be able to load bookmarks before running the update, and prepare the update
>>>>>>>> github/v0.13:application/legacy/LegacyLinkDB.php
if (!isset($link['created'])) {
$link['id'] = $link['linkdate'];
$link['created'] = DateTime::createFromFormat(self::LINK_DATE_FORMAT, $link['linkdate']);
if (!empty($link['updated'])) {
$link['updated'] = DateTime::createFromFormat(self::LINK_DATE_FORMAT, $link['updated']);
}
$link['shorturl'] = smallHash($link['linkdate']);
}
$this->urls[$link['url']] = $key;
$this->ids[$link['id']] = $key;
}
}
/**
* Saves the database from memory to disk
*
* @throws IOException the datastore is not writable
*/
private function write()
{
$this->reorder();
FileUtils::writeFlatDB($this->datastore, $this->links);
}
/**
* Saves the database from memory to disk
*
* @param string $pageCacheDir page cache directory
*/
public function save($pageCacheDir)
{
if (!$this->loggedIn) {
// TODO: raise an Exception instead
die('You are not authorized to change the database.');
}
$this->write();
$pageCacheManager = new PageCacheManager($pageCacheDir, $this->loggedIn);
$pageCacheManager->invalidateCaches();
}
/**
* Returns the link for a given URL, or False if it does not exist.
*
* @param string $url URL to search for
*
* @return mixed the existing link if it exists, else 'false'
*/
public function getLinkFromUrl($url)
{
if (isset($this->urls[$url])) {
return $this->links[$this->urls[$url]];
}
return false;
}
/**
* Returns the shaare corresponding to a smallHash.
*
* @param string $request QUERY_STRING server parameter.
*
* @return array $filtered array containing permalink data.
*
* @throws BookmarkNotFoundException if the smallhash is malformed or doesn't match any link.
*/
public function filterHash($request)
{
$request = substr($request, 0, 6);
$linkFilter = new LegacyLinkFilter($this->links);
return $linkFilter->filter(LegacyLinkFilter::$FILTER_HASH, $request);
}
/**
* Returns the list of articles for a given day.
*
* @param string $request day to filter. Format: YYYYMMDD.
*
* @return array list of shaare found.
*/
public function filterDay($request)
{
$linkFilter = new LegacyLinkFilter($this->links);
return $linkFilter->filter(LegacyLinkFilter::$FILTER_DAY, $request);
}
/**
* Filter bookmarks according to search parameters.
*
* @param array $filterRequest Search request content. Supported keys:
* - searchtags: list of tags
* - searchterm: term search
* @param bool $casesensitive Optional: Perform case sensitive filter
* @param string $visibility return only all/private/public bookmarks
* @param bool $untaggedonly return only untagged bookmarks
*
* @return array filtered bookmarks, all bookmarks if no suitable filter was provided.
*/
public function filterSearch(
$filterRequest = [],
$casesensitive = false,
$visibility = 'all',
$untaggedonly = false
) {
// Filter link database according to parameters.
$searchtags = isset($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : '';
$searchterm = isset($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : '';
// Search tags + fullsearch - blank string parameter will return all bookmarks.
$type = LegacyLinkFilter::$FILTER_TAG | LegacyLinkFilter::$FILTER_TEXT; // == "vuotext"
$request = [$searchtags, $searchterm];
$linkFilter = new LegacyLinkFilter($this);
return $linkFilter->filter($type, $request, $casesensitive, $visibility, $untaggedonly);
}
/**
* Returns the list tags appearing in the bookmarks with the given tags
*
* @param array $filteringTags tags selecting the bookmarks to consider
* @param string $visibility process only all/private/public bookmarks
*
* @return array tag => linksCount
*/
public function linksCountPerTag($filteringTags = [], $visibility = 'all')
{
$links = $this->filterSearch(['searchtags' => $filteringTags], false, $visibility);
$tags = [];
$caseMapping = [];
foreach ($links as $link) {
foreach (preg_split('/\s+/', $link['tags'], 0, PREG_SPLIT_NO_EMPTY) as $tag) {
if (empty($tag)) {
continue;
}
// The first case found will be displayed.
if (!isset($caseMapping[strtolower($tag)])) {
$caseMapping[strtolower($tag)] = $tag;
$tags[$caseMapping[strtolower($tag)]] = 0;
}
$tags[$caseMapping[strtolower($tag)]]++;
}
}
/*
* Formerly used arsort(), which doesn't define the sort behaviour for equal values.
* Also, this function doesn't produce the same result between PHP 5.6 and 7.
*
* So we now use array_multisort() to sort tags by DESC occurrences,
* then ASC alphabetically for equal values.
*
* @see https://github.com/shaarli/Shaarli/issues/1142
*/
$keys = array_keys($tags);
$tmpTags = array_combine($keys, $keys);
array_multisort($tags, SORT_DESC, $tmpTags, SORT_ASC, $tags);
return $tags;
}
/**
* Rename or delete a tag across all bookmarks.
*
* @param string $from Tag to rename
* @param string $to New tag. If none is provided, the from tag will be deleted
*
* @return array|bool List of altered bookmarks or false on error
*/
public function renameTag($from, $to)
{
if (empty($from)) {
return false;
}
$delete = empty($to);
// True for case-sensitive tag search.
$linksToAlter = $this->filterSearch(['searchtags' => $from], true);
foreach ($linksToAlter as $key => &$value) {
$tags = preg_split('/\s+/', trim($value['tags']));
if (($pos = array_search($from, $tags)) !== false) {
if ($delete) {
unset($tags[$pos]); // Remove tag.
} else {
$tags[$pos] = trim($to);
}
$value['tags'] = trim(implode(' ', array_unique($tags)));
$this[$value['id']] = $value;
}
}
return $linksToAlter;
}
/**
* Returns the list of days containing articles (oldest first)
* Output: An array containing days (in format YYYYMMDD).
*/
public function days()
{
$linkDays = [];
foreach ($this->links as $link) {
$linkDays[$link['created']->format('Ymd')] = 0;
}
$linkDays = array_keys($linkDays);
sort($linkDays);
return $linkDays;
}
/**
* Reorder bookmarks by creation date (newest first).
*
* Also update the urls and ids mapping arrays.
*
* @param string $order ASC|DESC
*/
public function reorder($order = 'DESC')
{
$order = $order === 'ASC' ? -1 : 1;
// Reorder array by dates.
usort($this->links, function ($a, $b) use ($order) {
if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) {
return $a['sticky'] ? -1 : 1;
}
if ($a['created'] == $b['created']) {
return $a['id'] < $b['id'] ? 1 * $order : -1 * $order;
}
return $a['created'] < $b['created'] ? 1 * $order : -1 * $order;
});
$this->urls = [];
$this->ids = [];
foreach ($this->links as $key => $link) {
$this->urls[$link['url']] = $key;
$this->ids[$link['id']] = $key;
}
}
/**
* Return the next key for link creation.
* E.g. If the last ID is 597, the next will be 598.
*
* @return int next ID.
*/
public function getNextId()
{
if (!empty($this->ids)) {
return max(array_keys($this->ids)) + 1;
}
return 0;
}
/**
* Returns a link offset in bookmarks array from its unique ID.
*
* @param int $id Persistent ID of a link.
*
* @return int Real offset in local array, or null if doesn't exist.
*/
protected function getLinkOffset($id)
{
if (isset($this->ids[$id])) {
return $this->ids[$id];
}
return null;
}
}
>>>>>>> github/v0.13

View file

@ -438,7 +438,7 @@ class LegacyUpdater
// Get latest branch major version digit
$latestVersion = ApplicationUtils::getLatestGitVersionCode(
'https://raw.githubusercontent.com/shaarli/Shaarli/latest/shaarli_version.php',
'https://raw.githubusercontent.com/shaarli/Shaarli/release/shaarli_version.php',
5
);
if (preg_match('/(\d+)\.\d+$/', $latestVersion, $matches) === false) {

View file

@ -1,6 +1,6 @@
{
"name": "shaarli/shaarli",
"description": "The personal, minimalist, super-fast, database-free bookmarking service",
"description": "The personal, minimalist, super fast, database-free bookmarking service",
"type": "project",
"license": "MIT",
"homepage": "https://github.com/shaarli/Shaarli",
@ -12,11 +12,11 @@
"config": {
"sort-packages": true,
"platform": {
"php": "7.1.29"
"php": "7.4.33"
}
},
"require": {
"php": ">=7.1",
"php": ">=7.4",
"ext-json": "*",
"ext-zlib": "*",
"arthurhoaro/web-thumbnailer": "^2.0",
@ -31,8 +31,8 @@
},
"require-dev": {
"roave/security-advisories": "dev-master",
"squizlabs/php_codesniffer": "3.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
"squizlabs/php_codesniffer": "^3.0",
"phpunit/phpunit": "^9.0"
},
"suggest": {
"ext-curl": "Allows fetching web pages and thumbnails in a more robust way",

1696
composer.lock generated

File diff suppressed because it is too large Load diff

49
doc/conf.py Normal file
View file

@ -0,0 +1,49 @@
# Configuration file for the Sphinx documentation builder.
# https://www.sphinx-doc.org/en/master/usage/configuration.html
project = 'shaarli'
author = 'shaarli community'
version = '0.13.0'
release = '0.13.0'
copyright = '2011-2023, the shaarli community'
language = 'en'
html_title = 'Shaarli documentation'
html_theme = 'furo'
html_show_sphinx = False
html_show_search_summary = True
html_copy_source = False
html_show_copyright = True
html_use_opensearch = 'https://shaarli.readthedocs.io/'
html_logo = 'md/images/doc-logo.svg'
html_favicon = 'md/images/icon.png'
extensions = ['myst_parser', 'sphinx_design']
source_suffix = ['.md']
templates_path = ['_templates']
exclude_patterns = []
suppress_warnings = ["myst.xref_missing"]
# myst-parser configuration (https://myst-parser.readthedocs.io/en/latest/configuration.html)
myst_enable_extensions = ['fieldlist']
myst_html_meta = {
"description lang=en": "The personal, minimalist, super fast, database-free bookmarking service",
"charset": "UTF-8"
}
# theme configuration (https://pradyunsg.me/furo/customisation/)
html_theme_options = {
"top_of_page_button": None,
# "announcement": "Example announcement!"
"source_repository": "https://github.com/shaarli/shaarli",
"source_branch": "master",
"footer_icons": [
{
"name": "GitHub",
"url": "https://github.com/shaarli/shaarli",
"html": """
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
</svg>
""",
"class": "",
},
]
}

View file

@ -1,23 +0,0 @@
{% extends "base.html" %}
{#
The entry point for the ReadTheDocs Theme.
Any theme customisations should override this file to redefine blocks defined in
the various templates. The custom theme should only need to define a main.html
which `{% extends "base.html" %}` and defines various blocks which will replace
the blocks defined in base.html and its included child templates.
#}
{%- block site_meta %}
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{%- if config.extra_css|length and 'media.readthedocs.org' not in config.extra_css[0] %}
<meta name="robots" content="noindex, nofollow">
{%- endif %}
{% if page and page.is_homepage %}<meta name="description" content="{{ config.site_description }}">{% endif %}
{% if config.site_author %}<meta name="author" content="{{ config.site_author }}">{% endif %}
{%- endblock %}

View file

@ -1,21 +0,0 @@
## CSS
- Yahoo UI [CSS Reset](http://yuilibrary.com/yui/docs/cssreset/) - standardize cross-browser rendering
## Javascript
- [Awesomeplete](https://leaverou.github.io/awesomplete/) ([GitHub](https://github.com/LeaVerou/awesomplete)) - autocompletion in input forms
- [bLazy](http://dinbror.dk/blazy/) ([GitHub](https://github.com/dinbror/blazy)) - lazy loading for thumbnails
- [qr.js](http://neocotic.com/qr.js/) ([GitHub](https://github.com/neocotic/qr.js)) - QR code generation
## PHP
- [RainTPL](https://github.com/rainphp/raintpl) - HTML templating for PHP
### Composer
Library | Usage
---|---
[`shaarli/netscape-bookmark-parser`](https://packagist.org/packages/shaarli/netscape-bookmark-parser) | Import bookmarks from Netscape files
[`erusev/parsedown`](https://packagist.org/packages/erusev/parsedown) | Parse MarkDown syntax for the MarkDown plugin
[`slim/slim`](https://packagist.org/packages/slim/slim) | Handle routes and middleware for the REST API

View file

@ -0,0 +1,11 @@
## Backup and restore
All data and [configuration](Shaarli-configuration.md) is kept in the `data` directory. Backup this directory:
```bash
rsync -avzP my.server.com:/var/www/shaarli.mydomain.org/data ~/backups/shaarli-data-$(date +%Y-%m-%d_%H%M)
```
It is strongly recommended to do periodic, automatic backups to a separate machine. You can automate the command above using a cron job or full-featured backup solutions such as [rsnapshot](https://rsnapshot.org/)
To restore a backup, simply put back the `data/` directory in place, overwriting any existing files.

View file

@ -1,37 +0,0 @@
## Plain text search
Use the `Search text` field to search in _any_ of the fields of all links (Title, URL, Description...)
**Exclude text/tags:** Use the `-` operator before a word or tag (example `-uninteresting`) to prevent entries containing (or tagged) `uninteresting` from showing up in the search results.
**Exact text search:** Use double-quotes (example `"exact search"`) to search for the exact expression.
Both exclude patterns and exact searches can be combined with normal searches (example `"exact search" term otherterm -notthis "very exact" stuff -notagain`)
## Tags search
Use the `Filter by tags` field to restrict displayed links to entries tagged with one or multiple tags (use space to separate tags).
**Hidden tags:** Tags starting with a dot `.` (example `.secret`) are private. They can only be seen and searched when logged in.
### Tag cloud
The `Tag cloud` page diplays a "cloud" view of all tags in your Shaarli.
* The most frequently used tags are displayed with a bigger font size.
* When sorting by `Most used` or `Alphabetical`, tags are displayed as a _list_, along with counters and edit/delete buttons for each tag.
* Clicking on any tag will display a list of all Shaares matching this tag.
* Clicking on the counter next to a tag `example`, will filter the tag cloud to only display tags found in Shaares tagged `example`. Repeat this any number of times to further filter the tag cloud. Click `List all links with those tags` to display Shaares matching your current tag filter.
## Filtering RSS feeds/Picture wall
RSS feeds can also be restricted to only return items matching a text/tag search: see [RSS feeds](RSS-feeds).
## Filter buttons
Filter buttons can be found at the top left of the link list. They allow you to apply different filters to the list:
* **Private links:** When this toggle button is enabled, only shaares set to `private` will be shown.
* **Untagged links:** When the this toggle button is enabled (top left of the link list), only shaares _without any tags_ will be shown in the link list.
Filter buttons are only available when logged in.

View file

@ -1,76 +0,0 @@
_Unofficial but related work on Shaarli. If you maintain one of these,
please get in touch with us to help us find a way to adapt your work to our fork._
## Related software
### REST API clients
See [REST API](REST-API) for a list of official and community clients.
### Third party plugins
- [autosave](https://github.com/kalvn/shaarli-plugin-autosave) by [@kalvn](https://github.com/kalvn): Automatically saves data when editing a link to avoid any loss in case of crash or unexpected shutdown.
- [Code Coloration](https://github.com/ArthurHoaro/code-coloration) by [@ArthurHoaro](https://github.com/ArthurHoaro): client side code syntax highlighter.
- [Disqus](https://github.com/kalvn/shaarli-plugin-disqus) by [@kalvn](https://github.com/kalvn): Adds Disqus comment system to your Shaarli.
- [emojione](https://github.com/NerosTie/emojione) by [@NerosTie](https://github.com/NerosTie): Add colorful emojis to your Shaarli.
- [twemoji](https://github.com/NerosTie/twemoji) by [@NerosTie](https://github.com/NerosTie): Add colorful emojis to your Shaarli (Twemoji version)
- [google analytics](https://github.com/ericjuden/Shaarli-Google-Analytics-Plugin) by [@ericjuden](http://github.com/ericjuden): Adds Google Analytics tracking support
- [launch](https://github.com/ArthurHoaro/launch-plugin) - Launch Plugin is a plugin designed to enhance and customize Launch Theme for Shaarli.
- [markdown-toolbar](https://github.com/immanuelfodor/shaarli-markdown-toolbar) by [@immanuelfodor](https://github.com/immanuelfodor) - Easily insert markdown syntax into the Description field when editing a link.
- [related](https://github.com/ilesinge/shaarli-related) by [@ilesinge](https://github.com/ilesinge) - Show related links based on the number of identical tags.
- [social](https://github.com/alexisju/social) by [@alexisju](https://github.com/alexisju): share links to social networks.
- [shaarli2twitter](https://github.com/ArthurHoaro/shaarli2twitter) by [@ArthurHoaro](https://github.com/ArthurHoaro) - Automatically tweet your shared links from Shaarli
- [shaarli2mastodon](https://github.com/kalvn/shaarli2mastodon) by [@kalvn](https://github.com/kalvn) - This Shaarli plugin allows you to automatically publish links you post on your Mastodon timeline.
- [shaarli-descriptor](https://github.com/immanuelfodor/shaarli-descriptor) by [@immanuelfodor](https://github.com/immanuelfodor) - Customize the default height/number of rows of the Description field when editing a link.
- [urlextern](https://github.com/trailjeep/shaarli-urlextern) by [@trailjeep](https://github.com/trailjeep) - Shaarli plugin to open external links in a new tab/window.
- [favicons](https://github.com/trailjeep/shaarli-favicons) by [@trailjeep](https://github.com/trailjeep) - Shaarli plugin to add favicon/filetype icons to links.
### Third-party themes
See [Theming](Theming) for a list of community-contributed themes, and an installation guide.
### Integration with other platforms
- [tt-rss-shaarli](https://github.com/jcsaaddupuy/tt-rss-shaarli) - [Tiny-Tiny RSS](http://tt-rss.org/) plugin that adds support for sharing articles with Shaarli
- [octopress-shaarli](https://github.com/ahmet2mir/octopress-shaarli) - Octopress plugin to retrieve Shaarli links on the sidebar
- [Scuttle to Shaarli](https://github.com/q2apro/scuttle-to-shaarli) - Import bookmarks from Scuttle
- [Shaarli app for Cloudron](https://git.cloudron.io/cloudron/shaarli-app) - Effortlessly run Shaarli with the help of [Cloudron](https://cloudron.io/) [![Install](https://cloudron.io/img/button.svg)](https://cloudron.io/button.html?app=com.github.shaarli)
- [Shaarli_ynh](https://github.com/YunoHost-Apps/shaarli_ynh) - Shaarli is available as a [Yunohost](https://yunohost.org) app [![Install Shaarli with YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=shaarli)
### Mobile Apps
- [ShaarliOS](https://github.com/mro/ShaarliOS) - Apple iOS share extension.
- [Shaarli for Android](http://sebsauvage.net/links/?ZAyDzg) - Android application that adds Shaarli as a sharing provider
- [Shaarlier for Android](https://github.com/dimtion/Shaarlier) - Android application to simply add links directly into your Shaarli
- [Stakali for Android](https://stakali.toneiv.eu) - Stakali is a personal bookmark manager which synchronizes with Shaarli
### Browser addons
- [Shaarli Firefox Extension](https://github.com/ikipatang/shaarli-web-extension) - toolbar button to share your current tab with Shaarli.
- [Shaarli Chrome Extension](https://github.com/octplane/Shiny-Shaarli) - toolbar button to share your current tab with Shaarli.
### Server apps
- [shaarchiver](https://github.com/nodiscc/shaarchiver) - Archive your Shaarli bookmarks and their content
- [shaarli-river](https://github.com/mknexen/shaarli-river) - An aggregator for shaarlis with many features
- [Shaarlo](https://github.com/DMeloni/shaarlo) - An aggregator for shaarlis with many features (a very popular running instance among French shaarliers: [shaarli.fr](http://shaarli.fr/))
- [Shaarlimages](https://github.com/BoboTiG/shaarlimages) - An image-oriented aggregator for Shaarlis
- [mknexen/shaarli-api](https://github.com/mknexen/shaarli-api) - A REST API for Shaarli
- [Self dead link](https://framagit.org/qwertygc/shaarli-dev-code/blob/master/self-dead-link.php) - Detect dead links on shaarli. This version use the database of shaarli. [Another version](https://framagit.org/qwertygc/shaarli-dev-code/blob/master/dead-link.php), can be used for other shaarli instances (but is more resource consuming).
- [Bookmark Archiver](https://github.com/pirate/bookmark-archiver) - Save an archived copy of all websites starred using browser bookmarks/Shaarli/Delicious/Instapaper/Unmark.it/Pocket/Pinboard. Outputs browseable html.
## Alternatives to Shaarli
See [awesome-selfhosted: bookmarks & link sharing](https://github.com/Kickball/awesome-selfhosted/#bookmarks--link-sharing).
## Community
- [Liens en vrac de sebsauvage](http://sebsauvage.net/links/) - the original Shaarli
- [A large list of Shaarlis](http://porneia.free.fr/pub/links/ou-est-shaarli.html)
- [A list of working Shaarli aggregators](https://raw.githubusercontent.com/Oros42/find_shaarlis/master/annuaires.json)
- [A list of some known Shaarlis](https://github.com/Oros42/shaarlis_list)
- [Adieu Delicious, Diigo et StumbleUpon. Salut Shaarli ! - sebsauvage.net](http://sebsauvage.net/rhaa/index.php?2011/09/16/09/29/58-adieu-delicious-diigo-et-stumbleupon-salut-shaarli-) (fr) _16/09/2011 - the original post about Shaarli_
- [Original ideas/fixme/TODO page](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:ideas)
- [Original discussion page](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion) (fr)
- [Original revisions history](http://sebsauvage.net/wiki/doku.php?id=php:shaarli:history)
- [Shaarli.fr/my](https://www.shaarli.fr/my.php) - Unofficial, unsupported (old fork) hosted Shaarlis provider, courtesy of [DMeloni](https://github.com/DMeloni)
### Articles and social media discussions
- 2016-09-22 - Hacker News - https://news.ycombinator.com/item?id=12552176
- 2015-08-15 - Reddit - [Question about migrating from WordPress to Shaarli.](https://www.reddit.com/r/selfhosted/comments/3h3zwh/question_about_migrating_from_wordpress_to_shaarli/)
- 2015-06-22 - Hacker News - https://news.ycombinator.com/item?id=9755366
- 2015-05-12 - Reddit - [shaarli - Self hosted Bookmarking / Delicious (PHP, MySQL)](https://www.reddit.com/r/selfhosted/comments/35pkkc/shaarli_self_hosted_bookmarking_delicious_php/)

View file

@ -0,0 +1,117 @@
# Community & related software
_Unofficial but related work on Shaarli. If you maintain one of these,
please get in touch with us to help us find a way to adapt your work to our fork._
## Related software
### REST API clients
See [REST API](REST-API.md) for a list of official and community clients.
### Third party plugins
- [autosave](https://github.com/kalvn/shaarli-plugin-autosave) by [@kalvn](https://github.com/kalvn): Automatically saves data when editing a Shaare to avoid any loss in case of crash or unexpected shutdown.
- [clickat](https://forge.tourmentine.com/n/shaarli-plugin-clickat) by [@n](https://forge.tourmentine.com/n): Makes Twitter and Fediverse addresses clickable.
- [code-coloration](https://github.com/ArthurHoaro/code-coloration) by [@ArthurHoaro](https://github.com/ArthurHoaro): client side code syntax highlighter.
- [custom-css](https://github.com/immanuelfodor/shaarli-custom-css) by [@immanuelfodor](https://github.com/immanuelfodor) - Customize the look and feel of the UI with custom CSS rules
- [disqus](https://github.com/kalvn/shaarli-plugin-disqus) by [@kalvn](https://github.com/kalvn): Adds Disqus comment system to your Shaarli.
- [emojione](https://github.com/immanuelfodor/emojione) by [@immanuelfodor](https://github.com/immanuelfodor) - Resurrected fork of the original emojione project
- [favicons](https://github.com/trailjeep/shaarli-favicons) by [@trailjeep](https://github.com/trailjeep) - Shaarli plugin to add favicon/filetype icons to Shaares.
- [google analytics](https://github.com/ericjuden/Shaarli-Google-Analytics-Plugin) by [@ericjuden](https://github.com/ericjuden): Adds Google Analytics tracking support
- [launch](https://github.com/ArthurHoaro/launch-plugin) - Launch Plugin is a plugin designed to enhance and customize Launch Theme for Shaarli.
- [markdown-toolbar](https://github.com/immanuelfodor/shaarli-markdown-toolbar) by [@immanuelfodor](https://github.com/immanuelfodor) - Easily insert markdown syntax into the Description field when editing a Shaare.
- [related](https://github.com/ilesinge/shaarli-related) by [@ilesinge](https://github.com/ilesinge) - Show related Shaares based on the number of identical tags.
- [shaargem](https://forge.tourmentine.com/n/shaarli-plugin-shaargem) by [@n](https://forge.tourmentine.com/n): Allow to shaare gemini capsules.
- [shaarli-descriptor](https://github.com/immanuelfodor/shaarli-descriptor) by [@immanuelfodor](https://github.com/immanuelfodor) - Customize the default height/number of rows of the Description field when editing a Shaare.
- [shaarli2mastodon](https://github.com/kalvn/shaarli2mastodon) by [@kalvn](https://github.com/kalvn) - This Shaarli plugin allows you to automatically publish links you post on your Mastodon timeline.
- [shaarli2twitter](https://github.com/ArthurHoaro/shaarli2twitter) by [@ArthurHoaro](https://github.com/ArthurHoaro) - Automatically tweet your Shaares from Shaarli
- [social](https://github.com/alexisju/social) by [@alexisju](https://github.com/alexisju): share links to social networks.
- [urlextern](https://github.com/trailjeep/shaarli-urlextern) by [@trailjeep](https://github.com/trailjeep) - Shaarli plugin to open external links in a new tab/window.
- [webhooks](https://gitlab.com/flow.gunso/shaarli-webhooks) by [@flow.gunso](https://gitlab.com/flow.gunso) - Shaarli plugin that enables user-defined callback URL, i.e. webhooks, for specific Shaarli events (link saving, deletion...)
### Themes
- [kalvn/Shaarli-Material](https://github.com/kalvn/Shaarli-Material) - A theme (template) based on Google's Material Design for Shaarli, the superfast delicious clone
- [ManufacturaInd/shaarli-2004licious-theme](https://github.com/ManufacturaInd/shaarli-2004licious-theme) - A template/theme as a humble homage to the early looks of the del.icio.us site
- [RolandTi/shaarli-stack](https://github.com/RolandTi/shaarli-stack) - A miminalist template/theme for Shaarli
- [xfnw/shaarli-default-dark](https://github.com/xfnw/shaarli-default-dark) - The default theme but nice and dark for your eyeballs
- [mrjovanovic/serious-theme-shaarli](https://github.com/mrjovanovic/serious-theme-shaarli) - A serious theme for Shaarli (custom CSS)
### Integration with other platforms
- [tt-rss-shaarli](https://github.com/jcsaaddupuy/tt-rss-shaarli) - [Tiny-Tiny RSS](https://tt-rss.org/) plugin that adds support for sharing articles with Shaarli
- [octopress-shaarli](https://github.com/ahmet2mir/octopress-shaarli) - Octopress plugin to retrieve Shaarli Shaares on the sidebar
- [Scuttle to Shaarli](https://github.com/q2apro/scuttle-to-shaarli) - Import bookmarks from Scuttle
- [Shaarli app for Cloudron](https://www.cloudron.io/button.html?app=com.github.shaarli) - [![](https://img.shields.io/badge/Cloudron-03A9F4?logo=Buffer)](https://www.cloudron.io/button.html?app=com.github.shaarli) Effortlessly run Shaarli with the help of [Cloudron](https://www.cloudron.io/)
- [Shaarli_ynh](https://github.com/YunoHost-Apps/shaarli_ynh) - [![](https://img.shields.io/badge/YunoHost-black?logo=Buffer)](https://install-app.yunohost.org/?app=shaarli) Shaarli is available as a [Yunohost](https://yunohost.org) app
- [shaarli_poster](https://github.com/getpelican/pelican-plugins/tree/master/shaarli_poster) - [pelican](https://getpelican.com) static blog generator plugin to auto-post articles on a Shaarli instance
- [shaarli .deb package](https://packages.debian.org/search?keywords=shaarli) - for [Debian](https://www.debian.org/) and [Freedombox](https://www.freedombox.org/)
### Mobile apps
- [ShaarliOS](https://github.com/mro/ShaarliOS) - [![](https://img.shields.io/badge/App%20Store-black?logo=apple)](https://apps.apple.com/app/shaarlios/id1027441388) Apple iOS share extension.
- [Shaarlier for Android](https://github.com/dimtion/Shaarlier) - [![](https://img.shields.io/badge/Play%20Store-3EB7C0?logo=Google%20Play)](https://play.google.com/store/apps/details?id=com.dimtion.shaarlier) Android application to simply add Shaares directly into your Shaarli via Sharing. Free software.
- [Stakali for Android](https://stakali.toneiv.eu) - [![](https://img.shields.io/badge/Play%20Store-3EB7C0?logo=Google%20Play)](https://play.google.com/store/apps/details?id=eu.toneiv.stakali) Stakali is a personal bookmark manager which synchronizes with Shaarli. Support offline work without instance, sync, browsing within app. Free use of up to 20 results.
- [Shaarli for Android](https://sebsauvage.net/links/?ZAyDzg) - Android application that adds Shaarli as a sharing provider.
### Desktop apps
- [Ulauncher Extension](https://github.com/sebw/ulauncher-shaarli) - Ulauncher is an an application launcher for Linux, this extension allows research in your Shaarli
### Browser extensions
- [Shaarli Firefox Extension](https://github.com/ikipatang/shaarli-web-extension) - [![](https://img.shields.io/badge/Firefox%20Add--ons-414141?logo=Firefox)](https://addons.mozilla.org/en-US/firefox/addon/shaarli/) toolbar button to share your current tab with Shaarli.
- [Add to Shaarli](https://github.com/burgyl/AddToShaarli) - [![](https://img.shields.io/badge/Chrome%20Web%20Store-white?logo=Google%20Chrome)](https://chrome.google.com/webstore/detail/add-to-shaarli/jhfblapoehcfajokolimghdfmeeakbee) lets you add the current tab or a note to your Shaarli instance.
- [WebLinks Ext](https://chrome.google.com/webstore/detail/weblinks-ext/pnejcofgljlklmmjkocipnanfdbaclke) - [![](https://img.shields.io/badge/Chrome%20Web%20Store-white?logo=Google%20Chrome)](https://chrome.google.com/webstore/detail/weblinks-ext/pnejcofgljlklmmjkocipnanfdbaclke) Save, edit and use your Shaarli. Support work offline, sync, trash, etc. Free software.
- [Shaarli Chrome Extension](https://github.com/octplane/Shiny-Shaarli) - toolbar button to share your current tab with Shaarli. (Removed from Chrome web store).
### Server apps
- [Shaarli Archiver](https://github.com/sebw/shaarli-archiver) - Shaarli and SingleFile to archive your bookmarks
- [shaarchiver](https://github.com/nodiscc/shaarchiver) - Archive your Shaarli bookmarks and their content
- [shaarli-river](https://github.com/mknexen/shaarli-river) - An aggregator for shaarlis with many features
- [Shaarlo](https://github.com/DMeloni/shaarlo) - An aggregator for shaarlis with many features
- [Shaarlimages](https://github.com/BoboTiG/shaarlimages) - An image-oriented aggregator for Shaarlis
- [mknexen/shaarli-api](https://github.com/mknexen/shaarli-api) - A REST API for Shaarli
- [Self dead link](https://framagit.org/qwertygc/shaarli-dev-code/blob/master/self-dead-link.php) - Detect dead links on shaarli. This version use the database of shaarli. [Another version](https://framagit.org/qwertygc/shaarli-dev-code/blob/master/dead-link.php), can be used for other shaarli instances (but is more resource consuming).
- [Bookmark Archiver](https://github.com/ArchiveBox/ArchiveBox) - Save an archived copy of all websites starred using browser bookmarks/Shaarli/Delicious/Instapaper/Unmark.it/Pocket/Pinboard. Outputs browseable html.
## Alternatives to Shaarli
See [awesome-selfhosted: bookmarks & link sharing](https://awesome-selfhosted.net/tags/bookmarks-and-link-sharing.html).
## Community
- [Liens en vrac de sebsauvage](https://sebsauvage.net/links/) - the original Shaarli
- [A large list of Shaarlis](http://porneia.free.fr/pub/links/ou-est-shaarli.html)
- [A list of working Shaarli aggregators](https://raw.githubusercontent.com/Oros42/find_shaarlis/master/annuaires.json)
- [A list of some known Shaarlis](https://github.com/Oros42/shaarlis_list)
- [Adieu Delicious, Diigo et StumbleUpon. Salut Shaarli ! - sebsauvage.net](https://sebsauvage.net/rhaa/index.php?2011/09/16/09/29/58-adieu-delicious-diigo-et-stumbleupon-salut-shaarli-) (fr) _16/09/2011 - the original post about Shaarli_
- [Original ideas/fixme/TODO page](https://sebsauvage.net/wiki/doku.php?id=php:shaarli:ideas)
- [Original discussion page](https://sebsauvage.net/wiki/doku.php?id=php:shaarli:discussion) (fr)
- [Original revisions history](https://sebsauvage.net/wiki/doku.php?id=php:shaarli:history)
### Articles and social media discussions
- 2020-04-05 - Hacker News - [Self-hosted instance of Shaarli - it is simple, fast and reliable](https://news.ycombinator.com/item?id=22780219)
- 2016-10-10 - Framasoft - [MyFrama : vos favoris partout, avec vous, rien quà vous !](https://framablog.org/2016/10/10/myframa-vos-favoris-et-framasofteries-partout-avec-vous-rien-qua-vous/)
- 2016-09-22 - Hacker News - [Shaarli Personal, minimalist, database-free, bookmarking service (github.com)](https://news.ycombinator.com/item?id=12552176)
- 2015-08-15 - Reddit - [Question about migrating from WordPress to Shaarli.](https://www.reddit.com/r/selfhosted/comments/3h3zwh/question_about_migrating_from_wordpress_to_shaarli/)
- 2015-06-22 - Hacker News - [Shaarli: Self-hosted del.icio.us alternative (sebsauvage.net)](https://news.ycombinator.com/item?id=9755366)
- 2015-05-12 - Reddit - [shaarli - Self hosted Bookmarking / Delicious (PHP, MySQL)](https://www.reddit.com/r/selfhosted/comments/35pkkc/shaarli_self_hosted_bookmarking_delicious_php/)
- 2014-10-15 - OpenSource.com - [Five open source alternatives to popular web apps](https://opensource.com/life/14/10/five-open-source-alternatives-popular-web-apps)
It also appears in the following recommendation lists:
- [AlternativeTo](https://alternativeto.net/software/shaarli/)
- [FramaLibre](https://framalibre.org/content/shaarli)
- [Awesome-Selfhosted - Bookmarks and Link Sharing](https://awesome-selfhosted.net/tags/bookmarks-and-link-sharing.html)

View file

@ -1,29 +0,0 @@
## Local development
A [`Makefile`](https://github.com/shaarli/Shaarli/blob/master/Makefile) is available to perform project-related operations:
- Documentation - generate a local HTML copy of the GitHub wiki
- [Static analysis](Static-analysis) - check that the code is compliant to PHP conventions
- [Unit tests](Unit-tests) - ensure there are no regressions introduced by new commits
## Automatic builds
[Travis CI](http://docs.travis-ci.com/) is a Continuous Integration build server, that runs a build:
- each time a commit is merged to the mainline (`master` branch)
- each time a Pull Request is submitted or updated
A build is composed of several jobs: one for each supported PHP version (see [Server requirements](Server requirements)).
Each build job:
- updates Composer
- installs 3rd-party test dependencies with Composer
- runs [Unit tests](Unit-tests)
- runs ESLint check
After all jobs have finished, Travis returns the results to GitHub:
- a status icon represents the result for the `master` branch: [![](https://api.travis-ci.org/shaarli/Shaarli.svg)](https://travis-ci.org/shaarli/Shaarli)
- Pull Requests are updated with the Travis result
- Green: all tests have passed
- Red: some tests failed
- Orange: tests are pending

View file

@ -1,13 +0,0 @@
## Development guidelines
Please have a look at the following pages:
- [Contributing to Shaarli](https://github.com/shaarli/Shaarli/tree/master/CONTRIBUTING.md)
- [Static analysis](Static-analysis) - patches should try to stick to the
[PHP Standard Recommendations](http://www.php-fig.org/psr/) (PSR), especially:
- [PSR-1](http://www.php-fig.org/psr/psr-1/) - Basic Coding Standard
- [PSR-2](http://www.php-fig.org/psr/psr-2/) - Coding Style Guide
- [Unit tests](Unit-tests)
- Javascript linting - Shaarli uses [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript).
Run `make eslint` to check JS style.
- [GnuPG signature](GnuPG-signature) for tags/releases

View file

@ -1,54 +0,0 @@
## Directory structure
Here is the directory structure of Shaarli and the purpose of the different files:
```bash
index.php # Main program
application/ # Shaarli classes
├── LinkDB.php
...
└── Utils.php
tests/ # Shaarli unitary & functional tests
├── LinkDBTest.php
...
├── utils # utilities to ease testing
│ └── ReferenceLinkDB.php
└── UtilsTest.php
assets/
├── common/ # Assets shared by multiple themes
├── ...
├── default/ # Assets for the default template, before compilation
├── fonts/ # Font files
├── img/ # Images used by the default theme
├── js/ # JavaScript files in ES6 syntax
├── scss/ # SASS files
└── vintage/ # Assets for the vintage template, before compilation
└── ...
COPYING # Shaarli license
inc/ # static assets and 3rd party libraries
└── rain.tpl.class.php # RainTPL templating library
images/ # Images and icons used in Shaarli
data/ # data storage: bookmark database, configuration, logs, banlist...
├── config.json.php # Shaarli configuration (login, password, timezone, title...)
├── datastore.php # Your link database (compressed).
├── ipban.php # IP address ban system data
├── lastupdatecheck.txt # Update check timestamp file
└── log.txt # login/IPban log.
tpl/ # RainTPL templates for Shaarli. They are used to build the pages.
├── default/ # Default Shaarli theme
├── fonts/ # Font files
├── img/ # Images
├── js/ # JavaScript files compiled by Babel and compatible with all browsers
├── css/ # CSS files compiled with SASS
└── vintage/ # Legacy Shaarli theme
└── ...
cache/ # thumbnails cache
# This directory is automatically created. You can erase it anytime you want.
tmp/ # Temporary directory for compiled RainTPL templates.
# This directory is automatically created. You can erase it anytime you want.
vendor/ # Third-party dependencies. This directory is created by Composer
```

227
doc/md/Docker.md Normal file
View file

@ -0,0 +1,227 @@
# Docker
[Docker](https://docs.docker.com/get-started/overview/) is an open platform for developing, shipping, and running applications
## Install Docker
Install [Docker](https://docs.docker.com/engine/install/), by following the instructions relevant to your OS / distribution, and start the service. For example on [Debian](https://docs.docker.com/engine/install/debian/):
```bash
# update your package lists
sudo apt update
# remove old versions
sudo apt-get remove docker docker-engine docker.io containerd runc
# install requirements
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
# add docker's GPG signing key
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
# add the repository
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
# install docker engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# Start and enable Docker service
sudo systemctl enable docker && sudo systemctl start docker
# verify that Docker is properly configured
sudo docker run hello-world
```
In order to run Docker commands as a non-root user, you must add the `docker` group to this user:
```bash
# Add docker group as secondary group
sudo usermod -aG docker your-user
# Reboot or logout
# Then verify that Docker is properly configured, as "your-user"
docker run hello-world
```
## Get and run a Shaarli image
Shaarli images are available on [GitHub Container Registry](https://github.com/shaarli/Shaarli/pkgs/container/shaarli) `ghcr.io/shaarli/shaarli`:
- `latest`: master (development) branch
- `vX.Y.Z`: shaarli [releases](https://github.com/shaarli/Shaarli/releases)
- `release`: always points to the last release
- `stable` and `master`: **deprecated**. These tags are no longer maintained and may be removed without notice
These images are built automatically on Github Actions and rely on:
- [Alpine Linux](https://www.alpinelinux.org/)
- [PHP7-FPM](https://php-fpm.org/)
- [Nginx](https://nginx.org/)
Additional Dockerfiles are provided for the `arm32v7` platform, relying on [Linuxserver.io Alpine armhf images](https://hub.docker.com/r/lsiobase/alpine.armhf/). These images must be built using [`docker build`](https://docs.docker.com/engine/reference/commandline/build/) on an `arm32v7` machine or using an emulator such as [qemu](https://blog.balena.io/building-arm-containers-on-any-x86-machine-even-dockerhub/).
Here is an example of how to run Shaarli latest image using Docker:
```bash
# download the 'latest' image from GitHub Container Registry
docker pull ghcr.io/shaarli/shaarli
# create persistent data volumes/directories on the host
docker volume create shaarli-data
docker volume create shaarli-cache
# create a new container using the Shaarli image
# --detach: run the container in background
# --name: name of the created container/instance
# --publish: map the host's :8000 port to the container's :80 port
# --rm: automatically remove the container when it exits
# --volume: mount persistent volumes in the container ($volume_name:$volume_mountpoint)
docker run --detach \
--name myshaarli \
--publish 8000:80 \
--rm \
--volume shaarli-data:/var/www/shaarli/data \
--volume shaarli-cache:/var/www/shaarli/cache \
ghcr.io/shaarli/shaarli:latest
# verify that the container is running
docker ps | grep myshaarli
# to completely remove the container
docker stop myshaarli # stop the running container
docker ps | grep myshaarli # verify the container is no longer running
docker ps -a | grep myshaarli # verify the container is stopped
docker rm myshaarli # destroy the container
docker ps -a | grep myshaarli # verify th container has been destroyed
```
After running `docker run` command, your Shaarli instance should be available on the host machine at [localhost:8000](http://localhost:8000). In order to access your instance through a reverse proxy, we recommend using our [Docker Compose](#docker-compose) build.
## Docker Compose
A [Compose file](https://docs.docker.com/compose/compose-file/) is a common format for defining and running multi-container Docker applications.
A `docker-compose.yml` file can be used to run a persistent/autostarted shaarli service using [Docker Compose](https://docs.docker.com/compose/) or in a [Docker stack](https://docs.docker.com/engine/reference/commandline/stack_deploy/).
Shaarli provides configuration file for Docker Compose, that will setup a Shaarli instance, a [Træfik](https://traefik.io/traefik/) instance (reverse proxy) with [Let's Encrypt](https://letsencrypt.org/) certificates, a Docker network, and volumes for Shaarli data and Træfik TLS configuration and certificates.
Download docker-compose from the [release page](https://docs.docker.com/compose/install/):
```bash
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
```
To run Shaarli container and its reverse proxy, you can execute the following commands:
```bash
# create a new directory to store the configuration:
$ mkdir shaarli && cd shaarli
# Download the latest version of Shaarli's docker-compose.yml
$ curl -L https://raw.githubusercontent.com/shaarli/Shaarli/latest/docker-compose.yml -o docker-compose.yml
# Create the .env file and fill in your VPS and domain information
# (replace <shaarli.mydomain.org>, <admin@mydomain.org> and <latest> with your actual information)
$ echo 'SHAARLI_VIRTUAL_HOST=shaarli.mydomain.org' > .env
$ echo 'SHAARLI_LETSENCRYPT_EMAIL=admin@mydomain.org' >> .env
# Available Docker tags can be found at https://github.com/shaarli/Shaarli/pkgs/container/shaarli/versions?filters%5Bversion_type%5D=tagged
$ echo 'SHAARLI_DOCKER_TAG=latest' >> .env
# Pull the Docker images
$ docker-compose pull
# Run!
$ docker-compose up -d
```
After a few seconds, you should be able to access your Shaarli instance at [https://shaarli.mydomain.org](https://shaarli.mydomain.org) (replace your own domain name).
## Running dockerized Shaarli as a systemd service
It is possible to start a dockerized Shaarli instance as a systemd service (systemd is the service management tool on several distributions). After installing Docker, use the following steps to run your shaarli container Shaarli to run on system start.
As root, create `/etc/systemd/system/docker.shaarli.service`:
```ini
[Unit]
Description=Shaarli Bookmark Manager Container
After=docker.service
Requires=docker.service
[Service]
Restart=always
# Put any environment you want in an included file, like $host- or $domainname in this example
EnvironmentFile=/etc/sysconfig/box-environment
# It's just an example..
ExecStart=/usr/bin/docker run \
-p 28010:80 \
--name ${hostname}-shaarli \
--hostname shaarli.${domainname} \
-v /srv/docker-volumes-local/shaarli-data:/var/www/shaarli/data:rw \
-v /etc/localtime:/etc/localtime:ro \
ghcr.io/shaarli/shaarli:latest
ExecStop=/usr/bin/docker rm -f ${hostname}-shaarli
[Install]
WantedBy=multi-user.target
```
```bash
# reload systemd services definitions
systemctl daemon-reload
# start the servie and enable it a boot time
systemctl enable docker.shaarli.service --now
# verify that the service is running
systemctl status docker.*
# inspect system log if needed
journalctl -f
```
## Docker cheatsheet
```bash
# pull/update an image
$ docker pull ghcr.io/shaarli/shaarli:release
# run a container from an image
$ docker run ghcr.io/shaarli/shaarli:latest
# list available images
$ docker images ls
# list running containers
$ docker ps
# list running AND stopped containers
$ docker ps -a
# run a command in a running container
$ docker exec -ti <container-name-or-first-letters-of-id> bash
# follow logs of a running container
$ docker logs -f <container-name-or-first-letters-of-id>
# delete unused images to free up disk space
$ docker system prune --images
# delete unused volumes to free up disk space (CAUTION all data in unused volumes will be lost)
$ docker system prune --volumes
# delete unused containers
$ docker system prune
```
## References
- [Docker: using volumes](https://docs.docker.com/storage/volumes/)
- [Dockerfile best practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
- [Dockerfile reference](https://docs.docker.com/engine/reference/builder/)
- [GitHub Container Registry](https://github.com/features/packages)
- [GithHub Packages documentation](https://docs.github.com/en/packages)
- [DockerHub: Teams and organizations](https://docs.docker.com/docker-hub/orgs/), [End of Docker free teams](https://www.docker.com/blog/we-apologize-we-did-a-terrible-job-announcing-the-end-of-docker-free-teams/)
- [Get Docker CE for Debian](https://docs.docker.com/engine/install/debian/)
- [Install Docker Compose](https://docs.docker.com/compose/install/)
- [Service management: Nginx in the foreground](https://nginx.org/en/docs/ngx_core_module.html#daemon)
- [Service management: Run multiple services in a container](https://docs.docker.com/config/containers/multi-service_container/)
- [Volumes](https://docs.docker.com/storage/volumes/)
- [Where are Docker images stored?](https://blog.thoward37.me/articles/where-are-docker-images-stored/)
- [docker create](https://docs.docker.com/engine/reference/commandline/create/)
- [Docker Documentation](https://docs.docker.com/)
- [docker exec](https://docs.docker.com/engine/reference/commandline/exec/)
- [docker images](https://docs.docker.com/engine/reference/commandline/images/)
- [docker logs](https://docs.docker.com/engine/reference/commandline/logs/)
- [Docker Overview](https://docs.docker.com/get-started/overview/)
- [docker ps](https://docs.docker.com/engine/reference/commandline/ps/)
- [docker pull](https://docs.docker.com/engine/reference/commandline/pull/)
- [docker run](https://docs.docker.com/engine/reference/commandline/run/)
- Træfik: [Documentation](https://doc.traefik.io/traefik/), [Docker image](https://hub.docker.com/_/traefik/)

View file

@ -1,124 +0,0 @@
To install Shaarli, simply place the files in a directory under your webserver's
Document Root (or directly at the document root).
Also, please make sure your server is properly [configured](Server-configuration).
Multiple releases branches are available:
- latest (last release)
- stable (previous major release)
- master (development)
Using one of the following methods:
- by downloading full release archives including all dependencies
- by downloading Github archives
- by cloning the Git repository
- using Docker: [see the documentation](docker/shaarli-images.md)
--------------------------------------------------------------------------------
## Latest release (recommended)
### Download as an archive
In most cases, you should download the latest Shaarli release from the [releases](https://github.com/shaarli/Shaarli/releases) page. Download our **shaarli-full** archive to include dependencies.
The current latest released version is `v0.10.4`
```bash
$ wget https://github.com/shaarli/Shaarli/releases/download/v0.10.4/shaarli-v0.10.4-full.zip
$ unzip shaarli-v0.10.4-full.zip
$ mv Shaarli /path/to/shaarli/
```
### Using git
Cloning using `git` or downloading Github branches as zip files requires additional steps:
* Install [Composer](Unit-tests.md#install_composer) to manage third-party [PHP dependencies](3rd-party-libraries.md#composer).
* Install [yarn](https://yarnpkg.com/lang/en/docs/install/) to build the frontend dependencies.
* Install [python3-virtualenv](https://pypi.python.org/pypi/virtualenv) to build the local HTML documentation.
```
$ mkdir -p /path/to/shaarli && cd /path/to/shaarli/
$ git clone -b latest https://github.com/shaarli/Shaarli.git .
$ composer install --no-dev --prefer-dist
$ make build_frontend
$ make translate
$ make htmldoc
```
--------------------------------------------------------------------------------
## Stable version
The stable version has been experienced by Shaarli users, and will receive security updates.
### Download as an archive
As a .zip archive:
```bash
$ wget https://github.com/shaarli/Shaarli/archive/stable.zip
$ unzip stable.zip
$ mv Shaarli-stable /path/to/shaarli/
```
As a .tar.gz archive :
```bash
$ wget https://github.com/shaarli/Shaarli/archive/stable.tar.gz
$ tar xvf stable.tar.gz
$ mv Shaarli-stable /path/to/shaarli/
```
### Using git
Install [Composer](Unit-tests.md#install_composer) to manage Shaarli dependencies.
```bash
$ git clone https://github.com/shaarli/Shaarli.git -b stable /path/to/shaarli/
# install/update third-party dependencies
$ cd /path/to/shaarli/
$ composer install --no-dev --prefer-dist
```
--------------------------------------------------------------------------------
## Development version (mainline)
_Use at your own risk!_
Install [Composer](Unit-tests.md#install_composer) to manage Shaarli PHP dependencies,
and [yarn](https://yarnpkg.com/lang/en/docs/install/)
for front-end dependencies.
To get the latest changes from the `master` branch:
```bash
# clone the repository
$ git clone https://github.com/shaarli/Shaarli.git -b master /path/to/shaarli/
# install/update third-party dependencies
$ cd /path/to/shaarli
$ composer install --no-dev --prefer-dist
$ make build_frontend
$ make translate
$ make htmldoc
```
-------------------------------------------------------------------------------
## Finish Installation
Once Shaarli is downloaded and files have been placed at the correct location, open it this location your favorite browser.
![install screenshot](images/install-shaarli.png)
Setup your Shaarli installation, and it's ready to use!
## Updating Shaarli
See [Upgrade and Migration](Upgrade-and-migration)

View file

@ -1,46 +0,0 @@
### Why did you create Shaarli ?
I was a StumbleUpon user. Then I got fed up with they big toolbar. I switched to delicious, which was lighter, faster and more beautiful. Until Yahoo bought it. Then the export API broke all the time, delicious became slow and was ditched by Yahoo. I switched to Diigo, which is not bad, but does too much. And Diigo is sslllooooowww and their Firefox extension a bit buggy. And… oh… **their Firefox addon sends to Diigo every single URL you visit** (Don't believe me ? Use [Tamper Data](https://addons.mozilla.org/en-US/firefox/addon/tamper-data/) and open any page).
Enough is enough. Saving simple links should not be a complicated heavy thing. I ditched them all and wrote my own: Shaarli. It's simple, but it does the job and does it well. And my data is not hosted on a foreign server, but on my server.
### Why use Shaarli and not Delicious/Diigo ?
With Shaarli:
- The data is yours: It's hosted on your server.
- Never fear of having your data locked-in.
- Never fear to have your data sold to third party.
- Your private links are not hosted on a third party server.
- You are not tracked by browser addons (like Diigo does)
- You can change the look and feel of the pages if you want.
- You can change the behaviour of the program.
- It's magnitude faster than most bookmarking services.
### What does Shaarli mean?
Shaarli stands for _shaaring_ your _links_.
### My Shaarli is broken!
First of all, ensure that both the [web server](Server-configuration) and
[Shaarli](Shaarli-configuration) are correctly configured, and that your
installation is [supported](Server-configuration).
If everything looks right but the issue(s) remain(s), please:
- take a look at the [troubleshooting](Troubleshooting) section
- come [chat with us](https://gitter.im/shaarli/Shaarli) on Gitter, we'll be happy to help ;-)
- browse active [issues](https://github.com/shaarli/Shaarli/issues) and [Pull Requests](https://github.com/shaarli/Shaarli/pulls)
- if you find one that is related to the issue, feel free to comment and provide additional details (host/Shaarli setup)
- else, [open a new issue](https://github.com/shaarli/Shaarli/issues/new), and provide information about the problem:
- _what happens?_ - display glitches, invalid data, security flaws...
- _what is your configuration?_ - OS, server version, activated extensions, web browser...
- _is it reproducible?_
### Why not use a real database? Files are slow!
Does browsing [this page](http://sebsauvage.net/links/) feel slow? Try browsing older pages, too.
It's not slow at all, is it? And don't forget the database contains more than 16000 links, and it's on a shared host, with 32000 visitors/day for my website alone. And it's still damn fast. Why?
The data file is only 3.7 Mb. It's read 99% of the time, and is probably already in the operation system disk cache. So generating a page involves no I/O at all most of the time.

View file

@ -1,78 +0,0 @@
## Introduction
### PGP and GPG
[Gnu Privacy Guard](https://gnupg.org/) (GnuPG) is an Open Source implementation of the
[Pretty Good Privacy](https://en.wikipedia.org/wiki/Pretty_Good_Privacy#OpenPGP)
(OpenPGP) specification. Its main purposes are digital authentication, signature and encryption.
It is often used by the [FLOSS](https://en.wikipedia.org/wiki/Free_and_open-source_software) community to verify:
- Linux package signatures: Debian [SecureApt](https://wiki.debian.org/SecureApt), ArchLinux [Master
Keys](https://www.archlinux.org/master-keys/)
- [SCM](https://en.wikipedia.org/wiki/Revision_control) releases & maintainer identity
### Trust
To quote Phil Pennock (the author of the [SKS](https://bitbucket.org/skskeyserver/sks-keyserver/wiki/Home) key server - http://sks.spodhuis.org/):
> You MUST understand that presence of data in the keyserver (pools) in no way connotes trust. Anyone can generate a key, with any name or email address, and upload it. All security and trust comes from evaluating security at the “object level”, via PGP Web-Of-Trust signatures. This keyserver makes it possible to retrieve keys, looking them up via various indices, but the collection of keys in this public pool is KNOWN to contain malicious and fraudulent keys. It is the common expectation of server operators that users understand this and use software which, like all known common OpenPGP implementations, evaluates trust accordingly. This expectation is so common that it is not normally explicitly stated.
Trust can be gained by having your key signed by other people (and signing their key back, too :) ), for instance during [key signing parties](https://en.wikipedia.org/wiki/Key_signing_party), see:
- [The Keysigning party HOWTO](http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html)
- [Web of trust](https://en.wikipedia.org/wiki/Web_of_trust)
## Generate a GPG key
- [Generating a GPG key for Git tagging](http://stackoverflow.com/a/16725717) (StackOverflow)
- [Generating a GPG key](https://help.github.com/articles/generating-a-gpg-key/) (GitHub)
### gpg - provide identity information
```bash
$ gpg --gen-key
gpg (GnuPG) 2.1.6; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Note: Use "gpg2 --full-gen-key" for a full featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: Marvin the Paranoid Android
Email address: marvin@h2g2.net
You selected this USER-ID:
"Marvin the Paranoid Android <marvin@h2g2.net>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
```
### gpg - entropy interlude
At this point, you will:
- be prompted for a secure password to protect your key (the input method will depend on your Desktop Environment and configuration)
- be asked to use your machine's input devices (mouse, keyboard, etc.) to generate random entropy; this step _may take some time_
### gpg - key creation confirmation
```bash
gpg: key A9D53A3E marked as ultimately trusted
public and secret key created and signed.
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
pub rsa2048/A9D53A3E 2015-07-31
Key fingerprint = AF2A 5381 E54B 2FD2 14C4 A9A3 0E35 ACA4 A9D5 3A3E
uid [ultimate] Marvin the Paranoid Android <marvin@h2g2.net>
sub rsa2048/8C0EACF1 2015-07-31
```
### gpg - submit your public key to a PGP server (Optional)
``` bash
$ gpg --keyserver pgp.mit.edu --send-keys A9D53A3E
gpg: sending key A9D53A3E to hkp server pgp.mit.edu
```
## Create and push a GPG-signed tag
See [Release Shaarli](Release Shaarli).

83
doc/md/Installation.md Normal file
View file

@ -0,0 +1,83 @@
# Installation
Once your server is [configured](Server-configuration.md), install Shaarli:
## From release ZIP
To install Shaarli, simply place the files from the latest [release .zip archive](https://github.com/shaarli/Shaarli/releases) under your webserver's document root (directly at the document root, or in a subdirectory). Download the **shaarli-vX.X.X-full** archive to include dependencies.
```bash
wget https://github.com/shaarli/Shaarli/releases/download/v0.11.1/shaarli-v0.11.1-full.zip
unzip shaarli-v0.11.1-full.zip
sudo rsync -avP Shaarli/ /var/www/shaarli.mydomain.org/
```
## From sources
These components are required to build Shaarli:
- [Composer](dev/Development.md#install-composer) to manage third-party [PHP dependencies](dev/Development#third-party-libraries).
- [yarn](https://classic.yarnpkg.com/en/docs/install/) to build frontend dependencies.
- [python3-virtualenv](https://pypi.org/project/virtualenv/) to build local HTML documentation.
```bash
# example from a Debian-based build machine
sudo apt install composer yarnpkg python3-virtualenv
```
Clone the repository, either pointing to:
- any [tagged release](https://github.com/shaarli/Shaarli/releases)
- `latest`: the latest tagged release
- `master`: development branch
```bash
# clone the branch/tag of your choice
$ git clone -b latest https://github.com/shaarli/Shaarli.git /home/me/Shaarli
# OR download/extract the tar.gz/zip: wget https://github.com/shaarli/Shaarli/archive/latest.tar.gz...
# enter the directory
$ cd /home/me/Shaarli
# install 3rd-party PHP dependencies
$ composer install --no-dev --prefer-dist
# build frontend static assets
$ make build_frontend
# build translations
$ make translate
# build HTML documentation
$ make htmldoc
# copy the resulting shaarli directory under your webserver's document root
$ rsync -avP /home/me/Shaarli/ /var/www/shaarli.mydomain.org/
```
## Set file permissions
Regardless of the installation method, appropriate [file permissions](dev/Development.md#directory-structure) must be set:
```bash
sudo chown -R root:www-data /var/www/shaarli.mydomain.org
sudo chmod -R g+rX /var/www/shaarli.mydomain.org
sudo chmod -R g+rwX /var/www/shaarli.mydomain.org/{cache/,data/,pagecache/,tmp/}
```
## Using Docker
[See the documentation](Docker.md)
## Finish Installation
Once Shaarli is downloaded and files have been placed at the correct location, open this location your web browser.
Enter basic settings for your Shaarli installation, and it's ready to use!
![](images/07-installation.jpg)
Congratulations! Your Shaarli is now available at `https://shaarli.mydomain.org`.
You can further [configure Shaarli](Shaarli-configuration.md), setup [Plugins](Plugins.md) or [additional software](Community-and-related-software.md).
## Upgrading Shaarli
See [Upgrade and Migration](Upgrade-and-migration)

View file

@ -1,18 +0,0 @@
## Link structure
Every link available through the `LinkDB` object is represented as an array
containing the following fields:
* `id` (integer): Unique identifier.
* `title` (string): Title of the link.
* `url` (string): URL of the link. Used for displayable links (without redirector, url encoding, etc.).
Can be absolute or relative for Notes.
* `real_url` (string): Real destination URL, can be redirected, encoded, etc.
* `shorturl` (string): Permalink small hash.
* `description` (string): Link text description.
* `private` (boolean): whether the link is private or not.
* `tags` (string): all link tags separated by a single space
* `thumbnail` (string|boolean): relative path of the thumbnail cache file, or false if there isn't any.
* `created` (DateTime): link creation date time.
* `updated` (DateTime): last modification date time.

View file

@ -1,725 +0,0 @@
[**I am a developer: ** Developer API](#developer-api)
[**I am a template designer: ** Guide for template designers](#guide-for-template-designer)
---
## Developer API
### What can I do with plugins?
The plugin system let you:
- insert content into specific places across templates.
- alter data before templates rendering.
- alter data before saving new links.
### How can I create a plugin for Shaarli?
First, chose a plugin name, such as `demo_plugin`.
Under `plugin` folder, create a folder named with your plugin name. Then create a <plugin_name>.php file in that folder.
You should have the following tree view:
```
| index.php
| plugins/
|---| demo_plugin/
| |---| demo_plugin.php
```
### Plugin initialization
At the beginning of Shaarli execution, all enabled plugins are loaded. At this point, the plugin system looks for an `init()` function to execute and run it if it exists. This function must be named this way, and takes the `ConfigManager` as parameter.
<plugin_name>_init($conf)
This function can be used to create initial data, load default settings, etc. But also to set *plugin errors*. If the initialization function returns an array of strings, they will be understand as errors, and displayed in the header to logged in users.
### Understanding hooks
A plugin is a set of functions. Each function will be triggered by the plugin system at certain point in Shaarli execution.
These functions need to be named with this pattern:
```
hook_<plugin_name>_<hook_name>($data, $conf)
```
Parameters:
- data: see [$data section](https://shaarli.readthedocs.io/en/master/Plugin-System/#plugins-data)
- conf: the `ConfigManager` instance.
For example, if my plugin want to add data to the header, this function is needed:
hook_demo_plugin_render_header
If this function is declared, and the plugin enabled, it will be called every time Shaarli is rendering the header.
### Plugin's data
#### Parameters
Every hook function has a `$data` parameter. Its content differs for each hooks.
**This parameter needs to be returned every time**, otherwise data is lost.
return $data;
#### Filling templates placeholder
Template placeholders are displayed in template in specific places.
RainTPL displays every element contained in the placeholder's array. These element can be added by plugins.
For example, let's add a value in the placeholder `top_placeholder` which is displayed at the top of my page:
```php
$data['top_placeholder'][] = 'My content';
# OR
array_push($data['top_placeholder'], 'My', 'content');
return $data;
```
#### Data manipulation
When a page is displayed, every variable send to the template engine is passed to plugins before that in `$data`.
The data contained by this array can be altered before template rendering.
For exemple, in linklist, it is possible to alter every title:
```php
// mind the reference if you want $data to be altered
foreach ($data['links'] as &$value) {
// String reverse every title.
$value['title'] = strrev($value['title']);
}
return $data;
```
### Metadata
Every plugin needs a `<plugin_name>.meta` file, which is in fact an `.ini` file (`KEY="VALUE"`), to be listed in plugin administration.
Each file contain two keys:
- `description`: plugin description
- `parameters`: user parameter names, separated by a `;`.
- `parameter.<PARAMETER_NAME>`: add a text description the specified parameter.
> Note: In PHP, `parse_ini_file()` seems to want strings to be between by quotes `"` in the ini file.
### It's not working!
Use `demo_plugin` as a functional example. It covers most of the plugin system features.
If it's still not working, please [open an issue](https://github.com/shaarli/Shaarli/issues/new).
### Hooks
| Hooks | Description |
| ------------- |:-------------:|
| [render_header](#render_header) | Allow plugin to add content in page headers. |
| [render_includes](#render_includes) | Allow plugin to include their own CSS files. |
| [render_footer](#render_footer) | Allow plugin to add content in page footer and include their own JS files. |
| [render_linklist](#render_linklist) | It allows to add content at the begining and end of the page, after every link displayed and to alter link data. |
| [render_editlink](#render_editlink) | Allow to add fields in the form, or display elements. |
| [render_tools](#render_tools) | Allow to add content at the end of the page. |
| [render_picwall](#render_picwall) | Allow to add content at the top and bottom of the page. |
| [render_tagcloud](#render_tagcloud) | Allow to add content at the top and bottom of the page, and after all tags. |
| [render_taglist](#render_taglist) | Allow to add content at the top and bottom of the page, and after all tags. |
| [render_daily](#render_daily) | Allow to add content at the top and bottom of the page, the bottom of each link and to alter data. |
| [render_feed](#render_feed) | Allow to do add tags in RSS and ATOM feeds. |
| [save_link](#save_link) | Allow to alter the link being saved in the datastore. |
| [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. |
| [save_plugin_parameters](#save_plugin_parameters) | Allow to manipulate plugin parameters before they're saved. |
#### render_header
Triggered on every page.
Allow plugin to add content in page headers.
##### Data
`$data` is an array containing:
- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `buttons_toolbar`: after the list of buttons in the header.
![buttons_toolbar_example](http://i.imgur.com/ssJUOrt.png)
- `fields_toolbar`: after search fields in the header.
> Note: This will only be called in linklist.
![fields_toolbar_example](http://i.imgur.com/3GMifI2.png)
#### render_includes
Triggered on every page.
Allow plugin to include their own CSS files.
##### Data
`$data` is an array containing:
- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `css_files`: called after loading default CSS.
> Note: only add the path of the CSS file. E.g: `plugins/demo_plugin/custom_demo.css`.
#### render_footer
Triggered on every page.
Allow plugin to add content in page footer and include their own JS files.
##### Data
`$data` is an array containing:
- `_PAGE_`: current target page (eg: `linklist`, `picwall`, etc.).
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `text`: called after the end of the footer text.
- `endofpage`: called at the end of the page.
![text_example](http://i.imgur.com/L5S2YEH.png)
- `js_files`: called at the end of the page, to include custom JS scripts.
> Note: only add the path of the JS file. E.g: `plugins/demo_plugin/custom_demo.js`.
#### render_linklist
Triggered when `linklist` is displayed (list of links, permalink, search, tag filtered, etc.).
It allows to add content at the begining and end of the page, after every link displayed and to alter link data.
##### Data
`$data` is an array containing:
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
- All templates data, including links.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `action_plugin`: next to the button "private only" at the top and bottom of the page.
![action_plugin_example](http://i.imgur.com/Q12PWg0.png)
- `link_plugin`: for every link, between permalink and link URL.
![link_plugin_example](http://i.imgur.com/3oDPhWx.png)
- `plugin_start_zone`: before displaying the template content.
![plugin_start_zone_example](http://i.imgur.com/OVBkGy3.png)
- `plugin_end_zone`: after displaying the template content.
![plugin_end_zone_example](http://i.imgur.com/6IoRuop.png)
#### render_editlink
Triggered when the link edition form is displayed.
Allow to add fields in the form, or display elements.
##### Data
`$data` is an array containing:
- All templates data.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `edit_link_plugin`: after tags field.
![edit_link_plugin_example](http://i.imgur.com/5u17Ens.png)
#### render_tools
Triggered when the "tools" page is displayed.
Allow to add content at the end of the page.
##### Data
`$data` is an array containing:
- All templates data.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `tools_plugin`: at the end of the page.
![tools_plugin_example](http://i.imgur.com/Bqhu9oQ.png)
#### render_picwall
Triggered when picwall is displayed.
Allow to add content at the top and bottom of the page.
##### Data
`$data` is an array containing:
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
- All templates data.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `plugin_start_zone`: before displaying the template content.
- `plugin_end_zone`: after displaying the template content.
![plugin_start_end_zone_example](http://i.imgur.com/tVTQFER.png)
#### render_tagcloud
Triggered when tagcloud is displayed.
Allow to add content at the top and bottom of the page.
##### Data
`$data` is an array containing:
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
- All templates data.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `plugin_start_zone`: before displaying the template content.
- `plugin_end_zone`: after displaying the template content.
For each tag, the following placeholder can be used:
- `tag_plugin`: after each tag
![plugin_start_end_zone_example](http://i.imgur.com/vHmyT3a.png)
#### render_taglist
Triggered when taglist is displayed.
Allow to add content at the top and bottom of the page.
##### Data
`$data` is an array containing:
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
- All templates data.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `plugin_start_zone`: before displaying the template content.
- `plugin_end_zone`: after displaying the template content.
For each tag, the following placeholder can be used:
- `tag_plugin`: after each tag
#### render_daily
Triggered when tagcloud is displayed.
Allow to add content at the top and bottom of the page, the bottom of each link and to alter data.
##### Data
`$data` is an array containing:
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
- All templates data, including links.
##### Template placeholders
Items can be displayed in templates by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `link_plugin`: used at bottom of each link.
![link_plugin_example](http://i.imgur.com/hzhMfSZ.png)
- `plugin_start_zone`: before displaying the template content.
- `plugin_end_zone`: after displaying the template content.
#### render_feed
Triggered when the ATOM or RSS feed is displayed.
Allow to add tags in the feed, either in the header or for each items. Items (links) can also be altered before being rendered.
##### Data
`$data` is an array containing:
- `_LOGGEDIN_`: true if user is logged in, false otherwise.
- `_PAGE_`: containing either `rss` or `atom`.
- All templates data, including links.
##### Template placeholders
Tags can be added in feeds by adding an entry in `$data['<placeholder>']` array.
List of placeholders:
- `feed_plugins_header`: used as a header tag in the feed.
For each links:
- `feed_plugins`: additional tag for every link entry.
#### save_link
Triggered when a link is save (new link or edit).
Allow to alter the link being saved in the datastore.
##### Data
`$data` is an array containing the link being saved:
- id
- title
- url
- shorturl
- description
- private
- tags
- created
- updated
#### delete_link
Triggered when a link is deleted.
Allow to execute any action before the link is actually removed from the datastore
##### Data
`$data` is an array containing the link being saved:
- id
- title
- url
- shorturl
- description
- private
- tags
- created
- updated
#### save_plugin_parameters
Triggered when the plugin parameters are saved from the plugin administration page.
Plugins can perform an action every times their settings are updated.
For example it is used to update the CSS file of the `default_colors` plugins.
##### Data
`$data` input contains the `$_POST` array.
So if the plugin has a parameter called `MYPLUGIN_PARAMETER`,
the array will contain an entry with `MYPLUGIN_PARAMETER` as a key.
## Guide for template designer
### Plugin administration
Your theme must include a plugin administration page: `pluginsadmin.html`.
> Note: repo's template link needs to be added when the PR is merged.
Use the default one as an example.
Aside from classic RainTPL loops, plugins order is handle by JavaScript. You can just include `plugin_admin.js`, only if:
- you're using a table.
- you call orderUp() and orderUp() onclick on arrows.
- you add data-line and data-order to your rows.
Otherwise, you can use your own JS as long as this field is send by the form:
<input type="hidden" name="order_{$key}" value="{$counter}">
### Placeholder system
In order to make plugins work with every custom themes, you need to add variable placeholder in your templates.
It's a RainTPL loop like this:
{loop="$plugin_variable"}
{$value}
{/loop}
You should enable `demo_plugin` for testing purpose, since it uses every placeholder available.
### List of placeholders
**page.header.html**
At the end of the menu:
{loop="$plugins_header.buttons_toolbar"}
{$value}
{/loop}
At the end of file, before clearing floating blocks:
{if="!empty($plugin_errors) && isLoggedIn()"}
<ul class="errors">
{loop="plugin_errors"}
<li>{$value}</li>
{/loop}
</ul>
{/if}
**includes.html**
At the end of the file:
```html
{loop="$plugins_includes.css_files"}
<link type="text/css" rel="stylesheet" href="{$value}#"/>
{/loop}
```
**page.footer.html**
At the end of your footer notes:
```html
{loop="$plugins_footer.text"}
{$value}
{/loop}
```
At the end of file:
```html
{loop="$plugins_footer.js_files"}
<script src="{$value}#"></script>
{/loop}
```
**linklist.html**
After search fields:
```html
{loop="$plugins_header.fields_toolbar"}
{$value}
{/loop}
```
Before displaying the link list (after paging):
```html
{loop="$plugin_start_zone"}
{$value}
{/loop}
```
For every links (icons):
```html
{loop="$value.link_plugin"}
<span>{$value}</span>
{/loop}
```
Before end paging:
```html
{loop="$plugin_end_zone"}
{$value}
{/loop}
```
**linklist.paging.html**
After the "private only" icon:
```html
{loop="$action_plugin"}
{$value}
{/loop}
```
**editlink.html**
After tags field:
```html
{loop="$edit_link_plugin"}
{$value}
{/loop}
```
**tools.html**
After the last tool:
```html
{loop="$tools_plugin"}
{$value}
{/loop}
```
**picwall.html**
Top:
```html
<div id="plugin_zone_start_picwall" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
```
Bottom:
```html
<div id="plugin_zone_end_picwall" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
```
**tagcloud.html**
Top:
```html
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
```
Bottom:
```html
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
```
**daily.html**
Top:
```html
<div id="plugin_zone_start_picwall" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
```
After every link:
```html
<div class="dailyEntryFooter">
{loop="$link.link_plugin"}
{$value}
{/loop}
</div>
```
Bottom:
```html
<div id="plugin_zone_end_picwall" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
```
**feed.atom.xml** and **feed.rss.xml**:
In headers tags section:
```xml
{loop="$feed_plugins_header"}
{$value}
{/loop}
```
After each entry:
```xml
{loop="$value.feed_plugins"}
{$value}
{/loop}
```

View file

@ -1,14 +1,13 @@
## Plugin installation
# Plugins
There is a bunch of plugins shipped with Shaarli, where there is nothing to do to install them.
## Installation
If you want to install a third party plugin:
For plugins shipped with Shaarli, no installation is required.
- Download it.
- Put it in the `plugins` directory in Shaarli's installation folder.
- Make sure you put it correctly:
If you want to install a third party plugin, download it to the `plugins` directory in Shaarli's installation folder:
```
```bash
# example directory structure
| index.php
| plugins/
|---| custom_plugin/
@ -17,63 +16,47 @@ If you want to install a third party plugin:
```
* Make sure your webserver can read and write the files in your plugin folder.
Make sure your webserver can read and write the files in your plugin folder.
## Plugin configuration
In Shaarli's administration page (`Tools` link), go to `Plugin administration`.
## Configuration
Here you can enable and disable all plugins available, and configure them.
From Shaarli's administration page (`Tools` link), go to `Plugin administration`. Here you can enable and disable all plugins available, and configure them.
![administration screenshot](https://camo.githubusercontent.com/5da68e191969007492ca0fbeb25f3b2357b748cc/687474703a2f2f692e696d6775722e636f6d2f766837544643712e706e67)
## Plugin order
## Order
In the plugin administration page, you can move enabled plugins to the top or bottom of the list. The first plugins in the list will be processed first.
This is important in case plugins are depending on each other. Read plugins README details for more information.
This is important in case plugins depend on each other. Read plugins READMEs for more information.
**Use case**: The (non existent) plugin `shaares_footer` adds a footer to every shaare in Markdown syntax. It needs to be processed *before* (higher in the list) the Markdown plugin. Otherwise its syntax won't be translated in HTML.
## File mode
Enabled plugin are stored in your `config.json.php` parameters file, under the `array`:
## Configuration file
```php
$GLOBALS['config']['ENABLED_PLUGINS']
```
Enabled plugins are stored in your [Configuration file](Shaarli-configuration.md).
You can edit them manually here.
Example:
## Usage
```php
$GLOBALS['config']['ENABLED_PLUGINS'] = array(
'qrcode',
'archiveorg',
'wallabag',
'markdown',
);
```
### Plugin usage
#### Official plugins
### Official plugins
Usage of each plugin is documented in it's README file:
* `addlink-toolbar`: Adds the addlink input on the linklist page
* `archiveorg`: For each link, add an Archive.org icon
* `addlink-toolbar`: Adds the addlink input on the Shaares list page
* `archiveorg`: For each Shaare, add a link to the archived page on Archive.org
* `default_colors`: Override default theme colors.
* `isso`: Let visitor comment your shaares on permalinks with Isso.
* [`markdown`](https://github.com/shaarli/Shaarli/blob/master/plugins/markdown/README.md): Render shaare description with Markdown syntax.
* `piwik`: A plugin that adds Piwik tracking code to Shaarli pages.
* [`playvideos`](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md): Add a button in the toolbar allowing to watch all videos.
* `pubsubhubbub`: Enable PubSubHubbub feed publishing
* `qrcode`: For each link, add a QRCode icon.
* [`wallabag`](https://github.com/shaarli/Shaarli/blob/master/plugins/wallabag/README.md): For each link, add a Wallabag icon to save it in your instance.
* `qrcode`: For each Shaare, add a QRCode icon.
* `readitlater`: Mark bookmarks to read them later, with bookmark list highlight and filter.
* [`wallabag`](https://github.com/shaarli/Shaarli/blob/master/plugins/wallabag/README.md): For each Shaare, add a Wallabag icon to save it in your instance.
### Third party plugins
#### Third party plugins
See [Community & related software](https://shaarli.readthedocs.io/en/master/Community-&-Related-software/)
See [Community & related software](Community-and-related-software.md)

View file

@ -1,103 +1,26 @@
## Usage and Prerequisites
# REST API
See the [REST API documentation](http://shaarli.github.io/api-documentation/)
for a list of available endpoints and parameters.
## Server requirements
Please ensure that your server meets the
[requirements](Server-configuration#prerequisites) and is properly
[configured](Server-configuration):
See the **[REST API documentation](https://shaarli.github.io/api-documentation/)** for a list of available endpoints and parameters.
Please ensure that your server meets the requirements and is properly [configured](Server-configuration.md):
- URL rewriting is enabled (see specific Apache and Nginx sections)
- the server's timezone is properly defined
- the server's clock is synchronized with
[NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol)
- the server's clock is synchronized with [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol)
The host where the API client is invoked should also be synchronized with NTP,
see [token expiration](#payload).
## Authentication
All requests to Shaarli's API must include a JWT token to verify their authenticity.
This token has to be included as an HTTP header called `Authentication: Bearer <jwt token>`.
JWT resources :
- [jwt.io](https://jwt.io) (including a list of client per language).
- RFC : https://tools.ietf.org/html/rfc7519
- https://float-middle.com/json-web-tokens-jwt-vs-sessions/
- HackerNews thread: https://news.ycombinator.com/item?id=11929267
### Shaarli JWT Token
JWT tokens are composed by three parts, separated by a dot `.` and encoded in base64:
```
[header].[payload].[signature]
```
#### Header
Shaarli only allow one hash algorithm, so the header will always be the same:
```json
{
"typ": "JWT",
"alg": "HS512"
}
```
Encoded in base64, it gives:
```
ewogICAgICAgICJ0eXAiOiAiSldUIiwKICAgICAgICAiYWxnIjogIkhTNTEyIgogICAgfQ==
```
#### Payload
**Token expiration**
To avoid infinite token validity, JWT tokens must include their creation date
in UNIX timestamp format (timezone independent - UTC) under the key `iat` (issued at).
This token will be valid during **9 minutes**.
```json
{
"iat": 1468663519
}
```
See [RFC reference](https://tools.ietf.org/html/rfc7519#section-4.1.6).
#### Signature
The signature authenticate the token validity. It contains the base64 of the header and the body, separated by a dot `.`, hashed in SHA512 with the API secret available in Shaarli administration page.
Signature example with PHP:
```php
$content = base64_encode($header) . '.' . base64_encode($payload);
$signature = hash_hmac('sha512', $content, $secret);
```
The host where the API client is invoked should also be synchronized with NTP, see _payload/token expiration_
## Clients and examples
### Android, Java, Kotlin
- [Android client example with Kotlin](https://gitlab.com/snippets/1665808)
by [Braincoke](https://github.com/Braincoke)
- **[python-shaarli-client](https://github.com/shaarli/python-shaarli-client)** - the reference API client ([Documentation](https://python-shaarli-client.readthedocs.io/en/latest/))
- [shaarli-client](https://www.npmjs.com/package/shaarli-client) - NodeJs client ([source code](https://github.com/laBecasse/shaarli-client)) by [laBecasse](https://github.com/laBecasse)
- [Android client example with Kotlin](https://gitlab.com/-/snippets/1665808) by [Braincoke](https://github.com/Braincoke)
### Javascript, NodeJS
- [shaarli-client](https://www.npmjs.com/package/shaarli-client)
([source code](https://github.com/laBecasse/shaarli-client))
by [laBecasse](https://github.com/laBecasse)
### PHP
This example uses the [PHP cURL](http://php.net/manual/en/book.curl.php) library.
This example uses the [PHP cURL](https://www.php.net/manual/en/book.curl.php) library.
```php
<?php
@ -145,13 +68,57 @@ function getInfo($baseUrl, $secret) {
var_dump(getInfo($baseUrl, $secret));
```
## Implementation
### Python
### Authentication
- All requests to Shaarli's API must include a **JWT token** to verify their authenticity.
- This token must be included as an HTTP header called `Authorization: Bearer <jwt token>`.
- JWT tokens are composed by three parts, separated by a dot `.` and encoded in base64:
```
[header].[payload].[signature]
```
##### Header
Shaarli only allow one hash algorithm, so the header will always be the same:
```json
{
"typ": "JWT",
"alg": "HS512"
}
```
Encoded in base64, it gives:
```
ewogICAgICAgICJ0eXAiOiAiSldUIiwKICAgICAgICAiYWxnIjogIkhTNTEyIgogICAgfQ==
```
##### Payload
Token expiration: To avoid infinite token validity, JWT tokens must include their creation date in UNIX timestamp format (timezone independent - UTC) under the key `iat` (issued at) field ([1](https://datatracker.ietf.org/doc/html/rfc7519)). This token will be valid during **9 minutes**.
```json
{
"iat": 1468663519
}
```
##### Signature
The signature authenticates the token validity. It contains the base64 of the header and the body, separated by a dot `.`, hashed in SHA512 with the API secret available in Shaarli administration page.
Example signature with PHP:
```php
$content = base64_encode($header) . '.' . base64_encode($payload);
$signature = hash_hmac('sha512', $content, $secret);
```
See the reference API client:
- [Documentation](http://python-shaarli-client.readthedocs.io/en/latest/) on ReadTheDocs
- [python-shaarli-client](https://github.com/shaarli/python-shaarli-client) on Github
## Troubleshooting
@ -171,3 +138,13 @@ to get the actual error message in the HTTP response body with:
}
}
```
## References
- [jwt.io](https://jwt.io) (including a list of client per language).
- [RFC - JSON Web Token (JWT)](https://datatracker.ietf.org/doc/html/rfc7519)
- [JSON Web Tokens (JWT) vs Sessions](https://float-middle.com/json-web-tokens-jwt-vs-sessions/), [HackerNews thread](https://news.ycombinator.com/item?id=11929267)

View file

@ -1,28 +0,0 @@
### Feeds options
Feeds are available in ATOM with `?do=atom` and RSS with `do=RSS`.
Options:
- You can use `permalinks` in the feed URL to get permalink to Shaares instead of direct link to shaared URL.
- E.G. `https://my.shaarli.domain/?do=atom&permalinks`.
- You can use `nb` parameter in the feed URL to specify the number of Shaares you want in a feed (default if not specified: `50`). The keyword `all` is available if you want everything.
- `https://my.shaarli.domain/?do=atom&permalinks&nb=42`
- `https://my.shaarli.domain/?do=atom&permalinks&nb=all`
### RSS Feeds or Picture Wall for a specific search/tag
It is possible to filter RSS/ATOM feeds and Picture Wall on a Shaarli to **only display results of a specific search, or for a specific tag**.
For example, if you want to subscribe only to links tagged `photography`:
- Go to the desired Shaarli instance.
- Search for the `photography` tag in the _Filter by tag_ box. Links tagged `photography` are displayed.
- Click on the `RSS Feed` button.
- You are presented with an RSS feed showing only these links. Subscribe to it to receive only updates with this tag.
- The same method **also works for a full-text search** (_Search_ box) **and for the Picture Wall** (want to only see pictures about `nature`?)
- You can also build the URLs manually:
- `https://my.shaarli.domain/?do=rss&searchtags=nature`
- `https://my.shaarli.domain/links/?do=picwall&searchterm=poney`
![](images/rss-filter-1.png) ![](images/rss-filter-2.png)

View file

@ -1,161 +0,0 @@
See [Git - Maintaining a project - Tagging your
releases](http://git-scm.com/book/en/v2/Distributed-Git-Maintaining-a-Project#Tagging-Your-Releases).
## Prerequisites
This guide assumes that you have:
- a GPG key matching your GitHub authentication credentials
- i.e., the email address identified by the GPG key is the same as the one in your `~/.gitconfig`
- a GitHub fork of Shaarli
- a local clone of your Shaarli fork, with the following remotes:
- `origin` pointing to your GitHub fork
- `upstream` pointing to the main Shaarli repository
- maintainer permissions on the main Shaarli repository, to:
- push the signed tag
- create a new release
- [Composer](https://getcomposer.org/) needs to be installed
- The [venv](https://docs.python.org/3/library/venv.html) Python 3 module needs to be installed for HTML documentation generation.
## GitHub release draft and `CHANGELOG.md`
See http://keepachangelog.com/en/0.3.0/ for changelog formatting.
### GitHub release draft
GitHub allows drafting the release note for the upcoming release, from the [Releases](https://github.com/shaarli/Shaarli/releases) page. This way, the release note can be drafted while contributions are merged to `master`.
### `CHANGELOG.md`
This file should contain the same information as the release note draft for the upcoming version.
Update it to:
- add new entries (additions, fixes, etc.)
- mark the current version as released by setting its date and link
- add a new section for the future unreleased version
```bash
$ cd /path/to/shaarli
$ nano CHANGELOG.md
[...]
## vA.B.C - UNRELEASED
TBA
## [vX.Y.Z](https://github.com/shaarli/Shaarli/releases/tag/vX.Y.Z) - YYYY-MM-DD
[...]
```
## Increment the version code, update docs, create and push a signed tag
### Update the list of Git contributors
```bash
$ make authors
$ git commit -s -m "Update AUTHORS"
```
### Create and merge a Pull Request
This one is pretty straightforward ;-)
### Bump Shaarli version to v0.x branch
```bash
$ git checkout master
$ git fetch upstream
$ git pull upstream master
# IF the branch doesn't exists
$ git checkout -b v0.5
# OR if the branch already exists
$ git checkout v0.5
$ git rebase upstream/master
# Bump shaarli version from dev to 0.5.0, **without the `v`**
$ vim shaarli_version.php
$ git add shaarli_version
$ git commit -s -m "Bump Shaarli version to v0.5.0"
$ git push upstream v0.5
```
### Create and push a signed tag
```bash
# update your local copy
$ git checkout v0.5
$ git fetch upstream
$ git pull upstream v0.5
# create a signed tag
$ git tag -s -m "Release v0.5.0" v0.5.0
# push it to "upstream"
$ git push --tags upstream
```
### Verify a signed tag
[`v0.5.0`](https://github.com/shaarli/Shaarli/releases/tag/v0.5.0) is the first GPG-signed tag pushed on the Community Shaarli.
Let's have a look at its signature!
```bash
$ cd /path/to/shaarli
$ git fetch upstream
# get the SHA1 reference of the tag
$ git show-ref tags/v0.5.0
f7762cf803f03f5caf4b8078359a63783d0090c1 refs/tags/v0.5.0
# verify the tag signature information
$ git verify-tag f7762cf803f03f5caf4b8078359a63783d0090c1
gpg: Signature made Thu 30 Jul 2015 11:46:34 CEST using RSA key ID 4100DF6F
gpg: Good signature from "VirtualTam <virtualtam@flibidi.net>" [ultimate]
```
## Publish the GitHub release
### Update release badges
Update `README.md` so version badges display and point to the newly released Shaarli version(s), in the `master` branch.
### Create a GitHub release from a Git tag
From the previously drafted release:
- edit the release notes (if needed)
- specify the appropriate Git tag
- publish the release
- profit!
### Generate and upload all-in-one release archives
Users with a shared hosting may have:
- no SSH access
- no possibility to install PHP packages or server extensions
- no possibility to run scripts
To ease Shaarli installations, it is possible to generate and upload additional release archives,
that will contain Shaarli code plus all required third-party libraries.
**From the `v0.5` branch:**
```bash
$ make release_archive
```
This will create the following archives:
- `shaarli-vX.Y.Z-full.tar`
- `shaarli-vX.Y.Z-full.zip`
The archives need to be manually uploaded on the previously created GitHub release.
### Update `stable` and `latest` branches
```
$ git checkout latest
# latest release
$ git merge v0.5.0
# fix eventual conflicts
$ make test
$ git push upstream latest
$ git checkout stable
# latest previous major
$ git merge v0.4.5
# fix eventual conflicts
$ make test
$ git push upstream stable
```

142
doc/md/Reverse-proxy.md Normal file
View file

@ -0,0 +1,142 @@
# Reverse proxy
If Shaarli is hosted on a server behind a [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy) (i.e. there is a proxy server between clients and the web server hosting Shaarli), configure it accordingly. See [Reverse proxy](Reverse-proxy.md) configuration. In this example:
- The Shaarli application server exposes port `10080` to the proxy (for example docker container started with `--publish 127.0.0.1:10080:80`).
- The Shaarli application server runs at `127.0.0.1` (container). Replace with the server's IP address if running on a different machine.
- Shaarli's Fully Qualified Domain Name (FQDN) is `shaarli.mydomain.org`.
- No HTTPS is setup on the application server, SSL termination is done at the reverse proxy.
In your [Shaarli configuration](Shaarli-configuration.md) `data/config.json.php`, add the public IP of your proxy under `security.trusted_proxies`.
See also [proxy-related](https://github.com/shaarli/Shaarli/issues?utf8=%E2%9C%93&q=label%3Aproxy+) issues.
## Apache
```apache
<VirtualHost *:80>
ServerName shaarli.mydomain.org
# For SSL/TLS certificates acquired with certbot or self-signed certificates
# Redirect HTTP requests to HTTPS, except Let's Encrypt ACME challenge requests
RewriteEngine on
RewriteRule ^.well-known/acme-challenge/ - [L]
RewriteCond %{HTTP_HOST} =shaarli.mydomain.org
RewriteRule ^ https://shaarli.mydomain.org%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
# SSL/TLS configuration for Let's Encrypt certificates managed with mod_md
#MDomain shaarli.mydomain.org
#MDCertificateAgreement accepted
#MDContactEmail admin@shaarli.mydomain.org
#MDPrivateKeys RSA 4096
<VirtualHost *:443>
ServerName shaarli.mydomain.org
# SSL/TLS configuration for Let's Encrypt certificates acquired with certbot standalone
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/shaarli.mydomain.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/shaarli.mydomain.org/privkey.pem
# Let's Encrypt settings from https://github.com/certbot/certbot/blob/master/certbot-apache/certbot_apache/_internal/tls_configs/current-options-ssl-apache.conf
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
SSLOptions +StrictRequire
# SSL/TLS configuration for self-signed certificates
#SSLEngine on
#SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
#SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
# let the proxied shaarli server/container know HTTPS URLs should be served
RequestHeader set X-Forwarded-Proto "https"
# send the original SERVER_NAME to the proxied host
ProxyPreserveHost On
# pass requests to the proxied host
# sets X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Server headers
ProxyPass / http://127.0.0.1:10080/
ProxyPassReverse / http://127.0.0.1:10080/
</VirtualHost>
```
## HAProxy
```
global
[...]
defaults
[...]
frontend http-in
bind :80
redirect scheme https code 301 if !{ ssl_fc }
bind :443 ssl crt /path/to/cert.pem
default_backend shaarli
backend shaarli
mode http
option http-server-close
option forwardfor
reqadd X-Forwarded-Proto: https
server shaarli1 127.0.0.1:10080
```
- [HAProxy documentation](https://cbonte.github.io/haproxy-dconv/)
## Nginx
```nginx
http {
[...]
index index.html index.php;
root /home/john/web;
access_log /var/log/nginx/access.log combined;
error_log /var/log/nginx/error.log;
server {
listen 80;
server_name shaarli.mydomain.org;
# redirect HTTP to HTTPS
return 301 https://shaarli.mydomain.org$request_uri;
}
server {
listen 443 ssl http2;
server_name shaarli.mydomain.org;
ssl_certificate /path/to/certificate
ssl_certificate_key /path/to/private/key
# if shaarli is installed in a subdirectory of the main domain, edit the location accordingly
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
# pass requests to the proxied host
proxy_pass http://localhost:10080/;
proxy_set_header Host $host;
proxy_connect_timeout 30s;
proxy_read_timeout 120s;
}
}
}
```
## References
- [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto)
- [`X-Forwarded-Host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host)
- [`X-Forwarded-For`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)

View file

@ -1,25 +0,0 @@
## Client browser
- Shaarli relies on `HTTP_REFERER` for some functions (like redirects and clicking on tags). If you have disabled or masqueraded `HTTP_REFERER` in your browser, some features of Shaarli may not work
## Server and sessions
- Directories are protected using `.htaccess` files
- Forms are protected against XSRF (Cross-site requests forgery):
- Forms which act on data (save,delete…) contain a token generated by the server.
- Any posted form which does not contain a valid token is rejected.
- Any token can only be used once.
- Tokens are attached to the session and cannot be reused in another session.
- Sessions automatically expire after 60 minutes.
- Sessions are protected against hijacking: the session ID cannot be used from a different IP address.
## Shaarli datastore and configuration
- The password is salted, hashed and stored in the data subdirectory, in a PHP file, and protected by htaccess. Even if the webserver does not support htaccess, the hash is not readable by URL. Even if the .php file is stolen, the password cannot deduced from the hash. The salt prevents rainbow-tables attacks.
- Links are stored as an associative array which is serialized, compressed (with deflate), base64-encoded and saved as a comment in a `.php` file.
- Even if the server does not support `.htaccess` files, the data file will still not be readable by URL.
- The database looks like this:
```php
<?php /* zP1ZjxxJtiYIvvevEPJ2lDOaLrZv7o...
...ka7gaco/Z+TFXM2i7BlfMf8qxpaSSYfKlvqv/x8= */ ?>
```
- Small hashes are used to make a link to an entry in Shaarli. They are unique. In fact, the date of the items (eg. `20110923_150523`) is hashed with CRC32, then converted to base64 and some characters are replaced. They are always 6 characters longs and use only `A-Z a-z 0-9 - _` and `@`.

View file

@ -1,96 +1,183 @@
# Server configuration
- [Prerequisites](#prerequisistes)
- [Apache](#apache)
- [Nginx](#nginx)
- [Proxies](#proxies)
- [See also](#see-also)
## Requirements
## Prerequisites
### Shaarli
### Operating system and web server
- A web server and PHP interpreter module/service have been installed.
- You have write access to the Shaarli installation directory.
- The correct read/write permissions have been granted to the web server user and group.
- Your PHP interpreter is compatible with supported PHP versions:
Shaarli can be hosted on dedicated/virtual servers, or shared hosting.
You need write access to the Shaarli installation directory - you should have received instructions from your hosting provider on how to connect to the server using SSH (or FTP for shared hosts).
Examples in this documentation are given for [Debian](https://www.debian.org/), a GNU/Linux distribution widely used in server environments. Please adapt them to your specific Linux distribution.
A $5/month VPS (1 CPU, 1 GiB RAM and 25 GiB SSD) will run any Shaarli installation without problems. Some hosting providers: [DigitalOcean](https://www.digitalocean.com/) ([1](https://docs.digitalocean.com/products/droplets/), [2](https://www.digitalocean.com/pricing/), [3](https://docs.digitalocean.com/products/droplets/how-to/create/), [4](https://docs.digitalocean.com/products/droplets/how-to/add-ssh-keys/), [5](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-debian-8), [6](https://www.digitalocean.com/community/tutorials/an-introduction-to-securing-your-linux-vps)), [Gandi](https://www.gandi.net/en), [OVH](https://www.ovhcloud.com/en-gb/), [RackSpace](https://www.rackspace.com/), etc.
### Network and domain name
Try to host the server in a region that is geographically close to your users.
A **domain name** ([DNS record](https://opensource.com/article/17/4/introduction-domain-name-system-dns)) pointing to the server's public IP address is required to obtain a SSL/TLS certificate and setup HTTPS to secure client traffic to your Shaarli instance.
You can obtain a domain name from a [registrar](https://en.wikipedia.org/wiki/Domain_name_registrar) ([1](https://www.ovhcloud.com/en-gb/domains), [2](https://www.gandi.net/en/domain)), or from free subdomain providers ([1](https://freedns.afraid.org/)). If you don't have a domain name, please set up a private domain name ([FQDN](ttps://en.wikipedia.org/wiki/Fully_qualified_domain_name)) in your clients' [hosts files](https://en.wikipedia.org/wiki/Hosts_(file)) to access the server (direct access by IP address can result in unexpected behavior).
Setup a **firewall** (using `iptables`, [ufw](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-debian-10), [firewalld](https://firewalld.org/) or any frontend of your choice) to deny all incoming traffic except `tcp/80` and `tcp/443`, which are needed to access the web server (and any other posrts you might need, like SSH). If the server is in a private network behind a NAT, ensure these **ports are forwarded** to the server.
Shaarli makes outbound HTTP/HTTPS connections to websites you bookmark to fetch page information (title, thumbnails), the server must then have access to the Internet as well, and a working DNS resolver.
--------------------------------------------------------------------------------
### PHP
Supported PHP versions:
Version | Status | Shaarli compatibility
:---:|:---:|:---:
7.2 | Supported | Yes
7.1 | Supported | Yes
8.2 | Supported | Yes
8.1 | Supported | Yes
8.0 | EOL: 2023-11-26| Yes
7.4 | EOL: 2022-11-28 | Yes
7.3 | EOL: 2021-12-06 | Yes (up to Shaarli 0.12.2)
7.2 | EOL: 2020-11-30 | Yes (up to Shaarli 0.12.2)
7.1 | EOL: 2019-12-01 | Yes (up to Shaarli 0.12.2)
7.0 | EOL: 2018-12-03 | Yes (up to Shaarli 0.10.x)
5.6 | EOL: 2018-12-31 | Yes (up to Shaarli 0.10.x)
5.5 | EOL: 2016-07-10 | Yes
5.4 | EOL: 2015-09-14 | Yes (up to Shaarli 0.8.x)
5.3 | EOL: 2014-08-14 | Yes (up to Shaarli 0.8.x)
- The following PHP extensions are installed on the server:
Required PHP extensions:
Extension | Required? | Usage
---|:---:|---
[`openssl`](http://php.net/manual/en/book.openssl.php) | All | OpenSSL, HTTPS
[`php-mbstring`](http://php.net/manual/en/book.mbstring.php) | CentOS, Fedora, RHEL, Windows, some hosting providers | multibyte (Unicode) string support
[`php-gd`](http://php.net/manual/en/book.image.php) | optional | required to use thumbnails
[`php-intl`](http://php.net/manual/en/book.intl.php) | optional | localized text sorting (e.g. `e->è->f`)
[`php-curl`](http://php.net/manual/en/book.curl.php) | optional | using cURL for fetching webpages and thumbnails in a more robust way
[`php-gettext`](http://php.net/manual/en/book.gettext.php) | optional | Use the translation system in gettext mode (faster)
[`openssl`](https://www.php.net/manual/en/book.openssl.php) | required | OpenSSL, HTTPS
[`php-json`](https://www.php.net/manual/en/book.json.php) | required | configuration parsing
[`php-simplexml`](https://www.php.net/manual/en/book.simplexml.php) | required | REST API (Slim framework)
[`php-mbstring`](https://www.php.net/manual/en/book.mbstring.php) | CentOS, Fedora, RHEL, Windows, some hosting providers | multibyte (Unicode) string support
[`php-ctype`](https://www.php.net/manual/en/book.ctype.php) | required (bundled with most PHP installation) | Type checking
[`php-iconv`](https://www.php.net/manual/en/book.iconv.php) | required (bundled with most PHP installation) | Character encoding used in translations
[`php-session`](https://www.php.net/manual/en/book.session.php) | required (bundled with most PHP installation) | User session
[`php-zlib`](https://www.php.net/manual/en/book.zlib.php) | required (bundled with most PHP installation) | Datastore I/O compression
[`php-gd`](https://www.php.net/manual/en/book.image.php) | optional | required to use thumbnails
[`php-intl`](https://www.php.net/manual/en/book.intl.php) | optional | localized text sorting (e.g. `e->è->f`)
[`php-curl`](https://www.php.net/manual/en/book.curl.php) | optional | using cURL for fetching webpages and thumbnails in a more robust way
[`php-gettext`](https://www.php.net/manual/en/book.gettext.php) | optional | Use the translation system in gettext mode (faster)
[`php-ldap`](https://www.php.net/manual/en/book.ldap.php) | optional | LDAP login support
Some [plugins](Plugins.md) may require additional configuration.
- [PHP: Supported versions](https://www.php.net/supported-versions.php)
- [PHP: Unsupported versions (EOL/End-of-life)](https://www.php.net/eol.php)
- [PHP 7 Changelog](https://www.php.net/ChangeLog-7.php)
- [PHP 5 Changelog](https://www.php.net/ChangeLog-5.php)
- [PHP: Bugs](https://bugs.php.net/)
## SSL/TLS (HTTPS)
We recommend setting up [HTTPS](https://en.wikipedia.org/wiki/HTTPS) (SSL/[TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security)) on your webserver for secure communication between clients and the server.
### Let's Encrypt
For public-facing web servers this can be done using free SSL/TLS certificates from [Let's Encrypt](https://en.wikipedia.org/wiki/Let's_Encrypt), a non-profit certificate authority provididing free certificates.
- [How to secure Apache with Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-debian-10)
- [How to secure Nginx with Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-debian-10)
- [How To Use Certbot Standalone Mode to Retrieve Let's Encrypt SSL Certificates](https://www.digitalocean.com/community/tutorials/how-to-use-certbot-standalone-mode-to-retrieve-let-s-encrypt-ssl-certificates-on-debian-10).
In short:
```bash
# install certbot
sudo apt install certbot
# stop your webserver if you already have one running
# certbot in standalone mode needs to bind to port 80 (only needed on initial generation)
sudo systemctl stop apache2
sudo systemctl stop nginx
# generate initial certificates
# Let's Encrypt ACME servers must be able to access your server! port forwarding and firewall must be properly configured
sudo certbot certonly --standalone --noninteractive --agree-tos --email "admin@shaarli.mydomain.org" -d shaarli.mydomain.org
# this will generate a private key and certificate at /etc/letsencrypt/live/shaarli.mydomain.org/{privkey,fullchain}.pem
# restart the web server
sudo systemctl start apache2
sudo systemctl start nginx
```
On apache `2.4.43+`, you can also delegate LE certificate management to [mod_md](https://httpd.apache.org/docs/2.4/mod/mod_md.html) [[1](https://www.cyberciti.biz/faq/how-to-secure-apache-with-mod_md-lets-encrypt-on-ubuntu-20-04-lts/)] in which case you don't need certbot and manual SSL configuration in virtualhosts.
### Self-signed
If you don't want to rely on a certificate authority, or the server can only be accessed from your own network, you can also generate self-signed certificates. Not that this will generate security warnings in web browsers/clients trying to access Shaarli:
- [How To Create a Self-Signed SSL Certificate for Apache](https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-apache-in-debian-10)
- [How To Create a Self-Signed SSL Certificate for Nginx](https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-on-debian-10)
- [How do I create my own Certificate Authority?](https://workaround.org/certificate-authority)
--------------------------------------------------------------------------------
### SSL/TLS configuration
## Examples
To setup HTTPS / SSL on your webserver (recommended), you must generate a public/private **key pair** and a **certificate**, and install, configure and activate the appropriate **webserver SSL extension**.
The following examples assume a Debian-based operating system is installed. On other distributions you may have to adapt details such as package installation procedures, configuration file locations, and webserver username/group (`www-data` or `httpd` are common values). In these examples we assume that the web server and the `php-fpm` PHP interpreter are running as the same user, and the document root for your web server/virtualhost is at `/var/www/shaarli.mydomain.org/`,:
#### Let's Encrypt
```bash
# create the document root (replace with your own domain name)
sudo mkdir -p /var/www/shaarli.mydomain.org/
```
[Let's Encrypt](https://en.wikipedia.org/wiki/Let%27s_Encrypt) is a certificate authority that provides free TLS/X.509 certificates via an automated process.
You can install Shaarli at the root of your virtualhost, or in a subdirectory as well. See [Directory structure](dev/Development.md#directory-structure)
* Install `certbot` using the appropriate method described on https://certbot.eff.org/.
Location of the `certbot` program and template configuration files may vary depending on which installation method was used. Change the file paths below accordingly. Here is an easy way to create a signed certificate using `certbot`, it assumes `certbot` was installed through APT on a Debian-based distribution:
* Stop the apache2/nginx service.
* Run `certbot --agree-tos --standalone --preferred-challenges tls-sni --email "youremail@example.com" --domain yourdomain.example.com`
* For the Apache webserver, copy `/usr/lib/python2.7/dist-packages/certbot_apache/options-ssl-apache.conf` to `/etc/letsencrypt/options-ssl-apache.conf` (paths may vary depending on installation method)
* For Nginx: TODO
* Setup your webserver as described below
* Restart the apache2/nginx service.
### Apache
#### Self-signed certificates
```bash
# Install apache + php-fpm
sudo apt update
sudo apt install apache2 libapache2-mod-md libapache2-mod-fcgid php8.2-fpm php8.2-mbstring php8.2-gd php8.2-intl php8.2-curl php8.2-gettext php8.2-ldap
If you don't want to request a certificate from Let's Encrypt, or are unable to (for example, webserver on a LAN, or domain name not registered in the public DNS system), you can generate a self-signed certificate. This certificate will trigger security warnings in web browsers, unless you add it to the browser's SSL store manually.
# Enable required modules
sudo a2enmod ssl # SSL/TLS certificates https://httpd.apache.org/docs/current/mod/mod_ssl.html
sudo a2enmod rewrite # REST API support https://httpd.apache.org/docs/current/mod/mod_rewrite.html
sudo a2enmod headers # custom HTTP headers
* Apache: run `make-ssl-cert generate-default-snakeoil --force-overwrite`
* Nginx: TODO
--------------------------------------------------------------------------------
## Apache
Here is a basic configuration example for the Apache web server with `mod_php`.
In `/etc/apache2/sites-available/shaarli.conf`:
# Edit the virtualhost configuration file with your favorite editor (replace the example domain name)
sudo nano /etc/apache2/sites-available/shaarli.mydomain.org.conf
```
```apache
<VirtualHost *:80>
ServerName shaarli.mydomain.org
DocumentRoot /var/www/shaarli.mydomain.org/
# If using certbot or self-signed certificates:
# Redirect HTTP requests to HTTPS, except Let's Encrypt ACME challenge requests
RewriteEngine on
RewriteRule ^.well-known/acme-challenge/ - [L]
RewriteCond %{HTTP_HOST} =shaarli.mydomain.org
RewriteRule ^ https://shaarli.mydomain.org%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
# If using mod_md:
MDomain shaarli.mydomain.org
MDCertificateAgreement accepted
MDContactEmail admin@shaarli.mydomain.org
MDPrivateKeys RSA 4096
<VirtualHost *:443>
ServerName shaarli.my-domain.org
DocumentRoot /absolute/path/to/shaarli/
# Logging
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
ErrorLog /var/log/apache2/shaarli-error.log
CustomLog /var/log/apache2/shaarli-access.log combined
# Let's Encrypt SSL configuration (recommended)
ServerName shaarli.mydomain.org
DocumentRoot /var/www/shaarli.mydomain.org/
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
# Self-signed SSL cert configuration
#SSLEngine on
#SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
#SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
# If using certbot:
SSLCertificateFile /etc/letsencrypt/live/shaarli.mydomain.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/shaarli.mydomain.org/privkey.pem
# If using self-signed certificates:
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
# Optional, log PHP errors, useful for debugging
#php_flag log_errors on
@ -98,345 +185,261 @@ In `/etc/apache2/sites-available/shaarli.conf`:
#php_value error_reporting 2147483647
#php_value error_log /var/log/apache2/shaarli-php-error.log
<Directory /absolute/path/to/shaarli/>
#Required for .htaccess support
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
<Directory /var/www/shaarli.mydomain.org/>
# Required for .htaccess support
AllowOverride All
Order allow,deny
Allow from all
Options Indexes FollowSymLinks MultiViews #TODO is Indexes/Multiviews required?
# Optional - required for playvideos plugin
#Header set Content-Security-Policy "script-src 'self' 'unsafe-inline' https://www.youtube.com https://s.ytimg.com 'unsafe-eval'"
Require all granted
</Directory>
<Directory /var/www/shaarli.mydomain.org/doc/html/>
DirectoryIndex index.html
<FilesMatch ".*\.html">
Require all granted
</FilesMatch>
</Directory>
<FilesMatch ".*\.(?!(ico|css|js|gif|jpe?g|png|ttf|oet|woff2?)$)[^\.]*$">
Require all denied
</FilesMatch>
DirectoryIndex index.php
<Files "index.php">
Require all granted
</Files>
<FilesMatch "\.(?:ico|css|js|gif|jpe?g|png|ttf|oet|woff2)$">
# allow client-side caching of static files
Header set Cache-Control "max-age=2628000, public, must-revalidate, proxy-revalidate"
</FilesMatch>
<FilesMatch "robots\.txt">
Require all granted
</FilesMatch>
# serve the Shaarli favicon from its custom location
Alias favicon.ico /var/www/shaarli.mydomain.org/images/favicon.ico
</VirtualHost>
```
Enable this configuration with `sudo a2ensite shaarli`
```bash
# Enable the virtualhost
sudo a2ensite shaarli.mydomain.org
_Note: If you use Apache 2.2 or lower, you need [mod_version](https://httpd.apache.org/docs/current/mod/mod_version.html) to be installed and enabled._
# Restart the apache service
sudo systemctl restart apache2
```
_Note: Apache module `mod_rewrite` must be enabled to use the REST API._
- [How to install the Apache web server](https://www.digitalocean.com/community/tutorials/how-to-install-the-apache-web-server-on-debian-10)
- [Apache/PHP - error log per VirtualHost - StackOverflow](https://stackoverflow.com/questions/176/error-log-per-virtual-host)
- [Apache - PHP: php_value vs php_admin_value and the use of php_flag explained](https://ma.ttias.be/php-php_value-vs-php_admin_value-and-the-use-of-php_flag-explained/)
- [Server-side TLS (Apache) - Mozilla](https://wiki.mozilla.org/Security/Server_Side_TLS)
- [Apache 2.4 documentation](https://httpd.apache.org/docs/2.4/)
- [Apache mod_proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html)
- [Apache Reverse Proxy Request Headers](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#x-headers)
## Nginx
### Nginx
Here is a basic configuration example for the Nginx web server, using the [php-fpm](http://php-fpm.org) PHP FastCGI Process Manager, and Nginx's [FastCGI](https://en.wikipedia.org/wiki/FastCGI) module.
```bash
# Install nginx and php-fpm
sudo apt install nginx php-fpm
<!--- TODO refactor everything below this point --->
### Common setup
Once Nginx and PHP-FPM are installed, we need to ensure:
- Nginx and PHP-FPM are running using the _same user and group_
- both these user and group have
- `read` permissions for Shaarli resources
- `execute` permissions for Shaarli directories _AND_ their parent directories
On a production server:
- `user:group` will likely be `http:http`, `www:www` or `www-data:www-data`
- files will be located under `/var/www`, `/var/http` or `/usr/share/nginx`
On a development server:
- files may be located in a user's home directory
- in this case, make sure both Nginx and PHP-FPM are running as the local user/group!
For all following configuration examples, this user/group pair will be used:
- `user:group = john:users`,
which corresponds to the following service configuration:
```ini
; /etc/php/php-fpm.conf
user = john
group = users
[...]
listen.owner = john
listen.group = users
# Edit the virtualhost configuration file with your favorite editor
sudo nano /etc/nginx/sites-available/shaarli.mydomain.org
```
```nginx
# /etc/nginx/nginx.conf
user john users;
server {
listen 80;
server_name shaarli.mydomain.org;
http {
[...]
}
```
### (Optional) Increase the maximum file upload size
Some bookmark dumps generated by web browsers can be _huge_ due to the presence of Base64-encoded images and favicons, as well as extra verbosity when nesting links in (sub-)folders.
To increase upload size, you will need to modify both nginx and PHP configuration:
```nginx
# /etc/nginx/nginx.conf
http {
[...]
client_max_body_size 10m;
[...]
}
```
```ini
# /etc/php5/fpm/php.ini
[...]
post_max_size = 10M
[...]
upload_max_filesize = 10M
```
### Minimal
_WARNING: Use for development only!_
```nginx
user john users;
worker_processes 1;
events {
worker_connections 1024;
# redirect all plain HTTP requests to HTTPS
return 301 https://shaarli.mydomain.org$request_uri;
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 20;
server {
# ipv4 listening port/protocol
listen 443 ssl http2;
# ipv6 listening port/protocol
listen [::]:443 ssl http2;
server_name shaarli.mydomain.org;
root /var/www/shaarli.mydomain.org;
index index.html index.php;
server {
listen 80;
server_name localhost;
root /home/john/web;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location /shaarli/ {
try_files $uri /shaarli/index.php$is_args$args;
access_log /var/log/nginx/shaarli.access.log;
error_log /var/log/nginx/shaarli.error.log;
}
location ~ (index)\.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
}
}
```
### Modular
The previous setup is sufficient for development purposes, but has several major caveats:
- every content that does not match the PHP rule will be sent to client browsers:
- dotfiles - in our case, `.htaccess`
- temporary files, e.g. Vim or Emacs files: `index.php~`
- asset / static resource caching is not optimized
- if serving several PHP sites, there will be a lot of duplication: `location /shaarli/`, `location /mysite/`, etc.
To solve this, we will split Nginx configuration in several parts, that will be included when needed:
```nginx
# /etc/nginx/deny.conf
location ~ /\. {
# deny access to dotfiles
access_log off;
log_not_found off;
deny all;
}
location ~ ~$ {
# deny access to temp editor files, e.g. "script.php~"
access_log off;
log_not_found off;
deny all;
}
```
```nginx
# /etc/nginx/php.conf
location ~ (index)\.php$ {
# Slim - split URL path into (script_filename, path_info)
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# filter and proxy PHP requests to PHP-FPM
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
location ~ \.php$ {
# deny access to all other PHP scripts
deny all;
}
```
```nginx
# /etc/nginx/static_assets.conf
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
```
```nginx
# /etc/nginx/nginx.conf
[...]
http {
[...]
root /home/john/web;
access_log /var/log/nginx/access.log;
# log file locations
# combined log format prepends the virtualhost/domain name to log entries
access_log /var/log/nginx/access.log combined;
error_log /var/log/nginx/error.log;
server {
# virtual host for a first domain
listen 80;
server_name my.first.domain.org;
# paths to private key and certificates for SSL/TLS
ssl_certificate /etc/ssl/shaarli.mydomain.org.crt;
ssl_certificate_key /etc/ssl/private/shaarli.mydomain.org.key;
location /shaarli/ {
# Slim - rewrite URLs
try_files $uri /shaarli/index.php$is_args$args;
# Let's Encrypt SSL settings from https://github.com/certbot/certbot/blob/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
access_log /var/log/nginx/shaarli.access.log;
error_log /var/log/nginx/shaarli.error.log;
}
# increase the maximum file upload size if needed: by default nginx limits file upload to 1MB (413 Entity Too Large error)
client_max_body_size 100m;
location = /shaarli/favicon.ico {
# serve the Shaarli favicon from its custom location
alias /var/www/shaarli/images/favicon.ico;
}
include deny.conf;
include static_assets.conf;
include php.conf;
# relative path to shaarli from the root of the webserver
# if shaarli is installed in a subdirectory of the main domain, edit the location accordingly
location / {
# default index file when no file URI is requested
index index.php;
try_files _ /index.php$is_args$args;
}
server {
# virtual host for a second domain
listen 80;
server_name second.domain.com;
location ~ (index)\.php$ {
try_files $uri =404;
# slim API - split URL path into (script_filename, path_info)
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# pass PHP requests to PHP-FPM
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
location /minigal/ {
access_log /var/log/nginx/minigal.access.log;
error_log /var/log/nginx/minigal.error.log;
}
location ~ /doc/html/ {
default_type "text/html";
try_files $uri $uri/ $uri.html =404;
}
include deny.conf;
include static_assets.conf;
include php.conf;
location = /favicon.ico {
# serve the Shaarli favicon from its custom location
alias /var/www/shaarli/images/favicon.ico;
}
# allow client-side caching of static files
location ~* \.(?:ico|css|js|gif|jpe?g|png|ttf|oet|woff2?)$ {
expires max;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
# HTTP 1.0 compatibility
add_header Pragma public;
}
}
```
### Redirect HTTP to HTTPS
Assuming you have generated a (self-signed) key and certificate, and they are
located under `/home/john/ssl/localhost.{key,crt}`, it is pretty straightforward
to set an HTTP (:80) to HTTPS (:443) redirection to force SSL/TLS usage.
```bash
# enable the configuration/virtualhost
sudo ln -s /etc/nginx/sites-available/shaarli.mydomain.org /etc/nginx/sites-enabled/shaarli.mydomain.org
# reload nginx configuration
sudo systemctl reload nginx
```
```nginx
# /etc/nginx/nginx.conf
- [How to install the Nginx web server](https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-debian-10)
- [Nginx Beginner's guide](https://nginx.org/en/docs/beginners_guide.html)
- [Nginx documentation](https://nginx.org/en/docs/)
- [Nginx ngx_http_fastcgi_module](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html)
- [Nginx Pitfalls](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/)
- [Server-side TLS (Nginx) - Mozilla](https://wiki.mozilla.org/Security/Server_Side_TLS)
## Reverse proxies
If Shaarli is hosted on a server behind a [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy) (i.e. there is a proxy server between clients and the web server hosting Shaarli), configure it accordingly. See [Reverse proxy](Reverse-proxy.md) configuration.
## Using Shaarli without URL rewriting
By default, Shaarli uses Slim framework's URL, which requires URL rewriting.
If you can't use URL rewriting for any reason (not supported by your web server, shared hosting, etc.), you *can* use Shaarli without URL rewriting.
You just need to prefix your URL by `/index.php/`. Example: instead of accessing `https://shaarli.mydomain.org/`, use `https://shaarli.mydomain.org/index.php/`.
**Recommended:**
* after installation, in the configuration page, set your header link to `/index.php/`.
* in your configuration file `config.json.php` set `general.root_url` to `https://shaarli.mydomain.org/index.php/`.
## Allow import of large browser bookmarks export
Web browser bookmark exports can be large due to the presence of base64-encoded images and favicons/long subfolder names. Edit the PHP configuration file.
- Apache: `/etc/php/<PHP_VERSION>/apache2/php.ini`
- Nginx + PHP-FPM: `/etc/php/<PHP_VERSION>/fpm/php.ini` (in addition to `client_max_body_size` in the [Nginx configuration](#nginx))
```ini
[...]
http {
[...]
index index.html index.php;
root /home/john/web;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
server {
listen 80;
server_name localhost;
return 301 https://localhost$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /home/john/ssl/localhost.crt;
ssl_certificate_key /home/john/ssl/localhost.key;
location /shaarli/ {
# Slim - rewrite URLs
try_files $uri /index.php$is_args$args;
access_log /var/log/nginx/shaarli.access.log;
error_log /var/log/nginx/shaarli.error.log;
}
location = /shaarli/favicon.ico {
# serve the Shaarli favicon from its custom location
alias /var/www/shaarli/images/favicon.ico;
}
include deny.conf;
include static_assets.conf;
include php.conf;
}
}
# (optional) increase the maximum file upload size:
post_max_size = 100M
[...]
# (optional) increase the maximum file upload size:
upload_max_filesize = 100M
```
## Proxies
To verify PHP settings currently set on the server, create a `phpinfo.php` in your webserver's document root
If Shaarli is served behind a proxy (i.e. there is a proxy server between clients and the web server hosting Shaarli), please refer to the proxy server documentation for proper configuration. In particular, you have to ensure that the following server variables are properly set:
```bash
# example
echo '<?php phpinfo(); ?>' | sudo tee /var/www/shaarli.mydomain.org/phpinfo.php
#give read-only access to this file to the webserver user
sudo chown www-data:root /var/www/shaarli.mydomain.org/phpinfo.php
sudo chmod 0400 /var/www/shaarli.mydomain.org/phpinfo.php
```
- `X-Forwarded-Proto`
- `X-Forwarded-Host`
- `X-Forwarded-For`
Access the file from a web browser (eg. <https://shaarli.mydomain.org/phpinfo.php> and look at the _Loaded Configuration File_ and _Scan this dir for additional .ini files_ entries
In you [Shaarli configuration](Shaarli-configuration) `data/config.json.php`, add the public IP of your proxy under `security.trusted_proxies`.
It is recommended to remove the `phpinfo.php` when no longer needed as it publicly discloses details about your webserver configuration.
See also [proxy-related](https://github.com/shaarli/Shaarli/issues?utf8=%E2%9C%93&q=label%3Aproxy+) issues.
## Robots and crawlers
Shaarli disallows indexing and crawling of your local documentation pages by search engines, using `<meta name="robots">` HTML tags.
Your Shaarli instance and other pages you host may still be indexed by various robots on the public Internet.
You may want to setup a robots.txt file or other crawler control mechanism on your server.
See [[1]](https://en.wikipedia.org/wiki/Robots_exclusion_standard), [[2]](https://support.google.com/webmasters/answer/6062608?hl=en) and [[3]](https://developers.google.com/search/reference/robots_meta_tag)
To opt-out of indexing your Shaarli instance by search engines, create a `robots.txt` file at the root of your virtualhost:
## See also
```
User-agent: *
Disallow: /
```
* [Server security](Server-security.md)
By default Shaarli already disallows indexing of your local copy of the documentation by default, using `<meta name="robots">` HTML tags. Your Shaarli instance may still be indexed by various robots on the public Internet, that do not respect this header or the robots standard.
#### Webservers
- [Robots exclusion standard](https://en.wikipedia.org/wiki/Robots_exclusion_standard)
- [Introduction to robots.txt](https://developers.google.com/search/docs/crawling-indexing/robots/intro?hl=en)
- [Robots meta tag, data-nosnippet, and X-Robots-Tag specifications](https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag)
- [About robots.txt](https://www.robotstxt.org)
- [About the robots META tag](https://www.robotstxt.org/meta.html)
- [Apache/PHP - error log per VirtualHost](http://stackoverflow.com/q/176) (StackOverflow)
- [Apache - PHP: php_value vs php_admin_value and the use of php_flag explained](https://ma.ttias.be/php-php_value-vs-php_admin_value-and-the-use-of-php_flag-explained/)
- [Server-side TLS (Apache)](https://wiki.mozilla.org/Security/Server_Side_TLS#Apache) (Mozilla)
- [Nginx Beginner's guide](http://nginx.org/en/docs/beginners_guide.html)
- [Nginx ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html)
- [Nginx Pitfalls](http://wiki.nginx.org/Pitfalls)
- [Nginx PHP configuration examples](http://kbeezie.com/nginx-configuration-examples/) (Karl Blessing)
- [Server-side TLS (Nginx)](https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx) (Mozilla)
- [How to Create Self-Signed SSL Certificates with OpenSSL](http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php)
- [How do I create my own Certificate Authority?](https://workaround.org/certificate-authority)
#### PHP
## Fail2ban
- [Travis configuration](https://github.com/shaarli/Shaarli/blob/master/.travis.yml)
- [PHP: Supported versions](http://php.net/supported-versions.php)
- [PHP: Unsupported versions](http://php.net/eol.php) _(EOL - End Of Life)_
- [PHP 7 Changelog](http://php.net/ChangeLog-7.php)
- [PHP 5 Changelog](http://php.net/ChangeLog-5.php)
- [PHP: Bugs](https://bugs.php.net/)
[fail2ban](https://github.com/fail2ban/fail2ban) is an intrusion prevention framework that reads server (Apache, SSH, etc.) and uses `iptables` profiles to block brute-force attempts. You need to create a filter to detect shaarli login failures in logs, and a jail configuation to configure the behavior when failed login attempts are detected:
```ini
# /etc/fail2ban/filter.d/shaarli-auth.conf
[INCLUDES]
before = common.conf
[Definition]
failregex = \s-\s<HOST>\s-\sLogin failed for user.*$
ignoreregex =
```
```ini
# /etc/fail2ban/jail.local
[shaarli-auth]
enabled = true
port = https,http
filter = shaarli-auth
logpath = /var/www/shaarli.mydomain.org/data/log.txt
# allow 3 login attempts per IP address
# (over a period specified by findtime = in /etc/fail2ban/jail.conf)
maxretry = 3
# permanently ban the IP address after reaching the limit
bantime = -1
```
Then restart the service: `sudo systemctl restart fail2ban`
## What next?
[Shaarli installation](Installation.md)

View file

@ -1,76 +0,0 @@
## php.ini
PHP settings are defined in:
- a main configuration file, usually found under `/etc/php5/php.ini`; some distributions provide different configuration environments, e.g.
- `/etc/php5/php.ini` - used when running console scripts
- `/etc/php5/apache2/php.ini` - used when a client requests PHP resources from Apache
- `/etc/php5/php-fpm.conf` - used when PHP requests are proxied to PHP-FPM
- additional configuration files/entries, depending on the installed/enabled extensions:
- `/etc/php/conf.d/xdebug.ini`
### Locate .ini files
#### Console environment
```bash
$ php --ini
Configuration File (php.ini) Path: /etc/php
Loaded Configuration File: /etc/php/php.ini
Scan for additional .ini files in: /etc/php/conf.d
Additional .ini files parsed: /etc/php/conf.d/xdebug.ini
```
#### Server environment
- create a `phpinfo.php` script located in a path supported by the web server, e.g.
- Apache (with user dirs enabled): `/home/myself/public_html/phpinfo.php`
- `/var/www/test/phpinfo.php`
- make sure the script is readable by the web server user/group (usually, `www`, `www-data` or `httpd`)
- access the script from a web browser
- look at the _Loaded Configuration File_ and _Scan this dir for additional .ini files_ entries
```php
<?php phpinfo(); ?>
```
## fail2ban
`fail2ban` is an intrusion prevention framework that reads server (Apache, SSH, etc.) and uses `iptables` profiles to block brute-force attempts:
- [Official website](http://www.fail2ban.org/wiki/index.php/Main_Page)
- [Source code](https://github.com/fail2ban/fail2ban)
### Read Shaarli logs to ban IPs
Example configuration:
- allow 3 login attempts per IP address
- after 3 failures, permanently ban the corresponding IP adddress
`/etc/fail2ban/jail.local`
```ini
[shaarli-auth]
enabled = true
port = https,http
filter = shaarli-auth
logpath = /var/www/path/to/shaarli/data/log.txt
maxretry = 3
bantime = -1
```
`/etc/fail2ban/filter.d/shaarli-auth.conf`
```ini
[INCLUDES]
before = common.conf
[Definition]
failregex = \s-\s<HOST>\s-\sLogin failed for user.*$
ignoreregex =
```
## Robots - Restricting search engines and web crawler traffic
Creating a `robots.txt` with the following contents at the root of your Shaarli installation will prevent _honest_ web crawlers from indexing each and every link and Daily page from a Shaarli instance, thus getting rid of a certain amount of unsollicited network traffic.
```
User-agent: *
Disallow: /
```
See:
- http://www.robotstxt.org
- http://www.robotstxt.org/robotstxt.html
- http://www.robotstxt.org/meta.html

View file

@ -1,130 +1,28 @@
## Foreword
**Do not edit configuration options in index.php! Your changes would be lost.**
# Shaarli configuration
Once your Shaarli instance is installed, the file `data/config.json.php` is generated:
* it contains all settings in JSON format, and can be edited to customize values
* it defines which [plugins](Plugin-System) are enabled
* its values override those defined in `index.php`
* it is wrap in a PHP comment to prevent anyone accessing it, regardless of server configuration
## File and directory permissions
- it contains all settings in JSON format, and can be edited to customize values
- it defines which [plugins](Plugins.md) are enabled
- its values override those defined in `index.php`
- it is wrapped in a PHP comment so that its contents are never served by the web server, regardless of configuration
The server process running Shaarli must have:
**Do not edit configuration options in index.php! Your changes would be lost.**
- `read` access to the following resources:
- PHP scripts: `index.php`, `application/*.php`, `plugins/*.php`
- 3rd party PHP and Javascript libraries: `inc/*.php`, `inc/*.js`
- static assets:
- CSS stylesheets: `inc/*.css`
- `images/*`
- RainTPL templates: `tpl/*.html`
- `read`, `write` and `execution` access to the following directories:
- `cache` - thumbnail cache
- `data` - link data store, configuration options
- `pagecache` - Atom/RSS feed cache
- `tmp` - RainTPL page cache
## Tools menu
On a Linux distribution:
Some settings can be configured directly from a web browser by accesing the `Tools` menu. Values are read/written to/from the configuration file.
- the web server user will likely be `www` or `http` (for Apache2)
- it will be a member of a group of the same name: `www:www`, `http:http`
- to give it access to Shaarli, either:
- unzip Shaarli in the default web server location (usually `/var/www/`) and set the web server user as the owner
- put users in the same group as the web server, and set the appropriate access rights
- if you have a domain / subdomain to serve Shaarli, [configure the server](Server-configuration) accordingly
![](https://i.imgur.com/boaaibC.png)
## Configuration
### LDAP
In `data/config.json.php`.
See also [Plugin System](Plugin-System).
### Credentials
_These settings should not be edited_
- **login**: Login username.
- **hash**: Generated password hash.
- **salt**: Password salt.
### General
- **title**: Shaarli's instance title.
- **header_link**: Link to the homepage.
- **links_per_page**: Number of shaares displayed per page.
- **timezone**: See [the list of supported timezones](http://php.net/manual/en/timezones.php).
- **enabled_plugins**: List of enabled plugins.
- **default_note_title**: Default title of a new note.
- **retrieve_description** (boolean): If set to true, for every new links Shaarli will try
to retrieve the description and keywords from the HTML meta tags.
### Security
- **session_protection_disabled**: Disable session cookie hijacking protection (not recommended).
It might be useful if your IP adress often changes.
- **ban_after**: Failed login attempts before being IP banned.
- **ban_duration**: IP ban duration in seconds.
- **open_shaarli**: Anyone can add a new link while logged out if enabled.
- **trusted_proxies**: List of trusted IP which won't be banned after failed login attemps. Useful if Shaarli is behind a reverse proxy.
- **allowed_protocols**: List of allowed protocols in shaare URLs or markdown-rendered descriptions. Useful if you want to store `javascript:` links (bookmarklets) in Shaarli (default: `["ftp", "ftps", "magnet"]`).
### Resources
- **data_dir**: Data directory.
- **datastore**: Shaarli's links database file path.
- **history**: Shaarli's operation history file path.
- **updates**: File path for the ran updates file.
- **log**: Log file path.
- **update_check**: Last update check file path.
- **raintpl_tpl**: Templates directory.
- **raintpl_tmp**: Template engine cache directory.
- **thumbnails_cache**: Thumbnails cache directory.
- **page_cache**: Shaarli's internal cache directory.
- **ban_file**: Banned IP file path.
### Translation
- **language**: translation language (also see [Translations](Translations))
- **auto** (default): The translation language is chosen from the browser locale.
It means that the language can be different for 2 different visitors depending on their locale.
- **en**: Use the English translation.
- **fr**: Use the French translation.
- **mode**:
- **auto** or **php** (default): Use the PHP implementation of gettext (slower)
- **gettext**: Use PHP builtin gettext extension
(faster, but requires `php-gettext` to be installed and to reload the web server on update)
- **extension**: Translation extensions for custom themes or plugins.
Must be an associative array: `translation domain => translation path`.
### Updates
- **check_updates**: Enable or disable update check to the git repository.
- **check_updates_branch**: Git branch used to check updates (e.g. `stable` or `master`).
- **check_updates_interval**: Look for new version every N seconds (default: every day).
### Privacy
- **default_private_links**: Check the private checkbox by default for every new link.
- **hide_public_links**: All links are hidden while logged out.
- **force_login**: if **hide_public_links** and this are set to `true`, all anonymous users are redirected to the login page.
- **hide_timestamps**: Timestamps are hidden.
- **remember_user_default**: Default state of the login page's *remember me* checkbox
- `true`: checked by default, `false`: unchecked by default
### Feed
- **rss_permalinks**: Enable this to redirect RSS links to Shaarli's permalinks instead of shaared URL.
- **show_atom**: Display ATOM feed button.
### Thumbnail
- **enable_thumbnails**: Enable or disable thumbnail display.
- **enable_localcache**: Enable or disable local cache.
- **host**: LDAP host used for user authentication
- **dn**: user DN template (`sprintf` format, `%s` being replaced by user login)
## Configuration file example
```json
```
<?php /*
{
"credentials": {
@ -164,10 +62,10 @@ Must be an associative array: `translation domain => translation path`.
"rss_permalinks": true,
"links_per_page": 20,
"default_private_links": true,
"enable_thumbnails": true,
"enable_localcache": true,
"check_updates_branch": "stable",
"check_updates_interval": 86400,
"download_max_size": 4194304,
"download_timeout": 30,
"enabled_plugins": [
"markdown",
"wallabag",
@ -176,23 +74,18 @@ Must be an associative array: `translation domain => translation path`.
"timezone": "Europe\/Paris",
"title": "My Shaarli",
"header_link": "?"
"tags_separator": " "
},
"dev": {
"debug": false,
}
"extras": {
"show_atom": false,
"hide_public_links": false,
"hide_timestamps": false,
"open_shaarli": false,
},
"general": {
"header_link": "?",
"links_per_page": 20,
"enabled_plugins": [
"markdown",
"wallabag"
],
"timezone": "Europe\/Paris",
"title": "My Shaarli"
},
"formatter": "markdown",
"updates": {
"check_updates": true,
"check_updates_branch": "stable",
@ -209,12 +102,13 @@ Must be an associative array: `translation domain => translation path`.
"hide_timestamps": false,
"remember_user_default": true
},
"thumbnail": {
"enable_thumbnails": true,
"enable_localcache": true
"thumbnails": {
"width": 125,
"height": 90,
"mode": "common"
},
"plugins": {
"WALLABAG_URL": "http://demo.wallabag.org",
"WALLABAG_URL": "https://demo.wallabag.org",
"WALLABAG_VERSION": "1"
},
"translation": {
@ -223,13 +117,119 @@ Must be an associative array: `translation domain => translation path`.
"extensions": {
"demo": "plugins/demo_plugin/languages/"
}
},
"ldap": {
"host": "ldap://localhost",
"dn": "uid=%s,ou=people,dc=example,dc=org"
}
} ?>
```
## Additional configuration
## Settings
The `playvideos` plugin may require that you adapt your server's
[Content Security Policy](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md#troubleshooting)
configuration to work properly.
### Credentials
_These settings should not be edited_
- **login**: Login username.
- **hash**: Generated password hash.
- **salt**: Password salt.
### General
- **title**: Shaarli's instance title.
- **header_link**: Link to the homepage.
- **links_per_page**: Number of Shaares displayed per page.
- **timezone**: See [the list of supported timezones](https://www.php.net/manual/en/timezones.php).
- **enabled_plugins**: List of enabled plugins.
- **default_note_title**: Default title of a new note.
- **download_max_size:**: Maximum number of bytes to download when retrieveing page content/metadata.
- **download_timeout:**: Network timeout (in seconds) when retrieveing page content/metadata.
- **enable_async_metadata** (boolean): Retrieve external bookmark metadata asynchronously to prevent bookmark creation slowdown.
- **retrieve_description** (boolean): If set to true, for every new Shaare Shaarli will try to retrieve the description and keywords from the HTML meta tags.
- **root_url**: Overrides automatic discovery of Shaarli instance's URL (e.g.) `https://sub.domain.tld/shaarli-folder/`.
- **tags_separator**: Defines your tags separator (default: whitespace).
### Security
- **session_protection_disabled**: Disable session cookie hijacking protection (not recommended).
It might be useful if your IP adress often changes.
- **ban_after**: Failed login attempts before being IP banned.
- **ban_duration**: IP ban duration in seconds.
- **open_shaarli**: Anyone can add a new Shaare while logged out if enabled.
- **trusted_proxies**: List of trusted IP which won't be banned after failed login attemps. Useful if Shaarli is behind a reverse proxy.
- **allowed_protocols**: List of allowed protocols in shaare URLs or markdown-rendered descriptions. Useful if you want to store `javascript:` links (bookmarklets) or `file:///` URIs in Shaarli (default: `["ftp", "ftps", "magnet"]`).
### Formatter
Single string value. Default available:
- `default`: supports line breaks, URL and hashtag auto-links.
- `markdown`: supports [Markdown](https://daringfireball.net/projects/markdown/syntax).
- `markdownExtra`: adds [extra](https://michelf.ca/projects/php-markdown/extra/) flavor to Markdown.
### Formatter Settings
Additional settings applied to formatters.
#### default
- **autolink**: boolean to enable or disable automatic linkification of URL and hashtags.
### Resources
- **data_dir**: Data directory.
- **datastore**: Shaarli's Shaares database file path.
- **history**: Shaarli's operation history file path.
- **updates**: File path for the ran updates file.
- **log**: Log file path.
- **update_check**: Last update check file path.
- **raintpl_tpl**: Templates directory.
- **raintpl_tmp**: Template engine cache directory.
- **thumbnails_cache**: Thumbnails cache directory.
- **page_cache**: Shaarli's internal cache directory.
- **ban_file**: Banned IP file path.
### Translation
- **language**: translation language (also see [Translations](dev/Development.md#translations))
- **auto** (default): The translation language is chosen from the browser locale.
It means that the language can be different for 2 different visitors depending on their locale.
- **en**: Use the English translation.
- **fr**: Use the French translation.
- **mode**:
- **auto** or **php** (default): Use the PHP implementation of gettext (slower)
- **gettext**: Use PHP builtin gettext extension
(faster, but requires `php-gettext` to be installed and to reload the web server on update)
- **extension**: Translation extensions for custom themes or plugins.
Must be an associative array: `translation domain => translation path`.
### Updates
- **check_updates**: Enable or disable update check to the git repository.
- **check_updates_branch**: Git branch used to check updates (e.g. `stable` or `master`).
- **check_updates_interval**: Look for new version every N seconds (default: every day).
### Privacy
- **default_private_links**: Check the private checkbox by default for every new Shaare.
- **hide_public_links**: All Shaares are hidden while logged out.
- **force_login**: if **hide_public_links** and this are set to `true`, all anonymous users are redirected to the login page.
- **hide_timestamps**: Timestamps are hidden.
- **remember_user_default**: Default state of the login page's *remember me* checkbox
- `true`: checked by default, `false`: unchecked by default
### Feed
- **rss_permalinks**: Enable this to redirect RSS links to Shaarli's permalinks instead of shaared URL.
- **show_atom**: Display ATOM feed button.
### Thumbnails
- **width:** width of generated thumbnails, in pixels
- **height:** height of generated thumbnails, in pixels
- **mode:** enable thumbnails for `all` shaares, or `common` media hosts, or `none`.
## Plugins configuration
See [Plugins](Plugins.md)

View file

@ -1,71 +0,0 @@
Content posted to Shaarli is separated in items called _Shaares_. For each Shaare,
you can customize the following aspects:
* URL to link to
* Title
* Free-text description
* Tags
* Public/private status
--------------------------------------------------------------------------------
## Adding new Shaares
While logged in to your Shaarli, you can add new Shaares in several ways:
* [+Shaare button](#shaare-button)
* [Bookmarklet](#bookmarklet)
* Third-party [apps and browser addons](Community-&-Related-software.md#mobile-apps)
* [REST API](https://shaarli.github.io/api-documentation/)
### +Shaare button
* While logged in to your Shaarli, click the **`+Shaare`** button located in the toolbar.
* Enter the URL of a link you want to share.
* Click `Add link`
* The `New Shaare` dialog appears, allowing you to fill in the details of your Shaare.
* The Description, Title, and Tags will help you find your Shaare later using tags or full-text search.
* You can also check the “Private” box so that the link is saved but only visible to you (the logged-in user).
* Click `Save`.
<!-- TODO Add screenshot of add/edit link dialog -->
### Bookmarklet
The _Bookmarklet_ \[[1](https://en.wikipedia.org/wiki/Bookmarklet)\] is a special
browser bookmark you can use to add new content to your Shaarli. This bookmarklet is
compatible with Firefox, Opera, Chrome and Safari. To set it up:
* Access the `Tools` page from the button in the toolbar.
* Drag the **`✚Shaare link` button** to your browser's bookmarks bar.
Once this is done, you can shaare any URL you are visiting simply by clicking the
bookmarklet in your browser! The same `New Shaare` dialog as above is displayed.
| Note | Websites which enforce Content Security Policy (CSP), such as github.com, disallow usage of bookmarklets. Unfortunately, there is nothing Shaarli can do about it. \[[1](https://github.com/shaarli/Shaarli/issues/196)]\ \[[2](https://bugzilla.mozilla.org/show_bug.cgi?id=866522)]\ \[[3](https://code.google.com/p/chromium/issues/detail?id=233903)]\ |
|---------|---------|
| Note | Under Opera, you can't drag'n drop the button: You have to right-click on it and add a bookmark to your personal toolbar. |
|---------|---------|
![](images/bookmarklet.png)
--------------------------------------------------------------------------------
## Editing Shaares
Any Shaare can edited by clicking its ![](images/edit_icon.png) `Edit` button.
Editing a Shaare will not change it's permalink, each permalink always points to the
latest revision of a Shaare.
--------------------------------------------------------------------------------
## Using shaarli as a blog, notepad, pastebin...
While adding or editing a link, leave the URL field blank to create a text-only
("note") post. This allows you to post any kind of text content, such as blog
articles, private or public notes, snippets... There is no character limit! You can
access your Shaare from its permalink.

View file

@ -1,13 +0,0 @@
## WIP
This topic is currently being discussed here:
- [Fix coding style (static analysis)](https://github.com/shaarli/Shaarli/issues/95) (#95)
- [Continuous Integration tools & features](https://github.com/shaarli/Shaarli/issues/130) (#130)
### Usage
Static analysis tools can be installed with Composer, and used through Shaarli's [Makefile](https://github.com/shaarli/Shaarli/blob/master/Makefile).
For an overview of the available features, see:
- [Code quality: Makefile to run static code checkers](https://github.com/shaarli/Shaarli/pull/124) (#124)
- [Run PHPCS against different coding standards](https://github.com/shaarli/Shaarli/pull/276) (#276)

View file

@ -1,85 +0,0 @@
## Foreword
There are two ways of customizing how Shaarli looks:
1. by using a custom CSS to override Shaarli's CSS
2. by using a full theme that provides its own RainTPL templates, CSS and Javascript resources
## Custom CSS
Shaarli's appearance can be modified by adding CSS rules to:
- Shaarli < `v0.9.0`: `inc/user.css`
- Shaarli >= `v0.9.0`: `data/user.css`
This file allows overriding rules defined in the template CSS files (only add changed rules), or define a whole new theme.
**Note**: Do not edit `tpl/default/css/shaarli.css`! Your changes would be overridden when updating Shaarli.
See also [Download CSS styles from an OPML list](Download CSS styles from an OPML list)
## Themes
Installation:
- find a theme you'd like to install
- copy or clone the theme folder under `tpl/<a_sweet_theme>`
- enable the theme:
- Shaarli < `v0.9.0`: edit `data/config.json.php` and set the value of `raintpl_tpl` to the new theme name:
`"raintpl_tpl": "tpl\/my-template\/"`
- Shaarli >= `v0.9.0`: select the theme through the _Tools_ page
## Community CSS & themes
### Custom CSS
- [mrjovanovic/serious-theme-shaarli](https://github.com/mrjovanovic/serious-theme-shaarli) - A serious theme for Shaarli
- [shaarli/shaarli-themes](https://github.com/shaarli/shaarli-themes)
### Themes
- [AkibaTech/Shaarli Superhero Theme](https://github.com/AkibaTech/Shaarli---SuperHero-Theme) - A template/theme for Shaarli
- [alexisju/albinomouse-template](https://github.com/alexisju/albinomouse-template) - A full template for Shaarli
- [ArthurHoaro/shaarli-launch](https://github.com/ArthurHoaro/shaarli-launch) - Customizable Shaarli theme
- [dhoko/ShaarliTemplate](https://github.com/dhoko/ShaarliTemplate) - A template/theme for Shaarli
- [kalvn/shaarli-blocks](https://github.com/kalvn/shaarli-blocks) - A template/theme for Shaarli
- [kalvn/Shaarli-Material](https://github.com/kalvn/Shaarli-Material) - A theme (template) based on Google's Material Design for Shaarli, the superfast delicious clone
- [ManufacturaInd/shaarli-2004licious-theme](https://github.com/ManufacturaInd/shaarli-2004licious-theme) - A template/theme as a humble homage to the early looks of the del.icio.us site
### Shaarli forks
- [misterair/Limonade](https://github.com/misterair/limonade) - A fork of (legacy) Shaarli with a new template
- [vivienhaese/shaarlitheme](https://github.com/vivienhaese/shaarlitheme) - A Shaarli fork meant to be run in an openshift instance
## Example installation: AlbinoMouse theme
With the following configuration:
- Apache 2 / PHP 5.6
- user sites are enabled, e.g. `/home/user/public_html/somedir` is served as `http://localhost/~user/somedir`
- `http` is the name of the Apache user
```bash
$ cd ~/public_html
# clone repositories
$ git clone https://github.com/shaarli/Shaarli.git shaarli
$ pushd shaarli/tpl
$ git clone https://github.com/alexisju/albinomouse-template.git
$ popd
# set access rights for Apache
$ chgrp -R http shaarli
$ chmod g+rwx shaarli shaarli/cache shaarli/data shaarli/pagecache shaarli/tmp
```
Get config written:
- go to the freshly installed site
- fill the install form
- log in to Shaarli
Edit Shaarli's [configuration](Shaarli-configuration):
```bash
# the file should be owned by Apache, thus not writeable => sudo
$ sudo sed -i s=tpl=tpl/albinomouse-template=g shaarli/data/config.php
```

View file

@ -1,164 +0,0 @@
## Translations
Shaarli supports [gettext](https://www.gnu.org/software/gettext/manual/gettext.html) translations
since `>= v0.9.2`.
Note that only the `default` theme supports translations.
### Contributing
We encourage the community to contribute to Shaarli's translation either by improving existing
translations or submitting a new language.
Contributing to the translation does not require development skill.
Please submit a pull request with the `.po` file updated/created. Note that the compiled file (`.mo`)
is not stored on the repository, and is generated during the release process.
### How to
First, install [Poedit](https://poedit.net/) tool.
Poedit will extract strings to translate from the PHP source code.
**Important**: due to the usage of a template engine, it's important to generate PHP cache files to extract
every translatable string.
You can either use [this script](https://gist.github.com/ArthurHoaro/5d0323f758ab2401ef444a53f54e9a07) (recommended)
or visit every template page in your browser to generate cache files, while logged in.
Here is a list :
```
http://<replace_domain>/
http://<replace_domain>/?nonope
http://<replace_domain>/?do=addlink
http://<replace_domain>/?do=changepasswd
http://<replace_domain>/?do=changetag
http://<replace_domain>/?do=configure
http://<replace_domain>/?do=tools
http://<replace_domain>/?do=daily
http://<replace_domain>/?post
http://<replace_domain>/?do=export
http://<replace_domain>/?do=import
http://<replace_domain>/?do=login
http://<replace_domain>/?do=picwall
http://<replace_domain>/?do=pluginadmin
http://<replace_domain>/?do=tagcloud
http://<replace_domain>/?do=taglist
```
#### Improve existing translation
In Poedit, click on "Edit a Translation", and from Shaarli's directory open
`inc/languages/<lang>/LC_MESSAGES/shaarli.po`.
The existing list of translatable strings should have been loaded, then click on the "Update" button.
You can start editing the translation.
![poedit-screenshot](images/poedit-1.jpg)
Save when you're done, then you can submit a pull request containing the updated `shaarli.po`.
#### Add a new language
Open Poedit and select "Create New Translation", then from Shaarli's directory open
`inc/languages/<lang>/LC_MESSAGES/shaarli.po`.
Then select the language you want to create.
Click on `File > Save as...`, and save your file in `<shaarli directory>/inc/language/<new language>/LC_MESSAGES/shaarli.po`.
`<new language>` here should be the language code respecting the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-2)
format in lowercase (e.g. `de` for German).
Then click on the "Update" button, and you can start to translate every available string.
Save when you're done, then you can submit a pull request containing the new `shaarli.po`.
### Theme translations
Theme translation extensions are loaded automatically if they're present.
As a theme developer, all you have to do is to add the `.po` and `.mo` compiled file like this:
tpl/<theme name>/language/<lang>/LC_MESSAGES/<theme name>.po
tpl/<theme name>/language/<lang>/LC_MESSAGES/<theme name>.mo
Where `<lang>` is the ISO 3166-1 alpha-2 language code.
Read the following section "Extend Shaarli's translation" to learn how to generate those files.
### Extend Shaarli's translation
If you're writing a custom theme, or a non official plugin, you might want to use the translation system,
but you won't be able to able to override Shaarli's translation.
However, you can add your own translation domain which extends the main translation list.
> Note that you can find a live example of translation extension in the `demo_plugin`.
First, create your translation files tree directory:
```
<your_module>/languages/<ISO 3166-1 alpha-2 language code>/LC_MESSAGES/
```
Your `.po` files must be named like your domain. E.g. if your translation domain is `my_theme`, then your file will be
`my_theme.po`.
Users have to register your extension in their configuration with the parameter
`translation.extensions.<domain>: <translation files path>`.
Example:
```php
if (! $conf->exists('translation.extensions.my_theme')) {
$conf->set('translation.extensions.my_theme', '<your_module>/languages/');
$conf->write(true);
}
```
> Note that the page needs to be reloaded after the registration.
It is then recommended to create a custom translation function which will call the `t()` function with your domain.
For example :
```php
function my_theme_t($text, $nText = '', $nb = 1)
{
return t($text, $nText, $nb, 'my_theme'); // the last parameter is your translation domain.
}
```
All strings which can be translated should be processed through your function:
```php
my_theme_t('Comment');
my_theme_t('Comment', 'Comments', 2);
```
Or in templates:
```php
{'Comment'|my_theme_t}
{function="my_theme_t('Comment', 'Comments', 2)"}
```
> Note than in template, you need to visit your page at least once to generate a cache file.
When you're done, open Poedit and load translation strings from sources:
1. `File > New`
2. Choose your language
3. Save your `PO` file in `<your_module>/languages/<language code>/LC_MESSAGES/my_theme.po`.
4. Go to `Catalog > Properties...`
5. Fill the `Translation Properties` tab
6. Add your source path in the `Sources Paths` tab
7. In the `Sources Keywords` tab uncheck "Also use default keywords" and add the following lines:
```
my_theme_t
my_theme_t:1,2
```
Click on the "Update" button and you're free to start your translations!

View file

@ -1,63 +1,7 @@
# Troubleshooting
## Browser
First of all, ensure that both the [web server](Server-configuration.md) and [Shaarli](Shaarli-configuration.md) are correctly configured.
### Redirection issues (HTTP Referer)
Depending on its configuration and installed plugins, the browser may remove or alter (spoof) HTTP referers, thus preventing Shaarli from properly redirecting between pages.
See:
- [HTTP referer](https://en.wikipedia.org/wiki/HTTP_referer) (Wikipedia)
- [Improve online privacy by controlling referrer information](http://www.ghacks.net/2015/01/22/improve-online-privacy-by-controlling-referrer-information/)
- [Better security, privacy and anonymity in Firefox](http://b.agilob.net/better-security-privacy-and-anonymity-in-firefox/)
### Firefox HTTP Referer options
HTTP settings are available by browsing `about:config`, here are the available settings and their values.
`network.http.sendRefererHeader` - determines when to send the Referer HTTP header
- `0`: Never send the referring URL
- not recommended, may break some sites
- `1`: Send only on clicked links
- `2` (default): Send for links and images
`network.http.referer.XOriginPolicy` - Cross-domain origin policy
- `0` (default): Always send
- `1`: Send if base domains match
- `2`: Send if hosts match
`network.http.referer.spoofSource` - Referer spoofing (~faking)
- `false` (default): real referer
- `true`: spoof referer (use target URI as referer)
- known to break some functionality in Shaarli
`network.http.referer.trimmingPolicy` - trim the URI not to send a full Referer
- `0`: (default): send full URI
- `1`: scheme+host+port+path
- `2`: scheme+host+port
### Firefox, localhost and redirections
`localhost` is not a proper Fully Qualified Domain Name (FQDN); if Firefox has
been set up to spoof referers, or only accept requests from the same base domain/host,
Shaarli redirections will not work properly.
To solve this, assign a local domain to your host, e.g.
```
127.0.0.1 localhost desktop localhost.lan
::1 localhost desktop localhost.lan
```
and browse Shaarli at http://localhost.lan/.
Related threads:
- [What is localhost.localdomain for?](https://bbs.archlinux.org/viewtopic.php?id=156064)
- [Stop returning to the first page after editing a bookmark from another page](https://github.com/shaarli/Shaarli/issues/311)
## Login
@ -67,31 +11,48 @@ Delete the file `data/config.json.php` and display the page again. You will be a
### I'm locked out - Login bruteforce protection
Login form is protected against brute force attacks: 4 failed logins will ban the IP address from login for 30 minutes. Banned IPs can still browse links.
Login form is protected against brute force attacks: 4 failed logins will ban the IP address from login for 30 minutes. Banned IPs can still browse Shaares.
To remove the current IP bans, delete the file `data/ipbans.php`
- To remove the current IP bans, delete the file `data/ipbans.php`
- To list all login attempts, see `data/log.txt` (succesful/failed logins, bans/lifted bans)
### List of all login attempts
--------------------------------------
The file `data/log.txt` shows all logins (successful or failed) and bans/lifted bans.
Search for `failed` in this file to look for unauthorized login attempts.
## Browser issues
### Redirection issues (HTTP Referer)
Shaarli relies on `HTTP_REFERER` for some functions (like redirects and clicking on tags). If you have disabled or altered/spoofed [HTTP referers](https://en.wikipedia.org/wiki/HTTP_referer) in your browser, some features of Shaarli may not work as expected (depending on configuration and installed plugins), notably redirections between pages.
Firefox Referer settings are available by browsing `about:config` and are documented [here](https://wiki.mozilla.org/Security/Referrer). `network.http.referer.spoofSource = true` in particular is known to break some functionality in Shaarli.
### Firefox, localhost and redirections
`localhost` is not a proper Fully Qualified Domain Name (FQDN); if Firefox has been set up to spoof referers, or only accept requests from the same base domain/host,
Shaarli redirections will not work properly. To solve this, assign a local domain to your host, e.g. `localhost.lan` in your [hosts file](https://en.wikipedia.org/wiki/Hosts_(file)) and browse Shaarli at http://localhost.lan/.
-----------------------------------------
## Hosting problems
### Old PHP versions
On **free.fr**: free.fr now supports php 5.6.x([link](http://les.pages.perso.chez.free.fr/migrations/php5v6.io))
and so support now the tag autocompletion but you have to do the following.
- On hosts (such as **free.fr**) which only support PHP 5.6, Shaarli [v0.10.4](https://github.com/shaarli/Shaarli/releases/tag/v0.10.4) is the maximum supported version. At the root of your webspace create a `sessions` directory and a `.htaccess` file containing:
At the root of your webspace create a `sessions` directory and a `.htaccess` file containing:
```xml
```apacheconf
<IfDefine Free>
php56 1
</IfDefine>
<Files ".ht*">
Order allow,deny
Deny from all
Satisfy all
</Files>
Options -Indexes
```
- If you have an error such as: `Parse error: syntax error, unexpected '=', expecting '(' in /links/index.php on line xxx`, it means that your host is using php4, not php5. Shaarli requires php 5.1. Try changing the file extension to `.php5`
- If you have an error such as: `Parse error: syntax error, unexpected '=', expecting '(' in /links/index.php on line xxx`, it means that your host is using PHP 4, not PHP 5. Shaarli requires PHP 5.1. Try changing the file extension to `.php5`
- On **1and1** : If you add the link from the page (and not from the bookmarklet), Shaarli will no be able to get the title of the page. You will have to enter it manually. (Because they have disabled the ability to download a file through HTTP).
- If you have the error `Warning: file_get_contents() [function.file-get-contents]: URL file-access is disabled in the server configuration in /…/index.php on line xxx`, it means that your host has disabled the ability to fetch a file by HTTP in the php config (Typically in 1and1 hosting). Bad host. Change host. Or comment the following lines:
@ -101,9 +62,11 @@ php56 1
//if (strpos($status,'200 OK')) $title=html_extract_title($data);
```
- On hosts which forbid outgoing HTTP requests (such as free.fr), some thumbnails will not work.
- On hosts (such as **free.fr**) which forbid outgoing HTTP requests, some thumbnails will not work.
- On hosts (such as **free.fr**) which limit the number of FTP connections, setup your FTP client accordingly (else some files may be missing after upload).
- On **lost-oasis**, RSS doesn't work correctly, because of this message at the begining of the RSS/ATOM feed : `<? // tout ce qui est charge ici (generalement des includes et require) est charge en permanence. ?>`. To fix this, remove this message from `php-include/prepend.php`
### Dates are not properly formatted
Shaarli tries to sniff the language of the browser (using `HTTP_ACCEPT_LANGUAGE` headers)
@ -123,6 +86,135 @@ This can be caused by several things:
- You may be using OperaTurbo or OperaMini, which use their own proxies which may change from time to time.
- If you have another application on the same webserver where Shaarli is installed, these application may forcefully expire php sessions.
## Sessions do not seem to work correctly on your server
Follow the instructions in the error message. Make sure you are accessing shaarli via a direct IP address or a proper hostname. If you have **no dots** in the hostname (e.g. `localhost` or `http://my-webserver/shaarli/`), some browsers will not store cookies at all (this respects the [HTTP cookie specification](http://curl.haxx.se/rfc/cookie_spec.html)).
### Old apache versions, Internal Server Error
If you hosting provider only provides apache 2.2 and no support for `mod_version`, `.htaccess` files may cause 500 errors (Internal Server Error). See [this workaround](https://github.com/shaarli/Shaarli/issues/1196#issuecomment-412271085).
### Sessions do not seem to work correctly on your server
Follow the instructions in the error message. Make sure you are accessing shaarli via a direct IP address or a proper hostname. If you have **no dots** in the hostname (e.g. `localhost` or `http://my-webserver/shaarli/`), some browsers will not store cookies at all (this respects the [HTTP cookie specification](https://curl.se/rfc/cookie_spec.html)).
### Error 406 "Not acceptable"
If attempting to save a link results in a `Not acceptable` error (HTTP status code of `406`), it is likely due to strict settings for `mod_security` (a module used with Apache). This cannot be mitigated by reconfiguring Shaarli itself, and must be dealt with at the level of the underlying web server instead.
On some shared hosting services (such as **Bluehost**), `mod_security` is enabled by default, so the recommended course of action is to get in touch with the helpdesk and ask them to disable `mod_security` for your domain, sub-domain, or the subdirectory where Shaarli is installed. Ideally, you want to narrow it down to a very specific location, so as to continue reaping the benefits of `mod_security` elsewhere on your domain. If asked for specific, you can refer support staff to this [issue](https://github.com/shaarli/Shaarli/issues/1736), where more technical details are available.
### Timeout during long-lasting operations
You may need to adjust timeouts to larger values in your [reverse proxy configuration](Reverse-proxy.md) if you're getting `504 Gateway Timeout` errors during long-lasting operations (like importing many bookmarks from HTML, or batch deleting tags) on slow hardware. The PHP setting `max_execution_time` may also need to be adjusted for your specific setup. See issues [#1854](https://github.com/shaarli/Shaarli/issues/1854) and [#1910](https://github.com/shaarli/Shaarli/issues/1910).
### Automatic title retrieval fails
When bookmarking a page using the `+ Shaare > Add Link` dialog, Shaarli cannot retrieve the page `<title>` HTML attribute if it is set by javascript at page load (e.g. Youtube videos). You can work around this limitation by using a [Browser extension](Community-and-related-software.md) or the [Bookmarklet](#Usage).
----------------------------------------------------------
## Upgrades
### You must specify an integer as a key
In `v0.8.1` we changed how Shaare keys are handled (from timestamps to incremental integers). Take a look at `data/updates.txt` content.
### `updates.txt` contains `updateMethodDatastoreIds`
Try to delete it and refresh your page while being logged in.
### `updates.txt` doesn't exist or doesn't contain `updateMethodDatastoreIds`
1. Create `data/updates.txt` if it doesn't exist
2. Paste this string in the update file `;updateMethodRenameDashTags;`
3. Login to Shaarli
4. Delete the update file
5. Refresh
--------------------------------------------------------
## Import/export
### Importing shaarli data to Firefox
- In Firefox, open the bookmark manager (`Bookmarks menu > Show all bookmarks` or `Ctrl+Shift+B`), select `Import and Backup > Import bookmarks in HTML format`
- Make sure the `Prepend note permalinks with this Shaarli instance's URL` box is checked when exporting, so that text-only/notes Shaares still point to the Shaarli instance you exported them from.
- Depending on the number of bookmarks, the import can take some time.
You may be interested in these Firefox addons to manage bookmarks imported from Shaarli
- [Bookmark Dupes](https://addons.mozilla.org/en-US/firefox/addon/bookmark-dupes/) - provides an easy way to deduplicate your bookmarks
### Diigo
If you export your bookmark from Diigo, make sure you use the Delicious export, not the Netscape export. (Their Netscape export is broken, and they don't seem to be interested in fixing it.)
### Mister Wong
See [this issue](https://github.com/sebsauvage/Shaarli/issues/146) for import tweaks.
### SemanticScuttle
To correctly import the tags from a [SemanticScuttle](https://semanticscuttle.sourceforge.net/) HTML export, edit the HTML file before importing and replace all occurences of `tags=` (lowercase) to `TAGS=` (uppercase).
### Scuttle
Shaarli cannot import data directly from [Scuttle](https://github.com/scronide/scuttle).
However, you can use the third-party [scuttle-to-shaarli](https://github.com/q2apro/scuttle-to-shaarli)
tool to export the Scuttle database to the Netscape HTML format compatible with the Shaarli importer.
### Refind.com
You can use the third-party tool [Derefind](https://github.com/ShawnPConroy/Derefind) to convert refind.com bookmark exports to a format that can be imported into Shaarli.
-------------------------------------------------------
## Other
### The bookmarklet doesn't work
Some websites may disallow usage of bookmarklets through [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). Unfortunately, there is nothing Shaarli can do about it ([1](https://github.com/shaarli/Shaarli/issues/196), [2](https://bugzilla.mozilla.org/show_bug.cgi?id=866522), [3](https://bugs.chromium.org/p/chromium/issues/detail?id=233903).
Under Opera, you can't drag'n drop the button: You have to right-click on it and add a bookmark to your personal toolbar.
### Changing the timestamp for a shaare
- Look for `<input type="hidden" name="lf_linkdate" value="{$link.linkdate}">` in `tpl/editlink.tpl` (line 14)
- Replace `type="hidden"` with `type="text"` from this line
- A new date/time field becomes available in the edit/new Shaare dialog.
- You can set the timestamp manually by entering it in the format `YYYMMDD_HHMMS`.
### Clearing Shaarli caches
For debugging purposes:
```bash
# clear raintpl cache and temporary files
find /var/www/links/cache/ /var/www/links/pagecache/ /var/www/links/tmp/ -type f -exec rm -v '{}' \;
# if you have a php accelerator such as php-apcu, restart the webserver
sudo systemctl restart apache2
```
-------------------------------------------------------
## Support
If the solutions above did not help, please:
- Come and ask question on the [Gitter chat](https://app.gitter.im/#/room/#shaarli_Shaarli:gitter.im)
- Search for [issues](https://github.com/shaarli/Shaarli/issues) and [Pull Requests](https://github.com/shaarli/Shaarli/pulls)
- if you find one that is related to the issue, feel free to comment and provide additional details (host/Shaarli setup...)
- check issues labeled [`feature`](https://github.com/shaarli/Shaarli/labels/feature), [`enhancement`](https://github.com/shaarli/Shaarli/labels/enhancement), and [`plugin`](https://github.com/shaarli/Shaarli/labels/plugin) if you would like a feature added to Shaarli.
- else, [open a new issue](https://github.com/shaarli/Shaarli/issues/new), and provide information about the problem:
- _what happens?_ - display glitches, invalid data, security flaws...
- _what is your configuration?_ - OS, server version, activated extensions, web browser...
- _is it reproducible?_

View file

@ -1,56 +0,0 @@
## Running tests inside Docker containers
Read first:
- [Docker 101](docker/docker-101.md)
- [Docker resources](docker/resources.md)
- [Unit tests](Unit-tests.md)
### Docker test images
Test Dockerfiles are located under `tests/docker/<distribution>/Dockerfile`,
and can be used to build Docker images to run Shaarli test suites under common
Linux environments.
Dockerfiles are provided for the following environments:
- `alpine36` - [Alpine 3.6](https://www.alpinelinux.org/downloads/)
- `debian8` - [Debian 8 Jessie](https://www.debian.org/DebianJessie) (oldstable)
- `debian9` - [Debian 9 Stretch](https://wiki.debian.org/DebianStretch) (stable)
- `ubuntu16` - [Ubuntu 16.04 Xenial Xerus](http://releases.ubuntu.com/16.04/) (LTS)
What's behind the curtains:
- each image provides:
- a base Linux OS
- Shaarli PHP dependencies (OS packages)
- test PHP dependencies (OS packages)
- Composer
- the local workspace is mapped to the container's `/shaarli/` directory,
- the files are rsync'd so tests are run using a standard Linux user account
(running tests as `root` would bypass permission checks and may hide issues)
- the tests are run inside the container.
### Building test images
```bash
# build the Debian 9 Docker image
$ cd /path/to/shaarli
$ cd tests/docker/debian9
$ docker build -t shaarli-test:debian9 .
```
### Running tests
```bash
$ cd /path/to/shaarli
# install/update 3rd-party test dependencies
$ composer install --prefer-dist
# run tests using the freshly built image
$ docker run -v $PWD:/shaarli shaarli-test:debian9 docker_test
# run the full test campaign
$ docker run -v $PWD:/shaarli shaarli-test:debian9 docker_all_tests
```

View file

@ -1,157 +0,0 @@
### Setup your environment for tests
The framework used is [PHPUnit](https://phpunit.de/); it can be installed with [Composer](https://getcomposer.org/), which is a dependency management tool.
### Install composer
You can either use:
- a system-wide version, e.g. installed through your distro's package manager
- a local version, downloadable [here](https://getcomposer.org/download/).
```bash
# system-wide version
$ composer install
$ composer update
# local version
$ php composer.phar self-update
$ php composer.phar install
$ php composer.phar update
```
#### Install Shaarli dev dependencies
```bash
$ cd /path/to/shaarli
$ composer update
```
#### Install and enable Xdebug to generate PHPUnit coverage reports
See http://xdebug.org/docs/install
For Debian-based distros:
```bash
$ aptitude install php5-xdebug
```
For ArchLinux:
```bash
$ pacman -S xdebug
```
Then add the following line to `/etc/php/php.ini`:
```ini
zend_extension=xdebug.so
```
#### Run unit tests
Successful test suite:
```bash
$ make test
-------
PHPUNIT
-------
PHPUnit 4.6.9 by Sebastian Bergmann and contributors.
Configuration read from /home/virtualtam/public_html/shaarli/phpunit.xml
....................................
Time: 759 ms, Memory: 8.25Mb
OK (36 tests, 65 assertions)
```
Test suite with failures and errors:
```bash
$ make test
-------
PHPUNIT
-------
PHPUnit 4.6.9 by Sebastian Bergmann and contributors.
Configuration read from /home/virtualtam/public_html/shaarli/phpunit.xml
E..FF...............................
Time: 802 ms, Memory: 8.25Mb
There was 1 error:
1) LinkDBTest::testConstructLoggedIn
Missing argument 2 for LinkDB::__construct(), called in /home/virtualtam/public_html/shaarli/tests/Link\
DBTest.php on line 79 and defined
/home/virtualtam/public_html/shaarli/application/LinkDB.php:58
/home/virtualtam/public_html/shaarli/tests/LinkDBTest.php:79
--
There were 2 failures:
1) LinkDBTest::testCheckDBNew
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'e3edea8ea7bb50be4bcb404df53fbb4546a7156e'
+'85eab0c610d4f68025f6ed6e6b6b5fabd4b55834'
/home/virtualtam/public_html/shaarli/tests/LinkDBTest.php:121
2) LinkDBTest::testCheckDBLoad
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'e3edea8ea7bb50be4bcb404df53fbb4546a7156e'
+'85eab0c610d4f68025f6ed6e6b6b5fabd4b55834'
/home/virtualtam/public_html/shaarli/tests/LinkDBTest.php:133
FAILURES!
Tests: 36, Assertions: 63, Errors: 1, Failures: 2.
```
#### Test results and coverage
By default, PHPUnit will run all suitable tests found under the `tests` directory.
Each test has 3 possible outcomes:
- `.` - success
- `F` - failure: the test was run but its results are invalid
- the code does not behave as expected
- dependencies to external elements: globals, session, cache...
- `E` - error: something went wrong and the tested code has crashed
- typos in the code, or in the test code
- dependencies to missing external elements
If Xdebug has been installed and activated, two coverage reports will be generated:
- a summary in the console
- a detailed HTML report with metrics for tested code
- to open it in a web browser: `firefox coverage/index.html &`
### Executing specific tests
Add a [`@group`](https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.group) annotation in a test class or method comment:
```php
/**
* Netscape bookmark import
* @group WIP
*/
class BookmarkImportTest extends PHPUnit_Framework_TestCase
{
[...]
}
```
To run all tests annotated with `@group WIP`:
```bash
$ vendor/bin/phpunit --group WIP tests/
```

View file

@ -1,96 +1,83 @@
## Preparation
# Upgrade and migration
### Note your current version
## Note your current version
If anything goes wrong, it's important for us to know which version you're upgrading from.
The current version is present in the `shaarli_version.php` file.
### Backup your data
Shaarli stores all user data under the `data` directory:
## Backup your data
- `data/config.json.php` (or `data/config.php` for older Shaarli versions) - main configuration file
- `data/datastore.php` - bookmarked links
- `data/ipbans.php` - banned IP addresses
- `data/updates.txt` - contains all automatic update to the configuration and datastore files already run
See [Shaarli configuration](Shaarli-configuration) for more information about Shaarli resources.
It is recommended to backup this repository _before_ starting updating/upgrading Shaarli:
- users with SSH access: copy or archive the directory to a temporary location
- users with FTP access: download a local copy of your Shaarli installation using your favourite client
### Migrating data from a previous installation
As all user data is kept under `data`, this is the only directory you need to worry about when migrating to a new installation, which corresponds to the following steps:
- backup the `data` directory
- install or update Shaarli:
- fresh installation - see [Download and Installation](Download-and-Installation)
- update - see the following sections
- check or restore the `data` directory
## Recommended : Upgrading from release archives
All tagged revisions can be downloaded as tarballs or ZIP archives from the [releases](https://github.com/shaarli/Shaarli/releases) page.
We recommend that you use the latest release tarball with the `-full` suffix. It contains the dependencies, please read [Download and Installation](Download-and-Installation) for `git` complete instructions.
Once downloaded, extract the archive locally and update your remote installation (e.g. via FTP) -be sure you keep the content of the `data` directory!
If you use translations in gettext mode - meaning you manually changed the default mode -,
reload your web server.
After upgrading, access your fresh Shaarli installation from a web browser; the configuration and data store will then be automatically updated, and new settings added to `data/config.json.php` (see [Shaarli configuration](Shaarli configuration) for more details).
## Upgrading with Git
### Updating a community Shaarli
If you have installed Shaarli from the [community Git repository](Download#clone-with-git-recommended), simply [pull new changes](https://www.git-scm.com/docs/git-pull) from your local clone:
Shaarli stores all user data and [configuration](Shaarli-configuration.md) under the `data` directory. [Backup](Backup-and-restore.md) this repository _before_ upgrading Shaarli. You will need to restore it after the following upgrade steps.
```bash
$ cd /path/to/shaarli
$ git pull
From github.com:shaarli/Shaarli
* branch master -> FETCH_HEAD
Updating ebd67c6..521f0e6
Fast-forward
application/Url.php | 1 +
shaarli_version.php | 2 +-
tests/Url/UrlTest.php | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
sudo cp -r /var/www/shaarli.mydomain.org/data ~/shaarli-data-backup
```
Shaarli >= `v0.8.x`: install/update third-party PHP dependencies using [Composer](https://getcomposer.org/):
## Upgrading from ZIP archives
If you installed Shaarli from a [release ZIP archive](Installation.md#from-release-zip):
```bash
$ composer install --no-dev
# Download the archive to the server, and extract it
cd ~
wget https://github.com/shaarli/Shaarli/releases/download/v0.X.Y/shaarli-v0.X.Y-full.zip
unzip shaarli-v0.X.Y-full.zip
Loading composer repositories with package information
Updating dependencies
- Installing shaarli/netscape-bookmark-parser (v1.0.1)
Downloading: 100%
# overwrite your Shaarli installation with the new release **All data will be lost, see _Backup your data_ above.**
sudo rsync -avP --delete Shaarli/ /var/www/shaarli.mydomain.org/
# restore file permissions as described on the installation page
sudo chown -R root:www-data /var/www/shaarli.mydomain.org
sudo chmod -R g+rX /var/www/shaarli.mydomain.org
sudo chmod -R g+rwX /var/www/shaarli.mydomain.org/{cache/,data/,pagecache/,tmp/}
# restore backups of the data directory
sudo cp -r ~/shaarli-data-backup/* /var/www/shaarli.mydomain.org/data/
# If you use gettext mode for translations (not the default), reload your web server.
sudo systemctl restart apache2
sudo systemctl restart nginx
```
Shaarli >= `v0.9.2` supports translations:
If you don't have shell access (eg. on shared hosting), backup the shaarli data directory, download the ZIP archive locally, extract it, upload it to the server using file transfer, and restore the data directory backup.
Access your fresh Shaarli installation from a web browser; the configuration and data store will then be automatically updated, and new settings added to `data/config.json.php` (see [Shaarli configuration](Shaarli-configuration.md) for more details).
## Upgrading from Git
If you have installed Shaarli [from sources](Installation.md#from-sources):
```bash
$ make translate
```
# pull new changes from your local clone
cd /var/www/shaarli.mydomain.org/
sudo git pull
If you use translations in gettext mode, reload your web server.
# update PHP dependencies (Shaarli >= v0.8)
sudo composer install --no-dev
Shaarli >= `v0.10.0` manages its front-end dependencies with nodejs. You need to install
[yarn](https://yarnpkg.com/lang/en/docs/install/):
# update translations (Shaarli >= v0.9.2)
sudo make translate
```bash
$ make build_frontend
# If you use translations in gettext mode (not the default), reload your web server.
sudo systemctl reload apache
sudo systemctl reload nginx
# update front-end dependencies (Shaarli >= v0.10.0)
sudo make build_frontend
# restore file permissions as described on the installation page
sudo chown -R root:www-data /var/www/shaarli.mydomain.org
sudo chmod -R g+rX /var/www/shaarli.mydomain.org
sudo chmod -R g+rwX /var/www/shaarli.mydomain.org/{cache/,data/,pagecache/,tmp/}
```
### Migrating and upgrading from Sebsauvage's repository
Access your fresh Shaarli installation from a web browser; the configuration and data store will then be automatically updated, and new settings added to `data/config.json.php` (see [Shaarli configuration](Shaarli-configuration.md) for more details).
---------------------------------------------------------------
## Migrating and upgrading from Sebsauvage's repository
If you have installed Shaarli from [Sebsauvage's original Git repository](https://github.com/sebsauvage/Shaarli), you can use [Git remotes](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes) to update your working copy.
@ -104,7 +91,7 @@ The following guide assumes that:
- no versioned file has been locally modified
- no untracked files are present
#### Step 0: show repository information
### Step 0: show repository information
```bash
$ cd /path/to/shaarli
@ -122,7 +109,7 @@ Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
```
#### Step 1: update Git remotes
### Step 1: update Git remotes
```
$ git remote rename origin sebsauvage
@ -146,7 +133,7 @@ From https://github.com/shaarli/Shaarli
* [new tag] v0.7.0 -> v0.7.0
```
#### Step 2: use the stable community branch
### Step 2: use the stable community branch
```bash
$ git checkout origin/stable -b stable
@ -177,8 +164,7 @@ $ make translate
If you use translations in gettext mode, reload your web server.
Shaarli >= `v0.10.0` manages its front-end dependencies with nodejs. You need to install
[yarn](https://yarnpkg.com/lang/en/docs/install/):
Shaarli >= `v0.10.0` manages its front-end dependencies with nodejs. You need to install [yarn](https://classic.yarnpkg.com/en/docs/install/):
```bash
$ make build_frontend
@ -204,30 +190,14 @@ Writing objects: 100% (3317/3317), done.
Total 3317 (delta 2050), reused 3301 (delta 2034)to
```
#### Step 3: configuration
### Step 3: configuration
After migrating, access your fresh Shaarli installation from a web browser; the
configuration will then be automatically updated, and new settings added to
`data/config.json.php` (see [Shaarli configuration](Shaarli-configuration) for more
`data/config.json.php` (see [Shaarli configuration](Shaarli-configuration.md) for more
details).
## Troubleshooting
If the solutions provided here don't work, please open an issue specifying which version you're upgrading from and to.
If the solutions provided here don't work, see [Troubleshooting](Troubleshooting.md) and/or open an issue specifying which version you're upgrading from and to.
### You must specify an integer as a key
In `v0.8.1` we changed how link keys are handled (from timestamps to incremental integers).
Take a look at `data/updates.txt` content.
#### `updates.txt` contains `updateMethodDatastoreIds`
Try to delete it and refresh your page while being logged in.
#### `updates.txt` doesn't exist or doesn't contain `updateMethodDatastoreIds`
1. Create `data/updates.txt` if it doesn't exist
2. Paste this string in the update file `;updateMethodRenameDashTags;`
3. Login to Shaarli
4. Delete the update file
5. Refresh

116
doc/md/Usage.md Normal file
View file

@ -0,0 +1,116 @@
# Usage
## Features
For any item posted to Shaarli (called a _Shaare_), you can customize the following aspects:
- URL to link to
- Title
- Free-text description
- Tags
- Public/private status
### Adding/editing Shaares
While logged in to your Shaarli, you can add, edit or delete Shaares:
- Using the **+Shaare** button: enter the URL you want to share, click `Add link`, fill in the details of your Shaare, and `Save`
- Using the [Bookmarklet](https://en.wikipedia.org/wiki/Bookmarklet): drag the `✚Shaare link` button from the `Tools` page to your browser's bookmarks bar, click it to share the current page.
- Using [apps and browser addons](Community-and-related-software.md#mobile-apps)
- Using the [REST API](https://shaarli.github.io/api-documentation/)
- Any Shaare can edited by clicking its ![](images/edit_icon.png) `Edit` button.
The `Shaare a new link` dialog also allows you to create multiple bookmarks at once (unfold the `bulk creation` section and add one URL per line).
### Tags
Tags can be be used to organize and categorize your Shaares:
- You can rename, merge and delete tags from the _Tools_ menu or the [tag cloud/list](#tag-cloud)
- Tags are auto-completed (from the list of existing tags) in all dialogs
- Tags can be combined with text in [search](#search) queries
### Public/private Shaares
Additional filter buttons can be found at the top left of the Shaare list **only when logged in**:
- **Only show private Shaares:** Private shares can be searched by clicking the `only show private links` toggle button top left of the Shaares list (only when logged in)
### Permalinks
Permalinks are fixed, short links attached to each Shaare. Editing a Shaare will not change it's permalink, each permalink always points to the latest revision of a Shaare.
### Text-only (note) Shaares
Shaarli can be used as a minimal blog, notepad, pastebin...: While adding or editing a Shaare, leave the URL field blank to create a text-only ("note") post. This allows you to post any kind of text content, such as blog articles, private or public notes, snippets... There is no character limit! You can access your post from its permalink.
### Search
- **Plain text search:** Use `Search text` to search in all fields of all Shaares (Title, URL, Description...). Use double-quotes (example `"exact search"`) to search for the exact expression.
- **Tags search:** `Filter by tags` allow only displaying Shaares tagged with one or multiple tags (use space to separate tags). A plus sign `+` is optional and will restrict suggested tags to only those starting with the string (example: `pr` will hint `apron` and `printer` but `+pr` will only hint printer).
- **Hidden tags:** tags starting with a dot `.` (example `.secret`) are private. They can only be seen and searched when logged in.
- **Exclude text/tags:** Use the `-` operator before a word or tag to exclude Shaares matching this word from search results (`NOT` operator).
- **Optional tags:** Use the `~` operator before multiple tags to search for any one of them (`OR` operator). Note that the OR operator only works if there are multiple tags with a tilde. A search for `webdesign ~ai ~youtube` search would match `webdesign AND (ai OR youtube)`. A search for `webdesign ~youtube` is equivalent to `+webdesign +youtube`.
- **Wildcard tag search:** An asterisk (`*`) can be used as a wildcard and will match any number of characters. Wildcards can appear in the middle of a search term or at the end (example: pro\*in\* will match programming and protein).
- **Untagged links:** Shaares without tags can be searched by clicking the `untagged` toggle button top left of the Shaares list (only when logged in).
Both exclude patterns and exact searches can be combined with normal searches (example `"exact search" term otherterm -notthis "very exact" stuff -notagain`). Only AND (and NOT) text search is currently supported.
Active search terms are displayed on top of the link list. To remove terms/tags from the current search, click the `x` next to any of them, or simply clear text/tag search fields.
### Tag cloud
The `Tag cloud` page displays a "cloud" or list view of all tags in your Shaarli (most frequently used tags are displayed with a bigger font size)
- **Tags list:** click on `Most used` or `Alphabetical` to display tags as a list. You can also edit/delete tags for this page.
- Click on any tag to search all Shaares matching this tag.
- **Filtering the tag cloud/list:** Click on the counter next to a tag to show other tags of Shaares with this tag. Repeat this any number of times to further filter the tag cloud. Click `List all links with those tags` to display Shaares matching your current tag filter set.
### RSS feeds
RSS/ATOM feeds feeds are available (in ATOM with `/feed/atom` and RSS with `/feed/rss`)
- **Filtering RSS feeds:** RSS feeds and picture wall can also be restricted to only return items matching a text/tag search. For example, search for `photography` (text or tags) in Shaarli, then click the `RSS Feed` button. A feed with only matching results is displayed.
- Add the `&nb` parameter in feed URLs to specify the number of Shaares you want in a feed (default if not specified: `50`). The keyword `all` is available if you want everything.
- Add the `&permalinks` parameter in feed URLs to point permalinks to the corresponding Shaarli entry/link instead of the direct, Shaare URL attribute
![](images/rss-filter-1.png) ![](images/rss-filter-2.png)
```bash
# examples
https://shaarli.mydomain.org/feed/atom?permalinks
https://shaarli.mydomain.org/feed/atom?permalinks&nb=42
https://shaarli.mydomain.org/feed/atom?permalinks&nb=all
https://shaarli.mydomain.org/feed/rss?searchtags=nature
https://shaarli.mydomain.org/links/picture-wall?searchterm=poney
```
### Picture wall
- The picture wall can be filtered by text or tags search in the same way as [RSS feeds](#rss-feeds)
### Import/export
To **export Shaares as a HTML file**, under _Tools > Export_, choose:
- `Export all` to export both public and private Shaares
- `Export public` to export public Shaares only
- `Export private` to export private Shaares only
Restore by using the `Import` feature.
- These exports contain the full data (URL, title, tags, date, description, public/private status of your Shaares)
- They can also be imported to your web browser bookmarks.
To **import a HTML bookmarks file** exported from your browser, just use the `Import` feature. For each "folder" in the bookmarks you imported, a new tag will be created (for example a bookmark in `Movies > Sci-fi` folder will be tagged `Movies` `Sci-fi`).

View file

@ -1,75 +0,0 @@
**WORK IN PROGRESS**
It's important to understand how Shaarli branches work, especially if you're maintaining a 3rd party tools for Shaarli (theme, plugin, etc.), to be sure stay compatible.
## `master` branch
The `master` branch is the development branch. Any new change MUST go through this branch using Pull Requests.
Remarks:
- This branch shouldn't be used for production as it isn't necessary stable.
- 3rd party aren't required to be compatible with the latest changes.
- Official plugins, themes and libraries (contained within Shaarli organization repos) must be compatible with the master branch.
- The version in this branch is always `dev`.
## `v0.x` branch
This `v0.x` branch, points to the latest `v0.x.y` release.
Explanation:
When a new version is released, it might contains a major bug which isn't detected right away. For example, a new PHP version is released, containing backward compatibility issue which doesn't work with Shaarli.
In this case, the issue is fixed in the `master` branch, and the fix is backported the to the `v0.x` branch. Then a new release is made from the `v0.x` branch.
This workflow allow us to fix any major bug detected, without having to release bleeding edge feature too soon.
## `latest` branch
This branch point the latest release. It recommended to use it to get the latest tested changes.
## `stable` branch
The `stable` branch doesn't contain any major bug, and is one major digit version behind the latest release.
For example, the current latest release is `v0.8.3`, the stable branch is an alias to the latest `v0.7.x` release. When the `v0.9.0` version will be released, the stable will move to the latest `v0.8.x` release.
Remarks:
- Shaarli release pace isn't fast, and the stable branch might be a few months behind the latest release.
## Releases
Releases are always made from the latest `v0.x` branch.
Note that for every release, we manually generate a tarball which contains all Shaarli dependencies, making Shaarli's installation only one step.
## Advices on 3rd party git repos workflow
### Versioning
Any time a new Shaarli release is published, you should publish a new release of your repo if the changes affected you since the latest release (take a look at the [changelog](https://github.com/shaarli/Shaarli/releases) (*Draft* means not released yet) and the commit log (like [`tpl` folder](https://github.com/shaarli/Shaarli/commits/master/tpl/default) for themes)). You can either:
- use the Shaarli version number, with your repo version. For example, if Shaarli `v0.8.3` is released, publish a `v0.8.3-1` release, where `v0.8.3` states Shaarli compatibility and `-1` is your own version digit for the current Shaarli version.
- use your own versioning scheme, and state Shaarli compatibility in the release description.
Using this, any user will be able to pick the release matching his own Shaarli version.
### Major bugfix backport releases
To be able to support backported fixes, it recommended to use our workflow:
```bash
# In master, fix the major bug
git commit -m "Katastrophe"
git push origin master
# Get your commit hash
git log --format="%H" -n 1
# Create a new branch from your latest release, let's say v0.8.2-1 (the tag name)
git checkout -b katastrophe v0.8.2-1
# Backport the fix commit to your brand new branch
git cherry-pick <fix commit hash>
git push origin katastrophe
# Then you just have to make a new release from the `katastrophe` branch tagged `v0.8.3-1`
```

1449
doc/md/dev/Development.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,140 +0,0 @@
## Basics
Install [Docker](https://www.docker.com/), by following the instructions relevant
to your OS / distribution, and start the service.
### Search an image on [DockerHub](https://hub.docker.com/)
```bash
$ docker search debian
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating s... 2065 [OK]
debian Debian is a Linux distribution that's comp... 603 [OK]
google/debian 47 [OK]
```
### Show available tags for a repository
```bash
$ curl https://index.docker.io/v1/repositories/debian/tags | python -m json.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1283 0 1283 0 0 433 0 --:--:-- 0:00:02 --:--:-- 433
```
Sample output:
```json
[
{
"layer": "85a02782",
"name": "stretch"
},
{
"layer": "59abecbc",
"name": "testing"
},
{
"layer": "bf0fd686",
"name": "unstable"
},
{
"layer": "60c52dbe",
"name": "wheezy"
},
{
"layer": "c5b806fe",
"name": "wheezy-backports"
}
]
```
### Pull an image from DockerHub
```bash
$ docker pull repository[:tag]
$ docker pull debian:wheezy
wheezy: Pulling from debian
4c8cbfd2973e: Pull complete
60c52dbe9d91: Pull complete
Digest: sha256:c584131da2ac1948aa3e66468a4424b6aea2f33acba7cec0b631bdb56254c4fe
Status: Downloaded newer image for debian:wheezy
```
Docker re-uses layers already downloaded. In other words if you have images based on Alpine or some Ubuntu version for example, those can share disk space.
### Start a container
A container is an instance created from an image, that can be run and that keeps running until its main process exits. Or until the user stops the container.
The simplest way to start a container from image is ``docker run``. It also pulls the image for you if it is not locally available. For more advanced use, refer to ``docker create``.
Stopped containers are not destroyed, unless you specify ``--rm``. To view all created, running and stopped containers, enter:
```bash
$ docker ps -a
```
Some containers may be designed or configured to be restarted, others are not. Also remember both network ports and volumes of a container are created on start, and not editable later.
### Access a running container
A running container is accessible using ``docker exec``, or ``docker copy``. You can use ``exec`` to start a root shell in the Shaarli container:
```bash
$ docker exec -ti <container-name-or-id> bash
```
Note the names and ID's of containers are listed in ``docker ps``. You can even type only one or two letters of the ID, given they are unique.
Access can also be through one or more network ports, or disk volumes. Both are specified on and fixed on ``docker create`` or ``run``.
You can view the console output of the main container process too:
```bash
$ docker logs -f <container-name-or-id>
```
### Docker disk use
Trying out different images can fill some gigabytes of disk quickly. Besides images, the docker volumes usually take up most disk space.
If you care only about trying out docker and not about what is running or saved, the following commands should help you out quickly if you run low on disk space:
```bash
$ docker rmi -f $(docker images -aq) # remove or mark all images for disposal
$ docker volume rm $(docker volume ls -q) # remove all volumes
```
### Systemd config
Systemd is the process manager of choice on Debian-based distributions. Once you have a ``docker`` service installed, you can use the following steps to set up Shaarli to run on system start.
```bash
systemctl enable /etc/systemd/system/docker.shaarli.service
systemctl start docker.shaarli
systemctl status docker.*
journalctl -f # inspect system log if needed
```
You will need sudo or a root terminal to perform some or all of the steps above. Here are the contents for the service file:
```
[Unit]
Description=Shaarli Bookmark Manager Container
After=docker.service
Requires=docker.service
[Service]
Restart=always
# Put any environment you want in an included file, like $host- or $domainname in this example
EnvironmentFile=/etc/sysconfig/box-environment
# It's just an example..
ExecStart=/usr/bin/docker run \
-p 28010:80 \
--name ${hostname}-shaarli \
--hostname shaarli.${domainname} \
-v /srv/docker-volumes-local/shaarli-data:/var/www/shaarli/data:rw \
-v /etc/localtime:/etc/localtime:ro \
shaarli/shaarli:latest
ExecStop=/usr/bin/docker rm -f ${hostname}-shaarli
[Install]
WantedBy=multi-user.target
```

View file

@ -1,19 +0,0 @@
### Docker
- [Interactive Docker training portal](https://www.katacoda.com/courses/docker/) on [Katakoda](https://www.katacoda.com/)
- [Where are Docker images stored?](http://blog.thoward37.me/articles/where-are-docker-images-stored/)
- [Dockerfile reference](https://docs.docker.com/reference/builder/)
- [Dockerfile best practices](https://docs.docker.com/articles/dockerfile_best-practices/)
- [Volumes](https://docs.docker.com/userguide/dockervolumes/)
### DockerHub
- [Repositories](https://docs.docker.com/userguide/dockerrepos/)
- [Teams and organizations](https://docs.docker.com/docker-hub/orgs/)
- [GitHub automated build](https://docs.docker.com/docker-hub/github/)
### Service management
- [Using supervisord](https://docs.docker.com/articles/using_supervisord/)
- [Nginx in the foreground](http://nginx.org/en/docs/ngx_core_module.html#daemon)
- [supervisord](http://supervisord.org/)

View file

@ -1,123 +0,0 @@
## Foreword
This guide assumes that:
- Shaarli runs in a Docker container
- The host's `10080` port is mapped to the container's `80` port
- Shaarli's Fully Qualified Domain Name (FQDN) is `shaarli.domain.tld`
- HTTP traffic is redirected to HTTPS
## Apache
- [Apache 2.4 documentation](https://httpd.apache.org/docs/2.4/)
- [mod_proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html)
- [Reverse Proxy Request Headers](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#x-headers)
The following HTTP headers are set when the `ProxyPass` directive is set:
- `X-Forwarded-For`
- `X-Forwarded-Host`
- `X-Forwarded-Server`
The original `SERVER_NAME` can be sent to the proxied host by setting the [`ProxyPreserveHost`](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#ProxyPreserveHost) directive to `On`.
```apache
<VirtualHost *:80>
ServerName shaarli.domain.tld
Redirect permanent / https://shaarli.domain.tld
</VirtualHost>
<VirtualHost *:443>
ServerName shaarli.domain.tld
SSLEngine on
SSLCertificateFile /path/to/cert
SSLCertificateKeyFile /path/to/certkey
LogLevel warn
ErrorLog /var/log/apache2/shaarli-error.log
CustomLog /var/log/apache2/shaarli-access.log combined
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:10080/
ProxyPassReverse / http://127.0.0.1:10080/
</VirtualHost>
```
## HAProxy
- [HAProxy documentation](https://cbonte.github.io/haproxy-dconv/)
```conf
global
[...]
defaults
[...]
frontend http-in
bind :80
redirect scheme https code 301 if !{ ssl_fc }
bind :443 ssl crt /path/to/cert.pem
default_backend shaarli
backend shaarli
mode http
option http-server-close
option forwardfor
reqadd X-Forwarded-Proto: https
server shaarli1 127.0.0.1:10080
```
## Nginx
- [Nginx documentation](https://nginx.org/en/docs/)
```nginx
http {
[...]
index index.html index.php;
root /home/john/web;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
server {
listen 80;
server_name shaarli.domain.tld;
return 301 https://shaarli.domain.tld$request_uri;
}
server {
listen 443 ssl http2;
server_name shaarli.domain.tld;
ssl_certificate /path/to/cert
ssl_certificate_key /path/to/certkey
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass http://localhost:10080/;
proxy_set_header Host $host;
proxy_connect_timeout 30s;
proxy_read_timeout 120s;
access_log /var/log/nginx/shaarli.access.log;
error_log /var/log/nginx/shaarli.error.log;
}
}
}
```

View file

@ -1,124 +0,0 @@
A brief guide on getting starting using docker is given in [Docker 101](docker-101.md).
To learn more about user data and how to keep it across versions, please see [Upgrade and Migration](../Upgrade-and-migration.md).
## Get and run a Shaarli image
### DockerHub repository
The images can be found in the [`shaarli/shaarli`](https://hub.docker.com/r/shaarli/shaarli/)
repository.
### Available image tags
- `latest`: latest branch
- `master`: master branch
- `stable`: stable branch
The `latest` and `master` images rely on:
- [Alpine Linux](https://www.alpinelinux.org/)
- [PHP7-FPM](http://php-fpm.org/)
- [Nginx](http://nginx.org/)
The `stable` image relies on:
- [Debian 8 Jessie](https://hub.docker.com/_/debian/)
- [PHP5-FPM](http://php-fpm.org/)
- [Nginx](http://nginx.org/)
Additional Dockerfiles are provided for the `arm32v7` platform, relying on
[Linuxserver.io Alpine armhf
images](https://hub.docker.com/r/lsiobase/alpine.armhf/). These images must be
built using [`docker
build`](https://docs.docker.com/engine/reference/commandline/build/) on an
`arm32v7` machine or using an emulator such as
[qemu](https://resin.io/blog/building-arm-containers-on-any-x86-machine-even-dockerhub/).
### Download from Docker Hub
```shell
$ docker pull shaarli/shaarli
latest: Pulling from shaarli/shaarli
32716d9fcddb: Pull complete
84899d045435: Pull complete
4b6ad7444763: Pull complete
e0345ef7a3e0: Pull complete
5c1dd344094f: Pull complete
6422305a200b: Pull complete
7d63f861dbef: Pull complete
3eb97210645c: Pull complete
869319d746ff: Already exists
869319d746ff: Pulling fs layer
902b87aaaec9: Already exists
Digest: sha256:f836b4627b958b3f83f59c332f22f02fcd495ace3056f2be2c4912bd8704cc98
Status: Downloaded newer image for shaarli/shaarli:latest
```
### Create and start a new container from the image
```shell
# map the host's :8000 port to the container's :80 port
$ docker create -p 8000:80 shaarli/shaarli
d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
# launch the container in the background
$ docker start d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
d40b7af693d678958adedfb88f87d6ea0237186c23de5c4102a55a8fcb499101
# list active containers
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d40b7af693d6 shaarli/shaarli /usr/bin/supervisor 15 seconds ago Up 4 seconds 0.0.0.0:8000->80/tcp backstabbing_galileo
```
### Stop and destroy a container
```shell
$ docker stop backstabbing_galileo # those docker guys are really rude to physicists!
backstabbing_galileo
# check the container is stopped
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# list ALL containers
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d40b7af693d6 shaarli/shaarli /usr/bin/supervisor 5 minutes ago Exited (0) 48 seconds ago backstabbing_galileo
# destroy the container
$ docker rm backstabbing_galileo # let's put an end to these barbarian practices
backstabbing_galileo
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
```
### Automatic builds
Docker users can start a personal instance from an
[autobuild image](https://hub.docker.com/r/shaarli/shaarli/).
For example to start a temporary Shaarli at ``localhost:8000``, and keep session
data (config, storage):
```shell
MY_SHAARLI_VOLUME=$(cd /path/to/shaarli/data/ && pwd -P)
docker run -ti --rm \
-p 8000:80 \
-v $MY_SHAARLI_VOLUME:/var/www/shaarli/data \
shaarli/shaarli
```
### Volumes and data persistence
Data can be persisted by [using volumes](https://docs.docker.com/storage/volumes/).
Volumes allow to keep your data when renewing and/or updating container images:
```shell
# Create data volumes
$ docker volume create shaarli-data
$ docker volume create shaarli-cache
# Create and start a Shaarli container using these volumes to persist data
$ docker create \
--name shaarli \
-v shaarli-cache:/var/www/shaarli/cache \
-v shaarli-data:/var/www/shaarli/data \
-p 8000:80 \
shaarli/shaarli:master
$ docker start shaarli
```

View file

@ -1,64 +0,0 @@
## Backup and restore the datastore file
Backup the file `data/datastore.php` (by FTP or SSH). Restore by putting the file back in place.
Example command:
```bash
rsync -avzP my.server.com:/var/www/shaarli/data/datastore.php datastore-$(date +%Y-%m-%d_%H%M).php
```
## Export links as...
To export links as an HTML file, under _Tools > Export_, choose:
- _Export all_ to export both public and private links
- _Export public_ to export public links only
- _Export private_ to export private links only
Restore by using the `Import` feature.
- This can be done using the [shaarchiver](https://github.com/nodiscc/shaarchiver) tool.
Example command:
```bash
./export-bookmarks.py --url=https://my.server.com/shaarli --username=myusername --password=mysupersecretpassword --download-dir=./ --type=all
```
## Import links from...
### Diigo
If you export your bookmark from Diigo, make sure you use the Delicious export, not the Netscape export. (Their Netscape export is broken, and they don't seem to be interested in fixing it.)
### Mister Wong
See [this issue](https://github.com/sebsauvage/Shaarli/issues/146) for import tweaks.
### SemanticScuttle
To correctly import the tags from a [SemanticScuttle](http://semanticscuttle.sourceforge.net/) HTML export, edit the HTML file before importing and replace all occurences of `tags=` (lowercase) to `TAGS=` (uppercase).
### Scuttle
Shaarli cannot import data directly from [Scuttle](https://github.com/scronide/scuttle).
However, you can use the third-party [scuttle-to-shaarli](https://github.com/q2apro/scuttle-to-shaarli)
tool to export the Scuttle database to the Netscape HTML format compatible with the Shaarli importer.
### Refind
You can use the third-party tool [Derefind](https://github.com/ShawnPConroy/Derefind) to convert refind.com bookmark exports to a format that can be imported into Shaarli.
## Import Shaarli links to Firefox
- Export your Shaarli links as described above.
- For compatibility reasons, check `Prepend note permalinks with this Shaarli instance's URL (useful to import bookmarks in a web browser)`
- In Firefox, open the bookmark manager (not the sidebar! `Bookmarks menu > Show all bookmarks` or `Ctrl+Shift+B`)
- Select `Import and Backup > Import bookmarks in HTML format`
Your bookmarks will be imported in Firefox, ready to use, with tags and descriptions retained. "Self" (notes) shaares will still point to the Shaarli instance you exported them from, but the note text can be viewed directly in the bookmark properties inside your browser. Depending on the number of bookmarks, the import can take some time.
You may be interested in these Firefox addons to manage links imported from Shaarli
- [Bookmark Deduplicator](https://addons.mozilla.org/en-US/firefox/addon/bookmark-deduplicator/) - provides an easy way to deduplicate your bookmarks
- [TagSieve](https://addons.mozilla.org/en-US/firefox/addon/tagsieve/) - browse your bookmarks by their tags

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

View file

@ -1,257 +0,0 @@
_Last updated on 2018-07-01._
## Goals
- Getting a Virtual Private Server (VPS)
- Running Shaarli:
- as a Docker container,
- using the Træfik reverse proxy,
- securized with TLS certificates from Let's Encrypt.
The following components and tools will be used:
- [Debian](https://www.debian.org/), a GNU/Linux distribution widely used in
server environments;
- [Docker](https://docs.docker.com/engine/docker-overview/), an open platform
for developing, shipping, and running applications;
- [Docker Compose](https://docs.docker.com/compose/), a tool for defining and
running multi-container Docker applications.
More information can be found in the [Resources](#resources) section at the
bottom of the guide.
## Getting a Virtual Private Server
For this guide, I went for the smallest VPS available from DigitalOcean,
a Droplet with 1 CPU, 1 GiB RAM and 25 GiB SSD storage, which costs
$5/month ($0.007/hour):
- [Droplets Overview](https://www.digitalocean.com/docs/droplets/overview/)
- [Pricing](https://www.digitalocean.com/pricing/)
- [How to Create a Droplet from the DigitalOcean Control Panel](https://www.digitalocean.com/docs/droplets/how-to/create/)
- [How to Add SSH Keys to Droplets](https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/)
- [Initial Server Setup with Debian 8](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-debian-8) (also applies to Debian 9)
- [An Introduction to Securing your Linux VPS](https://www.digitalocean.com/community/tutorials/an-introduction-to-securing-your-linux-vps)
### Creating a Droplet
Select `Debian 9` as the Droplet distribution:
<img src="../images/01-create-droplet-distro.jpg"
width="500px"
alt="Droplet distribution" />
Choose a region that is geographically close to you:
<img src="../images/02-create-droplet-region.jpg"
width="500px"
alt="Droplet region" />
Choose a Droplet size that corresponds to your usage and budget:
<img src="../images/03-create-droplet-size.jpg"
width="500px"
alt="Droplet size" />
Finalize the Droplet creation:
<img src="../images/04-finalize.jpg"
width="500px"
alt="Droplet finalization" />
Droplet information is displayed on the Control Panel:
<img src="../images/05-droplet.jpg"
width="500px"
alt="Droplet summary" />
Once your VPS has been created, you will receive an e-mail with connection
instructions.
## Obtaining a domain name
After creating your VPS, it will be reachable using its IP address; some hosting
providers also create a DNS record, e.g. `ns4853142.ip-01-47-127.eu`.
A domain name (DNS record) is required to obtain a certificate and setup HTTPS
(HTTP with TLS encryption).
Domain names can be obtained from registrars through hosting providers such as
[Gandi](https://www.gandi.net/en/domain).
Once you have your own domain, you need to create a new DNS record that points
to your VPS' IP address:
<img src="../images/06-domain.jpg"
width="650px"
alt="Domain configuration" />
## Host setup
Now's the time to connect to your freshly created VPS!
```shell
$ ssh root@188.166.85.8
Linux stretch-shaarli-02 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Jul 1 11:20:18 2018 from <REDACTED>
root@stretch-shaarli-02:~$
```
### Updating the system
```shell
root@stretch-shaarli-02:~$ apt update && apt upgrade -y
```
### Setting up Docker
_The following instructions are from the
[Get Docker CE for Debian](https://docs.docker.com/install/linux/docker-ce/debian/)
guide._
Install package dependencies:
```shell
root@stretch-shaarli-02:~$ apt install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common
```
Add Docker's package repository GPG key:
```shell
root@stretch-shaarli-02:~$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
```
Add Docker's package repository:
```shell
root@stretch-shaarli-02:~$ add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian stretch stable"
```
Update package lists and install Docker:
```shell
root@stretch-shaarli-02:~$ apt update && apt install -y docker-ce
```
Verify Docker is properly configured by running the `hello-world` image:
```shell
root@stretch-shaarli-02:~$ docker run hello-world
```
### Setting up Docker Compose
_The following instructions are from the
[Install Docker Compose](https://docs.docker.com/compose/install/)
guide._
Download the current version from the release page:
```shell
root@stretch-shaarli-02:~$ curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
root@stretch-shaarli-02:~$ chmod +x /usr/local/bin/docker-compose
```
## Running Shaarli
Shaarli comes with a configuration file for Docker Compose, that will setup:
- a local Docker network
- a Docker [volume](https://docs.docker.com/storage/volumes/) to store Shaarli data
- a Docker [volume](https://docs.docker.com/storage/volumes/) to store Træfik TLS configuration and certificates
- a [Shaarli](https://hub.docker.com/r/shaarli/shaarli/) instance
- a [Træfik](https://hub.docker.com/_/traefik/) instance
[Træfik](https://docs.traefik.io/) is a modern HTTP reverse proxy, with native
support for Docker and [Let's Encrypt](https://letsencrypt.org/).
### Compose configuration
Create a new directory to store the configuration:
```shell
root@stretch-shaarli-02:~$ mkdir shaarli && cd shaarli
root@stretch-shaarli-02:~/shaarli$
```
Download the current version of Shaarli's `docker-compose.yml`:
```shell
root@stretch-shaarli-02:~/shaarli$ curl -L https://raw.githubusercontent.com/shaarli/Shaarli/master/docker-compose.yml -o docker-compose.yml
```
Create the `.env` file and fill in your VPS and domain information (replace
`<MY_SHAARLI_DOMAIN>` and `<MY_CONTACT_EMAIL>` with your actual information):
```shell
root@stretch-shaarli-02:~/shaarli$ vim .env
```
```shell
SHAARLI_VIRTUAL_HOST=<MY_SHAARLI_DOMAIN>
SHAARLI_LETSENCRYPT_EMAIL=<MY_CONTACT_EMAIL>
```
### Pull the Docker images
```shell
root@stretch-shaarli-02:~/shaarli$ docker-compose pull
Pulling shaarli ... done
Pulling traefik ... done
```
### Run!
```shell
root@stretch-shaarli-02:~/shaarli$ docker-compose up -d
Creating network "shaarli_http-proxy" with the default driver
Creating volume "shaarli_traefik-acme" with default driver
Creating volume "shaarli_shaarli-data" with default driver
Creating shaarli_shaarli_1 ... done
Creating shaarli_traefik_1 ... done
```
## Conclusion
Congratulations! Your Shaarli instance should be up and running, and available
at `https://<MY_SHAARLI_DOMAIN>`.
<img src="../images/07-installation.jpg"
width="500px"
alt="Shaarli installation page" />
## Resources
### Related Shaarli documentation
- [Docker 101](../docker/docker-101.md)
- [Shaarli images](../docker/shaarli-images.md)
### Hosting providers
- [DigitalOcean](https://www.digitalocean.com/)
- [Gandi](https://www.gandi.net/en)
- [OVH](https://www.ovh.co.uk/)
- [RackSpace](https://www.rackspace.com/)
- etc.
### Domain Names and Registrars
- [Introduction to the Domain Name System (DNS)](https://opensource.com/article/17/4/introduction-domain-name-system-dns)
- [ICANN](https://www.icann.org/)
- [Domain name registrar](https://en.wikipedia.org/wiki/Domain_name_registrar)
- [OVH Domain Registration](https://www.ovh.co.uk/domains/)
- [Gandi Domain Registration](https://www.gandi.net/en/domain)
### HTTPS and Security
- [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security)
- [Let's Encrypt](https://letsencrypt.org/)
### Docker
- [Docker Overview](https://docs.docker.com/engine/docker-overview/)
- [Docker Documentation](https://docs.docker.com/)
- [Get Docker CE for Debian](https://docs.docker.com/install/linux/docker-ce/debian/)
- [docker logs](https://docs.docker.com/engine/reference/commandline/logs/)
- [Volumes](https://docs.docker.com/storage/volumes/)
- [Install Docker Compose](https://docs.docker.com/compose/install/)
- [docker-compose logs](https://docs.docker.com/compose/reference/logs/)
### Træfik
- [Getting Started](https://docs.traefik.io/)
- [Docker backend](https://docs.traefik.io/configuration/backends/docker/)
- [Let's Encrypt and Docker](https://docs.traefik.io/user-guide/docker-and-lets-encrypt/)
- [traefik](https://hub.docker.com/_/traefik/) Docker image

View file

@ -1,33 +0,0 @@
### Decode datastore content
To display the array representing the data saved in `data/datastore.php`, use the following snippet:
```php
$data = "tZNdb9MwFIb... <Commented content inside datastore.php>";
$out = unserialize(gzinflate(base64_decode($data)));
echo "<pre>"; // Pretty printing is love, pretty printing is life
print_r($out);
echo "</pre>";
exit;
```
This will output the internal representation of the datastore, "unobfuscated" (if this can really be considered obfuscation).
Alternatively, you can transform to JSON format (and pretty-print if you have `jq` installed):
```
php -r 'print(json_encode(unserialize(gzinflate(base64_decode(preg_replace("!.*/\* (.+) \*/.*!", "$1", file_get_contents("data/datastore.php")))))));' | jq .
```
### Changing the timestamp for a shaare
- Look for `<input type="hidden" name="lf_linkdate" value="{$link.linkdate}">` in `tpl/editlink.tpl` (line 14)
- Replace `type="hidden"` with `type="text"` from this line
- A new date/time field becomes available in the edit/new link dialog.
- You can set the timestamp manually by entering it in the format `YYYMMDD_HHMMS`.
### See also
- [Add a new custom field to shaares (example patch)](https://gist.github.com/nodiscc/8b0194921f059d7b9ad89a581ecd482c)
- [Download CSS styles for shaarlis listed in an opml file](https://gist.github.com/nodiscc/dede231c92cab22c3ad2cc24d5035012)
- [Copy an existing Shaarli installation over SSH, and serve it locally](https://gist.github.com/nodiscc/ed161c66e5b028b5299b0a3733d01c77)
- [Create multiple Shaarli instances, generate an HTML index of them](https://gist.github.com/nodiscc/52e711cda3bc47717c16065231cf6b20)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

View file

@ -1,121 +1,122 @@
# <img src="images/icon.png" width="20px" height="20px"> Shaarli
# Shaarli
The personal, minimalist, super-fast, database free, bookmarking service.
_The personal, minimalist, super fast, database-free, bookmarking service._
Do you want to share the links you discover?
Shaarli is a minimalist bookmark manager and link sharing service that you can install on your own server.
It is designed to be personal (single-user), fast and handy.
<!-- TODO screenshots -->
Do you want to share the links you discover? Shaarli is a minimalist bookmark manager and link sharing service that you can install on your own server. It is designed to be personal (single-user), fast and handy.
Visit the pages in the sidebar to find information on how to setup, use, configure, tweak and troubleshoot Shaarli.
* [GitHub project page](https://github.com/shaarli/Shaarli)
* [Online documentation](https://shaarli.readthedocs.io/)
* [Latest releases](https://github.com/shaarli/Shaarli/releases)
* [Documentation](https://shaarli.readthedocs.io/)
* [Changelog](https://github.com/shaarli/Shaarli/blob/master/CHANGELOG.md)
### Demo
[![](https://i.imgur.com/8wEBRSG.png)](https://i.imgur.com/WWPfSj0.png) [![](https://i.imgur.com/93PpLLs.png)](https://i.imgur.com/V09kAQt.png) [![](https://i.imgur.com/rrsjWYy.png)](https://i.imgur.com/TZzGHMs.png) [![](https://i.imgur.com/8iRzHfe.png)](https://i.imgur.com/sfJJ6NT.png) [![](https://i.imgur.com/GjZGvIh.png)](https://i.imgur.com/QsedIuJ.png) [![](https://i.imgur.com/TFZ9PEq.png)](https://i.imgur.com/KdtF8Ll.png) [![](https://i.imgur.com/tVvD3gH.png)](https://i.imgur.com/zGF4d6L.jpg)
```{toctree}
:maxdepth: 1
:hidden:
Server-configuration.md
Installation.md
Reverse-proxy.md
Docker.md
Shaarli-configuration.md
Usage.md
Backup-and-restore.md
Upgrade-and-migration.md
Community-and-related-software.md
Plugins.md
REST-API.md
Troubleshooting.md
dev/Development.md
```
## Demo
You can use this [public demo instance of Shaarli](https://demo.shaarli.org).
It runs the latest development version of Shaarli and is updated/reset daily.
Login: `demo`; Password: `demo`
## Getting started
- [Configure your server](Server-configuration.md)
- [Install Shaarli](Installation.md)
- Or install Shaarli using [Docker](Docker.md)
## Features
Shaarli can be used:
- to share, comment and save interesting links and news
- to share, comment and save interesting links
- to bookmark useful/frequent links and share them between computers
- as a minimal blog/microblog/writing platform
- as a read-it-later list
- to draft and save articles/posts/ideas
- to keep notes, documentation and code snippets
- as a shared clipboard/notepad/pastebin between machines
- as a todo list
- to store media playlists
- to keep extracts/comments from webpages that may disappear.
- to keep track of ongoing discussions
- to feed other blogs, aggregators, social networks... using RSS feeds
- as a read-it-later/todo list
- as a notepad to draft and save articles/posts/ideas
- as a knowledge base to keep notes, documentation and code snippets
- as a shared clipboard/notepad/pastebin between computers
- as playlist manager for online media
- to feed other blogs, aggregators, social networks...
### Edit, view and search your links
- Minimalist design
- FAST
- Customizable link titles and descriptions
- Tags to organize your links (features tag autocompletion, renaming, merging and deletion)
- Search by tag or using the full-text search
- Public and private links (visible only to logged-in users)
- Unique permalinks for easy reference
- Paginated link list (with image and video thumbnails)
- Tag cloud and list views
- Picture wall: image and video thumbnails view (with lazy loading)
- ATOM and RSS feeds (can also be filtered using tags or text search)
- Daily: newspaper-like daily digest (and daily RSS feed)
- URL cleanup: automatic removal of `?utm_source=...`, `fb=...`
- Extensible through [plugins](https://shaarli.readthedocs.io/en/master/Plugins/#plugin-usage)
- Editable URL, title, description, tags, private/public status for all your [Shaares](Usage.md)
- [Tags](Usage.md#tags) to organize your Shaares
- [Search](Usage.md#search) in all fields
- Unique [permalinks](Usage.md#permalinks) for easy reference
- Paginated Shaares list view (with image and video thumbnails)
- [Tag cloud/list](Usage.md#tag-cloud) views
- [Picture wall](Usage.md#picture-wall)/thumbnails view (with lazy loading)
- [ATOM and RSS feeds](Usage.md#rss-feeds) (can also be filtered using tags or text search)
- [Daily](Usage.md#daily): newspaper-like daily digest (and daily RSS feed)
- URL cleanup: automatic removal of `?utm_source=...`, `fb=...` tracking parameters
- Extensible through [plugins](Plugins.md)
- Easily extensible by any client using the [REST API](REST-API.md) exposed by Shaarli
- Bookmarklet and [other tools](Community-and-related-software.md) to share links in one click
- Responsive/support for mobile browsers, degrades gracefully with Javascript disabled
- LDAP (single-user) login support
### Easy setup
- Dead-simple installation: drop the files, open the page
- Links are stored in a file (no database required, easy backup: simply copy the datastore file)
- Import and export links as Netscape bookmarks compatible with most Web browsers
- Dead-simple [installation](Installation.md): drop the files on your server, open the page
- Shaares are stored in a file (no database required, easy [backup](Backup-and-restore.md))
- [Configurable](Shaarli-configuration.md) from dialog and configuration file
- Extensible through third-party [plugins and themes](Community-and-related-software.md)
### Accessibility
- Bookmarklet and other tools to share links in one click
- Support for mobile browsers
- Degrades gracefully with Javascript disabled
- Easy page customization through HTML/CSS/RainTPL
### Fast
### Security
- Fast! Small datastore file, write-once/read-many, served most of the time from OS disk caches (no disk I/O)
- Stays fast with even tens of thousands shaares!
- Discreet pop-up notification when a new release is available
- Bruteforce protection on the login form
- Protected against [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) and session cookie hijacking
<!-- TODO Limitations -->
### Self-hosted
### REST API
- Shaarli is an alternative to commercial services such as StumbleUpon, Delicio.us, Diigo...
- The data is yours, [import and export](Usage.md#import-export) it to HTML bookmarksformat compatible with most web browser, and from a variety of formats
- Shaarli does not send any telemetry/metrics/private information to developers
- Shaarli is Free and Open-Source software, inspect and change how the program works in the [source code](https://github.com/shaarli/Shaarli)
- Built-in [Security](dev/Development.md#security) features to help you protect your Shaarli instance
- Easily extensible by any client using the REST API exposed by Shaarli ([API documentation](http://shaarli.github.io/api-documentation/)).
## About
### Shaarli community fork
This [community fork](https://github.com/shaarli/Shaarli) of the original [Shaarli](https://github.com/sebsauvage/Shaarli/) project by [Sébastien Sauvage](https://sebsauvage.net/) (now [unmaintained](https://github.com/sebsauvage/Shaarli/issues/191)) has carried on the work to provide [many patches](https://github.com/sebsauvage/Shaarli/compare/master...shaarli:Shaarli:master) for [bug fixes and enhancements](https://github.com/shaarli/Shaarli/issues?q=is%3Aclosed+) in this repository, and will keep maintaining the project for the foreseeable future, while keeping Shaarli simple and efficient.
This friendly fork is maintained by the Shaarli community at <https://github.com/shaarli/Shaarli>
This is a community fork of the original [Shaarli](https://github.com/sebsauvage/Shaarli/) project by [Sébastien Sauvage](http://sebsauvage.net/).
The original project is currently unmaintained, and the developer [has informed us](https://github.com/sebsauvage/Shaarli/issues/191) that he would have no time to work on Shaarli in the near future.
The Shaarli community has carried on the work to provide [many
patches](https://github.com/shaarli/Shaarli/compare/sebsauvage:master...master) for
[bug fixes and enhancements](https://github.com/shaarli/Shaarli/issues?q=is%3Aclosed+)
in this repository, and will keep maintaining the project for the foreseeable
future, while keeping Shaarli simple and efficient.
The original Shaarli instance is still available [here](https://sebsauvage.net/links/) (+25000 shaares!)
### Contributing and getting help
Feedback is very appreciated!
Feedback is very appreciated! Feel free to propose solutions to existing problems, help us improve the documentation and [translations](dev/Development.md#translations), and submit pull requests :-)
- If you have any questions or ideas, please join the [chat](https://gitter.im/shaarli/Shaarli) (also reachable via [IRC](https://irc.gitter.im/)), post them in our [general discussion](https://github.com/shaarli/Shaarli/issues/308) or read the current [issues](https://github.com/shaarli/Shaarli/issues).
- Have a look at the open [issues](https://github.com/shaarli/Shaarli/issues) and [pull requests](https://github.com/shaarli/Shaarli/pulls)
- If you would like a feature added to Shaarli, check the issues labeled [`feature`](https://github.com/shaarli/Shaarli/labels/feature), [`enhancement`](https://github.com/shaarli/Shaarli/labels/enhancement), and [`plugin`](https://github.com/shaarli/Shaarli/labels/plugin).
- If you've found a bug, please create a [new issue](https://github.com/shaarli/Shaarli/issues/new).
- Feel free to propose solutions to existing problems, help us improve the documentation and translations, and submit pull requests :-)
See [Support](Troubleshooting.md#support) to get in touch with the Shaarli community.
### License
Shaarli is [Free Software](http://en.wikipedia.org/wiki/Free_software). See
[COPYING](https://github.com/shaarli/Shaarli/blob/master/COPYING) for a detail
of the contributors and licenses for each individual component. A list of
contributors is available
[here](https://github.com/shaarli/Shaarli/blob/master/AUTHORS).
Shaarli is [Free Software](https://en.wikipedia.org/wiki/Free_software). See [COPYING](https://github.com/shaarli/Shaarli/blob/master/COPYING) for a detail of the contributors and licenses for each individual component. A list of contributors is available [here](https://github.com/shaarli/Shaarli/blob/master/AUTHORS).

4
doc/requirements.txt Normal file
View file

@ -0,0 +1,4 @@
sphinx==7.1.0
furo==2023.7.26
myst-parser
sphinx-design

View file

@ -2,12 +2,13 @@
# Shaarli - Docker Compose example configuration
#
# See:
# - https://shaarli.readthedocs.io/en/master/docker/shaarli-images/
# - https://shaarli.readthedocs.io/en/master/guides/install-shaarli-with-debian9-and-docker/
# - https://shaarli.readthedocs.io/en/master/Docker/#docker-compose
#
# Environment variables:
# - SHAARLI_VIRTUAL_HOST Fully Qualified Domain Name for the Shaarli instance
# - SHAARLI_LETSENCRYPT_EMAIL Contact email for certificate renewal
# - SHAARLI_DOCKER_TAG Shaarli docker tag to use
# See: https://github.com/shaarli/Shaarli/pkgs/container/shaarli/versions?filters%5Bversion_type%5D=tagged
version: '3'
networks:
@ -20,7 +21,7 @@ volumes:
services:
shaarli:
image: shaarli/shaarli:master
image: ghcr.io/shaarli/shaarli:${SHAARLI_DOCKER_TAG}
build: ./
networks:
- http-proxy
@ -33,14 +34,14 @@ services:
traefik.frontend.rule: "Host:${SHAARLI_VIRTUAL_HOST}"
traefik:
image: traefik
image: traefik:1.7-alpine
command:
- "--defaultentrypoints=http,https"
- "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
- "--entrypoints=Name:https Address::443 TLS"
- "--retry"
- "--docker"
- "--docker.domain=docker.localhost"
- "--docker.domain=${SHAARLI_VIRTUAL_HOST}"
- "--docker.exposedbydefault=true"
- "--docker.watch=true"
- "--acme"

View file

@ -2,17 +2,17 @@ msgid ""
msgstr ""
"Project-Id-Version: Shaarli\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-23 23:57+0100\n"
"PO-Revision-Date: 2021-01-24 00:37+0100\n"
"POT-Creation-Date: 2023-04-05 08:38+0200\n"
"PO-Revision-Date: 2023-04-05 08:39+0200\n"
"Last-Translator: \n"
"Language-Team: Shaarli\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.2\n"
"X-Poedit-Basepath: ../../../..\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.2.2\n"
"X-Poedit-Basepath: ../../../..\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: t:1,2;t\n"
"X-Poedit-SearchPath-0: .\n"
@ -51,6 +51,10 @@ msgstr "Japanisch"
msgid "Russian"
msgstr "Russisch"
#: application/Languages.php:190
msgid "Chinese (Simplified)"
msgstr "Chinesisch (vereinfacht)"
#: application/Thumbnailer.php:62
msgid ""
"php-gd extension must be loaded to use thumbnails. Thumbnails are now "
@ -60,41 +64,41 @@ msgstr ""
"(Thumbnails) verwenden zu können. Thumbnails sind jetzt deaktiviert. Bitte "
"lade die Seite neu."
#: application/Utils.php:405 tests/UtilsTest.php:327
#: application/Utils.php:409 tests/UtilsTest.php:329
msgid "Setting not set"
msgstr "Einstellung nicht gesetzt"
#: application/Utils.php:412 tests/UtilsTest.php:325 tests/UtilsTest.php:326
#: application/Utils.php:416 tests/UtilsTest.php:327 tests/UtilsTest.php:328
msgid "Unlimited"
msgstr "Unbegrenzt"
#: application/Utils.php:415 tests/UtilsTest.php:322 tests/UtilsTest.php:323
#: tests/UtilsTest.php:337
#: application/Utils.php:419 tests/UtilsTest.php:324 tests/UtilsTest.php:325
#: tests/UtilsTest.php:339
msgid "B"
msgstr "B"
#: application/Utils.php:415 tests/UtilsTest.php:316 tests/UtilsTest.php:317
#: tests/UtilsTest.php:324
#: application/Utils.php:419 tests/UtilsTest.php:318 tests/UtilsTest.php:319
#: tests/UtilsTest.php:326
msgid "kiB"
msgstr "kiB"
#: application/Utils.php:415 tests/UtilsTest.php:318 tests/UtilsTest.php:319
#: tests/UtilsTest.php:335 tests/UtilsTest.php:336
#: application/Utils.php:419 tests/UtilsTest.php:320 tests/UtilsTest.php:321
#: tests/UtilsTest.php:337 tests/UtilsTest.php:338
msgid "MiB"
msgstr "MiB"
#: application/Utils.php:415 tests/UtilsTest.php:320 tests/UtilsTest.php:321
#: application/Utils.php:419 tests/UtilsTest.php:322 tests/UtilsTest.php:323
msgid "GiB"
msgstr "GiB"
#: application/bookmark/BookmarkFileService.php:185
#: application/bookmark/BookmarkFileService.php:207
#: application/bookmark/BookmarkFileService.php:229
#: application/bookmark/BookmarkFileService.php:243
#: application/bookmark/BookmarkFileService.php:203
#: application/bookmark/BookmarkFileService.php:225
#: application/bookmark/BookmarkFileService.php:247
#: application/bookmark/BookmarkFileService.php:261
msgid "You're not authorized to alter the datastore"
msgstr "Du bist nicht berechtigt, den Datenspeicher zu ändern"
#: application/bookmark/BookmarkFileService.php:210
#: application/bookmark/BookmarkFileService.php:228
msgid "This bookmarks already exists"
msgstr "Diese Lesezeichen sind bereits vorhanden"
@ -194,13 +198,13 @@ msgstr ""
"| Karotte | Gemüse | rot | 14 |\n"
#: application/bookmark/BookmarkInitializer.php:94
#: application/legacy/LegacyLinkDB.php:246
#: application/legacy/LegacyLinkDB.php:249
#: tmp/page.footer.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15
#: tmp/page.footer.b91ef64efc3688266305ea9b42e5017e.rtpl.php:48
#: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:15
#: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:48
msgid ""
"The personal, minimalist, super-fast, database free, bookmarking service"
"The personal, minimalist, super fast, database-free, bookmarking service"
msgstr ""
"Der persönliche, minimalistische, superschnelle, datenbankfreie "
"Lesezeichenservice"
@ -293,11 +297,11 @@ msgstr "Du bist nicht berechtigt, die Konfiguration zu ändern."
msgid "Error accessing"
msgstr "Fehler beim Zugriff"
#: application/feed/FeedBuilder.php:180
#: application/feed/FeedBuilder.php:174
msgid "Direct link"
msgstr "Direct Link"
#: application/feed/FeedBuilder.php:182
#: application/feed/FeedBuilder.php:176
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:103
#: tmp/dailyrss.b91ef64efc3688266305ea9b42e5017e.rtpl.php:26
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:179
@ -372,25 +376,25 @@ msgstr "Tags verwalten"
msgid "Invalid tags provided."
msgstr "Ungültige Tags übergeben."
#: application/front/controller/admin/ManageTagController.php:78
#: application/front/controller/admin/ManageTagController.php:81
#, php-format
msgid "The tag was removed from %d bookmark."
msgid_plural "The tag was removed from %d bookmarks."
msgstr[0] "Der Tag wurde aus dem Lesezeichen %d entfernt."
msgstr[1] "Der Tag wurde aus den Lesezeichen %d entfernt."
#: application/front/controller/admin/ManageTagController.php:83
#: application/front/controller/admin/ManageTagController.php:86
#, php-format
msgid "The tag was renamed in %d bookmark."
msgid_plural "The tag was renamed in %d bookmarks."
msgstr[0] "Der Tag wurde im Lesezeichen %d umbenannt."
msgstr[1] "Der Tag wurde in den Lesezeichen %d umbenannt."
#: application/front/controller/admin/ManageTagController.php:105
#: application/front/controller/admin/ManageTagController.php:108
msgid "Tags separator must be a single character."
msgstr "Tags müssen durch ein einzelnen Zeichen getrennt werden."
#: application/front/controller/admin/ManageTagController.php:111
#: application/front/controller/admin/ManageTagController.php:114
msgid "These characters are reserved and can't be used as tags separator: "
msgstr ""
"Diese Zeichen sind reserviert und können nicht als Tag-Trennzeichen genutzt "
@ -450,22 +454,32 @@ msgid "Shaare a new link"
msgstr "Teile einen neuen Link"
#: application/front/controller/admin/ShaareManageController.php:35
#: application/front/controller/admin/ShaareManageController.php:93
#: application/front/controller/admin/ShaareManageController.php:97
#: application/front/controller/admin/ShaareManageController.php:227
msgid "Invalid bookmark ID provided."
msgstr "Ungültige Lesezeichen-ID bereitgestellt."
#: application/front/controller/admin/ShaareManageController.php:47
#: application/front/controller/admin/ShaareManageController.php:116
#: application/front/controller/admin/ShaareManageController.php:156
#: application/front/controller/admin/ShaareManageController.php:120
#: application/front/controller/admin/ShaareManageController.php:160
#: application/front/controller/admin/ShaareManageController.php:257
#: application/front/controller/admin/ShaarePublishController.php:82
#, php-format
msgid "Bookmark with identifier %s could not be found."
msgstr "Lesezeichen mit der ID %s konnte nicht gefunden werden."
#: application/front/controller/admin/ShaareManageController.php:101
#: application/front/controller/admin/ShaareManageController.php:105
msgid "Invalid visibility provided."
msgstr "Ungültige Sichtbarkeit angegeben."
#: application/front/controller/admin/ShaareManageController.php:235
msgid "Invalid action provided."
msgstr "Ungültige Aktion übergeben."
#: application/front/controller/admin/ShaareManageController.php:243
msgid "Invalid tag name provided."
msgstr "Ungültiger Tag-Name übergeben."
#: application/front/controller/admin/ShaarePublishController.php:173
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:171
msgid "Edit"
@ -492,7 +506,7 @@ msgstr "Thumbnail-Aktualisierung"
msgid "Tools"
msgstr "Tools"
#: application/front/controller/visitor/BookmarkListController.php:121
#: application/front/controller/visitor/BookmarkListController.php:103
msgid "Search: "
msgstr "Suche: "
@ -566,6 +580,10 @@ msgstr ""
"Speicher fehlschlägt. Wir empfehlen den Zugriff auf deinen Server über die "
"IP-Adresse oder den Fully Qualified Domain Namen.<br>"
#: application/front/controller/visitor/InstallController.php:134
msgid "Shared Bookmarks"
msgstr "Geteilte Lesezeichen "
#: application/front/controller/visitor/InstallController.php:162
msgid ""
"Shaarli is now configured. Please login and start shaaring your bookmarks!"
@ -694,15 +712,15 @@ msgstr "Verwende das Übersetzungssystem im gettext-Modus"
msgid "Login using LDAP server"
msgstr "Anmeldung mittels LDAP-Server"
#: application/helper/DailyPageHelper.php:179
#: application/helper/DailyPageHelper.php:184
msgid "Week"
msgstr "Woche"
#: application/helper/DailyPageHelper.php:183
#: application/helper/DailyPageHelper.php:188
msgid "Today"
msgstr "Heute"
#: application/helper/DailyPageHelper.php:185
#: application/helper/DailyPageHelper.php:190
msgid "Yesterday"
msgstr "Gestern"
@ -730,7 +748,7 @@ msgstr "Du musst eine Ganzzahl als Schlüssel angeben."
msgid "Array offset and link ID must be equal."
msgstr "Array-Offset und Link-ID müssen gleich sein."
#: application/legacy/LegacyLinkDB.php:249
#: application/legacy/LegacyLinkDB.php:252
msgid ""
"Welcome to Shaarli! This is your first public bookmark. To edit or delete "
"me, you must first login.\n"
@ -750,11 +768,11 @@ msgstr ""
"Du verwendest die von der Community unterstützte Version des ursprünglichen "
"Shaarli-Projekts von Sebastien Sauvage."
#: application/legacy/LegacyLinkDB.php:266
#: application/legacy/LegacyLinkDB.php:269
msgid "My secret stuff... - Pastebin.com"
msgstr "Meine geheimen Sachen... - Pastebin.com"
#: application/legacy/LegacyLinkDB.php:268
#: application/legacy/LegacyLinkDB.php:271
msgid "Shhhh! I'm a private link only YOU can see. You can delete me too."
msgstr ""
"Pssst Ich bin ein privater Link, den nur du sehen kannst. Du kannst mich "
@ -772,16 +790,16 @@ msgstr "<a href=\"./admin/thumbnails\">"
msgid "Invalid export selection:"
msgstr "Ungültige Exportauswahl:"
#: application/netscape/NetscapeBookmarkUtils.php:215
#: application/netscape/NetscapeBookmarkUtils.php:213
#, php-format
msgid "File %s (%d bytes) "
msgstr "Datei %s (%d bytes) "
#: application/netscape/NetscapeBookmarkUtils.php:217
#: application/netscape/NetscapeBookmarkUtils.php:215
msgid "has an unknown file format. Nothing was imported."
msgstr "hat ein unbekanntes Dateiformat. Es wurde nichts importiert."
#: application/netscape/NetscapeBookmarkUtils.php:221
#: application/netscape/NetscapeBookmarkUtils.php:219
#, php-format
msgid ""
"was successfully processed in %d seconds: %d bookmarks imported, %d "
@ -790,8 +808,8 @@ msgstr ""
"wurde erfolgreich in %d Sekunden verarbeitet: %d Lesezeichen importiert, %d "
"Lesezeichen überschrieben, %d Lesezeichen übersprungen."
#: application/plugin/PluginManager.php:99
#: application/plugin/PluginManager.php:137
#: application/plugin/PluginManager.php:103
#: application/plugin/PluginManager.php:141
msgid " [plugin incompatibility]: "
msgstr " [Plugin-Inkompatibiliät]: "
@ -809,7 +827,7 @@ msgstr "Kann nicht löschen, %s ist kein Verzeichnis"
msgid "An error occurred while running the update "
msgstr "Beim Ausführen des Updates ist ein Fehler aufgetreten "
#: index.php:82
#: index.php:87
msgid "Shared bookmarks on "
msgstr "Geteilte Lesezeichen auf "
@ -858,7 +876,7 @@ msgstr "Hintergrund-Farbe (hellgrau)"
msgid "Dark main color (e.g. visited links)"
msgstr "Dunkle Haupt-Farbe (z. B. besuchte Links)"
#: plugins/demo_plugin/demo_plugin.php:495
#: plugins/demo_plugin/demo_plugin.php:528
msgid ""
"A demo plugin covering all use cases for template designers and plugin "
"developers."
@ -866,12 +884,12 @@ msgstr ""
"Ein Demo-Plugin, das alle Anwendungsfälle für Template-Designer und Plugin-"
"Entwickler abdeckt."
#: plugins/demo_plugin/demo_plugin.php:496
#: plugins/demo_plugin/demo_plugin.php:529
msgid "This is a parameter dedicated to the demo plugin. It'll be suffixed."
msgstr ""
"Dies ist ein Parameter, der dem Demo-Plugin gewidmet ist. Es wird angehängt."
#: plugins/demo_plugin/demo_plugin.php:497
#: plugins/demo_plugin/demo_plugin.php:530
msgid "Other demo parameter"
msgstr "Andere Demo-Parameter"
@ -885,9 +903,7 @@ msgstr ""
#: plugins/isso/isso.php:92
msgid "Let visitor comment your shaares on permalinks with Isso."
msgstr ""
"Lassen Sie Besucher Ihre Shaares auf Permalinks mit Isso "
"kommentieren."
msgstr "Lassen Sie Besucher Ihre Shaares auf Permalinks mit Isso kommentieren."
#: plugins/isso/isso.php:93
msgid "Isso server URL (without 'http://')"
@ -932,29 +948,41 @@ msgstr ""
msgid "plugins/playvideos/jquery-1.11.2.min.js"
msgstr "plugins/playvideos/jquery-1.11.2.min.js"
#: plugins/pubsubhubbub/pubsubhubbub.php:72
#: plugins/pubsubhubbub/pubsubhubbub.php:80
#, php-format
msgid "Could not publish to PubSubHubbub: %s"
msgstr "Veröffentlichung auf PubSubHubbub nicht möglich: %s"
#: plugins/pubsubhubbub/pubsubhubbub.php:99
#: plugins/pubsubhubbub/pubsubhubbub.php:107
#, php-format
msgid "Could not post to %s"
msgstr "Kann nicht posten auf %s"
#: plugins/pubsubhubbub/pubsubhubbub.php:103
#: plugins/pubsubhubbub/pubsubhubbub.php:111
#, php-format
msgid "Bad response from the hub %s"
msgstr "Ungültige Antwort vom Hub %s"
#: plugins/pubsubhubbub/pubsubhubbub.php:114
#: plugins/pubsubhubbub/pubsubhubbub.php:122
msgid "Enable PubSubHubbub feed publishing."
msgstr "Aktiviere PubSubHubbub Feed Veröffentlichung."
#: plugins/qrcode/qrcode.php:74 plugins/wallabag/wallabag.php:72
#: plugins/qrcode/qrcode.php:74
msgid "For each link, add a QRCode icon."
msgstr "Für jeden Link, füge eine QRCode Icon hinzu."
#: plugins/readitlater/readitlater.php:118
msgid "Mark as Read"
msgstr "Als gelesen markieren"
#: plugins/readitlater/readitlater.php:118
msgid "Read it later"
msgstr "Später lesen"
#: plugins/readitlater/readitlater.php:130
msgid "Filter ReadItLater bookmarks"
msgstr "ReadItLater-Lesezeichen filtern"
#: plugins/wallabag/wallabag.php:22
msgid ""
"Wallabag plugin error: Please define the \"WALLABAG_URL\" setting in the "
@ -967,6 +995,12 @@ msgstr ""
msgid "Save to wallabag"
msgstr "Auf Wallabag speichern"
#: plugins/wallabag/wallabag.php:72
msgid "For each link, add a Wallabag icon to save it in your instance."
msgstr ""
"Für jeden Link ein Wallabag-Symbol hinzufügen, um es in Deiner Instanz zu "
"speichern."
#: plugins/wallabag/wallabag.php:73
msgid "Wallabag API URL"
msgstr "Wallabag API URL"
@ -976,8 +1010,8 @@ msgid "Wallabag API version (1 or 2)"
msgstr "Wallabag API version (1 oder 2)"
#: tests/LanguagesTest.php:214 tests/LanguagesTest.php:227
#: tests/languages/fr/LanguagesFrTest.php:159
#: tests/languages/fr/LanguagesFrTest.php:172
#: tests/languages/fr/LanguagesFrTest.php:160
#: tests/languages/fr/LanguagesFrTest.php:173
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:46
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:87
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:139
@ -1071,6 +1105,7 @@ msgid "Rename tag"
msgstr "Tag umbenennen"
#: tmp/changetag.b91ef64efc3688266305ea9b42e5017e.rtpl.php:35
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:195
msgid "Delete tag"
msgstr "Lösche Tag"
@ -1108,6 +1143,38 @@ msgstr ""
"Beachten Sie, dass Hashtags nicht vollständig mit einem Nicht-"
"Leerraumtrennzeichen funktionieren."
#: tmp/configure.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:167
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:339
#: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:30
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102
msgid "All"
msgstr "Alle"
#: tmp/configure.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:171
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:343
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106
msgid "Only common media hosts"
msgstr "Nur gängige Medienhosts"
#: tmp/configure.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:175
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:347
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:110
msgid "None"
msgstr "Keine"
#: tmp/configure.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:182
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:324
msgid "You need to enable the extension <code>php-gd</code> to use thumbnails."
msgstr ""
"Sie müssen die Erweiterung <code>php-gd</code> aktivieren, um "
"Miniaturansichten zu verwenden."
#: tmp/configure.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:186
#, fuzzy
#| msgid "Synchronize thumbnails"
msgid "Synchonize thumbnails"
msgstr "Thumbnails synchronisieren"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
msgid "title"
msgstr "Titel"
@ -1121,17 +1188,16 @@ msgid "Default value"
msgstr "Standardwert"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:58
msgid "Theme"
msgstr "Thema"
msgid "Themes"
msgstr "Themen"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:85
msgid "Description formatter"
msgstr "Beschreibungsformatierer"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:114
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:77
msgid "Language"
msgstr "Sprache"
msgid "Languages"
msgstr "Sprachen"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:143
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:101
@ -1185,8 +1251,9 @@ msgid "Do not show any links if the user is not logged in"
msgstr "Zeige keine Links, wenn der Benutzer nicht angemeldet ist"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:258
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:149
msgid "Check updates"
#, fuzzy
#| msgid "Check updates"
msgid "Check for updates"
msgstr "Auf Updates prüfen"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:259
@ -1215,40 +1282,18 @@ msgstr ""
"Anwendung"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:306
msgid "API secret"
msgstr "API-Geheimnis"
msgid "REST API secret"
msgstr "REST API-Geheimnis"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:320
msgid "Enable thumbnails"
msgstr "Aktivierte Thunbnails"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:324
msgid "You need to enable the extension <code>php-gd</code> to use thumbnails."
msgstr ""
"Sie müssen die Erweiterung <code>php-gd</code> aktivieren, um "
"Miniaturansichten zu verwenden."
msgstr "Aktivierte Thumbnails"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:328
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:122
msgid "Synchronize thumbnails"
msgstr "Thumbnails synchronisieren"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:339
#: tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:30
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:102
msgid "All"
msgstr "Alle"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:343
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:106
msgid "Only common media hosts"
msgstr "Nur gängige Medienhosts"
#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:347
#: tmp/server.b91ef64efc3688266305ea9b42e5017e.rtpl.php:110
msgid "None"
msgstr "Keine"
#: tmp/daily.b91ef64efc3688266305ea9b42e5017e.rtpl.php:26
msgid "1 RSS entry per :type"
msgid_plural ""
@ -1315,6 +1360,7 @@ msgid "Markdown syntax"
msgstr "Markdown-Syntax"
#: tmp/editlink.b91ef64efc3688266305ea9b42e5017e.rtpl.php:115
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:198
msgid "Cancel"
msgstr "Abbruch"
@ -1400,14 +1446,14 @@ msgstr ""
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:32
#: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:16
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:167
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:167
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:209
msgid "Username"
msgstr "Benutzername"
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:47
#: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:20
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:168
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:168
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:210
msgid "Password"
msgstr "Passwort"
@ -1419,6 +1465,14 @@ msgstr "Shaarli Titel"
msgid "My links"
msgstr "Meine Links"
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:77
msgid "Language"
msgstr "Sprache"
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:149
msgid "Check updates"
msgstr "Auf Updates prüfen"
#: tmp/install.b91ef64efc3688266305ea9b42e5017e.rtpl.php:181
msgid "Install"
msgstr "Installiere"
@ -1504,6 +1558,7 @@ msgid "permalink"
msgstr "Permalink"
#: tmp/linklist.b91ef64efc3688266305ea9b42e5017e.rtpl.php:183
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:195
msgid "Add tag"
msgstr "Tag hinzufügen"
@ -1560,7 +1615,7 @@ msgstr "Links pro Seite"
#: tmp/loginform.b91ef64efc3688266305ea9b42e5017e.rtpl.php:25
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:171
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:171
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:213
msgid "Remember me"
msgstr "Erinnere dich an mich"
@ -1632,15 +1687,33 @@ msgid "Set private"
msgstr "Setze Status auf Privat"
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:189
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:189
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:231
msgid "is available"
msgstr "ist verfügbar"
#: tmp/page.header.b91ef64efc3688266305ea9b42e5017e.rtpl.php:196
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:196
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:238
msgid "Error"
msgstr "Fehler"
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:162
msgid "Add tags"
msgstr "Tags hinzufügen"
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:167
msgid "Delete tags"
msgstr "Lösche Tags"
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:184
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:185
msgid "Tag to add"
msgstr "Tag hinzufügen"
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:184
#: tmp/page.header.cedf684561d925457130839629000a81.rtpl.php:185
msgid "Tag to delete"
msgstr "Tag zur Löschung"
#: tmp/picwall.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15
msgid "There is no cached thumbnail."
msgstr "Es gibt keine zwischengespeicherte Miniaturansicht / Thumbnail."
@ -1658,7 +1731,9 @@ msgid "pics"
msgstr "Bilder"
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:15
msgid "You need to enable Javascript to change plugin loading order."
#, fuzzy
#| msgid "You need to enable Javascript to change plugin loading order."
msgid "You have to enable JavaScript to change plugin loading order."
msgstr ""
"Du musst Javascript aktivieren um die Ladereihenfolge der Plugins zu ändern."
@ -1678,8 +1753,10 @@ msgstr "Kein Plugin aktiviert."
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:40
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:73
msgid "Disable"
msgstr "Deaktivieren"
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:97
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:122
msgid "Enabled"
msgstr "Aktiviert"
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:41
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:74
@ -1701,11 +1778,6 @@ msgstr "Deaktivierte Plugins"
msgid "No plugin disabled."
msgstr "Kein Plugin deaktiviert."
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:97
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:122
msgid "Enable"
msgstr "Aktiviere"
#: tmp/pluginsadmin.b91ef64efc3688266305ea9b42e5017e.rtpl.php:134
msgid "More plugins available"
msgstr "Weitere Plugins verfügbar"
@ -1934,6 +2006,10 @@ msgstr ""
msgid "Export database"
msgstr "Exportiere Datenbank"
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:75
msgid "Bookmarklets"
msgstr "Lesezeichen (Bookmarklets)"
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:77
msgid ""
"Drag one of these button to your bookmarks toolbar or right-click it and "
@ -1985,15 +2061,14 @@ msgid "Add Note"
msgstr "Notiz hinzufügen"
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:132
msgid "3rd party"
msgstr "Von Dritten"
msgid "Third-party resources"
msgstr "Ressourcen von Dritt-Anbietern"
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:135
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:140
msgid "plugin"
msgstr "Plugin"
msgid "Community and related software"
msgstr "Gemeinschaft und zugehörige Software"
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:165
#: tmp/tools.b91ef64efc3688266305ea9b42e5017e.rtpl.php:144
msgid ""
"Drag this link to your bookmarks toolbar, or right-click it and choose "
"Bookmark This Link"
@ -2001,6 +2076,15 @@ msgstr ""
"Ziehe diesen Link in deine Lesezeichen-Symbolleiste oder klicke mit der "
"rechten Maustaste darauf und wähle \"Speichere diesen Link als Lesezeichen\""
#~ msgid "Disable"
#~ msgstr "Deaktivieren"
#~ msgid "3rd party"
#~ msgstr "Von Dritten"
#~ msgid "plugin"
#~ msgstr "Plugin"
#~ msgid "Rename"
#~ msgstr "Umbenennen"

View file

@ -193,7 +193,7 @@ msgstr ""
#: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:15
#: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:48
msgid ""
"The personal, minimalist, super-fast, database free, bookmarking service"
"The personal, minimalist, super fast, database-free, bookmarking service"
msgstr ""
"Le gestionnaire de marque-pages personnel, minimaliste, et sans base de "
"données"

View file

@ -194,7 +194,7 @@ msgstr ""
#: application/bookmark/BookmarkInitializer.php:94
#: application/legacy/LegacyLinkDB.php:246
msgid ""
"The personal, minimalist, super-fast, database free, bookmarking service"
"The personal, minimalist, super fast, database-free, bookmarking service"
msgstr ""
"個人向けの、ミニマムで高速でかつデータベースのいらないブックマークサービス"

View file

@ -196,7 +196,7 @@ msgstr ""
#: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:15
#: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:48
msgid ""
"The personal, minimalist, super-fast, database free, bookmarking service"
"The personal, minimalist, super fast, database-free, bookmarking service"
msgstr "Личный, минималистичный, сверхбыстрый сервис закладок без баз данных"
#: application/bookmark/BookmarkInitializer.php:97

View file

@ -195,7 +195,7 @@ msgstr ""
#: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:15
#: tmp/page.footer.cedf684561d925457130839629000a81.rtpl.php:48
msgid ""
"The personal, minimalist, super-fast, database free, bookmarking service"
"The personal, minimalist, super fast, database-free, bookmarking service"
msgstr "个人、超快、极简、掌握数据库的书签服务"
#: application/bookmark/BookmarkInitializer.php:97

Some files were not shown because too many files have changed in this diff Show more