Commit f9e77996 authored by  JosephK's avatar JosephK
Browse files

Squashed 'shaarli/' content from commit 340777a

git-subtree-dir: shaarli
git-subtree-split: 340777ad3f0b4e798a3eedfb730d993972adbe3e
# Set default behavior
* text=auto eol=lf
# Ensure sources are processed
*.conf text
*.css text
*.html text diff=html
*.js text
*.md text
*.php text diff=php
Dockerfile text
# Do not alter images nor minified scripts
*.ico binary
*.jpg binary
*.png binary
*.min.css binary
*.min.js binary
# Exclude from Git archives
.gitattributes export-ignore
.gitignore export-ignore
.travis.yml export-ignore
composer.json export-ignore
doc/**/*.json export-ignore
doc/**/*.md export-ignore
docker/ export-ignore
Doxyfile export-ignore
Makefile export-ignore
phpunit.xml export-ignore
tests/ export-ignore
# Ignore data/, tmp/, cache/ and pagecache/
# Eclipse project files
# Ignore raintpl generated pages
# Ignore test dependencies
# Ignore development and test resources
# Ignore user plugin configuration
sudo: false
language: php
- 7.0
- 5.6
- 5.5
- 5.4
- 5.3
- composer self-update
- composer install
- make clean
- make check_permissions
- make test
## Contributing to Shaarli (community repository)
### Bugs and feature requests
**Reporting bugs, feature requests: issues management**
You can look through existing bugs/requests and help reporting them [here](
Constructive input/experience reports/helping other users is welcome.
The general guideline of the fork is to keep Shaarli simple (project and code maintenance, and features-wise), while providing customization capabilities (plugin system, making more settings configurable).
Check the [milestones]( to see what issues have priority.
* The issues list should preferably contain **only tasks that can be actioned immediately**. Anyone should be able to open the issues list, pick one and start working on it immediately.
* If you have a clear idea of a **feature you expect, or have a specific bug/defect to report**, [search the issues list, both open and closed]( to check if it has been discussed, and comment on the appropriate issue. If you can't find one, please open a [new issue](
* **General discussions** fit in #44 so that we don't follow a slope where users and contributors have to track 90 "maybe" items in the bug tracker. Separate issues about clear, separate steps can be opened after discussion.
* You can also join instant discussion at, or via IRC as described [here](
### Documentation
**the [wiki]( is world-writable** - anyone can edit or add chapters and pages.
* Large changes should preferably be discussed in [General discussion]( beforehand (you can post a draft there and edit it).
* If you create a new page, please link it from the new page (eg from the [Other links]( section.
* The wiki is a general documentation about Shaarli: usage, development, hacks, usage tricks, related links, projects. Try to keep it organized.
* The wiki will be synced to Shaarli's `doc/` directory on each release. Keep that in mind when reviewing the quality of your edits.
You can make the project known by publishing blog posts/articles/videos about it and adding them to the links section in the wiki.
### Translations
Currently Shaarli has no translation/internationalization/localization system available and is single-language. You can help by proposing an i18n system (issue
### Beta testing
You can help testing Shaarli releases by immediately upgrading your installation after a [new version has been releases](
All current development happens in [Pull Requests]( You can test proposed patches by cloning the Shaarli repo, adding the Pull Request branch and `git checkout` to it. You can also merge multiple Pull Requests to a testing branch.
git clone
git remote add pull-request-25 owner/cool-new-feature
git remote add pull-request-26 anotherowner/bugfix
git remote update
git checkout -b testing
git merge cool-new-feature
git merge bugfix
Or see [Checkout Github Pull Requests locally](
Please report any problem you might find.
### Contributing code
#### Adding your own changes
* Pick or open an issue
* Fork the Shaarli repository on github
* `git clone` your fork
* starting from branch ` master`, switch to a new branch (eg. `git checkout -b my-awesome-feature`)
* edit the required files (from the Github web interface or your text editor)
* add and commit your changes with a meaningful commit message (eg `Cool new feature, fixes issue #1001`)
* run unit tests against your patched version, see [Running unit tests](
* Open your fork in the Github web interface and click the "Compare and Pull Request" button, enter required info and submit your Pull Request.
All changes you will do on the `my-awesome-feature` in the future will be added to your Pull Request. Don't work directly on the master branch, don't do unrelated work on your `my-awesome-feature` branch.
#### Contributing to an existing Pull Request
#### Useful links
If you are not familiar with Git or Github, here are a few links to set you on track:
* - 10 minutes Github workflow interactive tutorial
* - A Git cheatsheet
* - Helps you understand some basic Git concepts visually
* - Git tutorials
* - Git workflows
* - The official Git book, multiple languages
* - Git tutorials
* - Guide to Git
* - medium to advanced Git docs/tips/blog/articles
* - Participating in Open Source
This diff is collapsed.
This diff is collapsed.
# Shaarli, the personal, minimalist, super-fast, no-database delicious clone.
# Makefile for PHP code analysis & testing
# Prerequisites:
# - install Composer, either:
# - from your distro's package manager;
# - from the official website (;
# - install/update test dependencies:
# $ composer install # 1st setup
# $ composer update
# - install Xdebug for PHPUnit code coverage reports:
# - see
# - enable in php.ini
BIN = vendor/bin
PHP_SOURCE = index.php application tests plugins
PHP_COMMA_SOURCE = index.php,application,tests,plugins
all: static_analysis_summary check_permissions test
# Concise status of the project
# These targets are non-blocking: || exit 0
static_analysis_summary: code_sniffer_source copy_paste mess_detector_summary
# PHP_CodeSniffer
# Detects PHP syntax errors
# Documentation (usage, output formatting):
# -
# -
code_sniffer: code_sniffer_full
### - errors filtered by coding standard: PEAR, PSR1, PSR2, Zend...
@$(BIN)/phpcs $(PHP_SOURCE) --report-full --report-width=200 --standard=$*
### - errors by Git author
@$(BIN)/phpcs $(PHP_SOURCE) --report-gitblame
### - all errors/warnings
@$(BIN)/phpcs $(PHP_SOURCE) --report-full --report-width=200
### - errors grouped by kind
@$(BIN)/phpcs $(PHP_SOURCE) --report-source || exit 0
# PHP Copy/Paste Detector
# Detects code redundancy
# Documentation:
@echo "-----------------------"
@echo "-----------------------"
@$(BIN)/phpcpd $(PHP_SOURCE) || exit 0
# PHP Mess Detector
# Detects PHP syntax errors, sorted by category
# Rules documentation:
MESS_DETECTOR_RULES = cleancode,codesize,controversial,design,naming,unusedcode
@echo "-----------------"
@echo "-----------------"
### - all warnings
mess_detector: mess_title
@$(BIN)/phpmd $(PHP_COMMA_SOURCE) text $(MESS_DETECTOR_RULES) | sed 's_.*\/__'
### - all warnings + HTML output contains links to PHPMD's documentation
--reportfile phpmd.html || exit 0
### - warnings grouped by message, sorted by descending frequency order
mess_detector_grouped: mess_title
| cut -f 2 | sort | uniq -c | sort -nr
### - summary: number of warnings by rule set
mess_detector_summary: mess_title
@for rule in $$(echo $(MESS_DETECTOR_RULES) | tr ',' ' '); do \
warnings=$$($(BIN)/phpmd $(PHP_COMMA_SOURCE) text $$rule | wc -l); \
printf "$$warnings\t$$rule\n"; \
# Checks source file & script permissions
@echo "----------------------"
@echo "Check file permissions"
@echo "----------------------"
@for file in `git ls-files`; do \
if [ -x $$file ]; then \
errors=true; \
echo "$${file} is executable"; \
fi \
done; [ -z $$errors ] || false
# PHPUnit
# Runs unitary and functional tests
# Generates an HTML coverage report if Xdebug is enabled
# See phpunit.xml for configuration
@echo "-------"
@echo "PHPUNIT"
@echo "-------"
@mkdir -p sandbox
@$(BIN)/phpunit tests
# Targets for repository and documentation maintenance
### remove all unversioned files
@git clean -df
@rm -rf sandbox
### generate Doxygen documentation
doxygen: clean
@rm -rf doxygen
@( cat Doxyfile ; echo "PROJECT_NUMBER=`git describe`" ) | doxygen -
### update the local copy of the documentation
doc: clean
@rm -rf doc
@git clone doc
@rm -rf doc/.git
### Generate a custom sidebar
# Sidebar content:
# - convert GitHub-flavoured relative links to standard Markdown
# - trim HTML, only keep the list (<ul>[...]</ul>) part
@echo '<div id="local-sidebar">' > doc/sidebar.html
@awk 'BEGIN { FS = "[\\[\\]]{2}" }'\
'm = /\[/ { t=$$2; gsub(/ /, "-", $$2); print $$1"["t"]("$$2".html)"$$3 }'\
'!m { print $$0 }' doc/ > doc/
@pandoc -f markdown -t html5 -s doc/ | awk '/(ul>|li>)/' >> doc/sidebar.html
@echo '</div>' >> doc/sidebar.html
@rm doc/
### Convert local markdown documentation to HTML
# For all pages:
# - infer title from the file name
# - convert GitHub-flavoured relative links to standard Markdown
# - insert the sidebar menu
@for file in `find doc/ -maxdepth 1 -name "*.md"`; do \
base=`basename $$file .md`; \
sed -i "1i #$${base//-/ }" $$file; \
awk 'BEGIN { FS = "[\\[\\]]{2}" }'\
'm = /\[/ { t=$$2; gsub(/ /, "-", $$2); print $$1"["t"]("$$2".html)"$$3 }'\
'!m { print $$0 }' $$file > doc/; \
mv doc/ $$file; \
pandoc -f markdown_github -t html5 -s \
-c "github-markdown.css" \
-T Shaarli -M pagetitle:"$${base//-/ }" -B doc/sidebar.html \
-o doc/$$base.html $$file; \
htmldoc: doc htmlsidebar htmlpages
![Shaarli logo](doc/images/doc-logo.png)
The personal, minimalist, super-fast, database free, bookmarking service.
_Do you want to share the links you discover?_
_Shaarli is a minimalist delicious clone that you can install on your own server._
_It is designed to be personal (single-user), fast and handy._
[![Docker repository](](
[![Join the chat at](](
## Quickstart
- [Wiki/documentation](
- [Bugs/Feature requests/Discussion](
### Demo
You can use this [public demo instance of Shaarli](
It runs the latest development version of Shaarli and is updated/reset daily.
Login: `demo`; Password: `demo`
### Installation & upgrade
- [Download](
- [Server requirements](
- [Server configuration](
- [Shaarli configuration](
## Features
### Interface
- minimalist design (simple is beautiful)
- ATOM and RSS feeds
- views:
- paginated link list
- tag cloud
- picture wall: image and video thumbnails
- daily: newspaper-like daily digest
- daily RSS feed
- permalinks for easy reference
- links can be public or private
- extensible through [plugins](
### Tag, view and search your links!
- add a custom title and description to archived links
- add tags to classify and search links
- features tag autocompletion, renaming, merging and deletion
- full-text and tag search
### Easy setup
- dead-simple installation: drop the files, open the page
- links are stored in a file
- compact storage
- no database required
- easy backup: simply copy the datastore file
- import and export links as Netscape bookmarks
### Accessibility
- Firefox bookmarlet to share links in one click
- support for mobile browsers
- works with Javascript disabled
- easy page customization through HTML/CSS/RainTPL
### Security
- bruteforce-proof login form
- protected against [XSRF](
and session cookie hijacking
### Goodies
- thumbnail generation for images and video services:
dailymotion, flickr, imageshack, imgur, vimeo, xkcd, youtube...
- lazy-loading with [bLazy](
- [PubSubHubbub]( protocol support
- URL cleanup: automatic removal of `?utm_source=...`, `fb=...`
- discreet pop-up notification when a new release is available
### Other usages
Though Shaarli is primarily a bookmarking application, it can serve other purposes
(see [usage examples](
- micro-blogging
- pastebin
- online notepad
- snippet archive
## About
### Shaarli community fork
This friendly fork is maintained by the Shaarli community at
This is a community fork of the original [Shaarli]( project by [Sébastien Sauvage](
The original project is currently unmaintained, and the developer [has informed us](
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](
for [bug fixes and enhancements](
in this repository, and will keep maintaining the project for the foreseeable future, while keeping Shaarli simple and efficient.
### Contributing
If you'd like to help, please:
- have a look at the open [issues](
and [pull requests](
- feel free to report bugs (feedback is much appreciated)
- suggest new features and improvements to both code and [documentation](
- propose solutions to existing problems
- submit pull requests :-)
### License
Shaarli is [Free Software]( See [COPYING](COPYING) for a detail of the contributors and licenses for each individual component.
Allow from none
Deny from all
* Shaarli (application) utilities
class ApplicationUtils
private static $GIT_URL = '';
private static $GIT_BRANCHES = array('master', 'stable');
private static $VERSION_FILE = 'shaarli_version.php';
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.
* @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 str_replace(
array('', '', ''),
* 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
* @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,
if (! $isLoggedIn) {
// Do not check versions for visitors
return false;
if (empty($enableCheck)) {
// Do not check if the user doesn't want to
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
$latestVersion = static::getLatestGitVersionCode(
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) {
throw new Exception(
'Your PHP version is obsolete!'
.' Shaarli requires at least PHP '.$minVersion.', and thus cannot run.'
.' Your PHP version has known security vulnerabilities and should be'
.' updated as soon as possible.'
* Checks Shaarli has the proper access permissions to its resources
* @param array $globalConfig The $GLOBALS['config'] array
* @return array A list of the detected configuration issues
public static function checkResourcePermissions($globalConfig)
$errors = array();
// Check script and template directories are readable
foreach (array(
) as $path) {
if (! is_readable(realpath($path))) {
$errors[] = '"'.$path.'" directory is not readable';
// Check cache and data directories are readable and writeable
foreach (array(
) as $path) {
if (! is_readable(realpath($path))) {
$errors[] = '"'.$path.'" directory is not readable';
if (! is_writable(realpath($path))) {
$errors[] = '"'.$path.'" directory is not writable';
// Check configuration files are readable and writeable
foreach (array(