Compare commits

..

No commits in common. "4" and "2.4.5-rc1" have entirely different histories.
4 ... 2.4.5-rc1

58 changed files with 2118 additions and 595 deletions

View File

@ -1,15 +0,0 @@
{
"github-slug": "silverstripe/silverstripe-installer",
"child-stability-inherit": true,
"dependency-constraint": "loose",
"vendors": [
"silverstripe"
],
"tests": [
"vendor/bin/phpunit vendor/silverstripe/framework/tests/php",
"vendor/bin/phpunit vendor/silverstripe/cms/tests/php"
],
"exclude": [
"silverstripe/recipe-plugin"
]
}

View File

@ -1,79 +0,0 @@
# {{ version }}
## Overview
A full list of module versions included in CMS Recipe {{ version }} is provided below. We recommend referencing recipes in your dependencies, rather than individual modules, to simplify version tracking. See [Recipes](/getting_started/).
<details>
<summary>Included module versions</summary>
| Module | Version |
| ------ | ------- |
| silverstripe/admin | x.x.x |
| silverstripe/asset-admin | x.x.x |
| silverstripe/assets | x.x.x |
| silverstripe/campaign-admin | x.x.x |
| silverstripe/cms | x.x.x |
| silverstripe/config | x.x.x |
| silverstripe/errorpage | x.x.x |
| silverstripe/framework | x.x.x |
| silverstripe/graphql | x.x.x |
| silverstripe/login-forms | x.x.x |
| silverstripe/mimevalidator | x.x.x |
| silverstripe/reports | x.x.x |
| silverstripe/siteconfig | x.x.x |
| silverstripe/versioned | x.x.x |
| silverstripe/versioned-admin | x.x.x |
</details>
{% if version.stability == 'rc' %}
## Release Candidate
This version of Silverstripe CMS is a **release candidate** for an upcoming stable version, and should not be applied to production websites. We encourage developers to test this version in development / testing environments and [report any issues they encounter via GitHub](/contributing/issues_and_bugs/).
{% elseif version.stable %}
Upgrading to Recipe {{ version }} is recommended for all sites. This upgrade can be carried out by any development team familiar with Silverstripe.
## Security considerations
This release includes security fixes. Please see the release announcements for more detailed
descriptions of each. We highly encourage upgrading your project to include the latest security patches nonetheless.
We have provided a high-level severity rating of the vulnerabilities below based on the CVSS score, however please note this could vary based on the specifics of each project. You can [read the severity rating definitions in the Silverstripe CMS release process](/contributing/release_process/#severity-rating).
* [CVE-0000-0000 The Issue Title](https://www.silverstripe.org/download/security-releases/CVE-0000-0000) Severity: {# Critical/ High/ Medium/ Low #}
* [CVE-0000-0001 The Issue Title](https://www.silverstripe.org/download/security-releases/CVE-0000-0001) Severity: {# Critical/ High/ Medium/ Low #}
## New features
The [release announcement](#) includes the note worthy features, but be sure to review the change log for full detail.
{# other upgrade notes here #}
## Known issues
{#
* [Known issue](GitHub link)
#}
### Expected test failures
The following PHPUnit test failures are expected and do not represent functional issues:
{#
* List test failures here
#}
```
...
```
...
{% endif %}
{{ logs }}

View File

@ -1,25 +0,0 @@
# For more information about the properties used in
# this file, please see the EditorConfig documentation:
# http://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,json}]
# The indent size used in the `package.json` file cannot be changed
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
indent_size = 2
indent_style = space
[composer.json]
indent_size = 4

View File

@ -1,12 +0,0 @@
# For a complete list of core environment variables see
# https://docs.silverstripe.org/en/4/getting_started/environment_management/#core-environment-variables
# DB credentials
SS_DATABASE_CLASS="MySQLDatabase"
SS_DATABASE_SERVER="localhost"
SS_DATABASE_USERNAME="<user>"
SS_DATABASE_PASSWORD="<password>"
SS_DATABASE_NAME="<database>"
# WARNING: in a live environment, change this to "live" instead of dev
SS_ENVIRONMENT_TYPE="dev"

11
.gitattributes vendored
View File

@ -1,11 +0,0 @@
.github export-ignore
.cow.json export-ignore
.cow export-ignore
.gitattributes export-ignore
.travis.yml export-ignore
behat.yml export-ignore
build.xml export-ignore
CONTRIBUTING.md export-ignore
LICENSE export-ignore
phpunit.xml.dist export-ignore
README.md

View File

@ -1,27 +0,0 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
ci:
name: CI
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1
with:
# installer contains a sample behat.yml file, though there are no behat tests to run
endtoend: false
# require the following in ci.yml rather than composer.json require-dev specifically for installer because unlike
# regular modules, require-dev will get installed to projects during `composer create-project silverstripe/installer`
composer_require_extra: silverstripe/recipe-testing:^2 silverstripe/frameworktest:^0.4.2 mikey179/vfsstream:^1.6.10
extra_jobs: |
- endtoend: true
endtoend_suite: admin
endtoend_config: vendor/silverstripe/admin/behat.yml
- endtoend: true
endtoend_suite: asset-admin
endtoend_config: vendor/silverstripe/asset-admin/behat.yml
- endtoend: true
endtoend_suite: cms
endtoend_config: vendor/silverstripe/cms/behat.yml

View File

@ -1,16 +0,0 @@
name: Dispatch CI
on:
# At 4:00 PM and 5:00 PM
schedule:
- cron: '0 16,17 * * *'
jobs:
dispatch-ci:
name: Dispatch CI
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Dispatch CI
uses: silverstripe/gha-dispatch-ci@v1

View File

@ -1,17 +0,0 @@
name: Keepalive
on:
workflow_dispatch:
# The 8th of every month at 4:50pm UTC
schedule:
- cron: '50 16 8 * *'
jobs:
keepalive:
name: Keepalive
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Keepalive
uses: silverstripe/gha-keepalive@v1

8
.gitignore vendored
View File

@ -1,8 +0,0 @@
/silverstripe-cache/
/.env
/vendor/
/themes/simple/
/_resources/
/public/_resources/
/.graphql-generated/
/public/_graphql/

View File

@ -1,2 +1,28 @@
RewriteEngine On
RewriteRule ^(.*)$ public/$1
### SILVERSTRIPE START ###
<Files *.ss>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Files>
<Files web.config>
Order deny,allow
Deny from all
</Files>
ErrorDocument 404 /assets/error-404.html
ErrorDocument 500 /assets/error-500.html
<IfModule mod_alias.c>
RedirectMatch 403 /silverstripe-cache(/|$)
</IfModule>
<IfModule mod_rewrite.c>
SetEnv HTTP_MOD_REWRITE On
RewriteEngine On
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* sapphire/main.php?url=%1&%{QUERY_STRING} [L]
</IfModule>
### SILVERSTRIPE END ###

8
.mergesources.yml Normal file
View File

@ -0,0 +1,8 @@
# Data source for the "arb" svn merge tool (see http://github.com/sminnee/arborist).
# Keeps track of all opensource branches of submodules
# that could be merged back to the current submodule paths.
trunk:
.: /open/phpinstaller/trunk
sapphire: /open/modules/sapphire/trunk
cms: /open/modules/cms/trunk
jsparty: /open/modules/jsparty/trunk

View File

@ -1,28 +0,0 @@
# Contributing
Any open source product is only as good as the community behind it. You can participate by sharing code, ideas, or simply helping others. No matter what your skill level is, every contribution counts. See our [high level contribution overview](http://silverstripe.org/contributing-to-silverstripe) on silverstripe.org on how you can help out.
## Bugtracker ##
Bugs are tracked on [github.com](https://github.com/silverstripe/framework/issues).
Please read our [issue reporting guidelines](http://doc.silverstripe.org/framework/en/misc/contributing/issues).
## Development and Contribution ##
For submitting patches, please read our [guide to contributing code](http://doc.silverstripe.org/framework/en/misc/contributing/code). We only accept pull requests on github.com.
## Links ##
* [Server Requirements](http://doc.silverstripe.org/framework/en/installation/server-requirements)
* [Changelogs](http://doc.silverstripe.org/framework/en/changelogs/)
* [Bugtracker: Framework](https://github.com/silverstripe/silverstripe-framework/issues)
* [Bugtracker: CMS](https://github.com/silverstripe/silverstripe-cms/issues)
* [Bugtracker: Installer](https://github.com/silverstripe/silverstripe-installer/issues)
* [Forums](http://silverstripe.org/forums)
* [Developer Mailinglist](https://groups.google.com/forum/#!forum/silverstripe-dev)
## Copyright
**IMPORTANT: By supplying code to the SilverStripe core team in patches, tickets and pull requests, you agree to assign copyright of that code to SilverStripe Limited, on the condition that SilverStripe Limited releases that code under the BSD license.**
We ask for this so that the ownership in the license is clear and unambiguous, and so that community involvement doesn't stop us from being able to continue supporting these projects. By releasing this code under a permissive license, this copyright assignment won't prevent you from using the code in any way you see fit.

View File

@ -1,17 +1,17 @@
Copyright (c) 2007-2017, SilverStripe Limited - www.silverstripe.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of SilverStripe nor the names of its contributors may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
Copyright (c) 2007-2008, SilverStripe Limited - www.silverstripe.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of SilverStripe nor the names of its contributors may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.

1
ChangeLog Normal file
View File

@ -0,0 +1 @@
For a full change log, please visit http://open.silverstripe.org/wiki/ChangeLog.

19
INSTALL Normal file
View File

@ -0,0 +1,19 @@
Thanks for downloading SilverStripe CMS.
Simply extract the archive to a folder in a web-accessible location and visit the folder
in your web browser (which in turn runs index.php).
This will lead you through a web-based installation process.
Server Requirements
* PHP 5.0.4+ (5.2+ is recommended)
* MySQL 4.1+ (other databases are supported - details here: http://doc.silverstripe.com/doku.php?id=server-requirements)
* Apache or IIS 7.x
* More information on server requirements here: http://doc.silverstripe.com/doku.php?id=server-requirements
General documentation, tutorials:
* Wiki: http://doc.silverstripe.com/
* Tutorials: http://doc.silverstripe.org/doku.php?id=tutorials
Forum
* http://www.silverstripe.com/silverstripe-forum/

19
Makefile Normal file
View File

@ -0,0 +1,19 @@
#
# This makefile is a secondary way of installing SilverStripe.
# It is used for things like continuous integration
#
# Most users should simply visit the site root in your web browser.
#
test:
$(MAKE) QUERYSTRING="$(QUERYSTRING)" -C sapphire test
getallmodules:
if [ -d auth_openid ]; then svn update auth_openid; else svn co http://svn.silverstripe.com/open/modules/auth_openid/trunk auth_openid; fi
if [ -d blog ]; then svn update blog; else svn co http://svn.silverstripe.com/open/modules/blog/trunk blog; fi
if [ -d cmsworkflow ]; then svn update cmsworkflow; else svn co http://svn.silverstripe.com/open/modules/cmsworkflow/trunk cmsworkflow; fi
if [ -d forum ]; then svn update forum; else svn co http://svn.silverstripe.com/open/modules/forum/trunk forum; fi
if [ -d genericdataadmin ]; then svn update genericdataadmin; else svn co http://svn.silverstripe.com/open/modules/genericdataadmin/trunk genericdataadmin; fi
if [ -d multiform ]; then svn update multiform; else svn co http://svn.silverstripe.com/open/modules/multiform/trunk multiform; fi
if [ -d subsites ]; then svn update subsites; else svn co http://svn.silverstripe.com/open/modules/subsites/trunk subsites; fi
if [ -d userforms ]; then svn update userforms; else svn co http://svn.silverstripe.com/open/modules/userforms/trunk userforms; fi

View File

@ -1,32 +0,0 @@
## Overview
[![CI](https://github.com/silverstripe/silverstripe-installer/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-installer/actions/workflows/ci.yml)
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
Base project folder for a Silverstripe ([http://silverstripe.org](http://silverstripe.org)) installation. Required modules are installed via [http://github.com/silverstripe/recipe-cms](http://github.com/silverstripe/recipe-cms). For information on how to change the dependencies in a recipe, please have a look at [https://github.com/silverstripe/recipe-plugin](https://github.com/silverstripe/recipe-plugin). In addition, installer includes [theme/simple](https://github.com/silverstripe-themes/silverstripe-simple) as a default theme.
## Installation ##
`composer create-project silverstripe/installer my-app`
See [Getting Started](https://docs.silverstripe.org/en/4/getting_started/) for more information.
## Bugtracker ##
Bugs are tracked on github.com ([framework issues](https://github.com/silverstripe/silverstripe-framework/issues),
[cms issues](https://github.com/silverstripe/silverstripe-cms/issues)).
Please read our [issue reporting guidelines](https://docs.silverstripe.org/en/4/contributing/issues_and_bugs/).
## Development and Contribution ##
If you would like to make changes to the Silverstripe core codebase, we have an extensive [guide to contributing code](https://docs.silverstripe.org/en/4/contributing/code/).
## Links ##
* [Changelogs](https://docs.silverstripe.org/en/4/changelogs/)
* [Bugtracker: Framework](https://github.com/silverstripe/silverstripe-framework/issues)
* [Bugtracker: CMS](https://github.com/silverstripe/silverstripe-cms/issues)
* [Bugtracker: Installer](https://github.com/silverstripe/silverstripe-installer/issues)
* [Forums](http://silverstripe.org/forums)
* [Developer Mailinglist](https://groups.google.com/forum/#!forum/silverstripe-dev)
* [License](./LICENSE)

20
UPGRADING Normal file
View File

@ -0,0 +1,20 @@
Usually upgrading your SilverStripe installation just means overwriting files
and updating your database-schema.
- Backup your database
- Backup your webroot
- Download the new release and uncompress it to a temporary folder
- With these folders: cms, sapphire, googlesitemaps
- Delete your existing folders
- Extract and replace folders from your download (leave modules
and your custom directories alone)
- Moving your current folders (rather than installing on top) means
you can undo the installation, and ensures if the new release has no
longer contains some files, these files won't be left behind, which otherwise
could cause bugs.
- Visit http://your.silverstripe.site/dev/build (This adds new
fields/tables to the database, and empties your template cache)
- Check if any modules (e.g. blog or forum) in your installation are compatible
and need to be upgraded as well
- Check if you need to adapt your code to changed APIs, see
http://doc.silverstripe.com/doku.php?id=upgrading

View File

@ -1,26 +0,0 @@
# SilverStripe 4.4 changes the way files are resolved. `silverstripe-assets` resolves files using a variety of formats
# by default. When starting a brand new project on SilverStripe 4.4 or greater, those extra formats are not needed and
# will slowdown file resolution requests a bit. This config removes those redundant formats.
---
Name: project-assetsflysystem
After: '#assetsflysystem'
---
SilverStripe\Core\Injector\Injector:
# Define public resolution strategy
SilverStripe\Assets\FilenameParsing\FileResolutionStrategy.public:
class: SilverStripe\Assets\FilenameParsing\FileIDHelperResolutionStrategy
properties:
ResolutionFileIDHelpers:
- '%$SilverStripe\Assets\FilenameParsing\HashFileIDHelper'
- '%$SilverStripe\Assets\FilenameParsing\NaturalFileIDHelper'
DefaultFileIDHelper: '%$SilverStripe\Assets\FilenameParsing\NaturalFileIDHelper'
VersionedStage: Live
# Define protected resolution strategy
SilverStripe\Assets\FilenameParsing\FileResolutionStrategy.protected:
class: SilverStripe\Assets\FilenameParsing\FileIDHelperResolutionStrategy
properties:
DefaultFileIDHelper: '%$SilverStripe\Assets\FilenameParsing\HashFileIDHelper'
ResolutionFileIDHelpers:
- '%$SilverStripe\Assets\FilenameParsing\HashFileIDHelper'
VersionedStage: Stage

View File

@ -1,9 +0,0 @@
# See https://docs.silverstripe.org/en/4/developer_guides/email/ for additional information about setting up email
---
Name: project-emailconfig
After:
- '#emailconfig'
---
SilverStripe\Core\Injector\Injector:
Swift_Transport:
class: Swift_SendmailTransport

View File

@ -1,8 +0,0 @@
---
Name: mytheme
---
SilverStripe\View\SSViewer:
themes:
- '$public'
- 'simple'
- '$default'

37
assets/.htaccess Normal file
View File

@ -0,0 +1,37 @@
#
# Whitelist appropriate assets files.
# Note that you will need to maintain this whitelist yourself if you modify File::$allowed_extensions
#
# If you are not using Apache then you can ignore this file.
# If you are using IIS then you should look at assets/web.config instead.
#
# To add an extension to the list, you need to put another string of the form "ext|" on the
# FilesMatch line, inside the parentheses.
#
# For example, to add *.exe files to list of downloadable assets, change this line:
#
# <FilesMatch "\.(html|htm|xhtml...
#
# To this:
#
# <FilesMatch "\.(exe|html|htm|xhtml...
#
# Once you do this, visitors will be able to download *.exe files that are uploaded to the assets
# directory.
#
# For compatibility reasons, we include uppercase versions of allowed extensions, as Apache 1.3
# does not support regular expression case insensitive matches using PCRE style.
#
Deny from all
<FilesMatch "\.(html|HTML|htm|HTM|xhtml|XHTML|js|JS|css|CSS|bmp|BMP|png|PNG|gif|GIF|jpg|JPG|jpeg|JPEG|ico|ICO|pcx|PCX|tif|TIF|tiff|TIFF|au|AU|mid|MID|midi|MIDI|mpa|MPA|mp3|MP3|ogg|OGG|m4a|M4A|ra|RA|wma|WMA|wav|WAV|cda|CDA|avi|AVI|mpg|MPG|mpeg|MPEG|asf|ASF|wmv|WMV|m4v|M4V|mov|MOV|mkv|MKV|mp4|MP4|swf|SWF|flv|FLV|ram|RAM|rm|RM|doc|DOC|docx|DOCX|txt|TXT|rtf|RTF|xls|XLS|xlsx|XLSX|pages|PAGES|ppt|PPT|pptx|PPTX|pps|PPS|csv|CSV|cab|CAB|arj|ARJ|tar|TAR|zip|ZIP|zipx|ZIPX|sit|SIT|sitx|SITX|gz|GZ|tgz|TGZ|bz2|BZ2|ace|ACE|arc|ARC|pkg|PKG|dmg|DMG|hqx|HQX|jar|JAR|xml|XML|pdf|PDF)$">
Allow from all
</FilesMatch>
# We disable PHP via several methods
# Replace the handler with the default plaintext handler
AddHandler default-handler php phtml php3 php4 php5 inc
<IfModule mod_php5.c>
# Turn the PHP engine off
php_flag engine off
</IfModule>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -57,8 +57,6 @@ directory.
<add fileExtension=".mov" allowed="true" />
<add fileExtension=".mkv" allowed="true" />
<add fileExtension=".mp4" allowed="true" />
<add fileExtension=".ogv" allowed="true" />
<add fileExtension=".webm" allowed="true" />
<add fileExtension=".swf" allowed="true" />
<add fileExtension=".flv" allowed="true" />
<add fileExtension=".ram" allowed="true" />
@ -92,10 +90,8 @@ directory.
<add fileExtension=".jar" allowed="true" />
<add fileExtension=".xml" allowed="true" />
<add fileExtension=".pdf" allowed="true" />
<add fileExtension=".gpx" allowed="true" />
<add fileExtension=".kml" allowed="true" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
</configuration>
</configuration>

View File

@ -1,21 +0,0 @@
# Note: Currently chrome latest is recommended
# Behat test setup requires an `.env` with `SS_BASE_URL` defined, as well
# as each of the following commands to initiate a test run:
# ========================================================================= #
# composer require silverstripe/recipe-testing ^1
# vendor/bin/behat-ss @<module>
# ========================================================================= #
default:
suites: []
extensions:
SilverStripe\BehatExtension\MinkExtension:
default_session: facebook_web_driver
javascript_session: facebook_web_driver
facebook_web_driver:
browser: chrome
wd_host: "http://127.0.0.1:9515" #chromedriver port
browser_name: chrome
SilverStripe\BehatExtension\Extension:
bootstrap_file: vendor/silverstripe/cms/tests/behat/serve-bootstrap.php
screenshot_path: '%paths.base%/artifacts/screenshots'
retry_seconds: 4 # default is 2

View File

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Phing build tooling for SilverStripe releases (see phing.info).
Install through "pear channel-discover pear.phing.info && pear install phing/phing".
Most tooling is placed in a separate module, install with "composer require silverstripe/buildtools".
It is safe to remove this file for normal website operation.
-->
<project name="silverstripe-installer" default="help" phingVersion="2.4.5">
<import file="buildtools/build.xml" optional="true" />
<property name="basedir" value="." override="true" />
<target name="help">
<phingcall target="buildtools.help" />
</target>
<target name="phpunit"
description="Runs unit tests as defined through phpunix.xml. Requires the 'phpunit' binary.">
<if>
<available file="${basedir}/vendor/bin/phpunit" />
<then>
<property name="phpunit_bin" value="vendor/bin/phpunit" />
</then>
<else>
<property name="phpunit_bin" value="phpunit" />
</else>
</if>
<exec command="${phpunit_bin}" checkreturn="true" passthru="true" />
</target>
<target name="behat" if="basedir"
description="Runs behaviour tests through Behat, on the 'framework' and 'cms' modules (if available). Requires phpunit, composer and behat.">
<if>
<available file="${basedir}/framework/" type="dir" />
<then>
<echo msg="Testing 'framework' module" />
<exec command="vendor/bin/behat --ansi @framework" checkreturn="true" passthru="true" />
</then>
</if>
<if>
<available file="${basedir}/cms/" type="dir" />
<then>
<echo msg="Testing 'cms' module" />
<exec command="vendor/bin/behat --ansi @cms" checkreturn="true" passthru="true" />
</then>
</if>
</target>
</project>

View File

@ -1,37 +0,0 @@
{
"name": "silverstripe/installer",
"type": "silverstripe-recipe",
"description": "The SilverStripe Framework Installer",
"require": {
"php": "^7.4 || ^8.0",
"silverstripe/recipe-plugin": "^1.2",
"silverstripe/recipe-cms": "4.x-dev",
"silverstripe-themes/simple": "~3.2.0",
"silverstripe/login-forms": "4.x-dev"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
},
"extra": {
"project-files": [
"app/_config/*",
".env.example",
".graphql-generated/*"
],
"public-files": [
"assets/*",
"favicon.ico"
],
"resources-dir": "_resources"
},
"config": {
"process-timeout": 600,
"allow-plugins": {
"composer/installers": true,
"silverstripe/recipe-plugin": true,
"silverstripe/vendor-plugin": true
}
},
"prefer-stable": true,
"minimum-stability": "dev"
}

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

63
index.php Normal file
View File

@ -0,0 +1,63 @@
<?php
/************************************************************************************
************************************************************************************
** **
** If you can read this text in your browser then you don't have PHP installed. **
** Please install PHP 5.0 or higher, preferably PHP 5.2. **
** **
************************************************************************************
************************************************************************************/
/**
* This script bolts on top of SilverStripe/Sapphire to allow access without the use of .htaccess
* rewriting rules.
*/
// This is the URL of the script that everything must be viewed with.
define('BASE_SCRIPT_URL','index.php/');
$ruLen = strlen($_SERVER['REQUEST_URI']);
$snLen = strlen($_SERVER['SCRIPT_NAME']);
$isIIS = (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false);
// IIS will populate server variables using one of these two ways
if($isIIS) {
if($_SERVER['REQUEST_URI'] == $_SERVER['SCRIPT_NAME']) {
$url = "";
} else if($ruLen > $snLen && substr($_SERVER['REQUEST_URI'],0,$snLen+1) == ($_SERVER['SCRIPT_NAME'] . '/')) {
$url = substr($_SERVER['REQUEST_URI'],$snLen+1);
$url = strtok($url, '?');
} else {
$url = $_SERVER['REQUEST_URI'];
if($url[0] == '/') $url = substr($url,1);
$url = strtok($url, '?');
}
// Apache will populate the server variables this way
} else {
if($ruLen > $snLen && substr($_SERVER['REQUEST_URI'],0,$snLen+1) == ($_SERVER['SCRIPT_NAME'] . '/')) {
$url = substr($_SERVER['REQUEST_URI'],$snLen+1);
$url = strtok($url, '?');
} else {
$url = "";
}
}
$_GET['url'] = $_REQUEST['url'] = $url;
$fileName = dirname($_SERVER['SCRIPT_FILENAME']) . '/' . $url;
/**
* This code is a very simple wrapper for sending files
* Very quickly pass through references to files
*/
if($url && file_exists($fileName)) {
$fileURL = (dirname($_SERVER['SCRIPT_NAME'])=='/'?'':dirname($_SERVER['SCRIPT_NAME'])) . '/' . $url;
header($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently');
header("Location: $fileURL");
die();
}
require_once('sapphire/main.php');

1292
install.php Normal file
View File

@ -0,0 +1,1292 @@
<?php
/************************************************************************************
************************************************************************************
** **
** If you can read this text in your browser then you don't have PHP installed. **
** Please install PHP 5.0 or higher, preferably PHP 5.2. **
** **
************************************************************************************
************************************************************************************/
/**
* SilverStripe CMS Installer
* This installer doesn't use any of the fancy Sapphire stuff in case it's unsupported.
* It's also PHP4 syntax compatable
*/
// speed up mysql_connect timeout if the server can't be found
ini_set('mysql.connect_timeout', 5);
ini_set('max_execution_time', 0);
error_reporting(E_ALL ^ E_NOTICE);
session_start();
$majorVersion = strtok(phpversion(),'.');
if($majorVersion < 5) {
header("HTTP/1.1 500 Server Error");
echo str_replace('$PHPVersion', phpversion(), file_get_contents("sapphire/dev/install/php5-required.html"));
die();
}
// Include environment files
$usingEnv = false;
$envFileExists = false;
$envFiles = array('_ss_environment.php', '../_ss_environment.php', '../../_ss_environment.php');
foreach($envFiles as $envFile) {
if(@file_exists($envFile)) {
include_once($envFile);
$envFileExists = true;
$usingEnv = true;
break;
}
}
if($envFileExists) {
if(!empty($_REQUEST['useEnv'])) {
$usingEnv = true;
} else {
$usingEnv = false;
}
}
include_once('sapphire/core/Object.php');
include_once('sapphire/core/i18n.php');
include_once('sapphire/dev/install/DatabaseConfigurationHelper.php');
include_once('sapphire/dev/install/DatabaseAdapterRegistry.php');
// Set default locale, but try and sniff from the user agent
$locales = i18n::$common_locales;
$defaultLocale = i18n::get_locale();
if(isset($_SERVER['HTTP_USER_AGENT'])) {
foreach($locales as $code => $details) {
$bits = explode('_', $code);
if(preg_match("/{$bits[0]}.{$bits[1]}/", $_SERVER['HTTP_USER_AGENT'])) {
$defaultLocale = $code;
break;
}
}
}
// Discover which databases are available
DatabaseAdapterRegistry::autodiscover();
// Determine which external database modules are USABLE
foreach(DatabaseAdapterRegistry::get_adapters() as $class => $details) {
$databaseClasses[$class] = $details;
if(file_exists($details['helperPath'])) {
$databaseClasses[$class]['hasModule'] = true;
include_once($details['helperPath']);
} else {
$databaseClasses[$class]['hasModule'] = false;
}
}
// Load database config
if(isset($_REQUEST['db'])) {
if(isset($_REQUEST['db']['type'])) $type = $_REQUEST['db']['type'];
else $type = $_REQUEST['db']['type'] = defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : 'MySQLDatabase';
// Disabled inputs don't submit anything - we need to use the environment (except the database name)
if($usingEnv) {
$_REQUEST['db'][$type] = $databaseConfig = array(
"type" => defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : $type,
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost",
"username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root",
"password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "",
"database" => $_REQUEST['db'][$type]['database'],
);
} else {
// Normal behaviour without the environment
$databaseConfig = $_REQUEST['db'][$type];
$databaseConfig['type'] = $type;
}
} else {
$type = $_REQUEST['db']['type'] = defined('SS_DATABASE_CLASS') ? SS_DATABASE_CLASS : 'MySQLDatabase';
$_REQUEST['db'][$type] = $databaseConfig = array(
"type" => $type,
"server" => defined('SS_DATABASE_SERVER') ? SS_DATABASE_SERVER : "localhost",
"username" => defined('SS_DATABASE_USERNAME') ? SS_DATABASE_USERNAME : "root",
"password" => defined('SS_DATABASE_PASSWORD') ? SS_DATABASE_PASSWORD : "",
"database" => isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : "SS_mysite",
);
}
if(isset($_REQUEST['admin'])) {
// Disabled inputs don't submit anything - we need to use the environment (except the database name)
if($usingEnv) {
$_REQUEST['admin'] = $adminConfig = array(
'username' => defined('SS_DEFAULT_ADMIN_USERNAME') ? SS_DEFAULT_ADMIN_USERNAME : 'admin',
'password' => defined('SS_DEFAULT_ADMIN_PASSWORD') ? SS_DEFAULT_ADMIN_PASSWORD : '',
);
} else {
$adminConfig = $_REQUEST['admin'];
}
} else {
$_REQUEST['admin'] = $adminConfig = array(
'username' => defined('SS_DEFAULT_ADMIN_USERNAME') ? SS_DEFAULT_ADMIN_USERNAME : 'admin',
'password' => defined('SS_DEFAULT_ADMIN_PASSWORD') ? SS_DEFAULT_ADMIN_PASSWORD : '',
);
}
$alreadyInstalled = false;
if(file_exists('mysite/_config.php')) {
// Find the $database variable in the relevant config file without having to execute the config file
if(preg_match("/\\\$database\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) {
eval($parts[0]);
if($database) $alreadyInstalled = true;
// Assume that if $databaseConfig is defined in mysite/_config.php, then a non-environment-based installation has
// already gone ahead
} else if(preg_match("/\\\$databaseConfig\s*=\s*[^\n\r]+[\n\r]/", file_get_contents("mysite/_config.php"), $parts)) {
$alreadyInstalled = true;
}
}
if(file_exists('sapphire/silverstripe_version')) {
$sapphireVersionFile = file_get_contents('sapphire/silverstripe_version');
if(strstr($sapphireVersionFile, "/sapphire/trunk")) {
$silverstripe_version = "trunk";
} else {
preg_match("/sapphire\/(?:(?:branches)|(?:tags))(?:\/rc)?\/([A-Za-z0-9._-]+)\/silverstripe_version/", $sapphireVersionFile, $matches);
$silverstripe_version = $matches[1];
}
} else {
$silverstripe_version = "unknown";
}
// Check requirements
$req = new InstallRequirements();
$req->check();
$webserverConfigFile = '';
if($req->isIIS()) {
$webserverConfigFile = 'web.config';
} else {
$webserverConfigFile = '.htaccess';
}
if($req->hasErrors()) {
$hasErrorOtherThanDatabase = true;
}
if($databaseConfig) {
$dbReq = new InstallRequirements();
$dbReq->checkDatabase($databaseConfig);
}
if($adminConfig) {
$adminReq = new InstallRequirements();
$adminReq->checkAdminConfig($adminConfig);
}
if(isset($_REQUEST['go']) && !$req->hasErrors() && !$dbReq->hasErrors() && $adminConfig['username'] && $adminConfig['password']) {
// Confirm before reinstalling
if($alreadyInstalled) {
include('sapphire/dev/install/config-form.html');
} else {
$inst = new Installer();
if($_REQUEST) $inst->install($_REQUEST);
else $inst->install(array(
'db' => $databaseConfig,
'admin' => $adminConfig,
));
}
// Show the config form
} else {
include('sapphire/dev/install/config-form.html');
}
/**
* This class checks requirements
* Each of the requireXXX functions takes an argument which gives a user description of the test.
* It's an array of 3 parts:
* $description[0] - The test catetgory
* $description[1] - The test title
* $description[2] - The test error to show, if it goes wrong
*/
class InstallRequirements {
var $errors, $warnings, $tests;
/**
* Check the database configuration. These are done one after another
* starting with checking the database function exists in PHP, and
* continuing onto more difficult checks like database permissions.
*/
function checkDatabase($databaseConfig) {
if($this->requireDatabaseFunctions(
$databaseConfig,
array(
"Database Configuration",
"Database support",
"Database support in PHP",
$this->getDatabaseTypeNice($databaseConfig['type'])
)
)) {
if($this->requireDatabaseServer(
$databaseConfig,
array(
"Database Configuration",
"Database server",
$databaseConfig['type'] == 'SQLiteDatabase' ? "I couldn't write to path '$databaseConfig[path]'" : "I couldn't find a database server on '$databaseConfig[server]'",
$databaseConfig['type'] == 'SQLiteDatabase' ? $databaseConfig['path'] : $databaseConfig['server']
)
)) {
if($this->requireDatabaseConnection(
$databaseConfig,
array(
"Database Configuration",
"Database access credentials correct",
"That username/password doesn't work"
)
)) {
if($this->requireDatabaseVersion(
$databaseConfig,
array(
"Database Configuration",
"Database server meets required version",
'',
'Version ' . $this->getDatabaseConfigurationHelper($databaseConfig['type'])->getDatabaseVersion($databaseConfig)
)
)) {
$this->requireDatabaseOrCreatePermissions(
$databaseConfig,
array(
"Database Configuration",
"Can I access/create the database",
"I can't create new databases and the database '$databaseConfig[database]' doesn't exist"
)
);
}
}
}
}
}
function checkAdminConfig($adminConfig) {
if(!$adminConfig['username']) {
$this->error(array('', 'Please enter a username!'));
}
if(!$adminConfig['password']) {
$this->error(array('', 'Please enter a password!'));
}
}
/**
* Check if the web server is IIS.
* @return boolean
*/
function isIIS($version = 7) {
if(strpos($this->findWebserver(), 'IIS/' . $version) !== false) {
return true;
} else {
return false;
}
}
function isApache() {
if(strpos($this->findWebserver(), 'Apache') !== false) {
return true;
} else {
return false;
}
}
/**
* Find the webserver software running on the PHP host.
* @return string|boolean Server software or boolean FALSE
*/
function findWebserver() {
// Try finding from SERVER_SIGNATURE or SERVER_SOFTWARE
$webserver = @$_SERVER['SERVER_SIGNATURE'];
if(!$webserver) $webserver = @$_SERVER['SERVER_SOFTWARE'];
if($webserver) return strip_tags(trim($webserver));
else return false;
}
/**
* Check everything except the database
*/
function check() {
$this->errors = null;
$isApache = $this->isApache();
$isIIS = $this->isIIS(7);
$webserver = $this->findWebserver();
$this->requirePHPVersion('5.2.0', '5.1.0', array("PHP Configuration", "PHP5 installed", null, "PHP version " . phpversion()));
// Check that we can identify the root folder successfully
$this->requireFile('sapphire/dev/install/config-form.html', array("File permissions",
"Does the webserver know where files are stored?",
"The webserver isn't letting me identify where files are stored.",
$this->getBaseDir()
));
$this->requireModule('mysite', array("File permissions", "mysite/ directory exists?"));
$this->requireModule('sapphire', array("File permissions", "sapphire/ directory exists?"));
$this->requireModule('cms', array("File permissions", "cms/ directory exists?"));
if($isApache) {
$this->requireWriteable('.htaccess', array("File permissions", "Is the .htaccess file writeable?", null));
} elseif($isIIS) {
$this->requireWriteable('web.config', array("File permissions", "Is the web.config file writeable?", null));
}
$this->requireWriteable('mysite/_config.php', array("File permissions", "Is the mysite/_config.php file writeable?", null));
$this->requireWriteable('assets', array("File permissions", "Is the assets/ directory writeable?", null));
$tempFolder = $this->getTempFolder();
$this->requireTempFolder(array('File permissions', 'Is a temporary directory available?', null, $tempFolder));
if($tempFolder) {
// in addition to the temp folder being available, check it is writable
$this->requireWriteable($tempFolder, array("File permissions", sprintf("Is the temporary directory writeable?", $tempFolder), null), true);
}
$this->isRunningWebServer(array("Webserver Configuration", "Server software", "Unknown", $webserver));
if($isApache) {
$this->requireApacheRewriteModule('mod_rewrite', array("Webserver Configuration", "URL rewriting support", "You need mod_rewrite to use friendly URLs with SilverStripe, but it is not enabled."));
} elseif($isIIS) {
$this->requireIISRewriteModule('IIS_UrlRewriteModule', array("Webserver Configuration", "URL rewriting support", "You need to enable the IIS URL Rewrite Module to use friendly URLs with SilverStripe, but it is not installed or enabled. Download it for IIS 7 from http://www.iis.net/expand/URLRewrite"));
} else {
$this->warning(array("Webserver Configuration", "URL rewriting support", "I can't tell whether any rewriting module is running. You may need to configure a rewriting rule yourself."));
}
$this->requireServerVariables(array('SCRIPT_NAME','HTTP_HOST','SCRIPT_FILENAME'), array("Webserver config", "Recognised webserver", "You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."));
// Check for GD support
if(!$this->requireFunction("imagecreatetruecolor", array("PHP Configuration", "GD2 support", "PHP must have GD version 2."))) {
$this->requireFunction("imagecreate", array("PHP Configuration", "GD2 support", "GD support for PHP not included."));
}
// Check for XML support
$this->requireFunction('xml_set_object', array("PHP Configuration", "XML support", "XML support not included in PHP."));
$this->requireClass('DOMDocument', array("PHP Configuration", "DOM/XML support", "DOM/XML support not included in PHP."));
// Check for token_get_all
$this->requireFunction('token_get_all', array("PHP Configuration", "PHP Tokenizer", "PHP tokenizer support not included in PHP."));
// Check for session support
$this->requireFunction('session_start', array('PHP Configuration', 'Session support', 'Session support not included in PHP.'));
// Check for iconv support
$this->requireFunction('iconv', array('PHP Configuration', 'iconv support', 'iconv support not included in PHP.'));
// Check for hash support
$this->requireFunction('hash', array('PHP Configuration', 'hash support', 'hash support not included in PHP.'));
if(version_compare(PHP_VERSION, '5.3.0', '>=')) {
$this->requireDateTimezone(array('PHP Configuration', 'date.timezone set and valid', 'date.timezone option in php.ini must be set in PHP 5.3.0+', ini_get('date.timezone')));
}
$this->suggestPHPSetting('asp_tags', array(''), array('PHP Configuration', 'asp_tags option turned off', 'This should be turned off as it can cause issues with SilverStripe'));
$this->suggestPHPSetting('magic_quotes_gpc', array(''), array('PHP Configuration', 'magic_quotes_gpc option turned off', 'This should be turned off, as it can cause issues with cookies. More specifically, unserializing data stored in cookies.'));
// Check memory allocation
$this->requireMemory(32*1024*1024, 64*1024*1024, array("PHP Configuration", "Memory allocated (PHP config option 'memory_limit')", "SilverStripe needs a minimum of 32M allocated to PHP, but recommends 64M.", ini_get("memory_limit")));
return $this->errors;
}
function suggestPHPSetting($settingName, $settingValues, $testDetails) {
$this->testing($testDetails);
$val = ini_get($settingName);
if(!in_array($val, $settingValues) && $val != $settingValues) {
$testDetails[2] = "$settingName is set to '$val' in php.ini. $testDetails[2]";
$this->warning($testDetails);
}
}
function requireDateTimezone($testDetails) {
$this->testing($testDetails);
$result = ini_get('date.timezone') && in_array(ini_get('date.timezone'), timezone_identifiers_list());
if(!$result) {
$this->error($testDetails);
}
}
function requireMemory($min, $recommended, $testDetails) {
$_SESSION['forcemem'] = false;
$mem = $this->getPHPMemory();
if($mem < (64 * 1024 * 1024)) {
ini_set('memory_limit', '64M');
$mem = $this->getPHPMemory();
$testDetails[3] = ini_get("memory_limit");
}
$this->testing($testDetails);
if($mem < $min && $mem > 0) {
$testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated";
$this->error($testDetails);
} else if($mem < $recommended && $mem > 0) {
$testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated";
$this->warning($testDetails);
} elseif($mem == 0) {
$testDetails[2] .= " We can't determine how much memory you have allocated. Install only if you're sure you've allocated at least 20 MB.";
$this->warning($testDetails);
}
}
function getPHPMemory() {
$memString = ini_get("memory_limit");
switch(strtolower(substr($memString,-1))) {
case "k":
return round(substr($memString,0,-1)*1024);
case "m":
return round(substr($memString,0,-1)*1024*1024);
case "g":
return round(substr($memString,0,-1)*1024*1024*1024);
default:
return round($memString);
}
}
function listErrors() {
if($this->errors) {
echo "<p>The following problems are preventing me from installing SilverStripe CMS:</p>\n\n";
foreach($this->errors as $error) {
echo "<li>" . htmlentities(implode(", ", $error)) . "</li>\n";
}
}
}
function showTable($section = null) {
if($section) {
$tests = $this->tests[$section];
$id = strtolower(str_replace(' ', '_', $section));
echo "<table id=\"{$id}_results\" class=\"testResults\" width=\"100%\">";
foreach($tests as $test => $result) {
echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
}
echo "</table>";
} else {
foreach($this->tests as $section => $tests) {
$failedRequirements = 0;
$warningRequirements = 0;
$output = "";
foreach($tests as $test => $result) {
if(isset($result['0'])) {
switch($result['0']) {
case 'error':
$failedRequirements++;
break;
case 'warning':
$warningRequirements++;
break;
}
}
$output .= "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
}
$className = "good";
$text = "All Requirements Pass";
$pluralWarnings = ($warningRequirements == 1) ? 'Warning' : 'Warnings';
if($failedRequirements > 0) {
$className = "error";
$pluralWarnings = ($warningRequirements == 1) ? 'Warning' : 'Warnings';
$text = $failedRequirements . ' Failed and '. $warningRequirements . ' '. $pluralWarnings;
}
else if($warningRequirements > 0) {
$className = "warning";
$text = "All Requirements Pass but ". $warningRequirements . ' '. $pluralWarnings;
}
echo "<h5 class='requirement $className'><em class='inlineBarText'>$section</em> <a href='#'>See All Requirements</a> <span>$text</span></h5>";
echo "<table class=\"testResults\">";
echo $output;
echo "</table>";
}
}
}
function requireFunction($funcName, $testDetails) {
$this->testing($testDetails);
if(!function_exists($funcName)) $this->error($testDetails);
else return true;
}
function requireClass($className, $testDetails) {
$this->testing($testDetails);
if(!class_exists($className)) $this->error($testDetails);
else return false;
}
/**
* Require that the given class doesn't exist
*/
function requireNoClasses($classNames, $testDetails) {
$this->testing($testDetails);
$badClasses = array();
foreach($classNames as $className) {
if(class_exists($className)) $badClasses[] = $className;
}
if($badClasses) {
$testDetails[2] .= ". The following classes are at fault: " . implode(', ', $badClasses);
$this->error($testDetails);
}
else return true;
}
function requirePHPVersion($recommendedVersion, $requiredVersion, $testDetails) {
$this->testing($testDetails);
$installedVersion = phpversion();
if(version_compare($installedVersion, $requiredVersion, '<')) {
$testDetails[2] = "SilverStripe requires PHP version $requiredVersion or later.\n
PHP version $installedVersion is currently installed.\n
While SilverStripe requires at least PHP version $requiredVersion, upgrading to $recommendedVersion or later is recommended.\n
If you are installing SilverStripe on a shared web server, please ask your web hosting provider to upgrade PHP for you.";
$this->error($testDetails);
return;
}
if(version_compare($installedVersion, $recommendedVersion, '<')) {
$testDetails[2] = "PHP version $installedVersion is currently installed.\n
Upgrading to at least PHP version $recommendedVersion is recommended.\n
SilverStripe should run, but you may run into issues. Future releases may require a later version of PHP.\n";
$this->warning($testDetails);
return;
}
return true;
}
/**
* The same as {@link requireFile()} but does additional checks
* to ensure the module directory is intact.
*/
function requireModule($dirname, $testDetails) {
$this->testing($testDetails);
$path = $this->getBaseDir() . $dirname;
if(!file_exists($path)) {
$testDetails[2] .= " Directory '$path' not found. Please make sure you have uploaded the SilverStripe files to your webserver correctly.";
$this->error($testDetails);
} elseif(!file_exists($path . '/_config.php') && $dirname != 'mysite') {
$testDetails[2] .= " Directory '$path' exists, but is missing files. Please make sure you have uploaded the SilverStripe files to your webserver correctly.";
$this->error($testDetails);
}
}
function requireFile($filename, $testDetails) {
$this->testing($testDetails);
$filename = $this->getBaseDir() . $filename;
if(!file_exists($filename)) {
$testDetails[2] .= " (file '$filename' not found)";
$this->error($testDetails);
}
}
function requireWriteable($filename, $testDetails, $absolute = false) {
$this->testing($testDetails);
if($absolute) {
$filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
} else {
$filename = $this->getBaseDir() . str_replace('/', DIRECTORY_SEPARATOR, $filename);
}
if(file_exists($filename)) $isWriteable = is_writeable($filename);
else $isWriteable = is_writeable(dirname($filename));
if(!$isWriteable) {
if(function_exists('posix_getgroups')) {
$userID = posix_geteuid();
$user = posix_getpwuid($userID);
$currentOwnerID = fileowner(file_exists($filename) ? $filename : dirname($filename) );
$currentOwner = posix_getpwuid($currentOwnerID);
$testDetails[2] .= "User '$user[name]' needs to be able to write to this file:\n$filename\n\nThe file is currently owned by '$currentOwner[name]'. ";
if($user['name'] == $currentOwner['name']) {
$testDetails[2] .= "We recommend that you make the file writeable.";
} else {
$groups = posix_getgroups();
$groupList = array();
foreach($groups as $group) {
$groupInfo = posix_getgrgid($group);
if(in_array($currentOwner['name'], $groupInfo['members'])) $groupList[] = $groupInfo['name'];
}
if($groupList) {
$testDetails[2] .= " We recommend that you make the file group-writeable and change the group to one of these groups:\n - ". implode("\n - ", $groupList)
. "\n\nFor example:\nchmod g+w $filename\nchgrp " . $groupList[0] . " $filename";
} else {
$testDetails[2] .= " There is no user-group that contains both the web-server user and the owner of this file. Change the ownership of the file, create a new group, or temporarily make the file writeable by everyone during the install process.";
}
}
} else {
$testDetails[2] .= "The webserver user needs to be able to write to this file:\n$filename";
}
$this->error($testDetails);
}
}
function getTempFolder() {
if(file_exists($this->getBaseDir() . 'silverstripe-cache')) {
$sysTmp = $this->getBaseDir();
} elseif(function_exists('sys_get_temp_dir')) {
$sysTmp = sys_get_temp_dir();
} elseif(isset($_ENV['TMP'])) {
$sysTmp = $_ENV['TMP'];
} else {
@$tmpFile = tempnam('adfadsfdas', '');
@unlink($tmpFile);
$sysTmp = dirname($tmpFile);
}
$worked = true;
$ssTmp = $sysTmp . DIRECTORY_SEPARATOR . 'silverstripe-cache';
if(!@file_exists($ssTmp)) {
@$worked = mkdir($ssTmp);
if(!$worked) {
$ssTmp = dirname($_SERVER['SCRIPT_FILENAME']) . DIRECTORY_SEPARATOR . 'silverstripe-cache';
$worked = true;
if(!@file_exists($ssTmp)) {
@$worked = mkdir($ssTmp);
}
}
}
if($worked) return $ssTmp;
else return false;
}
function requireTempFolder($testDetails) {
$this->testing($testDetails);
$tempFolder = $this->getTempFolder();
if(!$tempFolder) {
$testDetails[2] = "Permission problem gaining access to a temp directory. " .
"Please create a folder named silverstripe-cache in the base directory " .
"of the installation and ensure it has the adequate permissions";
$this->error($testDetails);
}
}
function requireApacheModule($moduleName, $testDetails) {
$this->testing($testDetails);
if(!in_array($moduleName, apache_get_modules())) {
$this->error($testDetails);
return false;
} else {
return true;
}
}
function testApacheRewriteExists($moduleName = 'mod_rewrite') {
if(function_exists('apache_get_modules') && in_array($moduleName, apache_get_modules())) {
return true;
} elseif(isset($_SERVER['HTTP_MOD_REWRITE']) && $_SERVER['HTTP_MOD_REWRITE'] == 'On') {
return true;
} else {
return false;
}
}
function testIISRewriteModuleExists($moduleName = 'IIS_UrlRewriteModule') {
if(isset($_SERVER[$moduleName]) && $_SERVER[$moduleName]) {
return true;
} else {
return false;
}
}
function requireApacheRewriteModule($moduleName, $testDetails) {
$this->testing($testDetails);
if($this->testApacheRewriteExists()) {
return true;
} else {
$this->warning($testDetails);
return false;
}
}
/**
* Determines if the web server has any rewriting capability.
* @return boolean
*/
function hasRewritingCapability() {
return ($this->testApacheRewriteExists() || $this->testIISRewriteModuleExists());
}
function requireIISRewriteModule($moduleName, $testDetails) {
$this->testing($testDetails);
if($this->testIISRewriteModuleExists()) {
return true;
} else {
$this->warning($testDetails);
return false;
}
}
function getDatabaseTypeNice($databaseClass) {
return substr($databaseClass, 0, -8);
}
/**
* Get an instance of a helper class for the specific database.
* @param string $databaseClass e.g. MySQLDatabase or MSSQLDatabase
*/
function getDatabaseConfigurationHelper($databaseClass) {
$adapters = DatabaseAdapterRegistry::get_adapters();
if(isset($adapters[$databaseClass])) {
$helperPath = $adapters[$databaseClass]['helperPath'];
$class = str_replace('.php', '', basename($helperPath));
}
return (class_exists($class)) ? new $class() : new MySQLDatabaseConfigurationHelper();
}
function requireDatabaseFunctions($databaseConfig, $testDetails) {
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseFunctions($databaseConfig);
if($result) {
return true;
} else {
$this->error($testDetails);
return false;
}
}
function requireDatabaseConnection($databaseConfig, $testDetails) {
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseConnection($databaseConfig);
if($result['success']) {
return true;
} else {
$testDetails[2] .= ": " . $result['error'];
$this->error($testDetails);
return false;
}
}
function requireDatabaseVersion($databaseConfig, $testDetails) {
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
if(method_exists($helper, 'requireDatabaseVersion')) {
$result = $helper->requireDatabaseVersion($databaseConfig);
if($result['success']) {
return true;
} else {
$testDetails[2] .= $result['error'];
$this->warning($testDetails);
return false;
}
}
// Skipped test because this database has no required version
return true;
}
function requireDatabaseServer($databaseConfig, $testDetails) {
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseServer($databaseConfig);
if($result['success']) {
return true;
} else {
$testDetails[2] .= ": " . $result['error'];
$this->error($testDetails);
return false;
}
}
function requireDatabaseOrCreatePermissions($databaseConfig, $testDetails) {
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseOrCreatePermissions($databaseConfig);
if($result['success']) {
if($result['alreadyExists']) $testDetails[3] = "Database $databaseConfig[database]";
else $testDetails[3] = "Able to create a new database";
$this->testing($testDetails);
return true;
} else {
if(!@$result['cannotCreate']) {
$testDetails[2] .= ". Please create the database manually.";
} else {
$testDetails[2] .= " (user '$databaseConfig[username]' doesn't have CREATE DATABASE permissions.)";
}
$this->error($testDetails);
return false;
}
}
function requireServerVariables($varNames, $errorMessage) {
//$this->testing($testDetails);
foreach($varNames as $varName) {
if(!$_SERVER[$varName]) $missing[] = '$_SERVER[' . $varName . ']';
}
if(!isset($missing)) {
return true;
} else {
$testDetails[2] .= " (the following PHP variables are missing: " . implode(", ", $missing) . ")";
$this->error($testDetails);
}
}
function isRunningWebServer($testDetails) {
$this->testing($testDetails);
if($testDetails[3]) {
return true;
} else {
$this->warning($testDetails);
return false;
}
}
// Must be PHP4 compatible
var $baseDir;
function getBaseDir() {
// Cache the value so that when the installer mucks with SCRIPT_FILENAME half way through, this method
// still returns the correct value.
if(!$this->baseDir) $this->baseDir = realpath(dirname($_SERVER['SCRIPT_FILENAME'])) . DIRECTORY_SEPARATOR;
return $this->baseDir;
}
function testing($testDetails) {
if(!$testDetails) return;
$section = $testDetails[0];
$test = $testDetails[1];
$message = "OK";
if(isset($testDetails[3])) $message .= " ($testDetails[3])";
$this->tests[$section][$test] = array("good", $message);
}
function error($testDetails) {
$section = $testDetails[0];
$test = $testDetails[1];
$this->tests[$section][$test] = array("error", $testDetails[2]);
$this->errors[] = $testDetails;
}
function warning($testDetails) {
$section = $testDetails[0];
$test = $testDetails[1];
$this->tests[$section][$test] = array("warning", $testDetails[2]);
$this->warnings[] = $testDetails;
}
function hasErrors() {
return sizeof($this->errors);
}
function hasWarnings() {
return sizeof($this->warnings);
}
}
class Installer extends InstallRequirements {
function __construct() {
// Cache the baseDir value
$this->getBaseDir();
}
function install($config) {
?>
<html>
<head>
<title>Installing SilverStripe...</title>
<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/layout.css" />
<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/typography.css" />
<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/form.css" />
<link rel="stylesheet" type="text/css" href="sapphire/dev/install/install.css" />
<script src="sapphire/thirdparty/jquery/jquery.js"></script>
</head>
<body>
<div id="BgContainer">
<div id="Container">
<div id="Header">
<h1>SilverStripe CMS Installation</h1>
</div>
<div id="Navigation">&nbsp;</div>
<div class="clear"><!-- --></div>
<div id="Layout">
<div class="typography">
<h1>Installing SilverStripe...</h1>
<p>I am now running through the installation steps (this should take about 30 seconds)</p>
<p>If you receive a fatal error, refresh this page to continue the installation</p>
<ul>
<?php
$webserver = $this->findWebserver();
$isIIS = $this->isIIS();
$isApache = $this->isApache();
flush();
if(isset($config['stats'])) {
if(file_exists('sapphire/silverstripe_version')) {
$sapphireVersionFile = file_get_contents('sapphire/silverstripe_version');
if(strstr($sapphireVersionFile, "/sapphire/trunk")) {
$silverstripe_version = "trunk";
} else {
preg_match("/sapphire\/(?:(?:branches)|(?:tags))(?:\/rc)?\/([A-Za-z0-9._-]+)\/silverstripe_version/", $sapphireVersionFile, $matches);
$silverstripe_version = $matches[1];
}
} else {
$silverstripe_version = "unknown";
}
$phpVersion = urlencode(phpversion());
$encWebserver = urlencode($webserver);
$dbType = $config['db']['type'];
// Try to determine the database version from the helper
$databaseVersion = $config['db']['type'];
$helper = $this->getDatabaseConfigurationHelper($dbType);
if($helper && method_exists($helper, 'getDatabaseVersion')) {
$databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($config['db'][$dbType]));
}
$url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe=$silverstripe_version&PHP=$phpVersion&Database=$databaseVersion&WebServer=$encWebserver";
if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
$url .= '&ID=' . $_SESSION['StatsID'];
}
@$_SESSION['StatsID'] = file_get_contents($url);
}
if(file_exists('mysite/_config.php')) {
// Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly
// differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them
$fh = fopen('mysite/_config.php', 'wb');
fclose($fh);
}
$theme = isset($_POST['template']) ? $_POST['template'] : 'blackcandy';
$locale = isset($_POST['locale']) ? $_POST['locale'] : 'en_US';
$type = $config['db']['type'];
$dbConfig = $config['db'][$type];
if(!$dbConfig) {
echo "<p style=\"color: red\">Bad config submitted</p><pre>";
print_r($config);
echo "</pre>";
die();
}
// Write the config file
global $usingEnv;
if($usingEnv) {
$this->statusMessage("Setting up 'mysite/_config.php' for use with _ss_environment.php...");
$this->writeToFile("mysite/_config.php", <<<PHP
<?php
global \$project;
\$project = 'mysite';
global \$database;
\$database = '{$dbConfig['database']}';
require_once('conf/ConfigureFromEnv.php');
MySQLDatabase::set_connection_charset('utf8');
// This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('$theme');
// Set the site locale
i18n::set_locale('$locale');
// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls();
PHP
);
} else {
$this->statusMessage("Setting up 'mysite/_config.php'...");
$escapedPassword = addslashes($dbConfig['password']);
$this->writeToFile("mysite/_config.php", <<<PHP
<?php
global \$project;
\$project = 'mysite';
global \$databaseConfig;
\$databaseConfig = array(
"type" => '{$type}',
"server" => '{$dbConfig['server']}',
"username" => '{$dbConfig['username']}',
"password" => '{$escapedPassword}',
"database" => '{$dbConfig['database']}',
"path" => '{$dbConfig['path']}',
);
MySQLDatabase::set_connection_charset('utf8');
// This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('$theme');
// Set the site locale
i18n::set_locale('$locale');
// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls();
PHP
);
}
// Write the appropriate web server configuration file for rewriting support
if($this->hasRewritingCapability()) {
if($isApache) {
$this->statusMessage("Setting up '.htaccess' file...");
$this->createHtaccess();
} elseif($isIIS) {
$this->statusMessage("Setting up 'web.config' file...");
$this->createWebConfig();
}
}
// Load the sapphire runtime
$_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/sapphire/main.php';
chdir('sapphire');
// Rebuild the manifest
$_GET['flush'] = true;
// Show errors as if you're in development mode
$_SESSION['isDev'] = 1;
require_once('core/Core.php');
$this->statusMessage("Building database schema...");
// Build database
$con = new Controller();
$con->pushCurrent();
global $databaseConfig;
DB::connect($databaseConfig);
$dbAdmin = new DatabaseAdmin();
$dbAdmin->init();
$dbAdmin->doBuild(true);
// Create default administrator user and group in database
// (not using Security::setDefaultAdmin())
$adminMember = Security::findAnAdministrator();
$adminMember->Email = $config['admin']['username'];
$adminMember->Password = $config['admin']['password'];
$adminMember->PasswordEncryption = Security::get_password_encryption_algorithm();
// @todo Exception thrown if database with admin already exists with same Email
try {
$adminMember->write();
} catch(Exception $e) {
}
// Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266)
Filesystem::sync();
$_SESSION['username'] = $config['admin']['username'];
$_SESSION['password'] = $config['admin']['password'];
if(!$this->errors) {
if(isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) {
$this->statusMessage("Checking that friendly URLs work...");
$this->checkRewrite();
} else {
echo <<<HTML
<li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li>
<script>
setTimeout(function() {
window.location = "index.php/home/successfullyinstalled?flush=1";
}, 2000);
</script>
<noscript>
<li><a href="index.php/home/successfullyinstalled?flush=1">Click here to access your site.</li>
</noscript>
HTML;
}
}
return $this->errors;
}
function writeToFile($filename, $content) {
$base = $this->getBaseDir();
$this->statusMessage("Setting up $base$filename");
if((@$fh = fopen($base . $filename, 'wb')) && fwrite($fh, $content) && fclose($fh)) {
return true;
} else {
$this->error("Couldn't write to file $base$filename");
}
}
function createHtaccess() {
$start = "### SILVERSTRIPE START ###\n";
$end = "\n### SILVERSTRIPE END ###";
$base = dirname($_SERVER['SCRIPT_NAME']);
if(defined('DIRECTORY_SEPARATOR')) $base = str_replace(DIRECTORY_SEPARATOR, '/', $base);
else $base = str_replace("\\", '/', $base);
if($base != '.') $baseClause = "RewriteBase $base\n";
else $baseClause = "";
$rewrite = <<<TEXT
<Files *.ss>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Files>
<Files web.config>
Order deny,allow
Deny from all
</Files>
ErrorDocument 404 /assets/error-404.html
ErrorDocument 500 /assets/error-500.html
<IfModule mod_alias.c>
RedirectMatch 403 /silverstripe-cache(/|$)
</IfModule>
<IfModule mod_rewrite.c>
SetEnv HTTP_MOD_REWRITE On
RewriteEngine On
$baseClause
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* sapphire/main.php?url=%1&%{QUERY_STRING} [L]
</IfModule>
TEXT;
if(file_exists('.htaccess')) {
$htaccess = file_get_contents('.htaccess');
if(strpos($htaccess, '### SILVERSTRIPE START ###') === false && strpos($htaccess, '### SILVERSTRIPE END ###') === false) {
$htaccess .= "\n### SILVERSTRIPE START ###\n### SILVERSTRIPE END ###\n";
}
if(strpos($htaccess, '### SILVERSTRIPE START ###') !== false && strpos($htaccess, '### SILVERSTRIPE END ###') !== false) {
$start = substr($htaccess, 0, strpos($htaccess, '### SILVERSTRIPE START ###')) . "### SILVERSTRIPE START ###\n";
$end = "\n" . substr($htaccess, strpos($htaccess, '### SILVERSTRIPE END ###'));
}
}
$this->writeToFile('.htaccess', $start . $rewrite . $end);
}
/**
* Writes basic configuration to the web.config for IIS
* so that rewriting capability can be use.
*/
function createWebConfig() {
$content = <<<TEXT
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments applyToWebDAV="false">
<add segment="silverstripe-cache" />
</hiddenSegments>
</requestFiltering>
</security>
<rewrite>
<rules>
<rule name="SilverStripe Clean URLs" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="sapphire/main.php?url={R:1}" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
TEXT;
$this->writeToFile('web.config', $content);
}
function checkRewrite() {
echo <<<HTML
<li id="ModRewriteResult">Testing...</li>
<script>
if(typeof $ == 'undefined') {
document.getElemenyById('ModeRewriteResult').innerHTML = "I can't run jQuery ajax to set rewriting; I will redirect you to the homepage to see if everything is working.";
setTimeout(function() {
window.location = "home/successfullyinstalled?flush=1";
}, 10000);
} else {
$.ajax({
method: 'get',
url: 'InstallerTest/testrewrite',
complete: function(response) {
if(response.responseText == 'OK') {
$('#ModRewriteResult').html("Friendly URLs set up successfully; I am now redirecting you to your SilverStripe site...")
setTimeout(function() {
window.location = "home/successfullyinstalled?flush=1";
}, 2000);
} else {
$('#ModRewriteResult').html("Friendly URLs are not working. This is most likely because a rewrite module isn't configured "
+ "correctly on your site. You may need to get your web host or server administrator to do this for you: "
+ "<ul>"
+ "<li><strong>mod_rewrite</strong> or other rewrite module is enabled on your web server</li>"
+ "<li><strong>AllowOverride All</strong> is set for the directory where SilverStripe is installed</li>"
+ "</ul>");
}
}
});
}
</script>
<noscript>
<li><a href="home/successfullyinstalled?flush=1">Click here</a> to check friendly URLs are working. If you get a 404 then something is wrong.</li>
</noscript>
HTML;
}
function var_export_array_nokeys($array) {
$retval = "array(\n";
foreach($array as $item) {
$retval .= "\t'";
$retval .= trim($item);
$retval .= "',\n";
}
$retval .= ")";
return $retval;
}
/**
* Show an installation status message.
*/
function statusMessage($msg) {
echo "<li>$msg</li>\n";
flush();
}
}

3
mysite/.htaccess Normal file
View File

@ -0,0 +1,3 @@
<FilesMatch "\.(php|php3|php4|php5|phtml|inc)$">
Deny from all
</FilesMatch>

18
mysite/_config.php Normal file
View File

@ -0,0 +1,18 @@
<?php
global $project;
$project = 'mysite';
global $database;
$database = '';
require_once('conf/ConfigureFromEnv.php');
MySQLDatabase::set_connection_charset('utf8');
// This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('blackcandy');
// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls();

41
mysite/code/Page.php Executable file
View File

@ -0,0 +1,41 @@
<?php
class Page extends SiteTree {
public static $db = array(
);
public static $has_one = array(
);
}
class Page_Controller extends ContentController {
/**
* An array of actions that can be accessed via a request. Each array element should be an action name, and the
* permissions or conditions required to allow the user to access it.
*
* <code>
* array (
* 'action', // anyone can access this action
* 'action' => true, // same as above
* 'action' => 'ADMIN', // you must have ADMIN permissions to access this action
* 'action' => '->checkAction' // you can only access this action if $this->checkAction() returns true
* );
* </code>
*
* @var array
*/
public static $allowed_actions = array (
);
public function init() {
parent::init();
// Note: you should use SS template require tags inside your templates
// instead of putting Requirements calls here. However these are
// included so that our older themes still work
Requirements::themedCSS('layout');
Requirements::themedCSS('typography');
Requirements::themedCSS('form');
}
}

View File

@ -1,26 +0,0 @@
<?xml version="1.0"?>
<ruleset name="SS3">
<description>Coding standard for SilverStripe 4.x</description>
<file>app</file>
<!-- Don't sniff third party libraries -->
<exclude-pattern>*/vendor/*</exclude-pattern>
<exclude-pattern>*/thirdparty/*</exclude-pattern>
<!-- Show progress and output sniff names on violation, and add colours -->
<arg value="sp"/>
<arg name="colors"/>
<!-- Use PSR-2 as a base standard -->
<rule ref="PSR2">
<!-- Allow classes to not declare a namespace -->
<exclude name="PSR1.Classes.ClassDeclaration.MissingNamespace"/>
<!-- Allow underscores in class names -->
<exclude name="Squiz.Classes.ValidClassName.NotCamelCaps"/>
<!-- Allow non camel cased method names -->
<exclude name="PSR1.Methods.CamelCapsMethodName.NotCamelCaps"/>
</rule>
</ruleset>

View File

@ -1,59 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
PHPUnit configuration for SilverStripe
Requires PHPUnit 9+
Usage:
- "vendor/bin/phpunit": Runs all tests in all folders
- "vendor/bin/phpunit vendor/silverstripe/framework/tests/": Run all tests of the framework module
- "vendor/bin/phpunit vendor/silverstripe/framework/tests/filesystem": Run all filesystem tests within framework
- "vendor/bin/phpunit vendor/silverstripe/framework/tests/filesystem/FolderTest.php": Run a single test
- "vendor/bin/phpunit <dash><dash>coverage-html assets/": Generate coverage report (replace
<dash> with "-", requires xdebug or phpdbg)
More information:
- http://www.phpunit.de/manual/current/en/textui.html
- http://doc.silverstripe.org/framework/en/topics/testing/#configuration
It is safe to remove this file for normal website operation.
<!--
Usage:
- "phpunit": Runs all tests in all folders
- "phpunit sapphire/tests/": Run all tests of the sapphire module
- "phpunit sapphire/tests/filesystem": Run all filesystem tests within the sapphire module
- "phpunit sapphire/tests/filesystem/FolderTest.php": Run a single test
- "phpunit <dash><dash>coverage-html assets/": Generate coverage report (replace <dash> with "-", requires xdebug)
Further information:
- http://www.phpunit.de/manual/current/en/textui.html for more commandline options.
- http://github.com/chillu/silverstripe-doc-restructuring/blob/master/master/cms/docs/en/howto/phpunit-configuration.md
for more information on configuration and execution options.
- sapphire/dev/TestRunner.php for an alternative way to run unit tests through the "sake" CLI tool.
-->
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
<testsuites>
<testsuite name="Default">
<directory>app/tests</directory>
<directory>vendor/silverstripe/cms/tests/php</directory>
<directory>vendor/silverstripe/framework/tests/php</directory>
</testsuite>
<!-- Framework ORM tests are split up to run in parallel -->
<testsuite name="framework-core">
<directory>vendor/silverstripe/framework/tests/php</directory>
<exclude>vendor/silverstripe/framework/tests/php/ORM</exclude>
</testsuite>
<testsuite name="framework-orm">
<directory>vendor/silverstripe/framework/tests/php/ORM</directory>
</testsuite>
<!-- other core components -->
<testsuite name="core">
<directory>vendor/silverstripe/assets/tests/php/</directory>
<directory>vendor/silverstripe/versioned/tests/php/</directory>
</testsuite>
<!-- admin components -->
<testsuite name="admin">
<directory>vendor/silverstripe/admin/tests/php/</directory>
<directory>vendor/silverstripe/asset-admin/tests/php/</directory>
<directory>vendor/silverstripe/campaign-admin/tests/php/</directory>
<directory>vendor/silverstripe/cms/tests/</directory>
<directory>vendor/silverstripe/config/tests/</directory>
<directory>vendor/silverstripe/errorpage/tests/</directory>
<directory>vendor/silverstripe/graphql/tests/</directory>
<directory>vendor/silverstripe/login-forms/tests/php/</directory>
<directory>vendor/silverstripe/mimevalidator/tests/</directory>
<directory>vendor/silverstripe/reports/tests/</directory>
<directory>vendor/silverstripe/siteconfig/tests/php/</directory>
</testsuite>
</testsuites>
</phpunit>
<phpunit
bootstrap="/sapphire/tests/bootstrap.php"
colors="true"
>
<testsuite name="Default">
<directory>./</directory>
</testsuite>
<filter>
<blacklist>
<directory suffix=".php">sapphire/dev/</directory>
<directory suffix=".php">sapphire/thirdparty/</directory>
<directory suffix=".php">cms/thirdparty/</directory>
<file>sapphire/tests/PhpSyntaxTest.php</file>
</blacklist>
</filter>
<listeners>
<listener class="SS_TestListener" file="sapphire/dev/TestListener.php">
</listener>
</listeners>
<groups>
<exclude>
<group>sanitychecks</group>
</exclude>
</groups>
</phpunit>

View File

@ -1,4 +0,0 @@
/**/*
!.gitignore
!.htaccess
!web.config

View File

@ -1,35 +0,0 @@
#
# Whitelist appropriate assets files.
# This file is automatically generated via File.allowed_extensions configuration
# See AssetAdapter::renderTemplate() for reference.
#
# We disable PHP via several methods
# Replace the handler with the default plaintext handler
AddHandler default-handler php phtml php3 php4 php5 inc
<IfModule mod_php5.c>
# Turn the PHP engine off
php_flag engine off
</IfModule>
<IfModule mod_rewrite.c>
<IfModule mod_env.c>
SetEnv HTTP_MOD_REWRITE On
</IfModule>
RewriteEngine On
# Allow error pages
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule error[^\\/]*\.html$ - [L]
# Block invalid file extensions
RewriteCond %{REQUEST_URI} !^[^.]*\.(?i:css|js|ace|arc|arj|asf|au|avi|bmp|bz2|cab|cda|csv|dmg|doc|docx|dotx|flv|gif|gpx|gz|hqx|ico|jpeg|jpg|kml|m4a|m4v|mid|midi|mkv|mov|mp3|mp4|mpa|mpeg|mpg|ogg|ogv|pages|pcx|pdf|png|pps|ppt|pptx|potx|ra|ram|rm|rtf|sit|sitx|tar|tgz|tif|tiff|txt|wav|webm|wma|wmv|xls|xlsx|xltx|zip|zipx)$
RewriteRule .* - [F]
# Non-existent files passed to requesthandler
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ../index.php [QSA]
</IfModule>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,14 @@
/**
* This support file is used to style the WYSIWYG editor in the CMS
*/
@import "typography.css";
body.mceContentBody {
min-height: 200px;
font-size: 62.5%;
}
body.mceContentBody a.broken {
background-color: #FF7B71;
border: 1px red solid;
}

View File

@ -0,0 +1,64 @@
/* GENERIC FORM STYLING */
#Content form {
width:378px;
}
#Content form fieldset {
border:0;
padding:12px;
}
#Content .message {
color:red;
background:#ddd;
border:1px solid #ccc;
padding:5px;
margin:5px;
}
#Content span.message {
width: 300px;
}
#Content form div {
margin-top:10px;
width:100%;
}
#Content form label {
font-size:1.1em;
color:#333;
}
#Content form label.left {
float:left;
width:12em;
}
#Content form label.FormHeading {
font-size:1.3em;
color:#ff7200;
font-weight:bold;
}
#Content form input.text,
#Content form textarea,
#Content form select {
width:200px;
color:#000;
background:#f8f8f8;
border:1px solid #aaa;
padding:3px;
}
#Content form input.numeric {
width:20px;
background:#f0f0f0;
border:1px solid #aaa;
padding:3px;
color:#000;
margin-right:4px;
}
#Content form input.year {
width:35px;
}
#Content form p.Actions {
text-align:right;
padding:0 22px 15px 0;
}
#Content form p.Actions input {
padding:2px;
}

View File

@ -0,0 +1,287 @@
/* Global Resetting */
html{
width: 100%;
height: 100%;
background:url(../images/body_bg.gif) repeat;
}
body {
width: 100%;
height: 100%;
font-size: 62.5%;
/* reset font-sizes to 1em == 10px */
}
* {
font-size: 1em;
/* reset font-sizes to 1em == 10px */
padding: 0;
margin: 0;
font-family:Verdana,Helvetica,sans-serif;
list-style:none;
}
a img{
border:0;
}
.clear{
clear:both;
}
/* Layout CSS */
#Main {
margin:20px auto;
width:900px;
}
#Header {
background:url(../images/blueback.gif) bottom left repeat-x;
border-left:1px solid #ccc;
border-right:1px solid #ccc;
clear:left;
}
#Header h1 {
color:#fff;
font-size:1.5em;
line-height:4.5em;
padding-left:20px;
}
#Menu1 {
padding:10px 50px 0;
}
#Menu1 li {
float:left;
margin-left:2px;
background:url(../images/menu1_right.gif) no-repeat right top;
}
#Menu1 li.current,
#Menu1 li.section {
background:url(../images/menu1_right_on.gif) no-repeat right top;
}
#Menu1 li a {
display:block;
color:#fff;
font-weight:bold;
font-size:1.1em;
text-decoration:none;
padding:5px 15px;
background:url(../images/menu1_left.gif) no-repeat left top;
}
#Menu1 li a:hover {
color:#d2ebff;
}
#Menu1 li.current a,
#Menu1 li.section a {
background:url(../images/menu1_left_on.gif) no-repeat left top;
color:#d2ebff;
}
#ContentContainer {
background:#f5f5f5 url(../images/ss_watermark.gif) bottom left no-repeat;
padding-top:20px;
padding-bottom:20px;
overflow: auto;
}
#Banner {
text-align: center;
}
#Menu2 {
margin-left: 20px;
width: 17em;
float:left;
background:#f0f0f0;
border:1px solid #ddd;
padding:10px 10px 10px 10px;
}
#Menu2 li {
padding-left:15px;
background:url(../images/menu2_arrow.gif) no-repeat left center;
}
#Menu2 a {
color:#333;
font-weight:bold;
font-size:1.1em;
line-height:1.6em;
text-decoration:none;
}
#Menu2 a:hover {
text-decoration:underline;
}
#Menu2 li.current a,
#Menu2 li.section a {
color:#0083C8;
}
#Content {
float: left;
margin: 0px 20px;
width:70%;
}
div.breadcrumbs {
margin-bottom:10px;
font-size:1em;
color:#666;
}
div.breadcrumbs a {
text-decoration:none;
}
#Footer {
background:#015581;
clear:both;
text-align:right;
padding-right:20px;
border:1px solid #ccc;
border-top:0;
}
#Footer span {
color:#ccc;
font-size:1.1em;
line-height:2em;
font-weight:bold;
padding-left:20px;
background:url(../images/ss_logo.gif) no-repeat;
}
#Footer a {
color:#fff;
}
#Footer a:hover {
text-decoration:none;
}
/* The rest of this file is for the second tutorial */
#NewsList,
#StaffList {
background:#f0f0f0;
border:1px dotted #ccc;
padding:10px;
}
#NewsList li,
#StaffList li {
margin: 0;
list-style-type: none;
}
#NewsList li.newsDateTitle span {
color:#666;
line-height:2em;
}
#NewsList li.newsDateTitle a {
font-size:1.3em;
font-weight:bold;
color:#0083C8;
text-decoration:none;
padding-left:20px;
background:url(../images/treeicons/news-file.gif) no-repeat left center;
}
#NewsList li.newsDateTitle a:hover {
border-bottom:1px dotted #0083C8;
}
#NewsList li.newsSummary {
margin-bottom:20px;
}
#NewsList li.newsSummary span {
font-size:1.1em;
line-height:1.5em;
color:#333;
}
#NewsList li.newsSummary a.readMoreLink {
color:#0083C8;
text-decoration:none;
}
#NewsList li.newsSummary a.readMoreLink:hover {
border-bottom:1px dotted #0083C8;
}
div.newsDetails {
margin-bottom:10px;
}
div.newsDetails p {
color:#666;
margin:0;
font-size:1em;
}
div.pageComments {
background:#f0f0f0;
border:1px dotted #ccc;
padding:10px;
}
#StaffList .staffname {
clear: both;
padding-left: 60px;
height: 1.2em;
}
#StaffList .staffphoto {
float: left;
margin-left: 3px;
margin-top: -1.2em;
}
#StaffList .staffphoto img {
border:1px solid #AAA;
}
#StaffList .staffdescription {
margin-left: 60px;
margin-bottom:30px;
}
#StaffPhoto {
float: left;
margin-right: 10px;
}
#StaffPhoto img {
border:1px solid #AAA;
}
#PageComments {
list-style:none;
background:#e9e9e9;
border:1px solid #ccc;
border-bottom:0;
padding:0;
margin:0;
}
#PageComments li {
list-style:none;
padding:5px;
margin:0;
font-size:1em;
border-bottom:1px dotted #bbb;
}
#PageComments li p span {
font-style:italic;
}
#PageComments a.deletelink {
font-weight:bold;
}
#PageNumbers {
font-weight:bold;
color:#333;
font-size:1.1em;
text-align:center;
padding:5px;
border:1px solid #ddd;
background:#e9e9e9;
}
#PageNumbers * {
padding:0 5px;
line-height:1.5em;
}
#PageNumbers a {
color:#0083C8;
text-decoration:none;
}
#PageNumbers a:hover {
text-decoration:underline;
}

View File

@ -0,0 +1,113 @@
/**
* This typography file is included in the WYSIWYG editor
*/
.typography * {
font-family:Verdana,Arial,sans-serif;
font-size:1em;
}
.typography blockquote {
margin-left:20px;
}
.typography hr {
padding:5px;
}
.typography p,
.typography ul li,
.typography ol li,
.typography a {
color:#333;
line-height:1.5em;
font-size:1.1em;
}
.typography p {
margin-bottom:20px;
}
/** CMS LIST STYLES **/
.typography ul,
.typography ol {
margin-left:10px;
margin-bottom:20px;
}
.typography ul li,
.typography ol li {
margin:4px 10px;
line-height:1.4em;
}
.typography ul li {
list-style-type:disc;
}
.typography ol li {
list-style-type:decimal;
}
/* HEADER STYLES */
.typography h1,
.typography h2,
.typography h3,
.typography h4 {
margin-bottom:14px;
color:#0083C8;
}
.typography h1,
.typography h4 {
font-weight:bold;
}
.typography h2,
.typography h3 {
font-weight:normal;
}
.typography h1 {
font-size:2.2em;
}
.typography h2 {
font-size:2.2em;
}
.typography h3 {
font-size:1.6em;
}
.typography h4 {
font-size:1.4em;
}
/* LINK STYLES */
.typography a {
color:#0083C8;
font-size:1em;
text-decoration:none;
}
.typography a:hover {
text-decoration:underline;
}
.typography table {
font-size:1.1em;
}
.typography table tr td {
padding:3px 5px;
}
/* WYSIWYG EDITOR ALIGNMENT CLASSES */
.typography .left {
text-align:left;
}
.typography .center {
text-align:center;
}
.typography .right {
text-align:right;
}
.typography img.right {
float:right;
}
.typography img.left {
float:left;
}
.typography p.MsoNormal, .typography p.MsoBodyText {
margin: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<% base_tag %>
<link rel="stylesheet" type="text/css" href="tutorial/css/layout.css" />
<link rel="stylesheet" type="text/css" href="tutorial/css/typography.css" />
<link rel="stylesheet" type="text/css" href="tutorial/css/form.css" />
</head>
<body>
<div id="Main">
<div id="Header">
<h1>&nbsp;</h1>
</div>
<div id="ContentContainer">
<div id="Content" class="typography">
$Content
$Form
</div>
</div>
<div id="Footer">
<span>Visit <a href="http://www.silverstripe.org" title="Visit www.silverstripe.org">www.silverstripe.org</a> to download the CMS</span>
</div>
</div>
$SilverStripeNavigator
</body>
</html>

View File

@ -1,23 +1,5 @@
<!-- Routing configuration for Microsoft IIS web server -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="SilverStripe Global URLs">
<match url="^(.*)$" />
<conditions>
<add input="{R:1}" matchType="Pattern" pattern="public(/|$)" negate="true" />
</conditions>
<action type="Rewrite" url="public/{R:1}" appendQueryString="true" />
</rule>
<rule name="SilverStripe Preprocessed URLs" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="public/index.php" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
<system.webServer>
</system.webServer>
</configuration>