Compare commits

...

118 Commits

Author SHA1 Message Date
Andy Miller
8de55a745d Merge branch 'release/1.0.0-rc.3' 2015-10-29 14:08:38 -06:00
Andy Miller
6bf669815d version update 2015-10-29 14:08:09 -06:00
Andy Miller
8ba49e163d version update 2015-10-29 14:06:54 -06:00
Andy Miller
26918d90ab Merge pull request #397 from Sommerregen/patch-2
Addresses # 12 (form-plugin) Trim fields before validation
2015-10-29 11:57:11 -06:00
Benny
929b0806dc Addresses # 12 (form-plugin) Trim fields before validation 2015-10-29 16:58:41 +01:00
Flavio Copes
3e32e61db1 Revert "Add a items() method that returns the Data::items array"
This reverts commit fafd72fcd8.
2015-10-29 14:59:11 +01:00
Flavio Copes
038693bffb Merge pull request #396 from Sommerregen/patch-1
Fix #395
2015-10-29 14:00:54 +01:00
Benny
9445aa43e6 Fix #395 (Problem with default language and slugs that is starting with language name) 2015-10-29 13:44:29 +01:00
Andy Miller
658212e7be Merge pull request #392 from nickbalestra/readme
Update README.md
2015-10-28 21:01:56 -06:00
Nick Balestra
e91554770c Update README.md 2015-10-28 19:58:38 -07:00
Andy Miller
7f134e39f4 Merge branch 'develop' of https://github.com/getgrav/grav into develop 2015-10-28 20:52:30 -06:00
Andy Miller
07b2767ac9 Changed collection types from .recurse to .descendants 2015-10-28 20:52:22 -06:00
Andy Miller
0ca24a9786 Merge pull request #391 from tuphamnguyen/patch-1
Updated README.md
2015-10-28 20:39:58 -06:00
Tu Pham Nguyen
c84c1366e7 Updated README.md
Just a typo :)
2015-10-28 16:25:29 -05:00
Andy Miller
ebf9bb5c18 Improved collection support #384 2015-10-28 13:33:35 -06:00
Andy Miller
70b67a0805 Created whitelist for fallback route functionality 2015-10-28 10:39:15 -06:00
Andy Miller
545b97716f Merge pull request #387 from hwmaier/feature/asset-stream
Asset management uses now streams rather the constant ASSETS_DIR
2015-10-28 10:12:54 -06:00
Flavio Copes
f7140522f6 Merge pull request #388 from littmus/develop
Typo fixed
2015-10-28 09:56:02 +01:00
littmus
bd2f7088e9 Typo fixed 2015-10-28 17:55:23 +09:00
hwmaier
5260c181a1 Asset management uses now streams rather the constant ASSETS_DIR to configure location. In addition it supports subdirectories for assets location, for example assets/runtime. 2015-10-28 13:15:03 +10:00
Andy Miller
8bba0fd332 Merge branch 'release/1.0.0-rc.2' 2015-10-27 14:47:43 -06:00
Andy Miller
a9538adf2b Merge branch 'release/1.0.0-rc.2' into develop 2015-10-27 14:47:43 -06:00
Andy Miller
abf6d6638e version update 2015-10-27 14:47:27 -06:00
Andy Miller
36e52146f5 changelog updated 2015-10-27 12:35:29 -06:00
Flavio Copes
24eaa24839 Check that label is set prior to access it 2015-10-27 18:30:54 +01:00
Flavio Copes
fafd72fcd8 Add a items() method that returns the Data::items array 2015-10-27 18:30:54 +01:00
Andy Miller
df9b219a16 Merge pull request #386 from hwmaier/feature/onTwigPageVariables
onTwigPageVariables event handler gets Page object passed as Event parameter
2015-10-27 09:49:47 -06:00
hwmaier
5c9c378889 onTwigPageVariables event handler gets Page object passed 2015-10-27 23:04:21 +10:00
Andy Miller
47e1eab6c1 updated bundled composer.phar 2015-10-26 17:31:48 -06:00
Andy Miller
d88f56316d updated changelog 2015-10-26 17:15:25 -06:00
Andy Miller
8b414c388d wrapped_site option in system.yaml 2015-10-26 17:14:58 -06:00
Flavio Copes
acb828eacf Merge pull request #382 from tbreuss/develop
Use of capital and small initial letters
2015-10-26 20:40:31 +01:00
Thomas Breuss
293dfad87e Use of capital and small initial letters 2015-10-26 19:35:08 +01:00
Andy Miller
e4e1927126 Merge pull request #381 from getgrav/feature/check-positive-value
Check a positive value, not just "true"
2015-10-26 11:53:31 -06:00
Flavio Copes
edf6f86cb5 Add a Utils::isPositive(). Use that. 2015-10-26 18:29:22 +01:00
Flavio Copes
d086664a61 Check a positive value, not just "true" 2015-10-26 18:06:28 +01:00
Andy Miller
feed15f75b changelog update 2015-10-25 18:46:07 -06:00
Andy Miller
95fd54d909 Moved grav variable into globals and removed from template variables 2015-10-25 16:49:28 -06:00
Andy Miller
79f6380aae improved merging of meta tags into title/alt/class 2015-10-25 16:43:52 -06:00
Andy Miller
8478d690a0 Optimizations to the TAG regex handling for inline CSS/JS 2015-10-25 16:20:01 -06:00
Andy Miller
5db8197db2 use a regex to remove surrounding tags but not inline ones! #376 2015-10-24 22:35:44 -06:00
Andy Miller
8407e5b295 Metadata return a new Data object so nulls are possible #375 2015-10-24 16:01:22 -06:00
Andy Miller
3e3b4548e9 Fix for inline JS and HTML entities #376 2015-10-24 15:21:25 -06:00
Andy Miller
868a61dd34 Fail quietly if file doesn't exist 2015-10-24 14:53:16 -06:00
Andy Miller
a7a5625a8b Revert "Added CSS Group asset support #374"
This reverts commit f65633043a.
2015-10-24 12:19:47 -06:00
Andy Miller
a614c8c7cc Added CSS Group asset support #374 2015-10-24 12:19:22 -06:00
Andy Miller
f65633043a Added CSS Group asset support #374 2015-10-24 12:18:54 -06:00
Djamil Legato
de61d88d29 Synced travis.yml 2015-10-23 16:11:26 -07:00
Djamil Legato
dc57bef5f3 Merge branch 'release/1.0.0-rc.1' 2015-10-23 14:44:38 -07:00
Djamil Legato
9d86c0a9db Merge tag '1.0.0-rc.1' into develop
Release v1.0.0-rc.1
2015-10-23 14:44:38 -07:00
Djamil Legato
2721bb511a Quoting tag for github release 2015-10-23 14:02:52 -07:00
Andy Miller
1e07cb9b5b Merge branch 'release/1.0.0-rc.1' 2015-10-23 14:52:35 -06:00
Andy Miller
39a4a1e9bf Merge branch 'release/1.0.0-rc.1' into develop 2015-10-23 14:52:35 -06:00
Andy Miller
7a56a361a0 version update 2015-10-23 14:52:22 -06:00
Andy Miller
d54359d441 missing semicolons in safeEmailFilter() 2015-10-23 14:12:06 -06:00
Andy Miller
98d0538868 Option to allow all hidden files/folders #306 2015-10-23 10:23:01 -06:00
Andy Miller
f03921690c Created system option for redirect code + allowed [30x] syntax on redirect urls 2015-10-22 14:37:38 -06:00
Andy Miller
46869de29c don't do work if there are no assets found 2015-10-21 18:08:24 -06:00
Andy Miller
b7b29b3f84 Broke out pipeline into two methods for simplicity 2015-10-21 18:03:01 -06:00
Andy Miller
b9e1d9af6e Fix for broken CSS caused by variable overwriting 2015-10-21 17:38:13 -06:00
Andy Miller
edf313a7a2 Fix for empty pipeline asset file 2015-10-21 17:21:14 -06:00
Andy Miller
4f22d1c918 Fix for #373 - pipeline not respecting asset groups 2015-10-21 16:06:56 -06:00
Andy Miller
98b8f1f9e5 Fix issue with empty yaml not creating an empty array with native YAML parser 2015-10-20 14:39:08 -06:00
Andy Miller
9324847bac Added url_taxonomy_filters to the blueprints 2015-10-20 12:36:42 -06:00
Andy Miller
7c6471fe2a Added option to disable url_taxonomy_filters for page collections globally in system.yaml or in content: page header 2015-10-20 10:53:08 -06:00
Andy Miller
647ec528d3 Merge pull request #371 from markioooo/develop
Add dutch language file
2015-10-20 09:10:55 -06:00
Mark de Raaf
667ad5c580 add dutch language file 2015-10-20 16:50:45 +02:00
Mark de Raaf
2e4866f5fa Add dutch language file nl (nederland) 2015-10-20 16:07:57 +02:00
Andy Miller
077ba28706 Added support for collections with @root page and recurse flag 2015-10-19 15:12:21 -06:00
Andy Miller
db2caf4b04 Merge branch 'develop' of https://github.com/getgrav/grav into develop 2015-10-19 15:05:26 -06:00
Andy Miller
464a65b574 debugger update 2015-10-19 15:05:10 -06:00
Flavio Copes
00ae0988ab #368 Block direct access to files and folders beginning with a dot, block access to specific files in the root folder 2015-10-19 20:08:53 +02:00
Andy Miller
ce4350bc63 Fix to address #361 - ability to have multiple collections in a regular list. 2015-10-19 11:18:16 -06:00
Andy Miller
aa60d9f53d Deny direct access to any *.md files (CHANGELOG.md, README.md, etc) 2015-10-19 10:39:18 -06:00
Andy Miller
7cb7891fa7 Always fallback to english if other languages translations are not available. 2015-10-19 10:00:44 -06:00
Andy Miller
3848a266d0 Merge pull request #370 from getgrav/feature/configure-mime-for-downloads
Use media.yaml to determine downloaded files mime type
2015-10-19 09:04:30 -06:00
Flavio Copes
29b8c1d124 Use the 'file' type for some of the recently added mime types
Anything that is an 'image' should be able to have the image
manipulations applied to it. So BMP, Tiff, etc are not valid images in
in this sense. Same goes for Videos, they must be able to be supported
with the tag. -> http://www.w3schools.com/html/html5_video.asp, so
basically that's only: MP4, WebM, and Ogg

Everything else should be under 'files' which are accessible via
media['files'] but not much can be done with them outside of getting
their URL or a simple HTML link
2015-10-19 16:46:26 +02:00
Flavio Copes
813ab70895 Add a remove function to User 2015-10-19 11:39:37 +02:00
Flavio Copes
efcaf00e88 Use media.yaml to determine downloaded files mime type 2015-10-19 10:02:17 +02:00
Andy Miller
5476ef4fa8 Merge pull request #367 from joomline/patch-2
Update ru.yaml
2015-10-16 13:37:23 -06:00
joomline
5857882417 Update ru.yaml
Fix languages
2015-10-16 21:33:07 +02:00
Flavio Copes
fe4d178fb4 Fix #366 SVG content type 2015-10-16 21:24:22 +02:00
Flavio Copes
247e45bfea Merge pull request #365 from aranaur/patch-2
add specific links to 'adding functionality' intro
2015-10-16 15:59:23 +02:00
Drew Gates
b7784a23ff add specific links to 'adding functionality' intro
add links directly to the tabs for plugins and themes on getgrav.org. The first time I loaded the main downloads page I didn't see the plugins/themes tabs because I immediately started scrolling down. It might be worth adding to the bottom of that main page a quick line to the tune of "Looking for plugins or themes? Click here or here."
2015-10-16 09:57:46 -04:00
Flavio Copes
fa4893804e Merge pull request #364 from joomline/patch-1
ru.yaml
2015-10-16 14:52:10 +02:00
joomline
373130d8ac ru.yaml
Russian language for grav cms
2015-10-16 14:43:37 +02:00
Flavio Copes
8e781976eb Fix #362, correct Cache-Control: max-age value 2015-10-16 14:17:44 +02:00
Andy Miller
266b56f947 Updated changelog 2015-10-15 18:15:39 -06:00
Andy Miller
2b8adfee05 Make use of Native YAML parser if available (big speed boost!!) 2015-10-15 17:40:16 -06:00
Andy Miller
d4c4f8593e Updated to latest RocketTheme toolbox 2015-10-15 17:39:22 -06:00
Andy Miller
1f8aa032c4 ensconced leading @-based strings with quotes 2015-10-15 16:34:24 -06:00
Andy Miller
7194f7b674 Updated CHANGELOG 2015-10-15 15:14:12 -06:00
Andy Miller
24db4cfc49 Merge pull request #360 from aranaur/patch-1
formatting
2015-10-15 14:43:48 -06:00
Drew Gates
7781389dea formatting
added a comma.
2015-10-15 16:28:06 -04:00
Andy Miller
30f09994d6 Validate hostname to ensure no nefarious attacks are attempted by manipulating it. 2015-10-15 11:31:32 -06:00
Andy Miller
babd50fb6c Safety check on empty path 2015-10-15 10:23:10 -06:00
Andy Miller
5da88d2751 Ensure error handler is initialized before URI is processed 2015-10-15 10:22:47 -06:00
Andy Miller
1f23f20163 remove multiple slashes in URI 2015-10-15 10:21:56 -06:00
Andy Miller
dadce54a6a Turn off errors by default in preparation for 1.0 2015-10-15 09:58:43 -06:00
Andy Miller
0d3d396229 Various vendor lib updates 2015-10-14 15:44:02 -06:00
Andy Miller
6c39e432d2 Merge pull request #358 from Sommerregen/feature/better-theme-inheritance
Improved theme inheritance to support all kinds of streams
2015-10-14 10:33:27 -06:00
Sommerregen
2a6437a2f1 #357 Improved theme inheritance to support all kinds of streams 2015-10-14 18:22:51 +02:00
Andy Miller
52fcf7c39d Added for consistency #356 2015-10-14 06:07:39 -06:00
Andy Miller
f47d3faea9 fix for redirecting to external URL when under a language #339 2015-10-13 21:49:37 -06:00
Andy Miller
d1e7ec2e22 Merge pull request #353 from Sommerregen/feature/theme-inheritance
Feature/theme inheritance
2015-10-13 17:10:46 -06:00
Andy Miller
1efab799b5 Refactored to make #228 more robust and allow lang to be removed from URL. 2015-10-13 16:58:34 -06:00
Andy Miller
7ad9996cc3 Removed home_redirect settings (conflict with new include_default_lang setting) 2015-10-13 16:53:52 -06:00
Flavio Copes
00ec536761 Add the evaluate Twig function 2015-10-13 23:32:52 +02:00
Andy Miller
3f2d9b42c8 Merge pull request #355 from hwmaier/feature/backupignore
Add a few more common RCS to ignore folders
2015-10-13 11:27:02 -06:00
hwmaier
ce76eeb512 Add a few more common RCS to ignore folders 2015-10-13 19:14:52 +10:00
Andy Miller
1bc4a6f208 Support for a disabling the default language prepend in the URL #228 2015-10-12 17:45:36 -06:00
Sommerregen
8595b7972b Addresses #154 and finalize theme inheritance implementation 2015-10-12 18:47:40 +02:00
Sommerregen
22054e232f Load languages files in the correct way and fallback to parent theme language file else 2015-10-12 18:45:31 +02:00
Flavio Copes
5876b6693a Fix #349, use default language if active language is not set 2015-10-09 12:25:55 +02:00
Andy Miller
9ef501fe0c Merge pull request #346 from Sommerregen/bugfix/load-language-files
Load language files according to stream configurations
2015-10-08 10:14:04 -06:00
Andy Miller
79f244f012 Merge branch 'release/0.9.45' into develop 2015-10-08 10:04:00 -06:00
Sommerregen
f332cee568 Load plugins and themes from multiple directories 2015-10-06 19:20:15 +02:00
Sommerregen
0fa53d5f5d Load language files according to stream configurations 2015-10-06 19:19:42 +02:00
40 changed files with 1058 additions and 404 deletions

View File

@@ -47,6 +47,12 @@ RewriteRule .* index.php [L]
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [L]
# Block access to specific file types for these folders
RewriteRule ^(system|user|vendor)/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$ error [L]
# Block all direct access to .md files:
RewriteRule \.md$ error [L]
# Block all direct access to files and folders beginning with a dot
RewriteRule (^\.|/\.) - [F]
# Block access to specific files in the root folder
RewriteRule ^(LICENSE|composer.lock|composer.json|nginx.conf|web.config)$ error [F]
## End - Security
</IfModule>

View File

@@ -52,7 +52,11 @@ script:
FILES="$RT_DEVTOOLS/grav-dist/*.zip";
for file in ${FILES[@]}; do
NAME=${file##*/};
REPO="$(echo ${NAME} | rev | cut -f 2- -d "-" | rev)";
if [[ "$NAME" == *"-rc"* ]]; then
REPO="$(echo ${NAME} | rev | cut -f 3- -d "-" | rev)";
else
REPO="$(echo ${NAME} | rev | cut -f 2- -d "-" | rev)";
fi;
if [[ $REPO == 'grav' || $REPO == 'grav-admin' || $REPO == 'grav-update' ]]; then
REPO="grav";
fi;
@@ -60,7 +64,7 @@ script:
ASSETS="$(echo "${API}" | node gh-assets.js)";
TAG="$(echo "${API}" | grep tag_name | head -n 1 | cut -d '"' -f 4)";
if [ $REPO == "grav" ]; then
TAG=$TRAVIS_TAG;
TAG="$TRAVIS_TAG";
fi;
if [ ! -z "$ASSETS" ]; then
for asset in ${ASSETS[@]}; do
@@ -73,6 +77,6 @@ script:
done;
fi;
echo "Uploading package ${BOLD}${BLUE}${NAME}${TEXTRESET} to ${YELLOW}${REPO}${TEXTRESET}@${YELLOW}${TAG}${TEXTRESET}";
github-release upload --security-token $GH_TOKEN --user ${GH_USER} --repo $REPO --tag $TAG --name "$NAME" --file "$file";
github-release upload --security-token $GH_TOKEN --user ${GH_USER} --repo $REPO --tag "$TAG" --name "$NAME" --file "$file";
done;
fi

View File

@@ -1,3 +1,78 @@
# v1.0.0-rc.3
## 10/29/2015
1. [](#new)
* New Page collection options! `@self.parent, @self.siblings, @self.descendants` + more
* Whitelist of file types for fallback route functionality (images by default)
1. [](#improved)
* Assets switched from defines to streams
1. [](#bugfix)
* README.md typos fixed
* Fixed issue with routes that have lang string in them (`/en/english`)
* Trim strings before validation so whitespace is not satisfy 'required'
# v1.0.0-rc.2
## 10/27/2015
1. [](#new)
* Added support for CSS Asset groups
* Added a `wrapped_site` system option for themes/plugins to use
* Pass `Page` object as event to `onTwigPageVariables()` event hook
* New `Data.items()` method to get all items
1. [](#improved)
* Missing pipelined remote asset will now fail quietly
* More reliably handle inline JS and CSS to remove only surrounding HTML tags
* `Medium.meta` returns new Data object so null checks are possible
* Improved Medium metadata merging to allow for automatic title/alt/class attributes
* Moved Grav object to global variable rather than template variable (useful for macros)
* German language improvements
* Updated bundled composer
1. [](#bugfix)
* Accept variety of `true` values in `User.authorize()` method
* Fix for `Validation` throwing an error if no label set
# v1.0.0-rc.1
## 10/23/2015
1. [](#new)
* Use native PECL YAML parser if installed for 4X speed boost in parsing YAML files
* Support for inherited theme class
* Added new default language prepend system configuration option
* New `|evaluate` Twig filter to evaluate a string as twig
* New system option to ignore all **hidden** files and folders
* New system option for default redirect code
* Added ability to append specific `[30x]` codes to redirect URLs
* Added `url_taxonomy_filters` for page collections
* Added `@root` page and `recurse` flag for page collections
* Support for **multiple** page collection types as an array
* Added Dutch language file
* Added Russian language file
* Added `remove` method to User object
1. [](#improved)
* Moved hardcoded mimetypes to `media.yaml` to be treated as Page media files
* Set `errors: display: false` by default in `system.yaml`
* Strip out extra slashes in the URI
* Validate hostname to ensure it is valid
* Ignore more SCM folders in Backups
* Removed `home_redirect` settings from `system.yaml`
* Added Page `media` as root twig object for consistency
* Updated to latest vendor libraries
* Optimizations to Asset pipeline logic for minor speed increase
* Block direct access to a variety of files in `.htaccess` for increased security
* Debugbar vendor library update
* Always fallback to english if other translations are not available
1. [](#bugfix)
* Fix for redirecting external URL with multi-language
* Fix for Asset pipeline not respecting asset groups
* Fix language files with child/parent theme relationships
* Fixed a regression issue resulting in incorrect default language
* Ensure error handler is initialized before URI is processed
* Use default language in Twig if active language is not set
* Fixed issue with `safeEmailFilter()` Twig filter not separating with `;` properly
* Fixed empty YAML file causing error with native PECL YAML parser
* Fixed `SVG` mimetype
* Fixed incorrect `Cache-control: max-age` value format
# v0.9.45
## 10/08/2015

View File

@@ -4,15 +4,15 @@
Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.
The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies, to ensure that Grav is simple to use and easy to extend. Some of these key technologies include:
The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include:
* [Twig Templating](http://twig.sensiolabs.org/): for powerful control of the user interface
* [Markdown](http://en.wikipedia.org/wiki/Markdown): for easy content creation
* [YAML](http://yaml.org): for simple configuration
* [Parsedown](http://parsedown.org/): for fast Markdown and Mardown Extra support
* [Parsedown](http://parsedown.org/): for fast Markdown and Markdown Extra support
* [Doctrine Cache](http://docs.doctrine-project.org/en/2.0.x/reference/caching.html): layer for performance
* [Pimple Dependency Injection Container](http://pimple.sensiolabs.org/): for extensibility and maintainability
* [Symfony Event Dispacher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
* [Symfony Event Dispatcher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
* [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html): for CLI interface
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
@@ -47,13 +47,13 @@ Check out the [install procedures](http://learn.getgrav.org/basics/installation)
# Adding Functionality
You can download manually from the [Downloads page on http://getgrav.org](http://getgrav.org/downloads), but the preferred solution is to use the [Grav Package Manager](http://learn.getgrav.org/advanced/grav-gpm) or `GPM`:
You can download [plugins](http://getgrav.org/downloads/plugins) or [themes](http://getgrav.org/downloads/themes) manually from the appropriate tab on the [Downloads page on http://getgrav.org](http://getgrav.org/downloads), but the preferred solution is to use the [Grav Package Manager](http://learn.getgrav.org/advanced/grav-gpm) or `GPM`:
```
$ bin/gpm index
```
This will display all the available plugins and then you can install one ore more with:
This will display all the available plugins and then you can install one or more with:
```
$ bin/gpm install <plugin/theme>
@@ -76,7 +76,7 @@ $ bin/gpm update
# Contributing
We appreciate any contribution to Grav, whether it is related to bugs, grammar, or simply a suggestion or improvement.
However, we ask that any contribution follow our simple guidelines in order to be properly received.
However, we ask that any contributions follow our simple guidelines in order to be properly received.
All our projects follow the [GitFlow branching model][gitflow-model], from development to release. If you are not familiar with it, there are several guides and tutorials to make you understand what it is about.

Binary file not shown.

117
composer.lock generated
View File

@@ -78,16 +78,16 @@
},
{
"name": "donatj/phpuseragentparser",
"version": "v0.4.0",
"version": "v0.5.0",
"source": {
"type": "git",
"url": "https://github.com/donatj/PhpUserAgent.git",
"reference": "6392753c32f3d162897c02bd72c41e356b002a57"
"reference": "1acea75664179c8f0dcd57ced7e75a01af86bfa8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/6392753c32f3d162897c02bd72c41e356b002a57",
"reference": "6392753c32f3d162897c02bd72c41e356b002a57",
"url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/1acea75664179c8f0dcd57ced7e75a01af86bfa8",
"reference": "1acea75664179c8f0dcd57ced7e75a01af86bfa8",
"shasum": ""
},
"require": {
@@ -125,20 +125,20 @@
"user agent",
"useragent"
],
"time": "2015-08-25 16:30:11"
"time": "2015-09-22 21:04:13"
},
{
"name": "erusev/parsedown",
"version": "1.5.4",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "0e89e3714bda18973184d30646306bb0a482bd96"
"reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/0e89e3714bda18973184d30646306bb0a482bd96",
"reference": "0e89e3714bda18973184d30646306bb0a482bd96",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"shasum": ""
},
"type": "library",
@@ -164,7 +164,7 @@
"markdown",
"parser"
],
"time": "2015-08-03 09:24:05"
"time": "2015-10-04 16:44:32"
},
{
"name": "erusev/parsedown-extra",
@@ -216,12 +216,12 @@
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "cfe9ce209d2705fece1743f0af45f58fec840458"
"reference": "9a393ceb80f7497b6513feb574638e87048fed55"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/cfe9ce209d2705fece1743f0af45f58fec840458",
"reference": "cfe9ce209d2705fece1743f0af45f58fec840458",
"url": "https://api.github.com/repos/filp/whoops/zipball/9a393ceb80f7497b6513feb574638e87048fed55",
"reference": "9a393ceb80f7497b6513feb574638e87048fed55",
"shasum": ""
},
"require": {
@@ -266,7 +266,7 @@
"whoops",
"zf2"
],
"time": "2015-07-23 15:48:15"
"time": "2015-09-27 09:47:06"
},
{
"name": "gregwar/cache",
@@ -403,16 +403,16 @@
},
{
"name": "maximebf/debugbar",
"version": "v1.10.4",
"version": "v1.10.5",
"source": {
"type": "git",
"url": "https://github.com/maximebf/php-debugbar.git",
"reference": "7b2006e6e095126b5a061ec33fca3d90ea8a8219"
"reference": "30e53e8a28284b69dd223c9f5ee8957befd72636"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/7b2006e6e095126b5a061ec33fca3d90ea8a8219",
"reference": "7b2006e6e095126b5a061ec33fca3d90ea8a8219",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/30e53e8a28284b69dd223c9f5ee8957befd72636",
"reference": "30e53e8a28284b69dd223c9f5ee8957befd72636",
"shasum": ""
},
"require": {
@@ -455,20 +455,20 @@
"keywords": [
"debug"
],
"time": "2015-02-05 07:51:20"
"time": "2015-10-19 20:35:12"
},
{
"name": "monolog/monolog",
"version": "1.17.1",
"version": "1.17.2",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422"
"reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/0524c87587ab85bc4c2d6f5b41253ccb930a5422",
"reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/bee7f0dc9c3e0b69a6039697533dca1e845c8c24",
"reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24",
"shasum": ""
},
"require": {
@@ -482,10 +482,11 @@
"aws/aws-sdk-php": "^2.4.9",
"doctrine/couchdb": "~1.0@dev",
"graylog2/gelf-php": "~1.0",
"jakub-onderka/php-parallel-lint": "0.9",
"php-console/php-console": "^3.1.3",
"phpunit/phpunit": "~4.5",
"phpunit/phpunit-mock-objects": "2.3.0",
"raven/raven": "~0.11",
"raven/raven": "^0.13",
"ruflin/elastica": ">=0.90 <3.0",
"swiftmailer/swiftmailer": "~5.3",
"videlalvaro/php-amqplib": "~2.4"
@@ -531,7 +532,7 @@
"logging",
"psr-3"
],
"time": "2015-08-31 09:17:37"
"time": "2015-10-14 12:51:02"
},
{
"name": "mrclay/minify",
@@ -664,16 +665,16 @@
},
{
"name": "rockettheme/toolbox",
"version": "1.1.3",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/rockettheme/toolbox.git",
"reference": "4075cf3f5fca777db0209f65dd67f13c1c736b8a"
"reference": "ff677d8f66d1addd3590d0cb85bcbaff4174d9c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rockettheme/toolbox/zipball/4075cf3f5fca777db0209f65dd67f13c1c736b8a",
"reference": "4075cf3f5fca777db0209f65dd67f13c1c736b8a",
"url": "https://api.github.com/repos/rockettheme/toolbox/zipball/ff677d8f66d1addd3590d0cb85bcbaff4174d9c9",
"reference": "ff677d8f66d1addd3590d0cb85bcbaff4174d9c9",
"shasum": ""
},
"require": {
@@ -709,20 +710,20 @@
"php",
"rockettheme"
],
"time": "2015-09-14 04:05:48"
"time": "2015-10-15 23:27:40"
},
{
"name": "symfony/console",
"version": "v2.7.4",
"version": "v2.7.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/Console.git",
"reference": "9ff9032151186bd66ecee727d728f1319f52d1d8"
"url": "https://github.com/symfony/console.git",
"reference": "06cb17c013a82f94a3d840682b49425cd00a2161"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Console/zipball/9ff9032151186bd66ecee727d728f1319f52d1d8",
"reference": "9ff9032151186bd66ecee727d728f1319f52d1d8",
"url": "https://api.github.com/repos/symfony/console/zipball/06cb17c013a82f94a3d840682b49425cd00a2161",
"reference": "06cb17c013a82f94a3d840682b49425cd00a2161",
"shasum": ""
},
"require": {
@@ -766,20 +767,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2015-09-03 11:40:38"
"time": "2015-09-25 08:32:23"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.7.4",
"version": "v2.7.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
"reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa"
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "ae4dcc2a8d3de98bd794167a3ccda1311597c5d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/b58c916f1db03a611b72dd702564f30ad8fe83fa",
"reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ae4dcc2a8d3de98bd794167a3ccda1311597c5d9",
"reference": "ae4dcc2a8d3de98bd794167a3ccda1311597c5d9",
"shasum": ""
},
"require": {
@@ -824,20 +825,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2015-08-24 07:13:45"
"time": "2015-09-22 13:49:29"
},
{
"name": "symfony/var-dumper",
"version": "v2.7.4",
"version": "v2.7.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "b39221998ff5fc26ba63f96d2b833dfddc233d57"
"reference": "ba8c9a0edf18f70a7efcb8d3eb35323a10263338"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/b39221998ff5fc26ba63f96d2b833dfddc233d57",
"reference": "b39221998ff5fc26ba63f96d2b833dfddc233d57",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/ba8c9a0edf18f70a7efcb8d3eb35323a10263338",
"reference": "ba8c9a0edf18f70a7efcb8d3eb35323a10263338",
"shasum": ""
},
"require": {
@@ -883,20 +884,20 @@
"debug",
"dump"
],
"time": "2015-08-31 12:28:11"
"time": "2015-09-22 14:41:01"
},
{
"name": "symfony/yaml",
"version": "v2.7.4",
"version": "v2.7.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/Yaml.git",
"reference": "2dc7b06c065df96cc686c66da2705e5e18aef661"
"url": "https://github.com/symfony/yaml.git",
"reference": "31cb2ad0155c95b88ee55fe12bc7ff92232c1770"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Yaml/zipball/2dc7b06c065df96cc686c66da2705e5e18aef661",
"reference": "2dc7b06c065df96cc686c66da2705e5e18aef661",
"url": "https://api.github.com/repos/symfony/yaml/zipball/31cb2ad0155c95b88ee55fe12bc7ff92232c1770",
"reference": "31cb2ad0155c95b88ee55fe12bc7ff92232c1770",
"shasum": ""
},
"require": {
@@ -932,20 +933,20 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2015-08-24 07:13:45"
"time": "2015-09-14 14:14:09"
},
{
"name": "twig/twig",
"version": "v1.22.1",
"version": "v1.22.3",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "b7fc2469fa009897871fb95b68237286fc54a5ad"
"reference": "ebfc36b7e77b0c1175afe30459cf943010245540"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/b7fc2469fa009897871fb95b68237286fc54a5ad",
"reference": "b7fc2469fa009897871fb95b68237286fc54a5ad",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/ebfc36b7e77b0c1175afe30459cf943010245540",
"reference": "ebfc36b7e77b0c1175afe30459cf943010245540",
"shasum": ""
},
"require": {
@@ -993,7 +994,7 @@
"keywords": [
"templating"
],
"time": "2015-09-15 06:50:16"
"time": "2015-10-13 07:07:02"
}
],
"packages-dev": [],

View File

@@ -47,6 +47,12 @@ RewriteRule .* index.php [L]
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [L]
# Block access to specific file types for these folders
RewriteRule ^(system|user|vendor)/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$ error [L]
# Block all direct access to .md files:
RewriteRule \.md$ error [L]
# Block all direct access to files and folders beginning with a dot
RewriteRule (^\.|/\.) - [F]
# Block access to specific files in the root folder
RewriteRule ^(LICENSE|composer.lock|composer.json|nginx.conf|web.config)$ error [F]
## End - Security
</IfModule>

View File

@@ -44,7 +44,7 @@ form:
size: medium
classes: fancy
help: PLUGIN_ADMIN.TIMEZONE_HELP
@data-options: '\Grav\Common\Utils::timezones'
'@data-options': '\Grav\Common\Utils::timezones'
default: ''
options:
'': 'Default (Server Timezone)'
@@ -57,7 +57,7 @@ form:
label: PLUGIN_ADMIN.DEFAULT_DATE_FORMAT
help: PLUGIN_ADMIN.DEFAULT_DATE_FORMAT_HELP
placeholder: PLUGIN_ADMIN.DEFAULT_DATE_FORMAT_PLACEHOLDER
@data-options: '\Grav\Common\Utils::dateFormats'
'@data-options': '\Grav\Common\Utils::dateFormats'
options:
"": Auto Guess or Enter Custom
validate:
@@ -127,8 +127,8 @@ form:
help: PLUGIN_ADMIN.DATE_BASED_PUBLISHING_HELP
highlight: 1
options:
1: Yes
0: No
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
@@ -153,6 +153,17 @@ form:
validate:
type: bool
pages.redirect_default_code:
type: select
size: medium
classes: fancy
label: PLUGIN_ADMIN.REDIRECT_DEFAULT_CODE
help: PLUGIN_ADMIN.REDIRECT_DEFAULT_CODE_HELP
options:
301: 301 - Permanent
303: 303 - Other
307: 307 - Temporary
pages.redirect_trailing_slash:
type: toggle
label: PLUGIN_ADMIN.REDIRECT_TRAILING_SLASH
@@ -164,6 +175,17 @@ form:
validate:
type: bool
pages.ignore_hidden:
type: toggle
label: PLUGIN_ADMIN.IGNORE_HIDDEN
help: PLUGIN_ADMIN.IGNORE_HIDDEN_HELP
highlight: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
pages.ignore_files:
type: selectize
size: large
@@ -182,6 +204,26 @@ form:
validate:
type: commalist
pages.url_taxonomy_filters:
type: toggle
label: PLUGIN_ADMIN.ALLOW_URL_TAXONOMY_FILTERS
help: PLUGIN_ADMIN.ALLOW_URL_TAXONOMY_FILTERS_HELP
highlight: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
pages.fallback_types:
type: selectize
size: large
label: PLUGIN_ADMIN.FALLBACK_TYPES
help: PLUGIN_ADMIN.FALLBACK_TYPES_HELP
classes: fancy
validate:
type: commalist
languages:
type: section
title: PLUGIN_ADMIN.LANGUAGES
@@ -198,6 +240,18 @@ form:
validate:
type: commalist
languages.include_default_lang:
type: toggle
label: PLUGIN_ADMIN.INCLUDE_DEFAULT_LANG
help: PLUGIN_ADMIN.INCLUDE_DEFAULT_LANG_HELP
highlight: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
languages.translations:
type: toggle
label: PLUGIN_ADMIN.TRANSLATIONS_ENABLED
@@ -231,28 +285,6 @@ form:
validate:
type: bool
languages.home_redirect.include_lang:
type: toggle
label: PLUGIN_ADMIN.HOME_REDIRECT_INCLUDE_LANGUAGE
help: PLUGIN_ADMIN.HOME_REDIRECT_INCLUDE_LANGUAGE_HELP
highlight: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
languages.home_redirect.include_route:
type: toggle
label: PLUGIN_ADMIN.HOME_REDIRECT_INCLUDE_ROUTE
help: PLUGIN_ADMIN.HOME_REDIRECT_INCLUDE_ROUTE_HELP
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
languages.http_accept_language:
type: toggle
label: PLUGIN_ADMIN.HTTP_ACCEPT_LANGUAGE
@@ -585,7 +617,7 @@ form:
type: toggle
label: PLUGIN_ADMIN.DISPLAY_ERRORS
help: PLUGIN_ADMIN.DISPLAY_ERRORS_HELP
highlight: 1
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
@@ -727,6 +759,17 @@ form:
underline: true
fields:
wrapped_site:
type: toggle
label: PLUGIN_ADMIN.WRAPPED_SITE
highlight: 0
help: PLUGIN_ADMIN.WRAPPED_SITE_HELP
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
absolute_urls:
type: toggle
label: PLUGIN_ADMIN.ABSOLUTE_URLS
@@ -740,6 +783,7 @@ form:
param_sep:
type: select
size: medium
label: PLUGIN_ADMIN.PARAMETER_SEPARATOR
classes: fancy
help: PLUGIN_ADMIN.PARAMETER_SEPARATOR_HELP

View File

@@ -140,8 +140,8 @@ form:
type: select
label: PLUGIN_ADMIN.PARENT
classes: fancy
@data-options: '\Grav\Common\Page\Pages::parents'
@data-default: '\Grav\Plugin\admin::route'
'@data-options': '\Grav\Common\Page\Pages::parents'
'@data-default': '\Grav\Plugin\admin::route'
options:
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
@@ -151,7 +151,7 @@ form:
label: PLUGIN_ADMIN.PAGE_FILE
help: PLUGIN_ADMIN.PAGE_FILE_HELP
default: default
@data-options: '\Grav\Common\Page\Pages::pageTypes'
'@data-options': '\Grav\Common\Page\Pages::pageTypes'
header.body_classes:
type: text
@@ -204,7 +204,7 @@ form:
type: checkboxes
label: PLUGIN_ADMIN.PROCESS
toggleable: true
@config-default: system.pages.process
'@config-default': system.pages.process
default:
markdown: true
twig: false
@@ -219,7 +219,7 @@ form:
label: PLUGIN_ADMIN.DEFAULT_CHILD_TYPE
default: default
placeholder: PLUGIN_ADMIN.USE_GLOBAL
@data-options: '\Grav\Common\Page\Pages::types'
'@data-options': '\Grav\Common\Page\Pages::types'
header.routable:
type: toggle
@@ -262,7 +262,7 @@ form:
classes: fancy
label: PLUGIN_ADMIN.DISPLAY_TEMPLATE
default: default
@data-options: '\Grav\Common\Page\Pages::types'
'@data-options': '\Grav\Common\Page\Pages::types'
header.order_by:
type: hidden

View File

@@ -16,9 +16,9 @@ form:
header.content.items:
type: select
label: PLUGIN_ADMIN.ITEMS
default: @self.modular
default: '@self.modular'
options:
@self.modular: Children
'@self.modular': Children
header.content.order.by:
type: select

View File

@@ -29,8 +29,8 @@ form:
type: select
label: PLUGIN_ADMIN.PAGE
classes: fancy
@data-options: '\Grav\Common\Page\Pages::parents'
@data-default: '\Grav\Plugin\admin::route'
'@data-options': '\Grav\Common\Page\Pages::parents'
'@data-default': '\Grav\Plugin\admin::route'
options:
'': PLUGIN_ADMIN.DEFAULT_OPTION_SELECT
validate:
@@ -42,7 +42,7 @@ form:
label: PLUGIN_ADMIN.MODULAR_TEMPLATE
help: PLUGIN_ADMIN.PAGE_FILE_HELP
default: default
@data-options: '\Grav\Common\Page\Pages::modularTypes'
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
validate:
required: true

View File

@@ -69,8 +69,8 @@ form:
type: select
label: PLUGIN_ADMIN.PARENT
classes: fancy
@data-options: '\Grav\Common\Page\Pages::parents'
@data-default: '\Grav\Plugin\admin::route'
'@data-options': '\Grav\Common\Page\Pages::parents'
'@data-default': '\Grav\Plugin\admin::route'
options:
'': PLUGIN_ADMIN.DEFAULT_OPTION_SELECT
validate:
@@ -81,7 +81,7 @@ form:
classes: fancy
label: PLUGIN_ADMIN.MODULAR_TEMPLATE
default: default
@data-options: '\Grav\Common\Page\Pages::modularTypes'
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
validate:
required: true

View File

@@ -11,7 +11,7 @@ form:
type: select
label: PLUGIN_ADMIN.PARENT
classes: fancy
@data-options: '\Grav\Common\Page\Pages::parents'
@data-default: '\Grav\Plugin\admin::route'
'@data-options': '\Grav\Common\Page\Pages::parents'
'@data-default': '\Grav\Plugin\admin::route'
options:
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT

View File

@@ -31,8 +31,8 @@ form:
type: select
label: PLUGIN_ADMIN.PARENT_PAGE
classes: fancy
@data-options: '\Grav\Common\Page\Pages::parents'
@data-default: '\Grav\Plugin\admin::getLastPageRoute'
'@data-options': '\Grav\Common\Page\Pages::parents'
'@data-default': '\Grav\Plugin\admin::getLastPageRoute'
options:
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
validate:
@@ -43,8 +43,8 @@ form:
classes: fancy
label: PLUGIN_ADMIN.PAGE_FILE
help: PLUGIN_ADMIN.PAGE_FILE_HELP
@data-options: '\Grav\Common\Page\Pages::types'
@data-default: '\Grav\Plugin\admin::getLastPageName'
'@data-options': '\Grav\Common\Page\Pages::types'
'@data-default': '\Grav\Plugin\admin::getLastPageName'
validate:
required: true

View File

@@ -69,8 +69,8 @@ form:
type: select
label: PLUGIN_ADMIN.PARENT
classes: fancy
@data-options: '\Grav\Common\Page\Pages::parents'
@data-default: '\Grav\Plugin\admin::route'
'@data-options': '\Grav\Common\Page\Pages::parents'
'@data-default': '\Grav\Plugin\admin::route'
options:
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
@@ -80,7 +80,7 @@ form:
label: PLUGIN_ADMIN.DISPLAY_TEMPLATE
help: PLUGIN_ADMIN.DISPLAY_TEMPLATE_HELP
default: default
@data-options: '\Grav\Common\Page\Pages::types'
'@data-options': '\Grav\Common\Page\Pages::types'
validate:
required: true

View File

@@ -50,7 +50,7 @@ form:
label: PLUGIN_ADMIN.LANGUAGE
size: medium
classes: fancy
@data-options: '\Grav\Plugin\admin::adminLanguages'
'@data-options': '\Grav\Plugin\admin::adminLanguages'
default: 'en'
help: PLUGIN_ADMIN.LANGUAGE_HELP

View File

@@ -11,6 +11,10 @@ jpg:
type: image
thumb: media/thumb-jpg.png
mime: image/jpeg
jpe:
type: image
thumb: media/thumb-jpg.png
mime: image/jpeg
jpeg:
type: image
thumb: media/thumb-jpeg.png
@@ -70,6 +74,12 @@ wav:
type: audio
thumb: media/thumb-wav.png
mime: audio/wav
aiff:
type: audio
mime: audio/aiff
aif:
type: audio
mime: audio/aif
txt:
type: file
@@ -83,10 +93,73 @@ doc:
type: file
thumb: media/thumb-doc.png
mime: application/msword
docx:
type: file
mime: application/msword
xls:
type: file
mime: application/vnd.ms-excel
xlt:
type: file
mime: application/vnd.ms-excel
xlm:
type: file
mime: application/vnd.ms-excel
xld:
type: file
mime: application/vnd.ms-excel
xla:
type: file
mime: application/vnd.ms-excel
xlc:
type: file
mime: application/vnd.ms-excel
xlw:
type: file
mime: application/vnd.ms-excel
xll:
type: file
mime: application/vnd.ms-excel
ppt:
type: file
mime: application/vnd.ms-powerpoint
pps:
type: file
mime: application/vnd.ms-powerpoint
rtf:
type: file
mime: application/rtf
bmp:
type: file
mime: image/bmp
tiff:
type: file
mime: image/tiff
mpeg:
type: file
mime: video/mpeg
mpg:
type: file
mime: video/mpeg
mpe:
type: file
mime: video/mpeg
avi:
type: file
mime: video/msvideo
wmv:
type: file
mime: video/x-ms-wmv
html:
type: file
thumb: media/thumb-html.png
mime: text/html
htm:
type: file
thumb: media/thumb-html.png
mime: text/html
pdf:
type: file
thumb: media/thumb-pdf.png
@@ -99,6 +172,9 @@ gz:
type: file
thumb: media/thumb-gz.png
mime: application/gzip
tar:
type: file
mime: application/x-tar
css:
type: file
thumb: media/thumb-css.png

View File

@@ -2,15 +2,14 @@ absolute_urls: false # Absolute or relative URLs for `base_url
timezone: '' # Valid values: http://php.net/manual/en/timezones.php
default_locale: # Default locale (defaults to system)
param_sep: ':' # Parameter separator, use ';' for Apache on windows
wrapped_site: false # For themes/plugins to know if Grav is wrapped by another platform
languages:
supported: [] # List of languages supported. eg: [en, fr, de]
include_default_lang: true # Include the default lang prefix in all URLs
translations: true # Enable translations by default
translations_fallback: true # Fallback through supported translations if active lang doesn't exist
session_store_active: false # Store active language in session
home_redirect:
include_lang: true # Include language in home redirect (/en)
include_route: false # Include route in home redirect (/blog)
http_accept_language: false # Attempt to set the language based on http_accept_language header in the browser
override_locale: false # Override the default or system locale with language specific one
@@ -49,9 +48,13 @@ pages:
etag: false # Set the etag header tag
vary_accept_encoding: false # Add `Vary: Accept-Encoding` header
redirect_default_route: false # Automatically redirect to a page's default route
redirect_default_code: 301 # Default code to use for redirects
redirect_trailing_slash: true # Handle automatically or 301 redirect a trailing / URL
ignore_files: [.DS_Store] # Files to ignore in Pages
ignore_folders: [.git, .idea] # Folders to ignore in Pages
ignore_hidden: true # Ignore all Hidden files and folders
url_taxonomy_filters: true # Enable auto-magic URL-based taxonomy filters for page collections
fallback_types: [png,jpg,jpeg,gif] # Allowed types of files found if accessed via Page route
cache:
enabled: true # Set to true to enable caching
@@ -82,7 +85,7 @@ assets: # Configuration for Assets Manager (JS, C
jquery: system://assets/jquery/jquery-2.1.4.min.js
errors:
display: true # Display full backtrace-style error page
display: false # Display full backtrace-style error page
log: true # Log errors to /logs folder
debugger:

View File

@@ -2,7 +2,7 @@
// Some standard defines
define('GRAV', true);
define('GRAV_VERSION', '0.9.45');
define('GRAV_VERSION', '1.0.0-rc.3');
define('DS', '/');
// Directories and Paths
@@ -13,14 +13,14 @@ define('ROOT_DIR', GRAV_ROOT . '/');
define('USER_PATH', 'user/');
define('USER_DIR', ROOT_DIR . USER_PATH);
define('SYSTEM_DIR', ROOT_DIR .'system/');
define('ASSETS_DIR', ROOT_DIR . 'assets/');
define('CACHE_DIR', ROOT_DIR . 'cache/');
define('IMAGES_DIR', ROOT_DIR . 'images/');
define('LOG_DIR', ROOT_DIR .'logs/');
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
define('PAGES_DIR', USER_DIR .'pages/');
// DEPRECATED: Do not use!
define('ASSETS_DIR', ROOT_DIR . 'assets/');
define('IMAGES_DIR', ROOT_DIR . 'images/');
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
define('PAGES_DIR', USER_DIR .'pages/');
define('DATA_DIR', USER_DIR .'data/');
define('LIB_DIR', SYSTEM_DIR .'src/');
define('PLUGINS_DIR', USER_DIR .'plugins/');

View File

@@ -1,43 +1,43 @@
INFLECTOR_IRREGULAR:
'person': 'personen'
'man': 'menschen'
'child': 'kinder'
'sex': 'geschlecht'
'move': 'züge'
'person': 'Personen'
'man': 'Menschen'
'child': 'Kinder'
'sex': 'Geschlecht'
'move': 'Züge'
NICETIME:
NO_DATE_PROVIDED: Keine Daten vorhanden
BAD_DATE: Falsches Datum
AGO: her
FROM_NOW: ab jetzt
SECOND: sekunde
MINUTE: minute
HOUR: stunde
DAY: tag
WEEK: woche
MONTH: monat
YEAR: jahr
DECADE: dekade
SECOND: Sekunde
MINUTE: Minute
HOUR: Stunde
DAY: Tag
WEEK: Woche
MONTH: Monat
YEAR: Jahr
DECADE: Dekade
SEC: sek
MIN: min
HR: std
DAY: tag
DAY: Tag
WK: wo
MO: mo
YR: yh
DEC: dec
SECOND_PLURAL: sekunden
MINUTE_PLURAL: minuten
HOUR_PLURAL: stunden
DAY_PLURAL: tage
WEEK_PLURAL: wochen
MONTH_PLURAL: monate
YEAR_PLURAL: jahre
DECADE_PLURAL: dekaden
SEC_PLURAL: sekunden
MIN_PLURAL: minuten
HR_PLURAL: stunden
DAY_PLURAL: tage
WK_PLURAL: wochen
MO_PLURAL: monate
YR_PLURAL: jahre
DEC_PLURAL: dekaden
SECOND_PLURAL: Sekunden
MINUTE_PLURAL: Minuten
HOUR_PLURAL: Stunden
DAY_PLURAL: Tage
WEEK_PLURAL: Wochen
MONTH_PLURAL: Monate
YEAR_PLURAL: Jahre
DECADE_PLURAL: Dekaden
SEC_PLURAL: Sekunden
MIN_PLURAL: Minuten
HR_PLURAL: Stunden
DAY_PLURAL: Tage
WK_PLURAL: Wochen
MO_PLURAL: Monate
YR_PLURAL: Jahre
DEC_PLURAL: Dekaden

43
system/languages/nl.yaml Normal file
View File

@@ -0,0 +1,43 @@
INFLECTOR_IRREGULAR:
'person': 'personen'
'man': 'mensen'
'child': 'kinderen'
'sex': 'geslacht'
'move': 'verplaatsen'
NICETIME:
NO_DATE_PROVIDED: geen datum opgegeven
BAD_DATE: Datumformaat onjuist
AGO: geleden
FROM_NOW: vanaf nu
SECOND: seconde
MINUTE: minuut
HOUR: uur
DAY: dag
WEEK: week
MONTH: maand
YEAR: jaar
DECADE: decenium
SEC: sec
MIN: min
HR: hr
DAY: dag
WK: wk
MO: ma
YR: yr
DEC: dec
SECOND_PLURAL: seconden
MINUTE_PLURAL: minuten
HOUR_PLURAL: uren
DAY_PLURAL: dagen
WEEK_PLURAL: weken
MONTH_PLURAL: maanden
YEAR_PLURAL: jaren
DECADE_PLURAL: decennia
SEC_PLURAL: seconden
MIN_PLURAL: minuten
HR_PLURAL: uren
DAY_PLURAL: dagen
WK_PLURAL: weken
MO_PLURAL: maanden
YR_PLURAL: jaren
DEC_PLURAL: decs

43
system/languages/ru.yaml Normal file
View File

@@ -0,0 +1,43 @@
INFLECTOR_IRREGULAR:
'person': 'люди'
'man': 'человек'
'child': 'ребенок'
'sex': 'пол'
'move': 'движется'
NICETIME:
NO_DATE_PROVIDED: Дата не указана
BAD_DATE: Неверная дата
AGO: назад
FROM_NOW: теперь
SECOND: секунда
MINUTE: минута
HOUR: час
DAY: день
WEEK: неделя
MONTH: месяц
YEAR: год
DECADE: десятилетие
SEC: с
MIN: мин
HR: ч
DAY: д
WK: нед
MO: мес
YR: г.
DEC: гг.
SECOND_PLURAL: секунды
MINUTE_PLURAL: минуты
HOUR_PLURAL: часы
DAY_PLURAL: дни
WEEK_PLURAL: недели
MONTH_PLURAL: месяцы
YEAR_PLURAL: годы
DECADE_PLURAL: десятилетия
SEC_PLURAL: с
MIN_PLURAL: мин
HR_PLURAL: ч
DAY_PLURAL: д
WK_PLURAL: нед
MO_PLURAL: мес
YR_PLURAL: г.
DEC_PLURAL: гг.

View File

@@ -42,6 +42,8 @@ class Assets
/** @const Regex to match CSS import content */
const CSS_IMPORT_REGEX = '{@import(.*);}';
const HTML_TAG_REGEX = '#(<([A-Z][A-Z0-9]*)>)+(.*)(<\/\2>)#is';
/**
* Closure used by the pipeline to fetch assets.
@@ -72,6 +74,8 @@ class Assets
protected $config;
protected $base_url;
protected $timestamp = '';
protected $assets_dir;
protected $assets_url;
// Default values for pipeline settings
protected $css_minify = true;
@@ -115,7 +119,7 @@ class Assets
}
// Pipeline requires public dir
if (($this->js_pipeline || $this->css_pipeline) && !is_dir(ASSETS_DIR)) {
if (($this->js_pipeline || $this->css_pipeline) && !is_dir($this->assets_dir)) {
throw new \Exception('Assets: Public dir not found');
}
@@ -173,6 +177,11 @@ class Assets
$base_url = self::getGrav()['base_url'];
$asset_config = (array)$config->get('system.assets');
/** @var Locator $locator */
$locator = self::$grav['locator'];
$this->assets_dir = self::getGrav()['locator']->findResource('asset://') . DS;
$this->assets_url = self::getGrav()['locator']->findResource('asset://', false);
$this->config($asset_config);
$this->base_url = $base_url . '/';
@@ -227,21 +236,22 @@ class Assets
* It checks for duplicates.
* You may add more than one asset passing an array as argument.
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param bool $pipeline false if this should not be pipelined
* @param null $group
*
* @return $this
*/
public function addCss($asset, $priority = null, $pipeline = null)
public function addCss($asset, $priority = null, $pipeline = null, $group = null)
{
if (is_array($asset)) {
foreach ($asset as $a) {
$this->addCss($a, $priority, $pipeline);
$this->addCss($a, $priority, $pipeline, $group);
}
return $this;
} elseif (isset($this->collections[$asset])) {
$this->add($this->collections[$asset], $priority, $pipeline);
$this->add($this->collections[$asset], $priority, $pipeline, $group);
return $this;
}
@@ -253,7 +263,8 @@ class Assets
'asset' => $asset,
'priority' => intval($priority ?: 10),
'order' => count($this->css),
'pipeline' => $pipeline ?: true
'pipeline' => $pipeline ?: true,
'group' => $group ?: 'head'
];
// check for dynamic array and merge with defaults
@@ -369,20 +380,27 @@ class Assets
* For adding chunks of string-based inline CSS
*
* @param mixed $asset
* @param int $priority the priority, bigger comes first
* @param int $priority the priority, bigger comes first
* @param null $group
*
* @return $this
*/
public function addInlineCss($asset, $priority = null)
public function addInlineCss($asset, $priority = null, $group = null)
{
$asset = trim($asset);
if (is_a($asset, 'Twig_Markup')) {
$asset = strip_tags((string)$asset);
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
if (isset($matches[3])) {
$asset = $matches[3];
}
}
$data = [
'priority' => intval($priority ?: 10),
'order' => count($this->inline_css),
'asset' => $asset
'asset' => $asset,
'group' => $group ?: 'head'
];
// check for dynamic array and merge with defaults
@@ -416,8 +434,13 @@ class Assets
*/
public function addInlineJs($asset, $priority = null, $group = null)
{
$asset = trim($asset);
if (is_a($asset, 'Twig_Markup')) {
$asset = strip_tags((string)$asset);
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
if (isset($matches[3])) {
$asset = $matches[3];
}
}
$data = [
@@ -447,11 +470,12 @@ class Assets
/**
* Build the CSS link tags.
*
* @param string $group name of the group
* @param array $attributes
*
* @return string
*/
public function css($attributes = [])
public function css($group = 'head', $attributes = [])
{
if (!$this->css) {
return null;
@@ -479,26 +503,37 @@ class Assets
$attributes = $this->attributes(array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes));
$output = '';
$inline_css = '';
if ($this->css_pipeline) {
$output .= '<link href="' . $this->pipeline(CSS_ASSET) . '"' . $attributes . ' />' . "\n";
$pipeline_result = $this->pipelineCss($group);
if ($pipeline_result) {
$output .= '<link href="' . $pipeline_result . '"' . $attributes . ' />' . "\n";
}
foreach ($this->css_no_pipeline as $file) {
$media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : '';
$output .= '<link href="' . $file['asset'] . $this->timestamp . '"' . $attributes . $media . ' />' . "\n";
if ($group && $file['group'] == $group) {
$media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : '';
$output .= '<link href="' . $file['asset'] . $this->timestamp . '"' . $attributes . $media . ' />' . "\n";
}
}
} else {
foreach ($this->css as $file) {
$media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : '';
$output .= '<link href="' . $file['asset'] . $this->timestamp . '"' . $attributes . $media . ' />' . "\n";
if ($group && $file['group'] == $group) {
$media = isset($file['media']) ? sprintf(' media="%s"', $file['media']) : '';
$output .= '<link href="' . $file['asset'] . $this->timestamp . '"' . $attributes . $media . ' />' . "\n";
}
}
}
// Render Inline CSS
if (count($this->inline_css) > 0) {
$output .= "<style>\n";
foreach ($this->inline_css as $inline) {
$output .= $inline['asset'] . "\n";
foreach ($this->inline_css as $inline) {
if ($group && $inline['group'] == $group) {
$inline_css .= $inline['asset'] . "\n";
}
$output .= "</style>\n";
}
if ($inline_css) {
$output .= "\n<style>\n" . $inline_css . "\n</style>\n";
}
@@ -539,12 +574,14 @@ class Assets
$attributes = $this->attributes(array_merge(['type' => 'text/javascript'], $attributes));
$output = '';
$inline_js = '';
if ($this->js_pipeline) {
$output .= '<script src="' . $this->pipeline(JS_ASSET) . '"' . $attributes . ' ></script>' . "\n";
$pipeline_result = $this->pipelineJs($group);
if ($pipeline_result) {
$output .= '<script src="' . $pipeline_result . '"' . $attributes . ' ></script>' . "\n";
}
foreach ($this->js_no_pipeline as $file) {
if ($group && $file['group'] == $group) {
$output .= '<script src="' . $file['asset'] . $this->timestamp . '"' . $attributes . ' ' . $file['loading']. '></script>' . "\n";
@@ -572,45 +609,49 @@ class Assets
return $output;
}
/**
* Minify and concatenate CSS / JS files.
* Minify and concatenate CSS.
*
* @return string
*/
protected function pipeline($css = true)
protected function pipelineCss($group = 'head')
{
/** @var Cache $cache */
$cache = self::getGrav()['cache'];
$key = '?' . $cache->getKey();
if ($css) {
$file = md5(json_encode($this->css) . $this->js_minify . $this->css_minify . $this->css_rewrite) . '.css';
foreach ($this->css as $id => $asset) {
if (!$asset['pipeline']) {
$this->css_no_pipeline[] = $asset;
unset($this->css[$id]);
}
}
} else {
$file = md5(json_encode($this->js) . $this->js_minify . $this->css_minify . $this->css_rewrite) . '.js';
foreach ($this->js as $id => $asset) {
if (!$asset['pipeline']) {
$this->js_no_pipeline[] = $asset;
unset($this->js[$id]);
}
}
}
// temporary list of assets to pipeline
$temp_css = [];
$relative_path = "{$this->base_url}" . basename(ASSETS_DIR) . "/{$file}";
$absolute_path = ASSETS_DIR . $file;
// clear no-pipeline assets lists
$this->css_no_pipeline = [];
$file = md5(json_encode($this->css) . $this->css_minify . $this->css_rewrite . $group) . '.css';
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
$absolute_path = $this->assets_dir . $file;
// If pipeline exist return it
if (file_exists($absolute_path)) {
return $relative_path . $key;
}
// Remove any non-pipeline files
foreach ($this->css as $id => $asset) {
if ($asset['group'] == $group) {
if (!$asset['pipeline']) {
$this->css_no_pipeline[$id] = $asset;
} else {
$temp_css[$id] = $asset;
}
}
}
//if nothing found get out of here!
if (count($temp_css) == 0) {
return false;
}
$css_minify = $this->css_minify;
// If this is a Windows server, and minify_windows is false (default value) skip the
@@ -621,23 +662,77 @@ class Assets
}
// Concatenate files
if ($css) {
$buffer = $this->gatherLinks($this->css, CSS_ASSET);
if ($css_minify) {
$min = new \CSSmin();
$buffer = $min->run($buffer);
}
} else {
$buffer = $this->gatherLinks($this->js, JS_ASSET);
if ($this->js_minify) {
$buffer = \JSMin::minify($buffer);
}
$buffer = $this->gatherLinks($temp_css, CSS_ASSET);
if ($css_minify) {
$min = new \CSSmin();
$buffer = $min->run($buffer);
}
// Write file
file_put_contents($absolute_path, $buffer);
if (strlen(trim($buffer)) > 0) {
file_put_contents($absolute_path, $buffer);
return $relative_path . $key;
} else {
return false;
}
}
return $relative_path . $key;
/**
* Minify and concatenate JS files.
*
* @return string
*/
protected function pipelineJs($group = 'head')
{
/** @var Cache $cache */
$cache = self::getGrav()['cache'];
$key = '?' . $cache->getKey();
// temporary list of assets to pipeline
$temp_js = [];
// clear no-pipeline assets lists
$this->js_no_pipeline = [];
$file = md5(json_encode($this->js) . $this->js_minify . $group) . '.js';
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
$absolute_path = $this->assets_dir . $file;
// If pipeline exist return it
if (file_exists($absolute_path)) {
return $relative_path . $key;
}
// Remove any non-pipeline files
foreach ($this->js as $id => $asset) {
if ($asset['group'] == $group) {
if (!$asset['pipeline']) {
$this->js_no_pipeline[] = $asset;
} else {
$temp_js[$id] = $asset;
}
}
}
//if nothing found get out of here!
if (count($temp_js) == 0) {
return false;
}
// Concatenate files
$buffer = $this->gatherLinks($temp_js, JS_ASSET);
if ($this->js_minify) {
$buffer = \JSMin::minify($buffer);
}
// Write file
if (strlen(trim($buffer)) > 0) {
file_put_contents($absolute_path, $buffer);
return $relative_path . $key;
} else {
return false;
}
}
/**
@@ -764,12 +859,12 @@ class Assets
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
{
// Check if public_dir exists
if (!is_dir(ASSETS_DIR)) {
if (!is_dir($this->assets_dir)) {
throw new Exception('Assets: Public dir not found');
}
// Get files
$files = $this->rglob(ASSETS_DIR . DIRECTORY_SEPARATOR . $directory, $pattern, ASSETS_DIR);
$files = $this->rglob($this->assets_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $this->assets_dir);
// No luck? Nothing to do
if (!$files) {
@@ -869,6 +964,7 @@ class Assets
* Download and concatenate the content of several links.
*
* @param array $links
* @param bool $css
*
* @return string
*/
@@ -899,7 +995,12 @@ class Assets
$link = ROOT_DIR . $relative_path;
}
$file = ($this->fetch_command instanceof Closure) ? $this->fetch_command->__invoke($link) : file_get_contents($link);
$file = ($this->fetch_command instanceof Closure) ? @$this->fetch_command->__invoke($link) : @file_get_contents($link);
// No file found, skip it...
if ($file === false) {
continue;
}
// Double check last character being
if (!$css) {

View File

@@ -24,6 +24,8 @@ class ZipBackup
protected static $ignoreFolders = [
'.git',
'.svn',
'.hg',
'.idea'
];

View File

@@ -366,14 +366,16 @@ class Config extends Data
// Load languages.
$this->languages = new Languages;
if (isset($languageFiles['user/plugins'])) {
foreach ((array) $languageFiles['user/plugins'] as $plugin => $item) {
$lang_file = CompiledYamlFile::instance($item['file']);
$content = $lang_file->content();
$this->languages->mergeRecursive($content);
$pluginPaths = str_ireplace(GRAV_ROOT . '/', '', array_reverse($plugins));
foreach ($pluginPaths as $path) {
if (isset($languageFiles[$path])) {
foreach ((array) $languageFiles[$path] as $plugin => $item) {
$lang_file = CompiledYamlFile::instance($item['file']);
$content = $lang_file->content();
$this->languages->mergeRecursive($content);
}
unset($languageFiles[$path]);
}
unset($languageFiles['user/plugins']);
}
foreach ($languageFiles as $location) {

View File

@@ -36,7 +36,7 @@ class Validation
// Validate type with fallback type text.
$type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type'];
$method = 'type'.strtr($type, '-', '_');
$name = ucfirst($field['label'] ? $field['label'] : $field['name']);
$name = ucfirst(isset($field['label']) ? $field['label'] : $field['name']);
$message = (string) isset($field['validate']['message']) ? $field['validate']['message'] : 'Invalid input in "' . $language->translate($name) . '""';
if (method_exists(__CLASS__, $method)) {
@@ -588,6 +588,10 @@ class Validation
public static function validateRequired($value, $params)
{
if (is_string($value)) {
$value = trim($value);
}
return (bool) $params !== true || !empty($value);
}

View File

@@ -22,6 +22,9 @@ trait CompiledFile
*/
public function content($var = null)
{
// Set some options
$this->settings(['native' => true, 'compat' => true]);
// If nothing has been loaded, attempt to get pre-compiled version of the file first.
if ($var === null && $this->raw === null && $this->content === null) {
$key = md5($this->filename);
@@ -47,7 +50,7 @@ trait CompiledFile
$file->lock(false);
// Decode RAW file into compiled array.
$data = $this->decode($this->raw());
$data = (array) $this->decode($this->raw());
$cache = [
'@class' => $class,
'filename' => $this->filename,

View File

@@ -108,6 +108,8 @@ class Grav extends Container
$container['page'] = function ($c) {
/** @var Pages $pages */
$pages = $c['pages'];
/** @var Language $language */
$language = $c['language'];
/** @var Uri $uri */
$uri = $c['uri'];
@@ -117,9 +119,21 @@ class Grav extends Container
$page = $pages->dispatch($path);
// handle redirect if not 'default route' configuration
if ($page && $c['config']->get('system.pages.redirect_default_route') && $page->route() != $path) {
$c->redirectLangSafe($page->route());
// Redirection tests
if ($page) {
// Language-specific redirection scenarios
if ($language->enabled()) {
if ($language->isLanguageInUrl() && !$language->isIncludeDefaultLanguage()) {
$c->redirect($page->route());
}
if (!$language->isLanguageInUrl() && $language->isIncludeDefaultLanguage()) {
$c->redirectLangSafe($page->route());
}
}
// Default route test and redirect
if ($c['config']->get('system.pages.redirect_default_route') && $page->route() != $path) {
$c->redirectLangSafe($page->route());
}
}
// if page is not found, try some fallback stuff
@@ -171,12 +185,15 @@ class Grav extends Container
/** @var Debugger $debugger */
$debugger = $this['debugger'];
// Initialize configuration.
$debugger->startTimer('_config', 'Configuration');
$this['config']->init();
$this['errors']->resetHandlers();
$this['uri']->init();
$this['session']->init();
$this['errors']->resetHandlers();
$debugger->init();
$this['config']->debug();
$debugger->stopTimer('_config');
@@ -255,11 +272,23 @@ class Grav extends Container
* @param string $route Internal route.
* @param int $code Redirection code (30x)
*/
public function redirect($route, $code = 303)
public function redirect($route, $code = null)
{
/** @var Uri $uri */
$uri = $this['uri'];
//Check for code in route
$regex = '/.*(\[(30[1-7])\])$/';
preg_match($regex, $route, $matches);
if ($matches) {
$route = str_replace($matches[1], '', $matches[0]);
$code = $matches[2];
}
if ($code == null) {
$code = $this['config']->get('system.pages.redirect_default_code', 301);
}
if (isset($this['session'])) {
$this['session']->close();
}
@@ -280,15 +309,15 @@ class Grav extends Container
* @param string $route Internal route.
* @param int $code Redirection code (30x)
*/
public function redirectLangSafe($route, $code = 303)
public function redirectLangSafe($route, $code = null)
{
/** @var Language $language */
$language = $this['language'];
if ($language->enabled()) {
if (!$this['uri']->isExternal($route) && $language->enabled() && $language->isIncludeDefaultLanguage()) {
return $this->redirect($language->getLanguage() . $route, $code);
} else {
return $this->redirect($route);
return $this->redirect($route, $code);
}
}
@@ -332,7 +361,7 @@ class Grav extends Container
if ($expires > 0) {
$expires_date = gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT';
header('Cache-Control: max-age=' . $expires_date);
header('Cache-Control: max-age=' . $expires);
header('Expires: '. $expires_date);
}
@@ -428,6 +457,16 @@ class Grav extends Container
/** @var Uri $uri */
$uri = $this['uri'];
/** @var Config $config */
$config = $this['config'];
$uri_extension = $uri->extension();
// Only allow whitelisted types to fallback
if (!in_array($uri_extension, $config->get('system.pages.fallback_types'))) {
return;
}
$path_parts = pathinfo($path);
$page = $this['pages']->dispatch($path_parts['dirname'], true);
if ($page) {
@@ -449,7 +488,6 @@ class Grav extends Container
}
// unsupported media type, try to download it...
$uri_extension = $uri->extension();
if ($uri_extension) {
$extension = $uri_extension;
} else {
@@ -462,7 +500,7 @@ class Grav extends Container
if ($extension) {
$download = true;
if (in_array(ltrim($extension, '.'), $this['config']->get('system.media.unsupported_inline_types', []))) {
if (in_array(ltrim($extension, '.'), $config->get('system.media.unsupported_inline_types', []))) {
$download = false;
}
Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download);

View File

@@ -17,6 +17,7 @@ class Language
protected $active = null;
protected $config;
protected $http_accept_language;
protected $lang_in_url = false;
/**
* Constructor
@@ -161,12 +162,13 @@ class Language
*/
public function setActiveFromUri($uri)
{
$regex = '/(\/(' . $this->getAvailable() . ')).*/';
$regex = '/(^\/(' . $this->getAvailable() . '))(?:\/.*|$)/i';
// if languages set
if ($this->enabled()) {
// try setting from prefix of URL (/en/blah/blah)
if (preg_match($regex, $uri, $matches)) {
$this->lang_in_url = true;
$this->active = $matches[2];
$uri = preg_replace("/\\" . $matches[1] . "/", '', $matches[0], 1);
@@ -200,6 +202,52 @@ class Language
return $uri;
}
/**
* Get's a URL prefix based on configuration
*
* @param null $lang
* @return string
*/
public function getLanguageURLPrefix($lang = null)
{
// if active lang is not passed in, use current active
if (!$lang) {
$lang = $this->getLanguage();
}
return $this->isIncludeDefaultLanguage($lang) ? '/' . $lang : '';
}
/**
* Test to see if language is default and language should be included in the URL
*
* @param null $lang
* @return bool
*/
public function isIncludeDefaultLanguage($lang = null)
{
// if active lang is not passed in, use current active
if (!$lang) {
$lang = $this->getLanguage();
}
if ($this->default == $lang && $this->config->get('system.languages.include_default_lang') === false) {
return false;
} else {
return true;
}
}
/**
* Simple getter to tell if a language was found in the URL
*
* @return bool
*/
public function isLanguageInUrl()
{
return (bool) $this->lang_in_url;
}
/**
* Gets an array of valid extensions with active first, then fallback extensions
@@ -254,6 +302,8 @@ class Language
}
$this->fallback_languages = $fallback_languages;
}
// always add english in case a translation doesn't exist
$this->fallback_languages[] = 'en';
}
return $this->fallback_languages;

View File

@@ -36,6 +36,18 @@ class Collection extends Iterator
return $this->params;
}
/**
* Add a single page to a collection
*
* @param Page $page
* @return $this
*/
public function addPage(Page $page)
{
$this->items[$page->path()] = ['slug' => $page->slug()];
return $this;
}
/**
*
* Create a copy of this collection
@@ -96,6 +108,7 @@ class Collection extends Iterator
* Remove item from the list.
*
* @param Page|string|null $key
* @return $this|void
* @throws \InvalidArgumentException
*/
public function remove($key = null)
@@ -110,6 +123,7 @@ class Collection extends Iterator
}
parent::remove($key);
return $this;
}
/**

View File

@@ -68,6 +68,16 @@ class Medium extends Data implements RenderableInterface
$this->reset();
}
/**
* Return just metadata from the Medium object
*
* @return $this
*/
public function meta()
{
return new Data($this->items);
}
/**
* Add meta file for the medium.
*
@@ -203,9 +213,29 @@ class Medium extends Data implements RenderableInterface
}
$attributes['style'] = $style;
!empty($title) && empty($attributes['title']) && $attributes['title'] = $title;
!empty($alt) && empty($attributes['alt']) && $attributes['alt'] = $alt;
!empty($class) && empty($attributes['class']) && $attributes['class'] = $class;
if (empty($attributes['title'])) {
if (!empty($title)) {
$attributes['title'] = $title;
} elseif (!empty($this->items['title'])) {
$attributes['title'] = $this->items['title'];
}
}
if (empty($attributes['alt'])) {
if (!empty($alt)) {
$attributes['alt'] = $alt;
} elseif (!empty($this->items['alt'])) {
$attributes['alt'] = $this->items['alt'];
}
}
if (empty($attributes['class'])) {
if (!empty($class)) {
$attributes['class'] = $class;
} elseif (!empty($this->items['class'])) {
$attributes['class'] = $this->items['class'];
}
}
switch ($this->mode) {
case 'text':
@@ -376,8 +406,6 @@ class Medium extends Data implements RenderableInterface
$this->querystring($this->querystring(null, false) . '&' . $qs);
}
self::$grav['debugger']->addMessage($this->querystring());
return $this;
}

View File

@@ -259,6 +259,8 @@ class Page
if (!$this->header) {
$file = $this->file();
if ($file) {
// Set some options
$file->settings(['native' => true, 'compat' => true]);
try {
$this->raw_content = $file->markdown();
$this->frontmatter = $file->frontmatter();
@@ -1242,8 +1244,8 @@ class Page
$language = self::getGrav()['language'];
// get pre-route
if ($include_lang) {
$pre_route = $language->enabled() && $language->getActive() ? '/' . $language->getActive() : '';
if ($include_lang && $language->enabled()) {
$pre_route = $language->getLanguageURLPrefix();
} else {
$pre_route = '';
}
@@ -1861,20 +1863,24 @@ class Page
/** @var Config $config */
$config = self::getGrav()['config'];
foreach ((array) $config->get('site.taxonomies') as $taxonomy) {
if ($uri->param($taxonomy)) {
$items = explode(',', $uri->param($taxonomy));
$collection->setParams(['taxonomies' => [$taxonomy => $items]]);
$process_taxonomy = isset($params['url_taxonomy_filters']) ? $params['url_taxonomy_filters'] : $config->get('system.pages.url_taxonomy_filters');
foreach ($collection as $page) {
// Don't filter modular pages
if ($page->modular()) {
continue;
}
foreach ($items as $item) {
if (empty($page->taxonomy[$taxonomy])
|| !in_array(htmlspecialchars_decode($item, ENT_QUOTES), $page->taxonomy[$taxonomy])) {
$collection->remove();
if ($process_taxonomy) {
foreach ((array) $config->get('site.taxonomies') as $taxonomy) {
if ($uri->param($taxonomy)) {
$items = explode(',', $uri->param($taxonomy));
$collection->setParams(['taxonomies' => [$taxonomy => $items]]);
foreach ($collection as $page) {
// Don't filter modular pages
if ($page->modular()) {
continue;
}
foreach ($items as $item) {
if (empty($page->taxonomy[$taxonomy])
|| !in_array(htmlspecialchars_decode($item, ENT_QUOTES), $page->taxonomy[$taxonomy])) {
$collection->remove();
}
}
}
}
@@ -1929,14 +1935,19 @@ class Page
// Format: @command.param
$cmd = $value;
$params = array();
} elseif (is_array($value) && count($value) == 1) {
} elseif (is_array($value) && count($value) == 1 && !is_int(key($value))) {
// Format: @command.param: { attr1: value1, attr2: value2 }
$cmd = (string) key($value);
$params = (array) current($value);
} else {
$result = [];
foreach($value as $key => $val) {
$result = $result + $this->evaluate([$key=>$val])->toArray();
if (is_int($key)) {
$result = $result + $this->evaluate($val)->toArray();
} else {
$result = $result + $this->evaluate([$key=>$val])->toArray();
}
}
return new Collection($result);
}
@@ -1946,6 +1957,9 @@ class Page
return $value;
}
/** @var Pages $pages */
$pages = self::getGrav()['pages'];
$parts = explode('.', $cmd);
$current = array_shift($parts);
@@ -1955,24 +1969,75 @@ class Page
if (!empty($parts)) {
switch ($parts[0]) {
case 'modular':
$results = $this->children()->modular()->published();
// @self.modular: false (alternative to @self.children)
if (!empty($params) && $params[0] === false) {
$results = $this->children()->nonModular();
break;
}
$results = $this->children()->modular();
break;
case 'children':
$results = $this->children()->nonModular()->published();
$results = $this->children()->nonModular();
break;
case 'parent':
$collection = new Collection();
$results = $collection->addPage($this->parent());
break;
case 'siblings':
$results = $this->parent()->children()->remove($this->path());
break;
case 'descendants':
$results = $pages->all($this)->remove($this->path())->nonModular();
break;
}
}
$results = $results->published();
break;
case '@page':
$page = null;
if (!empty($params)) {
$page = $this->find($params[0]);
if ($page) {
$results = $page->children()->nonModular()->published();
}
// Handle a @page.descendants
if (!empty($parts) && isset($page)) {
switch ($parts[0]) {
case 'self':
$results = new Collection();
$results = $results->addPage($page);
break;
case 'descendants':
$results = $pages->all($page)->remove($page->path());
break;
case 'children':
$results = $page->children();
break;
}
} else {
$results = $page->children();
}
$results = $results->nonModular()->published();
break;
case '@root':
if (!empty($parts) && $parts[0] == 'descendants') {
$results = $pages->all($pages->root())->nonModular()->published();
} else {
$results = $pages->root()->children()->nonModular()->published();
}
break;
case '@taxonomy':
// Gets a collection of pages by using one of the following formats:
// @taxonomy.category: blog

View File

@@ -65,6 +65,7 @@ class Pages
protected $ignore_files;
protected $ignore_folders;
protected $ignore_hidden;
/**
* @var Types
@@ -108,6 +109,7 @@ class Pages
$config = $this->grav['config'];
$this->ignore_files = $config->get('system.pages.ignore_files');
$this->ignore_folders = $config->get('system.pages.ignore_folders');
$this->ignore_hidden = $config->get('system.pages.ignore_hidden');
$this->buildPages();
}
@@ -702,6 +704,13 @@ class Pages
foreach (new \FilesystemIterator($directory) as $file) {
$name = $file->getFilename();
// Ignore all hidden files if set.
if ($this->ignore_hidden) {
if ($name && $name[0] == '.') {
continue;
}
}
if ($file->isFile()) {
// Update the last modified if it's newer than already found
if (!in_array($file->getBasename(), $this->ignore_files) && ($modified = $file->getMTime()) > $last_modified) {

View File

@@ -94,18 +94,21 @@ class Plugins extends Iterator
{
$list = array();
$locator = Grav::instance()['locator'];
$iterator = new \DirectoryIterator($locator->findResource('plugins://', false));
/** @var \DirectoryIterator $directory */
foreach ($iterator as $directory) {
if (!$directory->isDir() || $directory->isDot()) {
continue;
$plugins = (array) $locator->findResources('plugins://', false);
foreach ($plugins as $path) {
$iterator = new \DirectoryIterator($path);
/** @var \DirectoryIterator $directory */
foreach ($iterator as $directory) {
if (!$directory->isDir() || $directory->isDot()) {
continue;
}
$type = $directory->getBasename();
$list[$type] = self::get($type);
}
$type = $directory->getBasename();
$list[$type] = self::get($type);
}
ksort($list);
return $list;

View File

@@ -27,6 +27,9 @@ class Themes extends Iterator
{
$this->grav = $grav;
$this->config = $grav['config'];
// Register instance as autoloader for theme inheritance
spl_autoload_register([$this, 'autoloadTheme']);
}
public function init()
@@ -60,18 +63,21 @@ class Themes extends Iterator
{
$list = array();
$locator = Grav::instance()['locator'];
$iterator = new \DirectoryIterator($locator->findResource('themes://', false));
/** @var \DirectoryIterator $directory */
foreach ($iterator as $directory) {
if (!$directory->isDir() || $directory->isDot()) {
continue;
$themes = (array) $locator->findResources('themes://', false);
foreach ($themes as $path) {
$iterator = new \DirectoryIterator($path);
/** @var \DirectoryIterator $directory */
foreach ($iterator as $directory) {
if (!$directory->isDir() || $directory->isDot()) {
continue;
}
$type = $directory->getBasename();
$list[$type] = self::get($type);
}
$type = $directory->getBasename();
$list[$type] = self::get($type);
}
ksort($list);
return $list;
@@ -96,9 +102,8 @@ class Themes extends Iterator
// Find thumbnail.
$thumb = "themes://{$name}/thumbnail.jpg";
if (file_exists($thumb)) {
$blueprint->set('thumbnail', $this->grav['base_url'] . "/user/themes/{$name}/thumbnail.jpg");
if ($path = $this->grav['locator']->findResource($thumb, false)) {
$blueprint->set('thumbnail', $this->grav['base_url'] . '/' . $path);
}
// Load default configuration.
@@ -216,18 +221,76 @@ class Themes extends Iterator
throw new \InvalidArgumentException("Stream '{$type}' could not be initialized.");
}
}
// Load languages after streams has been properly initialized
$this->loadLanguages($this->config);
}
/**
* Load theme configuration.
*
* @param string $name Theme name
* @param Config $config Configuration class
*/
protected function loadConfiguration($name, Config $config)
{
$themeConfig = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT)->content();
$config->joinDefaults("themes.{$name}", $themeConfig);
}
/**
* Load theme languages.
*
* @param Config $config Configuration class
*/
protected function loadLanguages(Config $config)
{
/** @var UniformResourceLocator $locator */
$locator = $this->grav['locator'];
if ($config->get('system.languages.translations', true)) {
$languageFiles = array_reverse($locator->findResources("theme://languages" . YAML_EXT));
$languages = [];
foreach ($languageFiles as $language) {
$languages[] = CompiledYamlFile::instance($language)->content();
}
if ($this->config->get('system.languages.translations', true)) {
$languages = CompiledYamlFile::instance("themes://{$name}/languages". YAML_EXT)->content();
if ($languages) {
$languages = call_user_func_array('array_replace_recursive', $languages);
$config->getLanguages()->mergeRecursive($languages);
}
}
}
/**
* Autoload theme classes for inheritance
*
* @param string $class Class name
*
* @return mixed false FALSE if unable to load $class; Class name if
* $class is successfully loaded
*/
protected function autoloadTheme($class)
{
/** @var UniformResourceLocator $locator */
$locator = $this->grav['locator'];
$prefix = "Grav\\Theme";
if (false !== strpos($class, $prefix)) {
// Remove prefix from class
$class = substr($class, strlen($prefix));
// Replace namespace tokens to directory separators
$path = ltrim(preg_replace('#\\\|_(?!.+\\\)#', '/', $class), '/');
$file = $locator->findResource("themes://{$path}/{$path}.php");
// Load class
if (stream_resolve_include_path($file)) {
return include_once($file);
}
}
return false;
}
}

View File

@@ -7,6 +7,7 @@ use Grav\Common\Page\Page;
use Grav\Common\Inflector;
use Grav\Common\Utils;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use RocketTheme\Toolbox\Event\Event;
/**
* The Twig object handles all the Twig template rendering for Grav. It's a singleton object
@@ -85,7 +86,7 @@ class Twig
// handle language templates if available
if ($language->enabled()) {
$lang_templates = $locator->findResource('theme://templates/'.$active_language);
$lang_templates = $locator->findResource('theme://templates/'.($active_language ? $active_language : $language->getDefault()));
if ($lang_templates) {
$this->twig_paths[] = $lang_templates;
}
@@ -142,7 +143,6 @@ class Twig
// Set some standard variables for twig
$this->twig_vars = array(
'grav' => $this->grav,
'config' => $config,
'uri' => $this->grav['uri'],
'base_dir' => rtrim(ROOT_DIR, '/'),
@@ -202,7 +202,7 @@ class Twig
$content = $content !== null ? $content : $item->content();
// override the twig header vars for local resolution
$this->grav->fireEvent('onTwigPageVariables');
$this->grav->fireEvent('onTwigPageVariables', new Event(['page' => $item]));
$twig_vars = $this->twig_vars;
$twig_vars['page'] = $item;
@@ -307,6 +307,7 @@ class Twig
$twig_vars['pages'] = $pages->root();
$twig_vars['page'] = $page;
$twig_vars['header'] = $page->header();
$twig_vars['media'] = $page->media();
$twig_vars['content'] = $content;
$ext = '.' . ($format ? $format : 'html') . TWIG_EXT;

View File

@@ -36,6 +36,18 @@ class TwigExtension extends \Twig_Extension
return 'GravTwigExtension';
}
/**
* Register some standard globals
*
* @return array
*/
public function getGlobals()
{
return array(
'grav' => $this->grav,
);
}
/**
* Return a list of all filters.
*
@@ -89,6 +101,7 @@ class TwigExtension extends \Twig_Extension
new \Twig_simpleFunction('t', [$this, 'translate']),
new \Twig_simpleFunction('ta', [$this, 'translateArray']),
new \Twig_SimpleFunction('url', [$this, 'urlFunc']),
new \Twig_SimpleFunction('evaluate', [$this, 'evaluateFunc']),
];
}
@@ -116,7 +129,7 @@ class TwigExtension extends \Twig_Extension
$email = '';
$str_len = strlen($str);
for ($i = 0; $i < $str_len; $i++) {
$email .= "&#" . ord($str[$i]);
$email .= "&#" . ord($str[$i]). ";";
}
return $email;
}
@@ -450,6 +463,19 @@ class TwigExtension extends \Twig_Extension
return $resource ? rtrim($uri->rootUrl($domain), '/') . '/' . $resource : null;
}
/**
* Evaluate a string
*
* @example {{ evaluate('grav.language.getLanguage') }}
*
* @param string $input String to be evaluated
* @return string Returns the evaluated string
*/
public function evaluateFunc($input)
{
return $this->grav['twig']->processString("{{ $input }}");
}
/**
* Based on Twig_Extension_Debug / twig_var_dump
* (c) 2011 Fabien Potencier

View File

@@ -12,6 +12,8 @@ use Grav\Common\Page\Pages;
*/
class Uri
{
const HOSTNAME_REGEX = '/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/';
public $url;
protected $basename;
@@ -35,6 +37,9 @@ class Uri
// Remove port from HTTP_HOST generated $name
$name = Utils::substrToString($name, ':');
// Validate the hostname
$name = preg_match(Uri::HOSTNAME_REGEX, $name) ? $name : 'unknown';
$port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80;
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
@@ -93,6 +98,9 @@ class Uri
// get any params and remove them
$uri = str_replace($this->root, '', $this->url);
// remove double slashes
$uri = preg_replace('#/{2,}#', '/', $uri);
// remove the setup.php based base if set:
$setup_base = $grav['pages']->base();
if ($setup_base) {
@@ -110,22 +118,11 @@ class Uri
// set active language
$uri = $language->setActiveFromUri($uri);
// redirect to language specific homepage if configured to do so
if ($uri == '/' && $language->enabled()) {
if ($config->get('system.languages.home_redirect.include_route', true)) {
$prefix = $config->get('system.languages.home_redirect.include_lang', true) ? $language->getLanguage() . '/' : '';
$grav->redirect($prefix . Pages::getHomeRoute());
} elseif ($config->get('system.languages.home_redirect.include_lang', true)) {
$grav->redirect($language->getLanguage() . '/');
}
}
// split the URL and params
$bits = parse_url($uri);
// process query string
if (isset($bits['query'])) {
if (isset($bits['query']) && isset($bits['path'])) {
$this->query = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$uri = $bits['path'];
}
@@ -136,11 +133,15 @@ class Uri
// set the original basename
$this->basename = $parts['basename'];
// set the extension
if (isset($parts['extension'])) {
$this->extension = $parts['extension'];
}
$valid_page_types = implode('|', $config->get('system.pages.types'));
if (preg_match("/\.(".$valid_page_types.")$/", $parts['basename'])) {
$uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS). '/' .$parts['filename'];
$this->extension = $parts['extension'];
}
// set the new url
@@ -493,11 +494,13 @@ class Uri
{
$grav = Grav::instance();
/** @var Grav\Common\Language\Language $language */
$language = $grav['language'];
// Link processing should prepend language
$language_append = '';
if ($type == 'link') {
$active_language = $grav['language']->getActive();
$language_append = $active_language ? '/'.$active_language : '';
if ($type == 'link' && $language->enabled()) {
$language_append = $language->getLanguageURLPrefix();
}
$pages_dir = $grav['locator']->findResource('page://');

View File

@@ -5,6 +5,7 @@ use Grav\Common\Data\Blueprints;
use Grav\Common\Data\Data;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\GravTrait;
use Grav\Common\Utils;
/**
* User object
@@ -45,6 +46,22 @@ class User extends Data
return $user;
}
/**
* Remove user account.
*
* @param string $username
* @return bool True is the action was performed
*/
public static function remove($username)
{
$file_path = self::getGrav()['locator']->findResource('account://' . $username . YAML_EXT);
if (file_exists($file_path) && unlink($file_path)) {
return true;
}
return false;
}
/**
* Authenticate user.
*
@@ -122,7 +139,7 @@ class User extends Data
return false;
}
return $this->get("access.{$action}") === true;
return Utils::isPositive($this->get("access.{$action}"));
}
/**

View File

@@ -264,99 +264,13 @@ abstract class Utils
public static function getMimeType($extension)
{
$extension = strtolower($extension);
$config = self::getGrav()['config']->get('media');
switch ($extension) {
case "js":
return "application/x-javascript";
case "json":
return "application/json";
case "jpg":
case "jpeg":
case "jpe":
return "image/jpg";
case "png":
case "gif":
case "bmp":
case "tiff":
return "image/" . $extension;
case "css":
return "text/css";
case "xml":
return "application/xml";
case "doc":
case "docx":
return "application/msword";
case "xls":
case "xlt":
case "xlm":
case "xld":
case "xla":
case "xlc":
case "xlw":
case "xll":
return "application/vnd.ms-excel";
case "ppt":
case "pps":
return "application/vnd.ms-powerpoint";
case "rtf":
return "application/rtf";
case "pdf":
return "application/pdf";
case "html":
case "htm":
case "php":
return "text/html";
case "txt":
return "text/plain";
case "mpeg":
case "mpg":
case "mpe":
return "video/mpeg";
case "mp3":
return "audio/mpeg3";
case "wav":
return "audio/wav";
case "aiff":
case "aif":
return "audio/aiff";
case "avi":
return "video/msvideo";
case "wmv":
return "video/x-ms-wmv";
case "mov":
return "video/quicktime";
case "zip":
return "application/zip";
case "tar":
return "application/x-tar";
case "swf":
return "application/x-shockwave-flash";
default:
return "application/octet-stream";
if (isset($config[$extension])) {
return $config[$extension]['mime'];
}
return 'application/octet-stream';
}
/**
@@ -463,4 +377,14 @@ abstract class Utils
}
}
/**
* Checks if a value is positive
*
* @param string $value
*
* @return boolean
*/
public static function isPositive($value) {
return in_array($value, [true, 1, '1', 'yes', 'on', 'true'], true);
}
}