diff --git a/.gitignore b/.gitignore index ac29bb403c7..10a4e85c2ed 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,12 @@ /phpBB/styles/* !/phpBB/styles/prosilver !/phpBB/styles/all +node_modules /phpBB/vendor +/phpBB/vendor-ext/* +!/phpBB/vendor-ext/.git-keep +/phpBB/composer-ext.json +/phpBB/composer-ext.lock /tests/phpbb_unit_tests.sqlite* /tests/test_config*.php /tests/tmp/* diff --git a/.postcss-sorting.json b/.postcss-sorting.json new file mode 100644 index 00000000000..11a55f3c3d9 --- /dev/null +++ b/.postcss-sorting.json @@ -0,0 +1,243 @@ +{ + "order": [ + "custom-properties", + "dollar-variables", + { + "type": "at-rule", + "name": "include" + }, + "declarations", + "rules", + { + "type": "at-rule", + "name": "media" + } + ], + "properties-order": [ + { + "emptyLineBefore": false, + "properties": [ + "font", + "font-family", + "font-size", + "font-weight", + "font-style", + "font-variant", + "font-size-adjust", + "font-stretch", + "font-effect", + "font-emphasize", + "font-emphasize-position", + "font-emphasize-style", + "font-smooth", + "font-smoothing", + "line-height", + "text-align", + "text-align-last", + "vertical-align", + "white-space", + "text-decoration", + "text-emphasis", + "text-emphasis-color", + "text-emphasis-style", + "text-emphasis-position", + "text-indent", + "text-justify", + "letter-spacing", + "word-spacing", + "writing-mode", + "text-outline", + "text-transform", + "text-size-adjust", + "text-wrap", + "text-overflow", + "text-overflow-ellipsis", + "text-overflow-mode", + "word-wrap", + "word-break", + "tab-size", + "hyphens" + ] + }, + { + "emptyLineBefore": false, + "properties": [ + "background", + "background-color", + "background-image", + "background-repeat", + "background-attachment", + "background-position", + "background-position-x", + "background-position-y", + "background-clip", + "background-origin", + "background-size", + "interpolation-mode", + "filter", + "border", + "border-width", + "border-style", + "border-color", + "border-top", + "border-top-width", + "border-top-style", + "border-top-color", + "border-right", + "border-right-width", + "border-right-style", + "border-right-color", + "border-bottom", + "border-bottom-width", + "border-bottom-style", + "border-bottom-color", + "border-left", + "border-left-width", + "border-left-style", + "border-left-color", + "border-radius", + "border-top-left-radius", + "border-top-right-radius", + "border-bottom-right-radius", + "border-bottom-left-radius", + "border-image", + "border-image-source", + "border-image-slice", + "border-image-width", + "border-image-outset", + "border-image-repeat", + "outline", + "outline-width", + "outline-style", + "outline-color", + "outline-offset", + "tap-highlight-color" + ] + }, + { + "emptyLineBefore": false, + "properties": [ + "box-decoration-break", + "box-shadow", + "text-shadow" + ] + }, + { + "emptyLineBefore": false, + "properties": [ + "color", + "opacity" + ] + }, + { + "emptyLineBefore": false, + "properties": [ + "position", + "z-index", + "top", + "right", + "bottom", + "left" + ] + }, + { + "emptyLineBefore": false, + "properties": [ + "display", + "visibility", + "float", + "clear", + "overflow", + "overflow-x", + "overflow-y", + "overflow-scrolling", + "clip", + "zoom", + "flex", + "flex-direction", + "flex-order", + "flex-pack", + "flex-align", + "flex-basis", + "flex-grow", + "flex-shrink", + "flex-wrap", + "justify-content", + "align-items", + "align-self" + ] + }, + { + "emptyLineBefore": false, + "properties": [ + "box-sizing", + "width", + "min-width", + "max-width", + "height", + "min-height", + "max-height", + "margin", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left" + ] + }, + { + "emptyLineBefore": false, + "properties": [ + "table-layout", + "empty-cells", + "caption-side", + "border-spacing", + "border-collapse", + "list-style", + "list-style-position", + "list-style-type", + "list-style-image" + ] + }, + { + "emptyLineBefore": false, + "properties": [ + "content", + "quotes", + "counter-reset", + "counter-increment", + "resize", + "cursor", + "touch-callout", + "touch-action", + "user-select", + "nav-index", + "nav-up", + "nav-right", + "nav-down", + "nav-left", + "transition", + "transition-delay", + "transition-timing-function", + "transition-duration", + "transition-property", + "transform", + "transform-origin", + "animation", + "animation-name", + "animation-duration", + "animation-play-state", + "animation-timing-function", + "animation-delay", + "animation-iteration-count", + "animation-direction", + "pointer-events" + ] + } + ], + "unspecified-properties-position": "bottomAlphabetical" +} diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 00000000000..fc50e40c1ca --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,391 @@ +{ + "plugins": [ + "stylelint-order" + ], + "ignoreFiles": [ + "./phpBB/styles/prosilver/theme/normalize.css", + ], + "rules": { + "at-rule-name-case": "lower", + "at-rule-name-newline-after": "always-multi-line", + "at-rule-name-space-after": "always-single-line", + "at-rule-no-vendor-prefix": true, + "at-rule-semicolon-newline-after": "always", + + "block-closing-brace-newline-after": [ + "always", { + "ignoreAtRules": ["if", "else"] + } + ], + "block-closing-brace-newline-before": "always-multi-line", + "block-closing-brace-space-before": "always-single-line", + + "block-no-empty": true, + + "block-opening-brace-newline-after": "always-multi-line", + "block-opening-brace-space-after": "always-single-line", + "block-opening-brace-space-before": "always", + + "color-hex-case": "lower", + "color-hex-length": "long", + "color-named": "never", + "color-no-invalid-hex": true, + + "comment-empty-line-before": [ + "always", { + "except": ["first-nested"], + "ignore": ["stylelint-commands"] + } + ], + "comment-whitespace-inside": "always", + + "declaration-bang-space-after": "never", + "declaration-bang-space-before": "always", + + "declaration-block-no-shorthand-property-overrides": true, + "declaration-block-semicolon-newline-after": "always-multi-line", + "declaration-block-semicolon-newline-before": "never-multi-line", + "declaration-block-semicolon-space-after": "always-single-line", + "declaration-block-semicolon-space-before": "never", + "declaration-block-trailing-semicolon": "always", + "declaration-block-single-line-max-declarations": 1, + "declaration-block-no-duplicate-properties": [ + true, { + "ignore": ["consecutive-duplicates-with-different-values"] + } + ], + + "declaration-colon-newline-after": "always-multi-line", + "declaration-colon-space-after": "always-single-line", + "declaration-colon-space-before": "never", + + "declaration-empty-line-before": "never", + + "declaration-property-unit-blacklist": { + "line-height": ["rem", "em", "%"] + }, + "declaration-property-unit-whitelist": { + "height": ["px", "%", "vh"], + "width": ["px", "%", "vw"], + "font-size": ["px", "rem", "%"], + "margin-left": ["px", "rem", "%"], + "margin-right": ["px", "rem", "%"], + "margin-top": ["px", "rem", "%"], + "margin-bottom": ["px", "rem", "%"], + "padding-left": ["px", "rem"], + "padding-right": ["px", "rem"], + "padding-top": ["px", "rem"], + "padding-bottom": ["px", "rem"], + "letter-spacing": ["em"], + "word-spacing": ["em"] + }, + + "font-family-name-quotes": "always-where-recommended", + "function-calc-no-unspaced-operator": true, + + "function-comma-newline-after": "never-multi-line", + "function-comma-newline-before": "never-multi-line", + "function-comma-space-after": "always-single-line", + "function-comma-space-before": "never-single-line", + + "function-linear-gradient-no-nonstandard-direction": true, + "function-max-empty-lines": 5, + + "function-name-case": "lower", + "function-parentheses-newline-inside": "always-multi-line", + "function-parentheses-space-inside": "never-single-line", + "function-url-quotes": "always", + "function-whitespace-after": "always", + + "indentation": "tab", + + "length-zero-no-unit": true, + + "max-empty-lines": 10, + "max-line-length": 180, + "max-nesting-depth": 4, + + "media-feature-colon-space-after": "always", + "media-feature-colon-space-before": "never", + "media-feature-name-case": "lower", + "media-feature-parentheses-space-inside": "never", + "media-feature-range-operator-space-after": "always", + "media-feature-range-operator-space-before": "always", + "media-query-list-comma-newline-after": "always-multi-line", + "media-query-list-comma-newline-before": "never-multi-line", + "media-query-list-comma-space-after": "always-single-line", + "media-query-list-comma-space-before": "never", + + "no-duplicate-selectors": true, + "no-empty-source": true, + "no-eol-whitespace": true, + "no-extra-semicolons": true, + "no-missing-end-of-source-newline": true, + "no-unknown-animations": true, + + "number-leading-zero": "always", + "number-max-precision": 10, + "number-no-trailing-zeros": true, + + "property-case": "lower", + "property-no-unknown": true, + + "rule-empty-line-before": ["always-multi-line", { + "ignore": ["after-comment"], + "except": ["first-nested"] + }], + + "selector-attribute-brackets-space-inside": "never", + "selector-attribute-operator-space-after": "never", + "selector-attribute-operator-space-before": "never", + "selector-attribute-quotes": "always", + + "selector-combinator-space-after": "always", + "selector-combinator-space-before": "always", + + "selector-list-comma-newline-after": "always", + "selector-list-comma-space-before": "never", + + "selector-max-empty-lines": 5, + "selector-max-compound-selectors": 5, + + "selector-pseudo-class-case": "lower", + "selector-pseudo-class-no-unknown": true, + "selector-pseudo-class-parentheses-space-inside": "never", + + "selector-pseudo-element-case": "lower", + "selector-pseudo-element-colon-notation": "single", + "selector-pseudo-element-no-unknown": true, + + "selector-type-case": "lower", + "selector-type-no-unknown": true, + + "selector-descendant-combinator-no-non-space": true, + "selector-max-id": 0, + "selector-no-qualifying-type": [ + true, { + "ignore": ["attribute"] + } + ], + + "shorthand-property-no-redundant-values": true, + + "string-no-newline": true, + "string-quotes": "double", + + "unit-case": "lower", + "unit-no-unknown": true, + + "value-list-comma-newline-after": "always-multi-line", + "value-list-comma-newline-before": "never-multi-line", + "value-list-comma-space-after": "always-single-line", + "value-list-comma-space-before": "never", + "order/declaration-block-order": [ + "custom-properties", + "dollar-variables", + { + "type": "at-rule", + "name": "include" + }, + "declarations", + "rules", + { + "type": "at-rule", + "name": "media" + } + ], + "order/declaration-block-properties-specified-order": [ + [ + "font", + "font-family", + "font-size", + "font-weight", + "font-style", + "font-variant", + "font-size-adjust", + "font-stretch", + "font-effect", + "font-emphasize", + "font-emphasize-position", + "font-emphasize-style", + "font-smooth", + "font-smoothing", + "line-height", + "text-align", + "text-align-last", + "vertical-align", + "white-space", + "text-decoration", + "text-emphasis", + "text-emphasis-color", + "text-emphasis-style", + "text-emphasis-position", + "text-indent", + "text-justify", + "letter-spacing", + "word-spacing", + "writing-mode", + "text-outline", + "text-transform", + "text-size-adjust", + "text-wrap", + "text-overflow", + "text-overflow-ellipsis", + "text-overflow-mode", + "word-wrap", + "word-break", + "tab-size", + "hyphens", + + "background", + "background-color", + "background-image", + "background-repeat", + "background-attachment", + "background-position", + "background-position-x", + "background-position-y", + "background-clip", + "background-origin", + "background-size", + "interpolation-mode", + "filter", + + "border", + "border-width", + "border-style", + "border-color", + "border-top", + "border-top-width", + "border-top-style", + "border-top-color", + "border-right", + "border-right-width", + "border-right-style", + "border-right-color", + "border-bottom", + "border-bottom-width", + "border-bottom-style", + "border-bottom-color", + "border-left", + "border-left-width", + "border-left-style", + "border-left-color", + "border-radius", + "border-top-left-radius", + "border-top-right-radius", + "border-bottom-right-radius", + "border-bottom-left-radius", + "border-image", + "border-image-source", + "border-image-slice", + "border-image-width", + "border-image-outset", + "border-image-repeat", + "outline", + "outline-width", + "outline-style", + "outline-color", + "outline-offset", + "tap-highlight-color", + + "box-decoration-break", + "box-shadow", + "text-shadow", + + "color", + "opacity", + + "position", + "z-index", + "top", + "right", + "bottom", + "left", + + "display", + "visibility", + "float", + "clear", + "overflow", + "overflow-x", + "overflow-y", + "overflow-scrolling", + "clip", + "zoom", + "flex", + "flex-direction", + "flex-order", + "flex-pack", + "flex-align", + "flex-basis", + "flex-grow", + "flex-shrink", + "flex-wrap", + "justify-content", + "align-items", + "align-self", + + "box-sizing", + "width", + "min-width", + "max-width", + "height", + "min-height", + "max-height", + "margin", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", + + "table-layout", + "empty-cells", + "caption-side", + "border-spacing", + "border-collapse", + "list-style", + "list-style-position", + "list-style-type", + "list-style-image", + + "content", + "quotes", + "counter-reset", + "counter-increment", + "resize", + "cursor", + "touch-callout", + "touch-action", + "user-select", + "nav-index", + "nav-up", + "nav-right", + "nav-down", + "nav-left", + "transition", + "transition-delay", + "transition-timing-function", + "transition-duration", + "transition-property", + "transform", + "transform-origin", + "animation", + "animation-name", + "animation-duration", + "animation-play-state", + "animation-timing-function", + "animation-delay", + "animation-iteration-count", + "animation-direction", + "pointer-events" + ], + { unspecified: "bottomAlphabetical" } + ] + } +} diff --git a/.travis.yml b/.travis.yml index 91b8b4932c0..39b858801b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,24 +4,20 @@ dist: precise matrix: include: - - php: 5.4 + - php: 5.6 env: DB=none;NOTESTS=1 - - php: 5.4 - env: DB=mysqli # MyISAM - - php: 5.4 - env: DB=mysql - - php: 5.4 + - php: 5.6 env: DB=mariadb - - php: 5.4 + - php: 5.6 env: DB=postgres - - php: 5.4 + - php: 5.6 env: DB=sqlite3 - - php: 5.4 + - php: 5.6 env: DB=mysqli;SLOWTESTS=1 - - php: 5.5 - env: DB=mysqli - php: 5.6 - env: DB=mysqli + env: DB=mysqli # MyISAM + - php: 5.6 + env: DB=mysql - php: 7.0 env: DB=mysqli - php: 7.1 @@ -34,6 +30,11 @@ matrix: - php: nightly fast_finish: true +addons: + apt: + sources: + - node + services: - redis-server @@ -49,6 +50,7 @@ script: - travis/check-sami-parse-errors.sh $DB $TRAVIS_PHP_VERSION $NOTESTS - travis/check-image-icc-profiles.sh $DB $TRAVIS_PHP_VERSION $NOTESTS - travis/check-executable-files.sh $DB $TRAVIS_PHP_VERSION $NOTESTS ./ + - travis/check-stylesheet.sh $NOTESTS - sh -c "if [ '$SLOWTESTS' != '1' -a '$DB' = 'mysqli' ]; then phpBB/vendor/bin/phpunit tests/lint_test.php; fi" - sh -c "if [ '$NOTESTS' != '1' -a '$SLOWTESTS' != '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --verbose --stop-on-error; fi" - sh -c "if [ '$SLOWTESTS' = '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --group slow; fi" diff --git a/build/build.xml b/build/build.xml index 1491b95b483..8bf6fb750f5 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,7 +2,7 @@ - + @@ -95,6 +95,7 @@ --ignore=${project.basedir}/phpBB/install/database_update.php --ignore=${project.basedir}/phpBB/phpbb/* --ignore=${project.basedir}/phpBB/vendor/* + --ignore=${project.basedir}/phpBB/vendor-ext/* phpBB" dir="." returnProperty="retval-php-legacy" passthru="true" /> 1%", + "last 2 versions" + ], + "keywords": [ + "phpBB", + "phpbb", + "forum", + "php", + "software", + "community" + ], + "author": "", + "license": "GPL-2.0", + "bugs": { + "url": "https://tracker.phpbb.com" + }, + "homepage": "https://www.phpbb.com", + "devDependencies": { + "stylelint": "8.0.0", + "stylelint-order": "0.3.0" + }, + "dependencies": { + "del": "^3.0.0", + "gulp": "^3.9.1", + "gulp-autoprefixer": "^4.0.0", + "gulp-cssnano": "^2.1.2", + "gulp-postcss": "^7.0.0", + "gulp-rename": "^1.2.2", + "gulp-sass": "^3.1.0", + "gulp-sourcemaps": "^2.6.1", + "gulp-stylefmt": "^1.1.0", + "postcss-import": "^11.0.0", + "postcss-pxtorem": "^4.0.1", + "postcss-sorting": "^3.0.2" + } +} diff --git a/phpBB/adm/style/acp_ext_catalog.html b/phpBB/adm/style/acp_ext_catalog.html new file mode 100644 index 00000000000..1be94258e82 --- /dev/null +++ b/phpBB/adm/style/acp_ext_catalog.html @@ -0,0 +1,130 @@ +{% include('overall_header.html') %} + + + +

{{ lang( 'EXTENSIONS_CATALOG') }}

+ +

{{ lang( 'EXTENSIONS_CATALOG_EXPLAIN') }}

+ +
+ {{ lang('BROWSE_EXTENSIONS_DATABASE') }}{{ lang('SETTINGS') }} +
+ +{% if pagination is defined %} + +{% endif %} + + + +{% if extensions is empty %} + +
{{ lang('NO_EXTENSION_AVAILABLE') }}
+ +{% else %} + + + + + + + + + + + +{% for extension in extensions %} + + + + + + +{% endfor %} + +
{{ lang("EXTENSION_NAME") }}{{ lang("VERSION") }}{{ lang("DESCRIPTION") }}{{ lang("EXTENSION_ACTIONS") }}
+ {{ extension.display_name }}
+ {{ extension.name }} +
{{ extension.version }}{{ extension.description }} • {{ lang('HOMEPAGE') }} + {% if extension.name in managed_extensions %} + {{ lang('INSTALLED') }} + {% elseif extension.name in installed_extensions -%} + {{ lang('INSTALLED_MANUALLY') }} + ({{ lang('MANAGE') }}) + {% elseif not enabled -%} + {{ lang('INSTALL') }} + {%- endif -%} +
+{% endif %} + +{% if pagination is defined %} + +{% endif %} + +{% include('overall_footer.html') %} diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html index 8e2c7452a36..5375342a5e6 100644 --- a/phpBB/adm/style/acp_ext_list.html +++ b/phpBB/adm/style/acp_ext_list.html @@ -7,7 +7,7 @@

{L_EXTENSIONS_ADMIN}

{L_EXTENSIONS_EXPLAIN}

- {L_BROWSE_EXTENSIONS_DATABASE}{L_VERSIONCHECK_FORCE_UPDATE_ALL}{L_SETTINGS} + {L_VERSIONCHECK_FORCE_UPDATE_ALL}{L_SETTINGS}
+ +{% include 'overall_footer.html' %} diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index efdd6f1e223..eb91ad59d66 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -8,49 +8,70 @@ ------------------------------------------------------------------------ */ +/* stylelint-disable selector-max-id */ +/* stylelint-disable selector-max-compound-selectors */ +/* stylelint-disable selector-no-qualifying-type */ +/* stylelint-disable declaration-property-unit-blacklist */ +/* stylelint-disable declaration-property-unit-whitelist */ + /* General markup styles ---------------------------------------- */ * { /* Reset browsers default margin, padding and font sizes */ + font-size: 100%; margin: 0; padding: 0; - font-size: 100%; } abbr { text-decoration: none; } -body, div, p, th, td, li, dd { - font-size: x-small; +body, +div, +p, +th, +td, +li, +dd { + font-size: small; voice-family: "\"}\""; voice-family: inherit; - font-size: small; } -html>body, html>div, html>p, html>th, html>td, html>li, html>dd { +html > body, +html > div, +html > p, +html > th, +html > td, +html > li, +html > dd { font-size: small; } html { + word-wrap: break-word; + background: #dbd7d1; color: #536482; - background: #DBD7D1; + /* Always show a scrollbar for short pages - stops the jump when the scrollbar appears. non-ie browsers */ height: 100%; margin-bottom: 1px; - word-wrap: break-word; } body { /* Text-Sizing with ems: http://www.clagnut.com/blog/348/ */ font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; + font-size: 62.5%; + background: #dbd7d1; color: #536482; - background: #DBD7D1; - font-size: 62.5%; /* This sets the default font size to be equivalent to 10px */ + + /* This sets the default font size to be equivalent to 10px */ margin: 10px 15px; } -code, samp { +code, +samp { font-size: 1.2em; } @@ -60,41 +81,44 @@ img { h1 { font-family: "Trebuchet MS", Helvetica, sans-serif; - font-size: 1.70em; + font-size: 1.7em; font-weight: normal; color: #333333; } -h2, caption { +h2, +caption { font-family: "Trebuchet MS", Helvetica, sans-serif; - font-size: 1.40em; + font-size: 1.4em; font-weight: normal; - color: #115098; text-align: left; + color: #115098; margin-top: 25px; } -.rtl h2, .rtl caption { +.rtl h2, +.rtl caption { text-align: right; } -h3, h4 { +h3, +h4 { font-family: "Trebuchet MS", Helvetica, sans-serif; - font-size: 1.20em; + font-size: 1.2em; + line-height: 1.2em; text-decoration: none; - line-height: 1.20em; margin-top: 25px; } p { + font-size: 0.9em; + line-height: 1.4em; margin-bottom: 0.7em; - line-height: 1.40em; - font-size: 0.90em; } ul { - list-style: disc; margin: 0 0 1em 2em; + list-style: disc; } .rtl ul { @@ -104,9 +128,9 @@ ul { hr { border: 0 none; border-top: 1px dashed #999999; + height: 1px; margin-bottom: 5px; padding-bottom: 5px; - height: 1px; } .centered-text { @@ -129,51 +153,53 @@ hr { display: none; } -@media only screen and (max-width: 800px), only screen and (max-device-width: 800px) -{ +@media only screen and (max-width: 800px), only screen and (max-device-width: 800px) { body { margin: 5px 5px 0; } } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ - html, body { +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { + html, + body { height: auto; margin: 0; padding: 0; } } - /* General links */ -a:link, a:visited { - color: #105289; +a:link, +a:visited { text-decoration: none; + color: #105289; } a:hover { - color: #BC2A4D; text-decoration: underline; + color: #bc2a4d; } a:active { - color: #368AD2; text-decoration: none; + color: #368ad2; } .install-body p a { font-weight: bold; } -a#maincontent, a#acl, a#assigned_to { +a#maincontent, +a#acl, +a#assigned_to { display: block; } /* List items */ -ul, ol { - list-style-position: inside; +ul, +ol { margin-left: 1em; + list-style-position: inside; } li { @@ -181,19 +207,18 @@ li { list-style-type: inherit; } - /* Main blocks ---------------------------------------- */ #wrap { - padding: 0 0 15px 0; min-width: 615px; + padding: 0 0 15px; } #page-header { + font-size: 0.85em; text-align: right; background: url("../images/phpbb_logo.png") top left no-repeat; height: 54px; - font-size: 0.85em; margin-bottom: 10px; } @@ -203,14 +228,14 @@ li { } #page-header h1 { + font-family: "Trebuchet MS", Helvetica, sans-serif; + font-size: 1.7em; color: #767676; - font-family: "Trebuchet MS",Helvetica,sans-serif; - font-size: 1.70em; padding-top: 10px; } #page-header p { - font-size: 1.00em; + font-size: 1em; } #page-header p#skip { @@ -227,13 +252,13 @@ li { } #content { - padding: 30px 10px 10px; position: relative; + padding: 30px 10px 10px; } #content h1 { - color: #115098; line-height: 1.2em; + color: #115098; margin-bottom: 0; } @@ -253,29 +278,30 @@ li { } .rtl .main { - margin-left: 0; margin-right: 210px; + margin-left: 0; } #page-body.simple-page-body { + min-width: 0; padding: 0; padding-right: 10px; - min-width: 0; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ - #wrap, #page-body, #page-body.simple-page-body { - padding: 0; +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { + #wrap, + #page-body, + #page-body.simple-page-body { min-width: 300px; + padding: 0; } #page-header { - margin: 5px; - padding-left: 160px; + overflow: hidden; height: auto; min-height: 54px; - overflow: hidden; + margin: 5px; + padding-left: 160px; } .rtl #page-header { @@ -286,22 +312,25 @@ li { #page-header h1 { font-size: 1.2em; white-space: nowrap; - overflow: hidden; text-overflow: ellipsis; + overflow: hidden; } #page-header fieldset { margin-top: 5px; } - #main, .rtl #main, .main, .rtl .main { + #main, + .rtl #main, + .main, + .rtl .main { float: none; width: auto; margin: 0; } #content { - background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top; + background: #f3f3f3 url("../images/innerbox_bg.gif") repeat-x top; padding: 5px; } @@ -310,12 +339,11 @@ li { } } -@media only screen and (max-width: 400px), only screen and (max-device-width: 400px) -{ +@media only screen and (max-width: 400px), only screen and (max-device-width: 400px) { #page-header { background-size: 76px 26.5px; - padding-left: 80px; min-height: 30px; + padding-left: 80px; } .rtl #page-header { @@ -323,34 +351,33 @@ li { } #page-header h1 { - padding-top: 0; font-size: 1.1em; + padding-top: 0; } } - /* Tabbed menu -----------------------------------------*/ +---------------------------------------- */ #tabs { font-family: Arial, Helvetica, sans-serif; line-height: normal; - margin: 0 7px; position: relative; z-index: 2; + margin: 0 7px; } #tabs > ul { - list-style: none; margin: 0; padding: 0; + list-style: none; } #tabs .tab { - display: inline-block; - float: left; font-size: 0.85em; font-weight: bold; line-height: 14px; + display: inline-block; + float: left; } .rtl #tabs .tab { @@ -358,47 +385,37 @@ li { } #tabs .tab > a { - background: #D4D6DA; - background: -moz-linear-gradient(top, #CACBCF 0%, #D4D6DA 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #CACBCF), color-stop(100%, #D4D6DA)); - background: -webkit-linear-gradient(top, #CACBCF 0%, #D4D6DA 100%); - background: -o-linear-gradient(top, #CACBCF 0%, #D4D6DA 100%); - background: -ms-linear-gradient(top, #CACBCF 0%, #D4D6DA 100%); - background: linear-gradient(to bottom, #CACBCF 0%, #D4D6DA 100%); - border: 1px solid #BBB; + font-weight: bold; + white-space: nowrap; + text-decoration: none; + text-transform: uppercase; + background: #d4d6da; + background: linear-gradient(to bottom, #cacbcf 0%, #d4d6da 100%); + border: 1px solid #bbbbbb; border-bottom-width: 0; border-radius: 5px 5px 0 0; color: #767676; + position: relative; display: block; - font-weight: bold; margin: 1px 1px 2px 0; padding: 6px 9px 4px; - position: relative; - text-decoration: none; - text-transform: uppercase; - white-space: nowrap; cursor: pointer; } #tabs .tab > a:hover { - background: #F1F1EE; - border-color: #C0BFBB; - color: #BC2A4D; + background: #f1f1ee; + border-color: #c0bfbb; + color: #bc2a4d; } #tabs .activetab > a, #tabs .activetab > a:hover { - background: #DCDEE2; - background: -moz-linear-gradient(top, #F2F2F2 0%, #DCDEE2 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F2F2F2), color-stop(100%, #DCDEE2)); - background: -webkit-linear-gradient(top, #F2F2F2 0%, #DCDEE2 100%); - background: -o-linear-gradient(top, #F2F2F2 0%, #DCDEE2 100%); - background: -ms-linear-gradient(top, #F2F2F2 0%, #DCDEE2 100%); - background: linear-gradient(to bottom, #F2F2F2 0%, #DCDEE2 100%); - border-color: #999; - border-bottom: 2px solid #DCDEE2; - box-shadow: 0 1px 1px #FFF inset; - color: #23649F; + background: #dcdee2; + background: linear-gradient(to bottom, #f2f2f2 0%, #dcdee2 100%); + border-color: #999999; + border-bottom: 2px solid #dcdee2; + box-shadow: 0 1px 1px #ffffff inset; + color: #23649f; margin: 0 1px 0 0; padding: 7px 10px 4px; } @@ -408,49 +425,50 @@ li { } /* Responsive tabs -----------------------------------------*/ +---------------------------------------- */ .responsive-tab { position: relative; } .responsive-tab > a.responsive-tab-link { - display: block; font-size: 16px; - position: relative; - width: 16px; line-height: 14px; text-decoration: none; - padding-left: 9px !important; + position: relative; + display: block; + width: 16px; padding-right: 9px !important; + padding-left: 9px !important; } .responsive-tab .responsive-tab-link:before { - content: ''; + border-top: 0.375em double #767676; + border-bottom: 0.125em solid #767676; position: absolute; - left: 10px; top: 7px; - height: .125em; + left: 10px; width: 14px; - border-bottom: 0.125em solid #767676; - border-top: 0.375em double #767676; + height: 0.125em; + content: ""; } .responsive-tab .responsive-tab-link:hover:before { - border-color: #BC2A4D; + border-color: #bc2a4d; } .responsive-tab.activetab .responsive-tab-link:before { - border-color: #23649F; + border-color: #23649f; } .responsive-tab.activetab .responsive-tab-link:hover:before { border-color: #115098; } -#tabs .dropdown, #minitabs .dropdown { +#tabs .dropdown, +#minitabs .dropdown { + font-weight: normal; top: 20px; margin-right: -2px; - font-weight: normal; } #tabs .dropdown-right .dropdown { @@ -458,12 +476,12 @@ li { } #tabs .dropdown-contents { - list-style: none; margin: 0; + list-style: none; } #tabs .dropdown li { - border-bottom: 1px dotted #DCDCDC; + border-bottom: 1px dotted #dcdcdc; } #tabs .dropdown li:last-child { @@ -471,23 +489,23 @@ li { } #tabs .dropdown a { + text-align: right; display: block; padding: 4px 8px; - text-align: right; } /* Main Panel ---------------------------------------- */ #acp { + background: #f3f3f3 url("../images/innerbox_bg.gif") repeat-x top; + border: 1px #999999 solid; + border-radius: 5px; + box-shadow: #ffffff 0 0 0 1px inset; position: relative; top: -2px; + min-width: 550px; margin: 0 0 2px; padding: 3px 1px; - min-width: 550px; - background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top; - border: 1px #999999 solid; - border-radius: 5px; - box-shadow: #FFF 0 0 0 1px inset; } #acp:first-child { @@ -495,22 +513,21 @@ li { } .panel { - background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top; - padding: 5px 0; + background: #f3f3f3 url("../images/innerbox_bg.gif") repeat-x top; border-radius: 5px; overflow: hidden; + padding: 5px 0; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { #acp { + background: #ffffff; + border-width: 1px 0; + border-radius: 0; + box-shadow: none; min-width: 0; min-height: 0; - border-radius: 0; - border-width: 1px 0; - background: #fff; padding: 1px 0; - box-shadow: none; } } @@ -519,18 +536,18 @@ li { /* Menu */ #menu { + font-size: 1em; + border-right: 1px solid #cccfd3; + position: relative; float: left; width: 200px; - font-size: 1.00em; padding: 0; - border-right: 1px solid #CCCFD3; - position: relative; } .rtl #menu { - float: right; border: none; - border-left: 1px solid #CCCFD3; + border-left: 1px solid #cccfd3; + float: right; } #menu p { @@ -538,104 +555,111 @@ li { } #menu ul { - list-style: none; + word-wrap: normal; margin: 0; padding: 0; - word-wrap: normal; + list-style: none; } /* Default list state */ -#menu li, #menu .header { - padding: 0; - margin: 0; +#menu li, +#menu .header { font-size: 0.85em; font-weight: bold; display: block; + margin: 0; + padding: 0; } /* Link styles for the sub-section links */ #menu li span { + font-weight: normal; + text-decoration: none; + color: #138ecb; display: block; - padding: 3px 3px 3px 8px; margin: 1px 0; - text-decoration: none; - font-weight: normal; - color: #138ECB; + padding: 3px 3px 3px 8px; } .rtl #menu li span { padding: 3px 8px 3px 3px; } -#menu li a:hover, #menu li a:hover span { +#menu li a:hover, +#menu li a:hover span { text-decoration: none; - background-color: #FFFFFF; - color: #BC2A4D; + background-color: #ffffff; + color: #bc2a4d; } -#menu li a:active, #menu li a:active span { - color: #F632A0; +#menu li a:active, +#menu li a:active span { + color: #f632a0; } #menu li#activemenu a span { - text-decoration: none; font-weight: bold; - color: #1180B7; + text-decoration: none; background: transparent url("../images/arrow_right.gif") 0% 50% no-repeat; + color: #1180b7; } .rtl #menu li#activemenu a span { background: transparent url("../images/arrow_left.gif") 100% 50% no-repeat; } -#menu li#activemenu a:hover span, #menu li#activemenu span { - text-decoration: none; +#menu li#activemenu a:hover span, +#menu li#activemenu span { font-weight: bold; - color: #BC2A4D; - background: #FFFFFF url("../images/arrow_right.gif") 1% 50% no-repeat; + text-decoration: none; + background: #ffffff url("../images/arrow_right.gif") 1% 50% no-repeat; + color: #bc2a4d; } -.rtl #menu li#activemenu a:hover span, .rtl #menu li#activemenu span { - background: #FFFFFF url("../images/arrow_left.gif") 99% 50% no-repeat; +.rtl #menu li#activemenu a:hover span, +.rtl #menu li#activemenu span { + background: #ffffff url("../images/arrow_left.gif") 99% 50% no-repeat; } -#menu li a:active, #menu li a:active span, #menu li#activemenu a:active span { - color: #F632A0; +#menu li a:active, +#menu li a:active span, +#menu li#activemenu a:active span { + color: #f632a0; } #menu li span.completed { text-decoration: none; - padding: 3px 3px 3px 12px; background: url("../images/arrow_down.gif") 1% 50% no-repeat; + padding: 3px 3px 3px 12px; } .rtl #menu li span.completed { text-decoration: none; - padding: 3px 12px 3px 3px; background: url("../images/arrow_down.gif") 99% 50% no-repeat; + padding: 3px 12px 3px 3px; } #menu .header { font-family: Tahoma, Helvetica, sans-serif; - display: block; + font-size: 0.75em; font-weight: bold; + text-decoration: none; + text-transform: uppercase; + border-bottom: 1px solid #327aa5; + outline-style: none; color: #115098; - border-bottom: 1px solid #327AA5; - padding: 4px 0 2px; + display: block; margin-top: 15px; - text-transform: uppercase; - font-size: 0.75em; - text-decoration: none; + padding: 4px 0 2px; cursor: inherit; - outline-style: none; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ - #menu, .rtl #menu { +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { + #menu, + .rtl #menu { + border-width: 0; float: none; width: auto; - border-width: 0; max-width: 200px; margin: 0 auto 10px; } @@ -645,10 +669,10 @@ li { } #menu .menu-block.active { + background: rgba(255, 255, 255, 0.5); + border-radius: 5px; margin: 0 -5px; padding: 0 5px 3px; - background: rgba(255, 255, 255, .5); - border-radius: 5px; } #menu .menu-block.no-header.active { @@ -656,31 +680,35 @@ li { } #menu .menu-block .header { - margin-top: 5px; - cursor: pointer; + text-decoration: underline; border-bottom-width: 0; position: relative; - text-decoration: underline; + margin-top: 5px; + cursor: pointer; } - #menu .menu-block .header:focus, #menu .menu-block.active .header { - color: #D31141; + #menu .menu-block .header:focus, + #menu .menu-block.active .header { text-decoration: none; + color: #d31141; } #menu .menu-block ul { display: none; } - .nojs #menu .menu-block:hover ul, #menu .menu-block.active ul, #menu .menu-block.no-header ul { + .nojs #menu .menu-block:hover ul, + #menu .menu-block.active ul, + #menu .menu-block.no-header ul { display: block; } #menu .menu-block li:last-child { - border-bottom: 1px solid #327AA5; + border-bottom: 1px solid #327aa5; } - #menu .menu-block:last-child li:last-child, #menu .menu-block.active li:last-child { + #menu .menu-block:last-child li:last-child, + #menu .menu-block.active li:last-child { border-bottom-width: 0; } @@ -689,48 +717,47 @@ li { } } - /* Table styles ---------------------------------------- */ - table { + background-color: #ffffff; + border: 1px solid #cccfd3; width: 100%; - border: 1px solid #CCCFD3; - background-color: #FFFFFF; padding: 1px; } th { - padding: 3px 4px; - color: #FFFFFF; - background: #70AED3 url("../images/gradient2b.gif") bottom left repeat-x; - border-top: 1px solid #6DACD2; - border-bottom: 1px solid #327AA5; - text-align: left; font-size: 0.75em; + text-align: left; text-transform: uppercase; + background: #70aed3 url("../images/gradient2b.gif") bottom left repeat-x; + border-top: 1px solid #6dacd2; + border-bottom: 1px solid #327aa5; + color: #ffffff; + padding: 3px 4px; } td { - text-align: left; font-size: 0.85em; + line-height: 1.2em; + text-align: left; padding: 4px; - line-height: 1.20em; } -.rtl th, .rtl td { +.rtl th, +.rtl td { text-align: right; } .table1 { - border-collapse: separate; - border-spacing: 1px; clear: both; + border-spacing: 1px; + border-collapse: separate; } dt#color_palette_placeholder table { - margin-right: 5px; width: 80px; + margin-right: 5px; } #color_palette_placeholder td { @@ -738,34 +765,34 @@ dt#color_palette_placeholder table { } table.type2 { - border: none; background: none; + border: none; padding: 0; } table.type2 th { + text-align: center; background: none; border-top: none; - text-align: center; color: #115098; padding: 2px 0; } table.type2 td { - padding: 0; font-size: 1em; + padding: 0; } table.type2 td.name { - padding: 2px; vertical-align: middle; + padding: 2px; } -table.type3 { +table.type3 { + background-color: transparent; + border: none; float: right; width: 300px; - border: none; - background-color: transparent; padding: 0; } @@ -774,25 +801,25 @@ table.type3 { } table.type3 thead th { + font-size: 0.85em; + font-weight: normal; + text-align: center; + text-transform: none; background-color: transparent; border-top: none; - text-align: center; color: #115098; padding: 0 3px; - font-size: 0.85em; - font-weight: normal; - text-transform: none; } table.type3 tbody th { - border-top: none; + font-size: 0.9em; + font-weight: normal; text-align: left; text-transform: none; - padding: 0; border: none; - font-size: 0.90em; - font-weight: normal; + border-top: none; width: 100%; + padding: 0; } .rtl table.type3 tbody th { @@ -814,8 +841,8 @@ th.name { } td.name { - text-align: left; font-weight: bold; + text-align: left; } .rtl td.name { @@ -823,8 +850,8 @@ td.name { } .entry { - text-align: left; font-weight: normal; + text-align: left; } .rtl .entry { @@ -832,95 +859,131 @@ td.name { } .row1 { - background-color: #F9F9F9; + background-color: #f9f9f9; } table.zebra-table tbody tr:nth-child(odd) { - background-color: #F9F9F9; + background-color: #f9f9f9; } .row2 { - background-color: #DCEBFE; + background-color: #dcebfe; } table.zebra-table tbody tr:nth-child(even) { - background-color: #DCEBFE; + background-color: #dcebfe; } -.row3 { background-color: #DBDFE2; } -.row4 { background-color: #E4E8EB; } -.col1 { background-color: #DCEBFE; } -.col2 { background-color: #F9F9F9; } +.row3 { + background-color: #dbdfe2; +} + +.row4 { + background-color: #e4e8eb; +} + +.col1 { + background-color: #dcebfe; +} + +.col2 { + background-color: #f9f9f9; +} /* 4 row background colours for trees */ -.row1a { background-color: #F9F9F9; } -.row1b { background-color: #F6F6F6; } -.row2a { background-color: #E7EEF4; } -.row2b { background-color: #E3EBF2; } +.row1a { + background-color: #f9f9f9; +} -tr.row-highlight:hover td { background-color: #DBDFE2; } +.row1b { + background-color: #f6f6f6; +} + +.row2a { + background-color: #e7eef4; +} + +.row2b { + background-color: #e3ebf2; +} + +tr.row-highlight:hover td { + background-color: #dbdfe2; +} .spacer { - background-color: #DBDFE2; - height: 1px; line-height: 1px; + background-color: #dbdfe2; + height: 1px; } /* Deactivated row */ .row-inactive { - color: #999; + color: #999999; } -.row-inactive a, .row-inactive strong { - color: #888; + +.row-inactive a, +.row-inactive strong { + color: #888888; } + .row-inactive a:hover { - color: #BC2A4D; + color: #bc2a4d; } /* Specific tables */ table.forums td.folder { - width: 27px; text-align: center; + width: 27px; } table td.actions { - vertical-align: middle; - width: 100px; text-align: center; + vertical-align: middle; white-space: nowrap; + width: 100px; } -table tr:first-child td.actions .up, table tr:last-child td.actions .down { +table tr:first-child td.actions .up, +table tr:last-child td.actions .down { display: none; } -table tr:first-child td.actions .up-disabled, table tr:last-child td.actions .down-disabled { +table tr:first-child td.actions .up-disabled, +table tr:last-child td.actions .down-disabled { display: inline !important; } -table.styles td.users, table td.mark { +table.styles td.users, +table td.mark { text-align: center; } table.fixed-width-table { - table-layout: fixed; word-break: break-word; + table-layout: fixed; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ - table.responsive, table.responsive tbody, table.responsive tr, table.responsive td { +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { + table.responsive, + table.responsive tbody, + table.responsive tr, + table.responsive td { display: block; } - table.responsive thead, table.responsive th, table.responsive colgroup { + table.responsive thead, + table.responsive th, + table.responsive colgroup { display: none; } - table.responsive.show-header thead, table.responsive.show-header th:first-child, table.responsive caption { + table.responsive.show-header thead, + table.responsive.show-header th:first-child, + table.responsive caption { + text-align: left !important; display: block; width: auto !important; - text-align: left !important; margin: 0; } @@ -931,45 +994,76 @@ table.fixed-width-table { } table.responsive caption { - padding: 3px 4px; - color: #FFFFFF; - background: #70AED3 url("../images/gradient2b.gif") bottom left repeat-x; - border-top: 1px solid #6DACD2; - border-bottom: 1px solid #327AA5; - text-align: left; font-size: 0.75em; font-weight: bold; + text-align: left; text-transform: uppercase; + background: #70aed3 url("../images/gradient2b.gif") bottom left repeat-x; + border-top: 1px solid #6dacd2; + border-bottom: 1px solid #327aa5; + color: #ffffff; + padding: 3px 4px; } - table.responsive.show-header th:first-child span.rank-img, table.responsive.no-caption caption, table.responsive.no-header thead { + table.responsive.show-header th:first-child span.rank-img, + table.responsive.no-caption caption, + table.responsive.no-header thead { display: none; } table.responsive tr { + background-color: #ffffff; + border: 1px solid #cccfd3; + overflow: hidden; margin: 2px 0; - border: 1px solid #CCCFD3; - background-color: #FFFFFF; padding: 1px 1px 0; - overflow: hidden; } - table.responsive tr.row1 td { background-color: #F9F9F9; } - table.responsive tr.row2 td { background-color: #DCEBFE; } - table.responsive tr.row3 td { background-color: #DBDFE2; } - table.responsive tr.row4 td { background-color: #E4E8EB; } - table.responsive tr.col1 td { background-color: #DCEBFE; } - table.responsive tr.col2 td { background-color: #F9F9F9; } - table.responsive tr.row1a td { background-color: #F9F9F9; } - table.responsive tr.row1b td { background-color: #F6F6F6; } - table.responsive tr.row2a td { background-color: #E7EEF4; } - table.responsive tr.row2b td { background-color: #E3EBF2; } + table.responsive tr.row1 td { + background-color: #f9f9f9; + } + + table.responsive tr.row2 td { + background-color: #dcebfe; + } + + table.responsive tr.row3 td { + background-color: #dbdfe2; + } + + table.responsive tr.row4 td { + background-color: #e4e8eb; + } + + table.responsive tr.col1 td { + background-color: #dcebfe; + } + + table.responsive tr.col2 td { + background-color: #f9f9f9; + } + + table.responsive tr.row1a td { + background-color: #f9f9f9; + } + + table.responsive tr.row1b td { + background-color: #f6f6f6; + } + + table.responsive tr.row2a td { + background-color: #e7eef4; + } + + table.responsive tr.row2b td { + background-color: #e3ebf2; + } table.responsive td { - width: auto !important; text-align: left !important; - padding: 4px; + width: auto !important; margin-bottom: 1px; + padding: 4px; } .rtl table.responsive td { @@ -985,15 +1079,14 @@ table.fixed-width-table { } table.responsive td > dfn:after { - content: ':'; padding-right: 5px; + content: ":"; } table.responsive.two-columns td { - width: 50% !important; float: left; - -moz-box-sizing: border-box; box-sizing: border-box; + width: 50% !important; } .rtl table.responsive.two-columns td { @@ -1015,28 +1108,29 @@ table.fixed-width-table { /* Specific tables */ table.responsive.forums td.folder { + background: transparent; float: left; width: 27px; - background: transparent; } + .rtl table.responsive.forums td.folder { float: right; } table.responsive.forums td.forum-desc { - margin-left: 35px; - min-height: 27px; background: transparent; + min-height: 27px; + margin-left: 35px; } .rtl table.responsive.forums td.forum-desc { - margin-left: 0; margin-right: 35px; + margin-left: 0; } table.responsive td.actions { - clear: both; text-align: right !important; + clear: both; } .rtl table.responsive td.actions { @@ -1044,15 +1138,17 @@ table.fixed-width-table { } table.responsive.styles tr.responsive-style-row td:first-child { - padding-left: 4px !important; padding-right: 4px !important; + padding-left: 4px !important; } - table.responsive.styles td:first-child > dfn, table.responsive td.actions > dfn { + table.responsive.styles td:first-child > dfn, + table.responsive td.actions > dfn { display: none !important; } - .horizontal-palette td:nth-child(2n), .vertical-palette tr:nth-child(2n) { + .horizontal-palette td:nth-child(2n), + .vertical-palette tr:nth-child(2n) { display: none; } @@ -1062,17 +1158,17 @@ table.fixed-width-table { } /* General form styles -----------------------------------------*/ +---------------------------------------- */ fieldset { + background-color: #ffffff; + border-top: 1px solid #d7d7d7; + border-right: 1px solid #cccccc; + border-bottom: 1px solid #cccccc; + border-left: 1px solid #d7d7d7; + border-radius: 3px; + position: relative; margin: 15px 0; padding: 10px; - border-top: 1px solid #D7D7D7; - border-right: 1px solid #CCCCCC; - border-bottom: 1px solid #CCCCCC; - border-left: 1px solid #D7D7D7; - background-color: #FFFFFF; - position: relative; - border-radius: 3px; } fieldset h2 { @@ -1080,10 +1176,10 @@ fieldset h2 { } .rtl fieldset { - border-top: 1px solid #D7D7D7; - border-right: 1px solid #D7D7D7; - border-bottom: 1px solid #CCCCCC; - border-left: 1px solid #CCCCCC; + border-top: 1px solid #d7d7d7; + border-right: 1px solid #d7d7d7; + border-bottom: 1px solid #cccccc; + border-left: 1px solid #cccccc; } fieldset p { @@ -1091,49 +1187,53 @@ fieldset p { } legend { - padding: 1px 0; - font-family: Tahoma,arial,Verdana,Sans-serif; - font-size: .9em; + font-family: Tahoma, arial, Verdana, Sans-serif; + font-size: 0.9em; font-weight: bold; - color: #115098; - margin-top: -.4em; - position: relative; - text-transform: none; line-height: 1.2em; - top: -.2em; vertical-align: middle; + text-transform: none; + color: #115098; + position: relative; + top: -0.2em; + margin-top: -0.4em; + padding: 1px 0; } -input, textarea { +input, +textarea { font-family: Verdana, Helvetica, Arial, sans-serif; - font-size: 0.90em; + font-size: 0.9em; font-weight: normal; vertical-align: middle; - padding: 2px; + background-color: #e3dfd8; + border-top: 1px solid #afaeaa; + border-right: 1px solid #d5d5c8; + border-bottom: 1px solid #d5d5c8; + border-left: 1px solid #afaeaa; color: #111111; - border-left: 1px solid #AFAEAA; - border-top: 1px solid #AFAEAA; - border-right: 1px solid #D5D5C8; - border-bottom: 1px solid #D5D5C8; - background-color: #E3DFD8; + padding: 2px; } -.rtl input, .rtl textarea { - border-left: 1px solid #D5D5C8; - border-top: 1px solid #AFAEAA; - border-right: 1px solid #AFAEAA; - border-bottom: 1px solid #D5D5C8; +.rtl input, +.rtl textarea { + border-top: 1px solid #afaeaa; + border-right: 1px solid #afaeaa; + border-bottom: 1px solid #d5d5c8; + border-left: 1px solid #d5d5c8; } -input:hover, textarea:hover { - border-left: 1px solid #AFAEAA; - border-top: 1px solid #AFAEAA; - border-right: 1px solid #AFAEAA; - border-bottom: 1px solid #AFAEAA; - background-color: #E9E9E2; +input:hover, +textarea:hover { + background-color: #e9e9e2; + border-top: 1px solid #afaeaa; + border-right: 1px solid #afaeaa; + border-bottom: 1px solid #afaeaa; + border-left: 1px solid #afaeaa; } -input.langvalue, textarea.langvalue { +input.langvalue, +textarea.langvalue { width: 90%; } @@ -1142,18 +1242,19 @@ input[type="number"] { -moz-padding-end: 0; } -optgroup, select { - background-color: #FAFAFA; - border: 1px solid #666666; +optgroup, +select { font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 0.85em; font-weight: normal; font-style: normal; - cursor: pointer; - padding: 1px; vertical-align: middle; + background-color: #fafafa; + border: 1px solid #666666; + color: #000000; width: auto; - color: #000; + padding: 1px; + cursor: pointer; } select:focus { @@ -1161,18 +1262,18 @@ select:focus { } optgroup { - font-size: 1.00em; + font-size: 1em; font-weight: bold; } optgroup.disabled-options { + background-color: #808080; display: none; - background-color: gray; } option { + color: #000000; padding: 0 1em 0 0; - color: #000; } option.disabled-option { @@ -1199,9 +1300,9 @@ textarea { } label { - cursor: pointer; font-size: 0.85em; padding: 0 5px 0 0; + cursor: pointer; } .rtl label { @@ -1209,7 +1310,7 @@ label { } label input { - font-size: 1.00em; + font-size: 1em; vertical-align: middle; } @@ -1217,28 +1318,42 @@ label img { vertical-align: middle; } -fieldset.quick, p.quick { +fieldset.quick, +p.quick { + text-align: right; + background-color: transparent; + border: none; margin: 0 0 5px; padding: 5px 0 0; - border: none; - background-color: transparent; - text-align: right; } -.rtl fieldset.quick, .rtl p.quick { +.rtl fieldset.quick, +.rtl p.quick { text-align: left; } +fieldset.quick-left, +p.quick-left { + float: left; + margin: 15px 0 5px; + padding: 0; +} + +.rtl fieldset.quick-left, +.rtl p.quick-left { + float: right; +} + fieldset.quick legend { display: none; } fieldset.tabulated { background: none; + border: 0; margin: 0; margin-top: 5px; padding: 0; - border: 0; } fieldset.tabulated legend { @@ -1246,29 +1361,31 @@ fieldset.tabulated legend { } fieldset.nobg { - margin: 15px 0 0 0; - padding: 0; - border: none; background-color: transparent; + border: none; + margin: 15px 0 0; + padding: 0; } fieldset.display-options { - margin: 15px 0 2px 0; - padding: 0 0 4px 0; - border: none; - background-color: transparent; - text-align: center; font-size: 0.85em; + text-align: center; + background-color: transparent; + border: none; + margin: 15px 0 2px; + padding: 0 0 4px; } -fieldset.display-options select, fieldset.display-options input, fieldset.display-options label { - font-size: 1.00em; +fieldset.display-options select, +fieldset.display-options input, +fieldset.display-options label { + font-size: 1em; vertical-align: middle; } select option.disabled { - background-color: #bbb; - color: #fff; + background-color: #bbbbbb; + color: #ffffff; } /* Special case inputs */ @@ -1277,15 +1394,15 @@ select#full_folder_action { width: 95%; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { fieldset { padding: 5px; } - fieldset.quick, p.quick { - float: none !important; + fieldset.quick, + p.quick { text-align: center; + float: none !important; } fieldset.display-options { @@ -1298,7 +1415,7 @@ select#full_folder_action { ---------------------------------------- */ dl { font-family: Verdana, Helvetica, Arial, sans-serif; - font-size: 1.00em; + font-size: 1em; } dt { @@ -1310,18 +1427,31 @@ dt { float: right; } -dd { color: #666666;} -dd + dd { padding-top: 5px;} -dt span { padding: 0 5px 0 0;} -.rtl dt span { padding: 0 0 0 5px;} +dd { + color: #666666; +} + +dd + dd { + padding-top: 5px; +} + +dt span { + padding: 0 5px 0 0; +} -dt .explain { font-style: italic;} +.rtl dt span { + padding: 0 0 0 5px; +} + +dt .explain { + font-style: italic; +} dt label { - font-size: 1.00em; - text-align: left; + font-size: 1em; font-weight: bold; - color: #4A5A73; + text-align: left; + color: #4a5a73; } .rtl dt label { @@ -1329,20 +1459,23 @@ dt label { } dd label { - font-size: 1.00em; + font-size: 1em; white-space: nowrap; + color: #4a5a73; margin: 0 10px 0 0; - color: #4A5A73; } .rtl dd label { margin: 0 0 0 10px; } -html>body dd label input { vertical-align: text-bottom;} /* Tweak for Moz to align checkboxes/radio buttons nicely */ +html > body dd label input { + vertical-align: text-bottom; +} +/* Tweak for Moz to align checkboxes/radio buttons nicely */ dd input { - font-size: 1.00em; + font-size: 1em; max-width: 100%; margin: 2px 0; } @@ -1356,27 +1489,27 @@ dd select { } dd textarea { - font-size: 0.90em; + font-size: 0.9em; width: 90%; } fieldset dl { - margin-bottom: 10px; font-size: 0.85em; + margin-bottom: 10px; } fieldset dt { - width: 45%; text-align: left; border: none; - border-right: 1px solid #CCCCCC; + border-right: 1px solid #cccccc; + width: 45%; padding-top: 3px; } .rtl fieldset dt { text-align: right; border: none; - border-left: 1px solid #CCCCCC; + border-left: 1px solid #cccccc; } fieldset #color_palette_placeholder { @@ -1384,32 +1517,34 @@ fieldset #color_palette_placeholder { } fieldset dd { + font-size: 1em; + vertical-align: top; + border: none; + border-left: 1px solid #cccccc; margin: 0 0 0 45%; padding: 0 0 0 5px; - border: none; - border-left: 1px solid #CCCCCC; - vertical-align: top; - font-size: 1.00em; } .rtl fieldset dd { + border: none; + border-right: 1px solid #cccccc; margin: 0 45% 0 0; padding: 0 5px 0 0; - border: none; - border-right: 1px solid #CCCCCC; } -dd.full, .rtl dd.full { - margin: 0; +dd.full, +.rtl dd.full { + text-align: center; border: 0; + width: 95%; + margin: 0; padding: 0; padding-top: 3px; - text-align: center; - width: 95%; } /* Hover highlights for form rows */ -fieldset dl:hover dt, fieldset dl:hover dd { +fieldset dl:hover dt, +fieldset dl:hover dd { border-color: #666666; } @@ -1418,35 +1553,39 @@ fieldset dl:hover dt label { } fieldset dl dd label:hover { - color: #BC2A4D; + color: #bc2a4d; } -input:focus, textarea:focus { - border: 1px solid #BC2A4D; - background-color: #E9E9E2; - color: #BC2A4D; +input:focus, +textarea:focus { + background-color: #e9e9e2; + border: 1px solid #bc2a4d; outline-style: none; + color: #bc2a4d; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { fieldset dl { + border-bottom: 1px solid #e8e8e8; margin-bottom: 5px; padding-bottom: 5px; - border-bottom: 1px solid #e8e8e8; } - fieldset > dl:last-child, fieldset > form:last-child > dl:last-child { + fieldset > dl:last-child, + fieldset > form:last-child > dl:last-child { border-bottom-width: 0; margin-bottom: 0; } - fieldset dt, .rtl fieldset dt, fieldset dd, .rtl fieldset dd { + fieldset dt, + .rtl fieldset dt, + fieldset dd, + .rtl fieldset dd { border-width: 0; - margin-left: 0; - margin-right: 0; float: none; width: auto; + margin-right: 0; + margin-left: 0; } fieldset .responsive-columns dt { @@ -1461,18 +1600,22 @@ input:focus, textarea:focus { padding-right: 20px; } - select, dd select, dd input { + select, + dd select, + dd input { max-width: 300px; } - input[type="number"], dd input[type="number"] { + input[type="number"], + dd input[type="number"] { max-width: 70px; } } -@media only screen and (max-width: 400px), only screen and (max-device-width: 400px) -{ - select, dd select, dd input { +@media only screen and (max-width: 400px), only screen and (max-device-width: 400px) { + select, + dd select, + dd input { max-width: 240px; } } @@ -1481,21 +1624,22 @@ input:focus, textarea:focus { ---------------------------------------- */ fieldset.submit-buttons { text-align: center; - border: none; background-color: transparent; + border: none; margin: 0; - padding: 4px; margin-top: -1px; + padding: 4px; } p.submit-buttons { text-align: center; margin: 0; - padding: 4px; margin-top: 10px; + padding: 4px; } -fieldset.submit-buttons input, p.submit-buttons input { +fieldset.submit-buttons input, +p.submit-buttons input { padding: 3px 2px; } @@ -1503,8 +1647,7 @@ fieldset.submit-buttons legend { display: none; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { p.submit-buttons { margin-top: 0; } @@ -1512,11 +1655,12 @@ fieldset.submit-buttons legend { /* Input field styles ---------------------------------------- */ - -input.radio, input.checkbox, input.permissions-checkbox { - width: auto !important; +input.radio, +input.checkbox, +input.permissions-checkbox { background-color: transparent; border: none; + width: auto !important; cursor: pointer; } @@ -1525,49 +1669,75 @@ textarea.full { width: 99%; } -input.medium { width: 50%;} -input.narrow { width: 25%;} -input.tiny { width: 10%;} -input.autowidth { width: auto !important;} -.box2 .inputbox { background-color: #E9E9E9;} +input.medium { + width: 50%; +} + +input.narrow { + width: 25%; +} + +input.tiny { + width: 10%; +} + +input.autowidth { + width: auto !important; +} + +.box2 .inputbox { + background-color: #e9e9e9; +} /* Form button styles ---------------------------------------- */ -a.button1, input.button1, -a.button2, input.button2 { - width: auto !important; - padding: 1px 3px 0 3px; +a.button1, +input.button1, +a.button2, +input.button2 { font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; - color: #000; font-size: 0.85em; - background: #EFEFEF url("../images/bg_button.gif") repeat-x top; + background: #efefef url("../images/bg_button.gif") repeat-x top; + color: #000000; + width: auto !important; + padding: 1px 3px 0; cursor: pointer; } -a.button1, input.button1 { +a.button1, +input.button1 { font-weight: bold; border: 1px solid #666666; } /* Alternative button */ -a.button2, input.button2 { +a.button2, +input.button2 { border: 1px solid #666666; } /* button in the style of the form buttons */ -a.button1, a.button1:link, a.button1:visited, a.button1:active, -a.button2, a.button2:link, a.button2:visited, a.button2:active { +a.button1, +a.button1:link, +a.button1:visited, +a.button1:active, +a.button2, +a.button2:link, +a.button2:visited, +a.button2:active { text-decoration: none; color: #000000; padding: 4px 8px; } /* Hover states */ -a.button1:hover, input.button1:hover, -a.button2:hover, input.button2:hover { - border: 1px solid #BC2A4D; - background: #EFEFEF url("../images/bg_button.gif") repeat bottom; - color: #BC2A4D; +a.button1:hover, +input.button1:hover, +a.button2:hover, +input.button2:hover { + background: #efefef url("../images/bg_button.gif") repeat bottom; + border: 1px solid #bc2a4d; + color: #bc2a4d; } input.disabled { @@ -1576,43 +1746,44 @@ input.disabled { } /* Focus states */ -input.button1:focus, input.button2:focus { +input.button1:focus, +input.button2:focus { outline-style: none; } /* jQuery popups ---------------------------------------- */ .phpbb_alert { - background-color: #FFFFFF; + background-color: #ffffff; border: 1px solid #999999; position: fixed; - display: none; + z-index: 50; top: 150px; - left: 0; right: 0; + left: 0; + display: none; width: 620px; margin: 0 auto; - z-index: 50; padding: 25px; - padding: 0 25px 20px 25px; + padding: 0 25px 20px; } .phpbb_alert .alert_close { + text-decoration: none !important; + background: transparent url("../images/alert_close.png") 0 0 no-repeat; display: block; float: right; + overflow: hidden; width: 16px; height: 16px; - overflow: hidden; - text-decoration: none !important; - background: transparent url("../images/alert_close.png") 0 0 no-repeat; margin-top: -7px; margin-right: -31px; } + .phpbb_alert .alert_close:hover { background-position: 0 -16px; } - .phpbb_alert p { margin: 8px 0; padding-bottom: 8px; @@ -1633,65 +1804,123 @@ input.button1:focus, input.button2:focus { } #darkenwrapper { - display: none; position: relative; z-index: 44; + display: none; } #darken { + background-color: #000000; + opacity: 0.5; position: fixed; - left: 0; + z-index: 45; top: 0; + left: 0; width: 100%; height: 100%; - background-color: #000000; - opacity: 0.5; - z-index: 45; } -@media only screen and (max-height: 500px), only screen and (max-device-width: 500px) -{ +@media only screen and (max-height: 500px), only screen and (max-device-width: 500px) { .phpbb_alert { top: 25px; } } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { .phpbb_alert { width: auto; margin: 0 25px; } } -#loading_indicator { - background: #000000 url("../images/loading.gif") center center no-repeat; - border-radius: 5px; - display: none; - opacity: 0.8; - margin-top: -50px; - margin-left: -50px; - height: 50px; - width: 50px; +.loading_indicator { position: fixed; - left: 50%; - top: 50%; z-index: 51; + top: 50%; + left: 50%; + display: none; +} + +.loader { + width: 48px; + height: 48px; + padding: 12px; +} + +.spinner { + animation: rotator 1s linear infinite; +} + +.spinner-path { + transform-origin: center; + animation: dash 1s ease-in-out infinite, colors 4s ease-in-out infinite; + stroke-dasharray: 187; + stroke-dashoffset: 0; +} + +@keyframes rotator { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(270deg); + } +} + +@keyframes dash { + 0% { + stroke-dashoffset: 187; + } + + 50% { + transform: rotate(135deg); + stroke-dashoffset: 46.75; + } + + 100% { + transform: rotate(450deg); + stroke-dashoffset: 187; + } +} + +@keyframes colors { + 0% { + stroke: #4285f4; + } + + 25% { + stroke: #de3e35; + } + + 50% { + stroke: #f7c223; + } + + 75% { + stroke: #1b9a59; + } + + 100% { + stroke: #4285f4; + } } /* Pagination ---------------------------------------- */ .pagination { - font-size: .85em; - height: 1%; /* IE tweak (holly hack) */ + font-size: 0.85em; + text-align: right; + + /* IE tweak (holly hack) */ width: auto; - text-align: right; + height: 1%; margin: 5px 0; } .top-pagination { float: right; - margin: 15px 0 5px 0; + margin: 15px 0 5px; } .rtl .pagination { @@ -1709,71 +1938,85 @@ li.pagination { .pagination ul { display: inline-block; - *display: inline; /* IE7 inline-block hack */ + *display: inline; + + /* IE7 inline-block hack */ *zoom: 1; - margin-left: 0; margin-bottom: 0; + margin-left: 0; } li.pagination ul { - margin-top: -2px; vertical-align: middle; + margin-top: -2px; } -.pagination ul li, dl .pagination ul li, dl.icon .pagination ul li { - display: inline; - padding: 0; +.pagination ul li, +dl .pagination ul li, +dl.icon .pagination ul li { font-size: 100%; line-height: normal; + display: inline; + padding: 0; } -.pagination li a, .pagnation li span, li .pagination li a, li .pagnation li span, .pagination li.active span, .pagination li.ellipsis span { +.pagination li a, +.pagnation li span, +li .pagination li a, +li .pagnation li span, +.pagination li.active span, +.pagination li.ellipsis span { + font-size: 0.9em; font-weight: normal; + line-height: 1.5em; text-decoration: none; - padding: 0 2px; border: 1px solid transparent; - font-size: 0.9em; - line-height: 1.5em; + padding: 0 2px; } -.pagination li a, .pagination li a:link, .pagination li a:visited { - color: #5C758C; - background-color: #ECEDEE; - border-color: #B4BAC0; +.pagination li a, +.pagination li a:link, +.pagination li a:visited { + background-color: #ecedee; + border-color: #b4bac0; + color: #5c758c; } -.pagination li.ellipsis span { +.pagination li.ellipsis span { background-color: transparent; color: #000000; } .pagination li.active span { - color: #FFFFFF; - background-color: #4692BF; - border-color: #4692BF; + background-color: #4692bf; + border-color: #4692bf; + color: #ffffff; } -.pagination li a:hover, .pagination .active a:hover { - color: #FFFFFF; - background-color: #368AD2; - border-color: #368AD2; +.pagination li a:hover, +.pagination .active a:hover { + background-color: #368ad2; + border-color: #368ad2; + color: #ffffff; } -.pagination li a:active, .pagination li.active a:active { - color: #5C758C; - background-color: #ECEDEE; - border-color: #B4BAC0; +.pagination li a:active, +.pagination li.active a:active { + background-color: #ecedee; + border-color: #b4bac0; + color: #5c758c; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ - .pagination, .rtl .pagination { - float: none; +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { + .pagination, + .rtl .pagination { text-align: center; + float: none; margin: 5px 0; } - .pagination li a, .pagination li span { + .pagination li a, + .pagination li span { display: inline-block; min-width: 10px; } @@ -1781,12 +2024,14 @@ li.pagination ul { /* Action Highlighting ---------------------------------------- */ -.successbox, .errorbox, .warningbox { - padding: 8px; - margin: 10px 0; - color: #FFFFFF; +.successbox, +.errorbox, +.warningbox { text-align: center; + color: #ffffff; clear: both; + margin: 10px 0; + padding: 8px; } .success { @@ -1794,7 +2039,7 @@ li.pagination ul { } .error { - color: #BC2A4D; + color: #bc2a4d; } .successbox { @@ -1802,52 +2047,59 @@ li.pagination ul { } .errorbox { - background-color: #BC2A4D; + background-color: #bc2a4d; } .warningbox { background-color: #fca600; } -.successbox h3, .errorbox h3 { - color: #FFFFFF; +.successbox h3, +.errorbox h3 { + font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; + font-size: 1.1em; + color: #ffffff; margin: 0 0 0.5em; - font-size: 1.10em; - font-family: "Lucida Grande",Verdana,Helvetica,Arial,sans-serif; } -.successbox p, .errorbox p { - color: #FFFFFF; +.successbox p, +.errorbox p { font-size: 0.85em; + color: #ffffff; margin-bottom: 0; } -.errorbox a:link, .errorbox a:active, .errorbox a:visited, -.successbox a:link, .successbox a:active, .successbox a:visited { - color: #DBD7D1; - text-decoration: underline; +.errorbox a:link, +.errorbox a:active, +.errorbox a:visited, +.successbox a:link, +.successbox a:active, +.successbox a:visited { font-weight: bold; + text-decoration: underline; + color: #dbd7d1; } -.errorbox a:hover, .successbox a:hover { - color: #FFFFFF; - text-decoration: none; +.errorbox a:hover, +.successbox a:hover { font-weight: bold; + text-decoration: none; + color: #ffffff; } #log-container { + background-color: #ffffff; display: none; - max-height: 300px; - padding: 8px; - margin: 10px 0; clear: both; overflow-y: auto; - background-color: #FFFFFF; + max-height: 300px; + margin: 10px 0; + padding: 8px; } #log-container.show_log_container { + border: 1px solid #dbd7d1; display: block; - border: 1px solid #DBD7D1; } .log { @@ -1855,11 +2107,11 @@ li.pagination ul { } .notice { - background-color: #62A5CC; + background-color: #62a5cc; } .download-box { - margin: 10px 0 10px 0; + margin: 10px 0; } /* Special cases for the error page */ @@ -1873,61 +2125,63 @@ li.pagination ul { } #errorpage #content h1 { - color: #DF075C; + color: #df075c; } #errorpage #content h2 { + border-bottom: 1px solid #cccccc; + color: #333333; margin-top: 20px; margin-bottom: 5px; - border-bottom: 1px solid #CCCCCC; padding-bottom: 5px; - color: #333333; } /* Tooltip for permission roles */ .tooltip { - width: 200px; - color: #000; text-align: center; - border: 1px solid #AAA; + border: 1px solid #aaaaaa; + color: #000000; + width: 200px; } .tooltip span.top { - background: #EFEFEF; font-weight: bold; + background: #efefef; padding: 2px; } .tooltip span.bottom { - padding: 5px; + background: #ffffff; color: #000000; - background: #FFFFFF; + padding: 5px; } /* Format Buttons for signature editor */ #format-buttons { - margin: 15px 0 2px 0; + margin: 15px 0 2px; } -#format-buttons input, #format-buttons select { +#format-buttons input, +#format-buttons select { vertical-align: middle; } -.row, fieldset dl { +.row, +fieldset dl { overflow: hidden; } /* Syntax Highlighting ---------------------------------------- */ .sourcenum { - color: gray; - font-family: Monaco, 'Courier New', monospace; + font-family: Monaco, "Courier New", monospace; font-size: 1.25em; font-weight: bold; - line-height: 1.20em; + line-height: 1.2em; text-align: right; + color: #808080; padding: 0; } @@ -1936,22 +2190,22 @@ li.pagination ul { } .source { - font-family: Monaco, 'Courier New', monospace; + font-family: Monaco, "Courier New", monospace; font-size: 1.25em; - line-height: 1.20em; + line-height: 1.2em; padding: 0; } .syntaxbg { - color: #FFFFFF; + color: #ffffff; } .syntaxcomment { - color: #FF8000; + color: #ff8000; } .syntaxdefault { - color: #0000BB; + color: #0000bb; } .syntaxhtml { @@ -1963,18 +2217,19 @@ li.pagination ul { } .syntaxstring { - color: #DD0000; + color: #dd0000; } /* Permission interface ---------------------------------------- */ - -.column1, .column2 { - width: 48%; +.column1, +.column2 { float: left; + width: 48%; } -.ltr .column2, .rtl .column1 { +.ltr .column2, +.rtl .column1 { float: right; } @@ -1982,7 +2237,7 @@ fieldset.permissions legend { text-transform: none; } -fieldset.permissions legend input{ +fieldset.permissions legend input { height: 1.1em; } @@ -1997,14 +2252,14 @@ fieldset.permissions .permissions-simple { } fieldset.permissions .permissions-advanced { - padding: 10px 0 0 5px; vertical-align: top; clear: right; + padding: 10px 0 0 5px; } .rtl fieldset.permissions .permissions-advanced { - padding: 10px 5px 0 0; clear: left; + padding: 10px 5px 0 0; } fieldset.permissions .permissions-switch { @@ -2015,12 +2270,9 @@ fieldset.permissions .permissions-switch { float: left; } -fieldset.permissions .padding { -} - .permissions-switch { + font-size: 0.9em; margin-top: -6px; - font-size: .9em; } .permissions-switch a { @@ -2032,15 +2284,15 @@ fieldset.permissions .padding { } .permissions-reset a { - font-size: .85em; + font-size: 0.85em; } /* Tabbed menu */ .permissions-category { + font-size: 0.85em; line-height: normal; - margin: 0 0 -1px 7px; min-width: 570px; - font-size: 0.85em; + margin: 0 0 -1px 7px; } .rtl .permissions-category { @@ -2054,20 +2306,20 @@ fieldset.permissions .padding { } .permissions-category li { + font-size: 1em; + font-weight: bold; display: inline; margin: 0; padding: 0; - font-size: 1em; - font-weight: bold; } .permissions-category a { - float: left; + text-decoration: none; background: url("../images/bg_tabs_alt1.gif") no-repeat 0% -35px; + position: relative; + float: left; margin: 0 1px 0 0; padding: 0 0 0 6px; - text-decoration: none; - position: relative; } .rtl .permissions-category a { @@ -2075,24 +2327,28 @@ fieldset.permissions .padding { } .permissions-category a span.tabbg { - float: left; - display: block; + white-space: nowrap; background: url("../images/bg_tabs_alt2.gif") no-repeat 100% -35px; - padding: 7px 12px 6px 6px; color: #536482; - white-space: nowrap; + display: block; + float: left; + padding: 7px 12px 6px 6px; } .rtl .permissions-category a span.tabbg { float: right; } -/* Commented Backslash Hack hides rule from IE5-Mac \*/ -.permissions-category a span.tabbg, .rtl .permissions-category a span.tabbg { float: none;} -/* End hack */ +/* Commented Backslash Hack hides rule from IE5-Mac \ */ +.permissions-category a span.tabbg, +.rtl .permissions-category a span.tabbg { + float: none; +} +/* End hack */ .permissions-category a:hover span.tabbg { - color: #DD6900; + background-position: 100% -70px; + color: #dd6900; } .permissions-category .activetab a { @@ -2101,21 +2357,17 @@ fieldset.permissions .padding { .permissions-category .activetab a span.tabbg { background-position: 100% 0; - padding-bottom: 7px; color: #333333; + padding-bottom: 7px; } .permissions-category a:hover { background-position: 0 -70px; } -.permissions-category a:hover span.tabbg { - background-position: 100% -70px; -} - .permissions-category .activetab a:hover span.tabbg { - color: #333333; background-position: 100% 0; + color: #333333; } .permissions-category .activetab a:hover { @@ -2137,13 +2389,12 @@ fieldset.permissions .padding { margin: 0 0 0 5px; } */ - .permissions-category .activetab span.colour { border-color: #333333; } .permissions-category a:hover span.colour { - border-color: #DD6900; + border-color: #dd6900; } .permissions-category .activetab a:hover span.colour { @@ -2153,30 +2404,30 @@ fieldset.permissions .padding { /* Permission preset colours */ .permissions-preset-yes span.colour, .yes { - background-color: #86F786; + background-color: #86f786; } .permissions-preset-custom span.colour { - background-color: #B2BBDD; + background-color: #b2bbdd; } .permissions-preset-never span.colour { - background-color: #DD0000; + background-color: #dd0000; } .permissions-preset-no span.colour, .never { - background-color: #EFB0B2; + background-color: #efb0b2; } /* Permission panel ---------------------------------------- */ .permissions-panel { - float: left; - background-color: #CADCEB; - width: 100%; + background-color: #cadceb; border-radius: 5px; + float: left; overflow: hidden; + width: 100%; padding: 5px 0; } @@ -2204,8 +2455,8 @@ fieldset.permissions .padding { .permissions-panel th.name { text-align: left; - width: auto; text-transform: none; + width: auto; } .rtl .permissions-panel th.name { @@ -2213,9 +2464,9 @@ fieldset.permissions .padding { } .permissions-panel th.permissions-name { + font-weight: normal; border: none; color: #536482; - font-weight: normal; } .permissions-panel th.permissions-name a.trace { @@ -2223,41 +2474,43 @@ fieldset.permissions .padding { } .permissions-panel th.row3 { + background-color: #d1d7dc; background-image: none; - background-color: #D1D7DC; - color: #536482; border: none; + color: #536482; } .permissions-panel th.row4 { + background-color: #e4e8eb; background-image: none; - background-color: #E4E8EB; - color: #536482; border: none; + color: #536482; } -.permissions-panel th a:link, .permissions-panel th a:hover, .permissions-panel th a:visited { - display: block; - color: #FFFFFF; +.permissions-panel th a:link, +.permissions-panel th a:hover, +.permissions-panel th a:visited { text-decoration: underline; + color: #ffffff; + display: block; } .permissions-panel td.permissions-yes label:hover { - background-color: #86F786; + background-color: #86f786; } .permissions-panel td.permissions-no label:hover { - background-color: #EFB0B2; + background-color: #efb0b2; } .permissions-panel td.permissions-never label:hover { - background-color: #DD0000; + background-color: #dd0000; } .permissions-panel td { - padding: 0; text-align: center; width: 10%; + padding: 0; } .permissions-panel td label { @@ -2266,9 +2519,9 @@ fieldset.permissions .padding { padding: 0; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ - .column1, .column2 { +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { + .column1, + .column2 { float: none !important; width: auto; } @@ -2277,10 +2530,11 @@ fieldset.permissions .padding { clear: both; } - .permissions-simple td, .permissions-simple dd { + .permissions-simple td, + .permissions-simple dd { width: auto !important; - margin-left: 0 !important; margin-right: 0 !important; + margin-left: 0 !important; } .permissions-simple dd { @@ -2296,23 +2550,24 @@ fieldset.permissions .padding { margin: 0 !important; } - .permissions-category a, .permissions-category a span.tabbg { + .permissions-category a, + .permissions-category a span.tabbg { + background: transparent none; display: block; float: none !important; - background: transparent none; } .permissions-category a { + text-decoration: underline; background: #d9e5ee; + border-radius: 3px; margin: 5px 0; padding: 0 !important; - border-radius: 3px; - text-decoration: underline; } .permissions-category .activetab a { background-color: #dd6900; - color: #fff; + color: #ffffff; } .permissions-category a span.tabbg { @@ -2322,7 +2577,7 @@ fieldset.permissions .padding { } .permissions-category .activetab span.colour { - border-color: #fff; + border-color: #ffffff; } } @@ -2330,40 +2585,40 @@ fieldset.permissions .padding { ---------------------------------------- */ #gallery { display: block; + overflow: hidden; margin: 0 -5px; padding: 0; - overflow: hidden; } #gallery li { + background: #ffffff; + border: 1px solid #cccccc; + border-radius: 2px; display: block; float: left; - border: 1px solid #ccc; - border-radius: 2px; - background: #fff; - padding: 5px; margin: 5px; + padding: 5px; } #gallery li:hover { - background-color: #eee; + background-color: #eeeeee; } #gallery li label { - display: block; text-align: center; + display: block; padding: 0; } /* Dropdown menu -----------------------------------------*/ +---------------------------------------- */ .dropdown { - position: absolute; - left: 0; - top: 22px; - z-index: 2; border: 1px solid transparent; border-radius: 5px; + position: absolute; + z-index: 2; + top: 22px; + left: 0; padding: 9px 0 0; } @@ -2374,78 +2629,74 @@ fieldset.permissions .padding { } .dropdown-left .dropdown { - left: auto; right: 0; + left: auto; } -.dropdown .pointer, .dropdown .pointer-inner { - position: absolute; - width: 0; - height: 0; +.dropdown .pointer, +.dropdown .pointer-inner { border-top-width: 0; + border-right: 10px dashed transparent; border-bottom: 10px solid transparent; border-left: 10px dashed transparent; - border-right: 10px dashed transparent; - -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */ + position: absolute; + + /* better anti-aliasing in webkit */ display: block; + width: 0; + height: 0; + -webkit-transform: rotate(360deg); } -.dropdown-up .pointer, .dropdown-up .pointer-inner { - border-bottom-width: 0; +.dropdown-up .pointer, +.dropdown-up .pointer-inner { border-top: 10px solid transparent; + border-bottom-width: 0; } .dropdown .pointer { + border-color: #b9b9b9 transparent; + z-index: 3; + top: 0; right: auto; left: 10px; - top: 0; - z-index: 3; } .dropdown-up .pointer { - bottom: 0; top: auto; + bottom: 0; } .dropdown-left .dropdown .pointer { - left: auto; right: 10px; + left: auto; } .dropdown .pointer-inner { + border-color: #ffffff transparent; top: auto; bottom: -11px; left: -10px; } .dropdown-up .pointer-inner { - bottom: auto; top: -11px; -} - -.dropdown .pointer { - border-color: #B9B9B9 transparent; -} - -.dropdown .pointer-inner { - border-color: #FFF transparent; + bottom: auto; } .dropdown .dropdown-contents { - z-index: 2; - overflow: hidden; - overflow-y: auto; - background: #fff; + background: #ffffff; border: 1px solid #b9b9b9; border-radius: 5px; - padding: 5px; + box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2); position: relative; + z-index: 2; + overflow: hidden; + overflow-y: auto; + box-sizing: border-box; min-width: 40px; max-height: 200px; - box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + padding: 5px; } .dropdown-up .dropdown-contents { @@ -2453,26 +2704,29 @@ fieldset.permissions .padding { } .dropdown li { + text-align: left; + white-space: nowrap; float: none; margin: 0; - white-space: nowrap; - text-align: left; } .rtl .dropdown li { text-align: right; } -.wrap .dropdown li, .dropdown.wrap li { + +.wrap .dropdown li, +.dropdown.wrap li { white-space: normal; } -.dropdown li:before, .dropdown li:after { +.dropdown li:before, +.dropdown li:after { display: none !important; } .roles-options > .dropdown { - left: auto; top: 3.2em; + left: auto; width: 250px; } @@ -2481,25 +2735,25 @@ fieldset.permissions .padding { } .roles-options { + width: 250px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; - width: 250px; } .roles-options > span { - border: 1px solid #DEDEDE; + background: url("../images/arrow_down.gif") no-repeat 245px 0.7em; + border: 1px solid #dedede; border-radius: 3px; - padding: 4px; - width: 250px; display: none; - background: url('../images/arrow_down.gif') no-repeat 245px .7em; + width: 250px; + padding: 4px; } .rtl .roles-options > span { - background: url('../images/arrow_down.gif') no-repeat 7px .7em; + background: url("../images/arrow_down.gif") no-repeat 7px 0.7em; } .roles-options li { @@ -2508,19 +2762,17 @@ fieldset.permissions .padding { .roles-highlight { background-color: #1e90ff; - color: #fff; + color: #ffffff; } - /* Classes for additional tasks ---------------------------------------- */ - .current-ext { color: #228822; } .outdated-ext { - color: #BC2A4D; + color: #bc2a4d; } .phpinfo { @@ -2529,26 +2781,40 @@ fieldset.permissions .padding { direction: ltr; } -.phpinfo td, .phpinfo th, .phpinfo h2, .phpinfo h1 { +.phpinfo td, +.phpinfo th, +.phpinfo h2, +.phpinfo h1 { text-align: left; } .requirements_not_met { + background-color: #bc2a4d; padding: 5px; - background-color: #BC2A4D; } -.requirements_not_met dt label, .requirements_not_met dd p { - color: #FFFFFF; +.requirements_not_met dt label, +.requirements_not_met dd p { font-size: 1.4em; + color: #ffffff; } -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ - .responsive-hide { display: none !important; } - .responsive-show { display: block !important; } - .responsive-show-inline { display: inline !important; } - .responsive-show-inline-block { display: inline-block !important; } +@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) { + .responsive-hide { + display: none !important; + } + + .responsive-show { + display: block !important; + } + + .responsive-show-inline { + display: inline !important; + } + + .responsive-show-inline-block { + display: inline-block !important; + } } .clearfix { @@ -2563,42 +2829,42 @@ fieldset.permissions .padding { #tabs li:after, #acp:after, #content:after { - content: ''; - clear: both; display: block; + clear: both; + content: ""; } #progress-bar { + text-align: center; + border: 1px solid #cecece; position: relative; width: 90%; - text-align: center; height: 25px; margin: 20px auto; - border: 1px solid #cecece; } #progress-bar #progress-bar-text { + color: #000000; position: absolute; top: 0; width: 100%; - color: #000; } #progress-bar #progress-bar-filler { - display: block; + background-color: #3c84ad; + color: #ffffff; position: relative; top: 0; left: 0; - background-color: #3c84ad; + display: block; + overflow: hidden; width: 0; height: 25px; - overflow: hidden; - color: #fff; } #progress-bar p { - line-height: 25px; font-weight: bold; + line-height: 25px; } .send-stats-row { @@ -2611,18 +2877,18 @@ fieldset.permissions .padding { } .send-stats-tile { - position: relative; - padding: 14px; - margin-bottom: 20px; background-color: #eff0f2; border-radius: 6px; - box-shadow: rgba(0,0,0,0.3) 1px 1px 5px; + box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 5px; + position: relative; + margin-bottom: 20px; + padding: 14px; } .send-stats-tile h2 { - margin-top: 0; text-align: center; - padding-bottom: 1em; + margin-top: 0; + padding-bottom: 1em; } .send-stats-tile i { @@ -2636,12 +2902,12 @@ fieldset.permissions .padding { .send-stats-data-row { background: #f9f9f9; - border-radius: 6px; - border: #DEDEDE 1px solid; - padding: 10px; + border: #dedede 1px solid; border-top-width: 0; - border-top-right-radius: 0; + border-radius: 6px; border-top-left-radius: 0; + border-top-right-radius: 0; + padding: 10px; } .send-stats-data-hidden .configlist { @@ -2649,26 +2915,27 @@ fieldset.permissions .padding { } .send-stats-data-only-row { - border-radius: 6px !important; border-bottom-width: 1px !important; + border-radius: 6px !important; } .send-stats-data-hidden { - padding: 0; border: none; + padding: 0; } .send-stats-row > .send-stats-data-row:first-child { background-color: #d9edf7; + border-top-width: 1px; border-bottom-width: 0; - border-top-right-radius: 6px; border-top-left-radius: 6px; - border-top-width: 1px; - border-bottom-left-radius: 0; + border-top-right-radius: 6px; border-bottom-right-radius: 0; + border-bottom-left-radius: 0; } -.send-stats-settings dt, .send-stats-settings dd { +.send-stats-settings dt, +.send-stats-settings dd { min-width: 25px; } @@ -2680,15 +2947,15 @@ fieldset.permissions .padding { display: none; } -.send-stats-settings input[type=checkbox] + label:before { - content: "\f096"; +.send-stats-settings input[type="checkbox"] + label:before { font-family: FontAwesome; font-size: 1.5em; + content: "\f096"; } -.send-stats-settings input[type=checkbox]:checked + label:before { - content: "\f14a"; +.send-stats-settings input[type="checkbox"]:checked + label:before { color: #3c763d; + content: "\f14a"; } .send-stats-data-row a:hover span { @@ -2709,11 +2976,23 @@ fieldset.permissions .padding { word-break: break-all; } -/* stylelint-disable declaration-property-unit-whitelist */ + .emoji { - min-height: 18px; + width: 1em; min-width: 18px; height: 1em; - width: 1em; + min-height: 18px; +} + +.console-output { + font-family: monospace; + background-color: #2a2a2a; + color: #f1f1f1; + overflow-x: scroll; } + +/* stylelint-enable selector-max-id */ +/* stylelint-enable selector-max-compound-selectors */ +/* stylelint-enable selector-no-qualifying-type */ +/* stylelint-enable declaration-property-unit-blacklist */ /* stylelint-enable declaration-property-unit-whitelist */ diff --git a/phpBB/adm/style/detailed_message_body.html b/phpBB/adm/style/detailed_message_body.html new file mode 100644 index 00000000000..bc904d7eb62 --- /dev/null +++ b/phpBB/adm/style/detailed_message_body.html @@ -0,0 +1,14 @@ + + +
+

{{ MESSAGE_TITLE }}

+

{{ MESSAGE_TEXT }}

+
+ +
+
+
{{ MESSAGE_DETAIL }}
+
+
+ + diff --git a/phpBB/adm/style/overall_footer.html b/phpBB/adm/style/overall_footer.html index 8745286d64e..048254f283e 100644 --- a/phpBB/adm/style/overall_footer.html +++ b/phpBB/adm/style/overall_footer.html @@ -20,7 +20,14 @@
 
-
+
+
+ + {L_LOADING} + + +
+
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index bd1925baf62..726048bfb02 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -27,11 +27,7 @@ phpbb.isTouch = (window && typeof window.ontouchstart !== 'undefined'); */ phpbb.loadingIndicator = function() { if (!$loadingIndicator) { - $loadingIndicator = $('
', { - 'id': 'loading_indicator', - 'class': 'loading_indicator' - }); - $loadingIndicator.appendTo('#page-footer'); + $loadingIndicator = $('#loading_indicator'); } if (!$loadingIndicator.is(':visible')) { diff --git a/phpBB/bin/phpbbcli.php b/phpBB/bin/phpbbcli.php index 3061fee817e..4a3253af717 100755 --- a/phpBB/bin/phpbbcli.php +++ b/phpBB/bin/phpbbcli.php @@ -71,6 +71,11 @@ register_compatibility_globals(); +if (@is_file($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php')) +{ + require_once($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php'); +} + /** @var \phpbb\language\language $language */ $language = $phpbb_container->get('language'); $language->set_default_language($phpbb_container->get('config')['default_lang']); diff --git a/phpBB/common.php b/phpBB/common.php index 172503f0783..7ace4cf12ac 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -65,8 +65,7 @@ // Eliminate . and .. from the path require($phpbb_root_path . 'phpbb/filesystem.' . $phpEx); - $phpbb_filesystem = new phpbb\filesystem\filesystem(); - $script_path = $phpbb_filesystem->clean_path($script_path); + $script_path = \phpbb\filesystem\helper::clean_path($script_path); $url = (($secure) ? 'https://' : 'http://') . $server_name; @@ -136,6 +135,11 @@ register_compatibility_globals(); +if (@is_file($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php')) +{ + require_once($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php'); +} + // Add own hook handler require($phpbb_root_path . 'includes/hooks/index.' . $phpEx); $phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display'))); diff --git a/phpBB/composer-ext.json b/phpBB/composer-ext.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/phpBB/composer-ext.lock b/phpBB/composer-ext.lock new file mode 100644 index 00000000000..e69de29bb2d diff --git a/phpBB/composer.json b/phpBB/composer.json index 4f796a9dcb2..04e73a2c83b 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -25,51 +25,52 @@ "phpbb/phpbb-core": "self.version" }, "require": { - "php": ">=5.4", + "php": ">=5.6", "bantu/ini-get-wrapper": "1.0.*", + "composer/composer": "^1.6", + "composer/installers": "^1.4", "google/recaptcha": "~1.1", - "guzzlehttp/guzzle": "~5.3", + "guzzlehttp/guzzle": "~6.3", "lusitanian/oauth": "^0.8.1", "marc1706/fast-image-size": "^1.1", "paragonie/random_compat": "^1.4", "patchwork/utf8": "^1.1", "s9e/text-formatter": "~0.13.0", - "symfony/config": "^2.8", - "symfony/console": "^2.8", - "symfony/debug": "^2.8", - "symfony/dependency-injection": "^2.8", - "symfony/event-dispatcher": "^2.8", - "symfony/filesystem": "^2.8", - "symfony/finder": "^2.8", - "symfony/http-foundation": "^2.8", - "symfony/http-kernel": "^2.8", - "symfony/proxy-manager-bridge": "^2.8", - "symfony/routing": "^2.8", - "symfony/twig-bridge": "^2.8", - "symfony/yaml": "^2.8", + "symfony/config": "~3.1", + "symfony/console": "~3.1", + "symfony/debug": "~3.1", + "symfony/dependency-injection": "~3.1", + "symfony/event-dispatcher": "~3.1", + "symfony/filesystem": "~3.1", + "symfony/finder": "~3.1", + "symfony/http-foundation": "~3.1", + "symfony/http-kernel": "~3.1", + "symfony/proxy-manager-bridge": "~3.1", + "symfony/routing": "~3.1", + "symfony/twig-bridge": "~3.1", + "symfony/yaml": "~3.1", "twig/twig": "^1.0" }, "require-dev": { - "fabpot/goutte": "~2.0", + "fabpot/goutte": "~3.1", "facebook/webdriver": "~1.1", - "laravel/homestead": "~2.2", + "laravel/homestead": "~4.0", "phing/phing": "2.4.*", - "phpunit/dbunit": "1.3.*", - "phpunit/phpunit": "^4.1", - "sami/sami": "1.*", + "phpunit/dbunit": "~2.0", + "phpunit/phpunit": "^5.7", "squizlabs/php_codesniffer": "2.*", - "symfony/browser-kit": "^2.8", - "symfony/css-selector": "^2.8", - "symfony/dom-crawler": "^2.8" + "symfony/browser-kit": "~3.1", + "symfony/css-selector": "~3.1", + "symfony/dom-crawler": "~3.1" }, "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-master": "3.3.x-dev" } }, "config": { "platform": { - "php": "5.4.7" + "php": "5.6" } } } diff --git a/phpBB/composer.lock b/phpBB/composer.lock index 5b948eddc1f..cb98ab14094 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "620519ab8cf439078c08f8a4fb49efb8", - "content-hash": "c843abc1344cd9df37f63c08a125cad0", + "content-hash": "8679db725dd0df075765f914b01a8ab9", "packages": [ { "name": "bantu/ini-get-wrapper", @@ -35,27 +34,403 @@ "MIT" ], "description": "Convenience wrapper around ini_get()", - "time": "2014-09-15 13:12:35" + "time": "2014-09-15T13:12:35+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "943b2c4fcad1ef178d16a713c2468bf7e579c288" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/943b2c4fcad1ef178d16a713c2468bf7e579c288", + "reference": "943b2c4fcad1ef178d16a713c2468bf7e579c288", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2017-11-29T09:37:33+00:00" + }, + { + "name": "composer/composer", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "db191abd24b0be110c98ba2271ca992e1c70962f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/db191abd24b0be110c98ba2271ca992e1c70962f", + "reference": "db191abd24b0be110c98ba2271ca992e1c70962f", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.2", + "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/cli-prompt": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7", + "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2018-01-05T14:28:42+00:00" + }, + { + "name": "composer/installers", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "049797d727261bf27f2690430d935067710049c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/049797d727261bf27f2690430d935067710049c2", + "reference": "049797d727261bf27f2690430d935067710049c2", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "phpunit/phpunit": "^4.8.36" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "time": "2017-12-29T09:13:20+00:00" + }, + { + "name": "composer/semver", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2016-08-30T16:08:34+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "2d899e9b33023c631854f36c39ef9f8317a7ab33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/2d899e9b33023c631854f36c39ef9f8317a7ab33", + "reference": "2d899e9b33023c631854f36c39ef9f8317a7ab33", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2018-01-03T16:37:06+00:00" }, { "name": "google/recaptcha", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/google/recaptcha.git", - "reference": "2b7e00566afca82a38a1d3adb8e42c118006296e" + "reference": "5a56d15ca10a7b75158178752b2ad8f755eb4f78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/google/recaptcha/zipball/2b7e00566afca82a38a1d3adb8e42c118006296e", - "reference": "2b7e00566afca82a38a1d3adb8e42c118006296e", + "url": "https://api.github.com/repos/google/recaptcha/zipball/5a56d15ca10a7b75158178752b2ad8f755eb4f78", + "reference": "5a56d15ca10a7b75158178752b2ad8f755eb4f78", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "4.5.*" + "phpunit/phpunit": "^4.8" }, "type": "library", "extra": { @@ -80,33 +455,45 @@ "recaptcha", "spam" ], - "time": "2015-09-02 17:23:59" + "time": "2017-03-09T18:44:34+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "5.3.2", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "f9acb4761844317e626a32259205bec1f1bc60d2" + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f9acb4761844317e626a32259205bec1f1bc60d2", - "reference": "f9acb4761844317e626a32259205bec1f1bc60d2", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", "shasum": "" }, "require": { - "guzzlehttp/ringphp": "^1.1", - "php": ">=5.4.0", - "react/promise": "^2.2" + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.0" + "phpunit/phpunit": "^4.0 || ^5.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2-dev" + } + }, "autoload": { + "files": [ + "src/functions_include.php" + ], "psr-4": { "GuzzleHttp\\": "src/" } @@ -122,7 +509,7 @@ "homepage": "https://github.com/mtdowling" } ], - "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "description": "Guzzle is a PHP HTTP client library", "homepage": "http://guzzlephp.org/", "keywords": [ "client", @@ -133,44 +520,41 @@ "rest", "web service" ], - "time": "2018-01-15 07:18:01" + "time": "2017-06-22T18:50:49+00:00" }, { - "name": "guzzlehttp/ringphp", - "version": "1.1.0", + "name": "guzzlehttp/promises", + "version": "v1.3.1", "source": { "type": "git", - "url": "https://github.com/guzzle/RingPHP.git", - "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b" + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", - "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", "shasum": "" }, "require": { - "guzzlehttp/streams": "~3.0", - "php": ">=5.4.0", - "react/promise": "~2.0" + "php": ">=5.5.0" }, "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "ext-curl": "Guzzle will use specific adapters if cURL is present" + "phpunit/phpunit": "^4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "1.4-dev" } }, "autoload": { "psr-4": { - "GuzzleHttp\\Ring\\": "src/" - } + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -183,25 +567,32 @@ "homepage": "https://github.com/mtdowling" } ], - "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", - "time": "2015-05-20 03:37:09" + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" }, { - "name": "guzzlehttp/streams", - "version": "3.0.0", + "name": "guzzlehttp/psr7", + "version": "1.4.2", "source": { "type": "git", - "url": "https://github.com/guzzle/streams.git", - "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", - "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" }, "require-dev": { "phpunit/phpunit": "~4.0" @@ -209,13 +600,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "1.4-dev" } }, "autoload": { "psr-4": { - "GuzzleHttp\\Stream\\": "src/" - } + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -226,38 +620,59 @@ "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" } ], - "description": "Provides a simple abstraction over streams of data", - "homepage": "http://guzzlephp.org/", + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ - "Guzzle", - "stream" + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" ], - "time": "2014-10-12 19:18:40" + "time": "2017-03-20T17:10:46+00:00" }, { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", + "name": "justinrainbow/json-schema", + "version": "5.2.6", "source": { "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/d283e11b6e14c6f4664cf080415c4341293e5bbd", + "reference": "d283e11b6e14c6f4664cf080415c4341293e5bbd", "shasum": "" }, + "require": { + "php": ">=5.3.3" + }, "require-dev": { - "phpunit/phpunit": "4.*" + "friendsofphp/php-cs-fixer": "^2.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.22" }, + "bin": [ + "bin/validate-json" + ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, "autoload": { - "files": [ - "lib/password.php" - ] + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -265,18 +680,29 @@ ], "authors": [ { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" } ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", "keywords": [ - "hashing", - "password" + "json", + "schema" ], - "time": "2014-11-20 16:49:30" + "time": "2017-10-21T13:15:38+00:00" }, { "name": "lusitanian/oauth", @@ -343,7 +769,7 @@ "oauth", "security" ], - "time": "2016-07-12 22:15:00" + "time": "2016-07-12T22:15:00+00:00" }, { "name": "marc1706/fast-image-size", @@ -395,7 +821,7 @@ "php", "size" ], - "time": "2017-10-23 18:52:01" + "time": "2017-10-23T18:52:01+00:00" }, { "name": "ocramius/proxy-manager", @@ -458,7 +884,7 @@ "proxy pattern", "service proxies" ], - "time": "2015-08-09 04:28:19" + "time": "2015-08-09T04:28:19+00:00" }, { "name": "paragonie/random_compat", @@ -506,7 +932,7 @@ "pseudorandom", "random" ], - "time": "2017-03-13 16:22:52" + "time": "2017-03-13T16:22:52+00:00" }, { "name": "patchwork/utf8", @@ -565,20 +991,69 @@ "utf-8", "utf8" ], - "time": "2016-05-18 13:57:10" + "time": "2016-05-18T13:57:10+00:00" }, { - "name": "psr/log", - "version": "1.0.2", + "name": "psr/container", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", "shasum": "" }, "require": { @@ -592,7 +1067,7 @@ }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Http\\Message\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -605,43 +1080,45 @@ "homepage": "http://www.php-fig.org/" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", "keywords": [ - "log", + "http", + "http-message", "psr", - "psr-3" + "psr-7", + "request", + "response" ], - "time": "2016-10-10 12:19:37" + "time": "2016-08-06T14:39:51+00:00" }, { - "name": "react/promise", - "version": "v2.5.1", + "name": "psr/log", + "version": "1.0.2", "source": { "type": "git", - "url": "https://github.com/reactphp/promise.git", - "reference": "62785ae604c8d69725d693eb370e1d67e94c4053" + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/62785ae604c8d69725d693eb370e1d67e94c4053", - "reference": "62785ae604c8d69725d693eb370e1d67e94c4053", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" + "php": ">=5.3.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { "psr-4": { - "React\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] + "Psr\\Log\\": "Psr/Log/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -649,16 +1126,18 @@ ], "authors": [ { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ - "promise", - "promises" + "log", + "psr", + "psr-3" ], - "time": "2017-03-25 12:08:31" + "time": "2016-10-10T12:19:37+00:00" }, { "name": "s9e/text-formatter", @@ -723,28 +1202,175 @@ "parser", "shortcodes" ], - "time": "2017-12-10 00:55:53" + "time": "2017-12-10T00:55:53+00:00" + }, + { + "name": "seld/cli-prompt", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "time": "2017-03-18T11:32:45+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "9b355654ea99460397b89c132b5c1087b6bf4473" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9b355654ea99460397b89c132b5c1087b6bf4473", + "reference": "9b355654ea99460397b89c132b5c1087b6bf4473", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2018-01-03T12:13:57+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13T18:44:15+00:00" }, { "name": "symfony/config", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "17605ff58313d9fe94e507620a399721fc347b6d" + "reference": "cfd5c972f7b4992a5df41673d25d980ab077aa5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/17605ff58313d9fe94e507620a399721fc347b6d", - "reference": "17605ff58313d9fe94e507620a399721fc347b6d", + "url": "https://api.github.com/repos/symfony/config/zipball/cfd5c972f7b4992a5df41673d25d980ab077aa5b", + "reference": "cfd5c972f7b4992a5df41673d25d980ab077aa5b", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/filesystem": "~2.3|~3.0.0" + "php": "^5.5.9|>=7.0.8", + "symfony/filesystem": "~2.8|~3.0|~4.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.3", + "symfony/finder": "<3.3" }, "require-dev": { - "symfony/yaml": "~2.7|~3.0.0" + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/finder": "~3.3|~4.0", + "symfony/yaml": "~3.0|~4.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" @@ -752,7 +1378,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -779,41 +1405,49 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-01-21 19:03:25" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/console", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "162ca7d0ea597599967aa63b23418e747da0896b" + "reference": "8394c8ef121949e8f858f13bc1e34f05169e4e7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/162ca7d0ea597599967aa63b23418e747da0896b", - "reference": "162ca7d0ea597599967aa63b23418e747da0896b", + "url": "https://api.github.com/repos/symfony/console/zipball/8394c8ef121949e8f858f13bc1e34f05169e4e7d", + "reference": "8394c8ef121949e8f858f13bc1e34f05169e4e7d", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/debug": "^2.7.2|~3.0.0", + "php": "^5.5.9|>=7.0.8", + "symfony/debug": "~2.8|~3.0|~4.0", "symfony/polyfill-mbstring": "~1.0" }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0" + "symfony/config": "~3.3|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.3|~4.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/lock": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -840,37 +1474,36 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-01-29 08:54:45" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/debug", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "35e36287fc0fdc8a08f70efcd4865ae6d8a6ee55" + "reference": "603b95dda8b00020e4e6e60dc906e7b715b1c245" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/35e36287fc0fdc8a08f70efcd4865ae6d8a6ee55", - "reference": "35e36287fc0fdc8a08f70efcd4865ae6d8a6ee55", + "url": "https://api.github.com/repos/symfony/debug/zipball/603b95dda8b00020e4e6e60dc906e7b715b1c245", + "reference": "603b95dda8b00020e4e6e60dc906e7b715b1c245", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": "^5.5.9|>=7.0.8", "psr/log": "~1.0" }, "conflict": { "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" }, "require-dev": { - "symfony/class-loader": "~2.2|~3.0.0", - "symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0" + "symfony/http-kernel": "~2.8|~3.0|~4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -897,43 +1530,51 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2018-01-18 22:12:33" + "time": "2018-01-03T17:14:19+00:00" }, { "name": "symfony/dependency-injection", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "91ad61e6f140b050eba4aa39bc52eece713f2a71" + "reference": "35f957ca171a431710966bec6e2f8636d3b019c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/91ad61e6f140b050eba4aa39bc52eece713f2a71", - "reference": "91ad61e6f140b050eba4aa39bc52eece713f2a71", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/35f957ca171a431710966bec6e2f8636d3b019c4", + "reference": "35f957ca171a431710966bec6e2f8636d3b019c4", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" }, "conflict": { - "symfony/expression-language": "<2.6" + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" }, "require-dev": { - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7" + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" }, "suggest": { "symfony/config": "", "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", "symfony/yaml": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -960,31 +1601,34 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-01-29 08:55:23" + "time": "2018-01-04T15:56:45+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d64be24fc1eba62f9daace8a8918f797fc8e87cc" + "reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d64be24fc1eba62f9daace8a8918f797fc8e87cc", - "reference": "d64be24fc1eba62f9daace8a8918f797fc8e87cc", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/26b87b6bca8f8f797331a30b76fdae5342dc26ca", + "reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8" + }, + "conflict": { + "symfony/dependency-injection": "<3.3" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/stopwatch": "~2.8|~3.0|~4.0" }, "suggest": { "symfony/dependency-injection": "", @@ -993,7 +1637,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1020,29 +1664,29 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-01-03 07:36:31" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/filesystem", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "1f4e8351e0196562f5e8ec584baeceeb8e2e92f6" + "reference": "e078773ad6354af38169faf31c21df0f18ace03d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/1f4e8351e0196562f5e8ec584baeceeb8e2e92f6", - "reference": "1f4e8351e0196562f5e8ec584baeceeb8e2e92f6", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d", + "reference": "e078773ad6354af38169faf31c21df0f18ace03d", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1069,29 +1713,29 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-01-03 07:36:31" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/finder", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9786ccb6a1f94a89ae18fc6a1b68de1f070823ed" + "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9786ccb6a1f94a89ae18fc6a1b68de1f070823ed", - "reference": "9786ccb6a1f94a89ae18fc6a1b68de1f070823ed", + "url": "https://api.github.com/repos/symfony/finder/zipball/613e26310776f49a1773b6737c6bd554b8bc8c6f", + "reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1118,35 +1762,34 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-01-29 08:54:45" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/http-foundation", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "686464910bbe58a2b38eb1f898aa45dc6c4de0cb" + "reference": "4a213be1cc8598089b8c7451529a2927b49b5d26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/686464910bbe58a2b38eb1f898aa45dc6c4de0cb", - "reference": "686464910bbe58a2b38eb1f898aa45dc6c4de0cb", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/4a213be1cc8598089b8c7451529a2927b49b5d26", + "reference": "4a213be1cc8598089b8c7451529a2927b49b5d26", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php54": "~1.0", - "symfony/polyfill-php55": "~1.0" + "symfony/polyfill-php70": "~1.6" }, "require-dev": { - "symfony/expression-language": "~2.4|~3.0.0" + "symfony/expression-language": "~2.8|~3.0|~4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1173,53 +1816,58 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-01-29 08:54:45" + "time": "2018-01-03T17:14:19+00:00" }, { "name": "symfony/http-kernel", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "af74cd947d63ae1294aed71b9456f2a04f7f6d45" + "reference": "1c2a82d6a8ec9b354fe4ef48ad1ad3f1a4f7db0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/af74cd947d63ae1294aed71b9456f2a04f7f6d45", - "reference": "af74cd947d63ae1294aed71b9456f2a04f7f6d45", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1c2a82d6a8ec9b354fe4ef48ad1ad3f1a4f7db0e", + "reference": "1c2a82d6a8ec9b354fe4ef48ad1ad3f1a4f7db0e", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": "^5.5.9|>=7.0.8", "psr/log": "~1.0", - "symfony/debug": "^2.6.2", - "symfony/event-dispatcher": "^2.6.7|~3.0.0", - "symfony/http-foundation": "~2.7.36|~2.8.29|~3.1.6" + "symfony/debug": "~2.8|~3.0|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/http-foundation": "^3.3.11|~4.0" }, "conflict": { - "symfony/config": "<2.7", + "symfony/config": "<2.8", + "symfony/dependency-injection": "<3.4", + "symfony/var-dumper": "<3.3", "twig/twig": "<1.34|<2.4,>=2" }, + "provide": { + "psr/log-implementation": "1.0" + }, "require-dev": { - "symfony/browser-kit": "~2.3|~3.0.0", - "symfony/class-loader": "~2.1|~3.0.0", - "symfony/config": "~2.8", - "symfony/console": "~2.3|~3.0.0", - "symfony/css-selector": "^2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.8|~3.0.0", - "symfony/dom-crawler": "^2.0.5|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/finder": "^2.0.5|~3.0.0", - "symfony/process": "^2.0.5|~3.0.0", - "symfony/routing": "~2.8|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0", - "symfony/templating": "~2.2|~3.0.0", - "symfony/translation": "^2.0.5|~3.0.0", - "symfony/var-dumper": "~2.6|~3.0.0" + "psr/cache": "~1.0", + "symfony/browser-kit": "~2.8|~3.0|~4.0", + "symfony/class-loader": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/console": "~2.8|~3.0|~4.0", + "symfony/css-selector": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/dom-crawler": "~2.8|~3.0|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/process": "~2.8|~3.0|~4.0", + "symfony/routing": "~3.4|~4.0", + "symfony/stopwatch": "~2.8|~3.0|~4.0", + "symfony/templating": "~2.8|~3.0|~4.0", + "symfony/translation": "~2.8|~3.0|~4.0", + "symfony/var-dumper": "~3.3|~4.0" }, "suggest": { "symfony/browser-kit": "", - "symfony/class-loader": "", "symfony/config": "", "symfony/console": "", "symfony/dependency-injection": "", @@ -1229,7 +1877,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1256,7 +1904,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2018-01-29 10:48:12" + "time": "2018-01-05T08:33:00+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1315,23 +1963,24 @@ "portable", "shim" ], - "time": "2018-01-30 19:27:44" + "time": "2017-10-11T12:05:26+00:00" }, { - "name": "symfony/polyfill-php54", - "version": "v1.7.0", + "name": "symfony/polyfill-php70", + "version": "v1.6.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5" + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/84e2b616c197ef400c6d0556a0606cee7c9e21d5", - "reference": "84e2b616c197ef400c6d0556a0606cee7c9e21d5", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff", + "reference": "0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff", "shasum": "" }, "require": { + "paragonie/random_compat": "~1.0|~2.0", "php": ">=5.3.3" }, "type": "library", @@ -1342,7 +1991,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" + "Symfony\\Polyfill\\Php70\\": "" }, "files": [ "bootstrap.php" @@ -1365,7 +2014,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -1373,38 +2022,37 @@ "portable", "shim" ], - "time": "2018-01-30 19:27:44" + "time": "2017-10-11T12:05:26+00:00" }, { - "name": "symfony/polyfill-php55", - "version": "v1.7.0", + "name": "symfony/process", + "version": "v3.4.3", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "168371cb3dfb10e0afde96e7c2688be02470d143" + "url": "https://github.com/symfony/process.git", + "reference": "ff69f110c6b33fd33cd2089ba97d6112f44ef0ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/168371cb3dfb10e0afde96e7c2688be02470d143", - "reference": "168371cb3dfb10e0afde96e7c2688be02470d143", + "url": "https://api.github.com/repos/symfony/process/zipball/ff69f110c6b33fd33cd2089ba97d6112f44ef0ba", + "reference": "ff69f110c6b33fd33cd2089ba97d6112f44ef0ba", "shasum": "" }, "require": { - "ircmaxell/password-compat": "~1.0", - "php": ">=5.3.3" + "php": "^5.5.9|>=7.0.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-master": "3.4-dev" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" + "Symfony\\Component\\Process\\": "" }, - "files": [ - "bootstrap.php" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1413,50 +2061,44 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", + "description": "Symfony Process Component", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-01-30 19:27:44" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/proxy-manager-bridge", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/proxy-manager-bridge.git", - "reference": "d73283cfe025d73c70551c45d22c54bd43c2c53b" + "reference": "ffb375b65cf112364b5374ed99059975ca84a6bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/d73283cfe025d73c70551c45d22c54bd43c2c53b", - "reference": "d73283cfe025d73c70551c45d22c54bd43c2c53b", + "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/ffb375b65cf112364b5374ed99059975ca84a6bd", + "reference": "ffb375b65cf112364b5374ed99059975ca84a6bd", "shasum": "" }, "require": { "ocramius/proxy-manager": "~0.4|~1.0|~2.0", - "php": ">=5.3.9", - "symfony/dependency-injection": "~2.8|~3.0.0" + "php": "^5.5.9|>=7.0.8", + "symfony/dependency-injection": "~3.4|~4.0" }, "require-dev": { - "symfony/config": "~2.3|~3.0.0" + "symfony/config": "~2.8|~3.0|~4.0" }, "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1483,36 +2125,39 @@ ], "description": "Symfony ProxyManager Bridge", "homepage": "https://symfony.com", - "time": "2018-01-03 07:36:31" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/routing", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "627ea100720dac15d8165648caac57456dda84aa" + "reference": "e2b6d6fe7b090c7af720b75c7722c6dfa7a52658" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/627ea100720dac15d8165648caac57456dda84aa", - "reference": "627ea100720dac15d8165648caac57456dda84aa", + "url": "https://api.github.com/repos/symfony/routing/zipball/e2b6d6fe7b090c7af720b75c7722c6dfa7a52658", + "reference": "e2b6d6fe7b090c7af720b75c7722c6dfa7a52658", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8", + "symfony/dependency-injection": "<3.3", + "symfony/yaml": "<3.4" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/common": "~2.2", "psr/log": "~1.0", - "symfony/config": "~2.7|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/yaml": "^2.0.5|~3.0.0" + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/http-foundation": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" }, "suggest": { "doctrine/annotations": "For using the annotation loader", @@ -1525,7 +2170,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1558,46 +2203,50 @@ "uri", "url" ], - "time": "2018-01-16 18:00:04" + "time": "2018-01-04T15:09:34+00:00" }, { "name": "symfony/twig-bridge", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "efdc8b39b5a05def32824e578ccf3fcdec8190cc" + "reference": "d5c5d63b89800ead1b1cd9908b77211a22d2f3cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/efdc8b39b5a05def32824e578ccf3fcdec8190cc", - "reference": "efdc8b39b5a05def32824e578ccf3fcdec8190cc", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/d5c5d63b89800ead1b1cd9908b77211a22d2f3cd", + "reference": "d5c5d63b89800ead1b1cd9908b77211a22d2f3cd", "shasum": "" }, "require": { - "php": ">=5.3.9", - "twig/twig": "~1.34|~2.4" + "php": "^5.5.9|>=7.0.8", + "twig/twig": "^1.35|^2.4.4" }, "conflict": { - "symfony/form": "<2.8.23" + "symfony/console": "<3.4", + "symfony/form": "<3.4" }, "require-dev": { - "symfony/asset": "~2.7|~3.0.0", - "symfony/console": "~2.8|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/finder": "~2.3|~3.0.0", - "symfony/form": "^2.8.23", - "symfony/http-foundation": "^2.8.29|~3.0.0", - "symfony/http-kernel": "~2.8|~3.0.0", + "symfony/asset": "~2.8|~3.0|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/dependency-injection": "~2.8|~3.0|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/form": "~3.4|~4.0", + "symfony/http-foundation": "^3.3.11|~4.0", + "symfony/http-kernel": "~3.2|~4.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/routing": "~2.2|~3.0.0", - "symfony/security": "~2.6|~3.0.0", - "symfony/security-acl": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.2|~3.0.0", - "symfony/templating": "~2.1|~3.0.0", - "symfony/translation": "~2.7|~3.0.0", - "symfony/var-dumper": "~2.7.16|~2.8.9|~3.0.9", - "symfony/yaml": "^2.0.5|~3.0.0" + "symfony/routing": "~2.8|~3.0|~4.0", + "symfony/security": "~2.8|~3.0|~4.0", + "symfony/security-acl": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0|~4.0", + "symfony/templating": "~2.8|~3.0|~4.0", + "symfony/translation": "~2.8|~3.0|~4.0", + "symfony/var-dumper": "~2.8.10|~3.1.4|~3.2|~4.0", + "symfony/web-link": "~3.3|~4.0", + "symfony/workflow": "~3.3|~4.0", + "symfony/yaml": "~2.8|~3.0|~4.0" }, "suggest": { "symfony/asset": "For using the AssetExtension", @@ -1611,12 +2260,13 @@ "symfony/templating": "For using the TwigEngine", "symfony/translation": "For using the TranslationExtension", "symfony/var-dumper": "For using the DumpExtension", + "symfony/web-link": "For using the WebLinkExtension", "symfony/yaml": "For using the YamlExtension" }, "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1643,29 +2293,38 @@ ], "description": "Symfony Twig Bridge", "homepage": "https://symfony.com", - "time": "2018-01-03 17:12:09" + "time": "2018-01-03T17:14:19+00:00" }, { "name": "symfony/yaml", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "be720fcfae4614df204190d57795351059946a77" + "reference": "25c192f25721a74084272671f658797d9e0e0146" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/be720fcfae4614df204190d57795351059946a77", - "reference": "be720fcfae4614df204190d57795351059946a77", + "url": "https://api.github.com/repos/symfony/yaml/zipball/25c192f25721a74084272671f658797d9e0e0146", + "reference": "25c192f25721a74084272671f658797d9e0e0146", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -1692,7 +2351,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-01-03 07:36:31" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "twig/twig", @@ -1757,42 +2416,41 @@ "keywords": [ "templating" ], - "time": "2017-09-27 18:06:46" + "time": "2017-09-27T18:06:46+00:00" }, { "name": "zendframework/zend-code", - "version": "2.5.1", + "version": "2.6.3", "source": { "type": "git", "url": "https://github.com/zendframework/zend-code.git", - "reference": "5d998f261ec2a55171c71da57a11622745680153" + "reference": "95033f061b083e16cdee60530ec260d7d628b887" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/5d998f261ec2a55171c71da57a11622745680153", - "reference": "5d998f261ec2a55171c71da57a11622745680153", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/95033f061b083e16cdee60530ec260d7d628b887", + "reference": "95033f061b083e16cdee60530ec260d7d628b887", "shasum": "" }, "require": { - "php": ">=5.3.23", - "zendframework/zend-eventmanager": "~2.5" + "php": "^5.5 || 7.0.0 - 7.0.4 || ^7.0.6", + "zendframework/zend-eventmanager": "^2.6 || ^3.0" }, "require-dev": { - "doctrine/common": ">=2.1", + "doctrine/annotations": "~1.0", "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-stdlib": "~2.5", - "zendframework/zend-version": "~2.5" + "phpunit/phpunit": "^4.8.21", + "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "suggest": { - "doctrine/common": "Doctrine\\Common >=2.1 for annotation features", + "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", "zendframework/zend-stdlib": "Zend\\Stdlib component" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" } }, "autoload": { @@ -1810,35 +2468,41 @@ "code", "zf2" ], - "time": "2015-06-03 15:31:59" + "time": "2016-04-20T17:26:42+00:00" }, { "name": "zendframework/zend-eventmanager", - "version": "2.5.1", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "d94a16039144936f107f906896349900fd634443" + "reference": "9d72db10ceb6e42fb92350c0cb54460da61bd79c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/d94a16039144936f107f906896349900fd634443", - "reference": "d94a16039144936f107f906896349900fd634443", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/9d72db10ceb6e42fb92350c0cb54460da61bd79c", + "reference": "9d72db10ceb6e42fb92350c0cb54460da61bd79c", "shasum": "" }, "require": { - "php": ">=5.3.23", - "zendframework/zend-stdlib": "~2.5" + "php": "^5.6 || ^7.0" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" + "athletic/athletic": "^0.1", + "container-interop/container-interop": "^1.1.0", + "phpunit/phpunit": "^6.0.7 || ^5.7.14", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-stdlib": "^2.7.3 || ^3.0" + }, + "suggest": { + "container-interop/container-interop": "^1.1.0, to use the lazy listeners feature", + "zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "3.2-dev", + "dev-develop": "3.3-dev" } }, "autoload": { @@ -1850,68 +2514,15 @@ "license": [ "BSD-3-Clause" ], + "description": "Trigger and listen to events within a PHP application", "homepage": "https://github.com/zendframework/zend-eventmanager", "keywords": [ + "event", "eventmanager", + "events", "zf2" ], - "time": "2015-06-03 15:32:01" - }, - { - "name": "zendframework/zend-stdlib", - "version": "2.5.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/cc8e90a60dd5d44b9730b77d07b97550091da1ae", - "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae", - "shasum": "" - }, - "require": { - "php": ">=5.3.23" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-config": "~2.5", - "zendframework/zend-eventmanager": "~2.5", - "zendframework/zend-filter": "~2.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-serializer": "~2.5", - "zendframework/zend-servicemanager": "~2.5" - }, - "suggest": { - "zendframework/zend-eventmanager": "To support aggregate hydrator usage", - "zendframework/zend-filter": "To support naming strategy hydrator usage", - "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Stdlib\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-stdlib", - "keywords": [ - "stdlib", - "zf2" - ], - "time": "2015-06-03 15:32:03" + "time": "2017-07-11T19:17:22+00:00" } ], "packages-dev": [ @@ -1967,39 +2578,45 @@ "constructor", "instantiate" ], - "time": "2015-06-14 21:17:01" + "time": "2015-06-14T21:17:01+00:00" }, { "name": "fabpot/goutte", - "version": "v2.0.4", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/Goutte.git", - "reference": "0ad3ee6dc2d0aaa832a80041a1e09bf394e99802" + "reference": "395f61d7c2e15a813839769553a4de16fa3b3c96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/0ad3ee6dc2d0aaa832a80041a1e09bf394e99802", - "reference": "0ad3ee6dc2d0aaa832a80041a1e09bf394e99802", + "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/395f61d7c2e15a813839769553a4de16fa3b3c96", + "reference": "395f61d7c2e15a813839769553a4de16fa3b3c96", "shasum": "" }, "require": { - "guzzlehttp/guzzle": ">=4,<6", - "php": ">=5.4.0", - "symfony/browser-kit": "~2.1", - "symfony/css-selector": "~2.1", - "symfony/dom-crawler": "~2.1" + "guzzlehttp/guzzle": "^6.0", + "php": ">=5.5.0", + "symfony/browser-kit": "~2.1|~3.0|~4.0", + "symfony/css-selector": "~2.1|~3.0|~4.0", + "symfony/dom-crawler": "~2.1|~3.0|~4.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.3 || ^4" }, "type": "application", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { "psr-4": { "Goutte\\": "Goutte" - } + }, + "exclude-from-classmap": [ + "Goutte/Tests" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2016,35 +2633,44 @@ "keywords": [ "scraper" ], - "time": "2015-05-05 21:14:57" + "time": "2017-11-19T08:45:40+00:00" }, { "name": "facebook/webdriver", - "version": "1.1.3", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/facebook/php-webdriver.git", - "reference": "b7186fb1bcfda956d237f59face250d06ef47253" + "reference": "86b5ca2f67173c9d34340845dd690149c886a605" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/b7186fb1bcfda956d237f59face250d06ef47253", - "reference": "b7186fb1bcfda956d237f59face250d06ef47253", + "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/86b5ca2f67173c9d34340845dd690149c886a605", + "reference": "86b5ca2f67173c9d34340845dd690149c886a605", "shasum": "" }, "require": { "ext-curl": "*", - "php": ">=5.3.19" + "ext-zip": "*", + "php": "^5.6 || ~7.0", + "symfony/process": "^2.8 || ^3.1 || ^4.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^1.11", - "phpunit/phpunit": "4.6.* || ~5.0", - "squizlabs/php_codesniffer": "^2.6" - }, - "suggest": { - "phpdocumentor/phpdocumentor": "2.*" + "friendsofphp/php-cs-fixer": "^2.0", + "guzzle/guzzle": "^3.4.1", + "php-coveralls/php-coveralls": "^1.0.2", + "php-mock/php-mock-phpunit": "^1.1", + "phpunit/phpunit": "^5.7", + "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0", + "squizlabs/php_codesniffer": "^2.6", + "symfony/var-dumper": "^3.3 || ^4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-community": "1.5-dev" + } + }, "autoload": { "psr-4": { "Facebook\\WebDriver\\": "lib/" @@ -2054,7 +2680,7 @@ "license": [ "Apache-2.0" ], - "description": "A PHP client for WebDriver", + "description": "A PHP client for Selenium WebDriver", "homepage": "https://github.com/facebook/php-webdriver", "keywords": [ "facebook", @@ -2062,31 +2688,36 @@ "selenium", "webdriver" ], - "time": "2016-08-10 00:44:08" + "time": "2017-11-15T11:08:09+00:00" }, { "name": "laravel/homestead", - "version": "v2.2.2", + "version": "v4.0.5", "source": { "type": "git", "url": "https://github.com/laravel/homestead.git", - "reference": "f4e45f895d8707042c2d0698627d33c484e7c6ba" + "reference": "a1bcbde2462d8ac1fa608cd6f00b46623aabd705" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/homestead/zipball/f4e45f895d8707042c2d0698627d33c484e7c6ba", - "reference": "f4e45f895d8707042c2d0698627d33c484e7c6ba", + "url": "https://api.github.com/repos/laravel/homestead/zipball/a1bcbde2462d8ac1fa608cd6f00b46623aabd705", + "reference": "a1bcbde2462d8ac1fa608cd6f00b46623aabd705", "shasum": "" }, "require": { - "php": ">=5.4", - "symfony/console": "~2.0 || ~3.0", - "symfony/process": "~2.0 || ~3.0" + "php": ">=5.5.9", + "symfony/console": "~2.3|~3.0", + "symfony/process": "~2.3|~3.0" }, "bin": [ "homestead" ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, "autoload": { "psr-4": { "Laravel\\Homestead\\": "src/" @@ -2103,184 +2734,235 @@ } ], "description": "A virtual machine for web artisans.", - "time": "2016-09-17 04:42:33" + "time": "2017-02-07T19:06:26+00:00" }, { - "name": "michelf/php-markdown", - "version": "1.8.0", + "name": "myclabs/deep-copy", + "version": "1.7.0", "source": { "type": "git", - "url": "https://github.com/michelf/php-markdown.git", - "reference": "01ab082b355bf188d907b9929cd99b2923053495" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/01ab082b355bf188d907b9929cd99b2923053495", - "reference": "01ab082b355bf188d907b9929cd99b2923053495", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" }, "type": "library", "autoload": { "psr-4": { - "Michelf\\": "Michelf/" - } + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phing/phing", + "version": "2.4.14", + "source": { + "type": "git", + "url": "https://github.com/phingofficial/phing.git", + "reference": "41075d93ca254f1c90c79ec7ce81be2b2629e138" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phingofficial/phing/zipball/41075d93ca254f1c90c79ec7ce81be2b2629e138", + "reference": "41075d93ca254f1c90c79ec7ce81be2b2629e138", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "bin": [ + "bin/phing" + ], + "type": "library", + "autoload": { + "classmap": [ + "classes/phing/" + ] }, "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "classes" + ], "license": [ - "BSD-3-Clause" + "LGPL3" ], "authors": [ { - "name": "Michel Fortin", - "email": "michel.fortin@michelf.ca", - "homepage": "https://michelf.ca/", - "role": "Developer" + "name": "Michiel Rook", + "email": "mrook@php.net" }, { - "name": "John Gruber", - "homepage": "https://daringfireball.net/" + "name": "Phing Community", + "homepage": "http://www.phing.info/trac/wiki/Development/Contributors" } ], - "description": "PHP Markdown", - "homepage": "https://michelf.ca/projects/php-markdown/", + "description": "PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.", + "homepage": "http://www.phing.info/", "keywords": [ - "markdown" + "build", + "task", + "tool" ], - "time": "2018-01-15 00:49:33" + "time": "2012-11-29T21:23:47+00:00" }, { - "name": "nikic/php-parser", - "version": "v0.9.5", + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb" + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ef70767475434bdb3615b43c327e2cae17ef12eb", - "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=5.2" + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.9-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { - "psr-0": { - "PHPParser": "lib/" + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" } ], - "description": "A PHP parser written in PHP", + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", "keywords": [ - "parser", - "php" + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" ], - "time": "2014-07-23 18:24:17" + "time": "2017-09-11T18:02:19+00:00" }, { - "name": "phing/phing", - "version": "2.4.14", + "name": "phpdocumentor/reflection-docblock", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/phingofficial/phing.git", - "reference": "41075d93ca254f1c90c79ec7ce81be2b2629e138" + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phingofficial/phing/zipball/41075d93ca254f1c90c79ec7ce81be2b2629e138", - "reference": "41075d93ca254f1c90c79ec7ce81be2b2629e138", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", "shasum": "" }, "require": { - "php": ">=5.2.0" + "php": "^5.6 || ^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" }, - "bin": [ - "bin/phing" - ], "type": "library", "autoload": { - "classmap": [ - "classes/phing/" - ] + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "classes" - ], "license": [ - "LGPL3" + "MIT" ], "authors": [ { - "name": "Michiel Rook", - "email": "mrook@php.net" - }, - { - "name": "Phing Community", - "homepage": "http://www.phing.info/trac/wiki/Development/Contributors" + "name": "Mike van Riel", + "email": "me@mikevanriel.com" } ], - "description": "PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.", - "homepage": "http://www.phing.info/", - "keywords": [ - "build", - "task", - "tool" - ], - "time": "2012-11-29 21:23:47" + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-10T14:09:06+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.5", + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", - "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { - "psr-0": { - "phpDocumentor": [ + "psr-4": { + "phpDocumentor\\Reflection\\": [ "src/" ] } @@ -2292,10 +2974,10 @@ "authors": [ { "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" + "email": "me@mikevanriel.com" } ], - "time": "2016-01-25 08:17:30" + "time": "2017-07-14T14:27:02+00:00" }, { "name": "phpspec/prophecy", @@ -2358,48 +3040,44 @@ "spy", "stub" ], - "time": "2018-02-19 10:16:54" + "time": "2017-11-24T13:59:53+00:00" }, { "name": "phpunit/dbunit", - "version": "1.3.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/dbunit.git", - "reference": "1507040c2541bdffd7fbd71fc792cecdea6a7c61" + "reference": "5c35d74549c21ba55d0ea74ba89d191a51f8cf25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/1507040c2541bdffd7fbd71fc792cecdea6a7c61", - "reference": "1507040c2541bdffd7fbd71fc792cecdea6a7c61", + "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/5c35d74549c21ba55d0ea74ba89d191a51f8cf25", + "reference": "5c35d74549c21ba55d0ea74ba89d191a51f8cf25", "shasum": "" }, "require": { "ext-pdo": "*", "ext-simplexml": "*", - "php": ">=5.3.3", - "phpunit/phpunit": "~3.7|~4.0", - "symfony/yaml": "~2.1" + "php": "^5.4 || ^7.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0", + "symfony/yaml": "^2.1 || ^3.0" }, "bin": [ - "composer/bin/dbunit" + "dbunit" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ - "PHPUnit/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], "license": [ "BSD-3-Clause" ], @@ -2417,43 +3095,44 @@ "testing", "xunit" ], - "time": "2015-03-29 14:23:04" + "time": "2016-12-02T14:39:14+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "2.2.4", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", "shasum": "" }, "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" }, "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" }, "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" + "ext-xdebug": "^2.5.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2.x-dev" + "dev-master": "4.0.x-dev" } }, "autoload": { @@ -2479,7 +3158,7 @@ "testing", "xunit" ], - "time": "2015-10-06 15:47:00" + "time": "2017-04-02T07:44:40+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2526,7 +3205,7 @@ "filesystem", "iterator" ], - "time": "2017-11-27 13:52:08" + "time": "2017-11-27T13:52:08+00:00" }, { "name": "phpunit/php-text-template", @@ -2567,7 +3246,7 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", @@ -2616,7 +3295,7 @@ "keywords": [ "timer" ], - "time": "2017-02-26 11:10:40" + "time": "2017-02-26T11:10:40+00:00" }, { "name": "phpunit/php-token-stream", @@ -2665,44 +3344,54 @@ "keywords": [ "tokenizer" ], - "time": "2017-12-04 08:55:13" + "time": "2017-12-04T08:55:13+00:00" }, { "name": "phpunit/phpunit", - "version": "4.8.36", + "version": "5.7.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" + "reference": "7fbc25c13309de0c4c9bb48b7361f1eca34c7fbd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7fbc25c13309de0c4c9bb48b7361f1eca34c7fbd", + "reference": "7fbc25c13309de0c4c9bb48b7361f1eca34c7fbd", "shasum": "" }, "require": { "ext-dom": "*", "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.2.2", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0.3|~2.0", + "symfony/yaml": "~2.1|~3.0|~4.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" }, "suggest": { + "ext-xdebug": "*", "phpunit/php-invoker": "~1.1" }, "bin": [ @@ -2711,7 +3400,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.8.x-dev" + "dev-master": "5.7.x-dev" } }, "autoload": { @@ -2737,30 +3426,33 @@ "testing", "xunit" ], - "time": "2017-06-21 08:07:12" + "time": "2017-12-17T06:14:38+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^5.4" }, "suggest": { "ext-soap": "*" @@ -2768,7 +3460,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3.x-dev" + "dev-master": "3.2.x-dev" } }, "autoload": { @@ -2793,24 +3485,27 @@ "mock", "xunit" ], - "time": "2015-10-02 06:51:40" + "time": "2017-06-30T09:13:00+00:00" }, { - "name": "pimple/pimple", - "version": "v1.0.2", + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94" + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94", - "reference": "ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" }, "type": "library", "extra": { @@ -2819,86 +3514,23 @@ } }, "autoload": { - "psr-0": { - "Pimple": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - } - ], - "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", - "homepage": "http://pimple.sensiolabs.org", - "keywords": [ - "container", - "dependency injection" - ], - "time": "2013-03-08 08:21:40" - }, - { - "name": "sami/sami", - "version": "v1.4.1", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/Sami.git", - "reference": "160018bfefffa730dc35a2c606691a45acbf41a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/Sami/zipball/160018bfefffa730dc35a2c606691a45acbf41a1", - "reference": "160018bfefffa730dc35a2c606691a45acbf41a1", - "shasum": "" - }, - "require": { - "michelf/php-markdown": "~1.3", - "nikic/php-parser": "0.9.*", - "php": ">=5.3.0", - "pimple/pimple": "1.0.*", - "symfony/console": "~2.1", - "symfony/filesystem": "~2.1", - "symfony/finder": "~2.1", - "symfony/process": "~2.1", - "symfony/yaml": "~2.1", - "twig/twig": "1.*" - }, - "bin": [ - "sami.php" - ], - "type": "application", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-0": { - "Sami": "." - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Sami, an API documentation generator", - "homepage": "http://sami.sensiolabs.org", - "keywords": [ - "phpdoc" - ], - "time": "2015-06-05 03:36:34" + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" }, { "name": "sebastian/comparator", @@ -2962,7 +3594,7 @@ "compare", "equality" ], - "time": "2017-01-29 09:50:25" + "time": "2017-01-29T09:50:25+00:00" }, { "name": "sebastian/diff", @@ -3014,32 +3646,32 @@ "keywords": [ "diff" ], - "time": "2017-05-22 07:24:03" + "time": "2017-05-22T07:24:03+00:00" }, { "name": "sebastian/environment", - "version": "1.3.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" + "phpunit/phpunit": "^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -3064,25 +3696,25 @@ "environment", "hhvm" ], - "time": "2016-08-18 05:49:44" + "time": "2016-11-26T07:53:53+00:00" }, { "name": "sebastian/exporter", - "version": "1.2.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", "shasum": "" }, "require": { "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" + "sebastian/recursion-context": "~2.0" }, "require-dev": { "ext-mbstring": "*", @@ -3091,7 +3723,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -3131,7 +3763,7 @@ "export", "exporter" ], - "time": "2016-06-17 09:04:28" + "time": "2016-11-19T08:54:04+00:00" }, { "name": "sebastian/global-state", @@ -3182,20 +3814,66 @@ "keywords": [ "global state" ], - "time": "2015-10-12 03:26:01" + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-02-18T15:18:39+00:00" }, { "name": "sebastian/recursion-context", - "version": "1.0.5", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", "shasum": "" }, "require": { @@ -3207,7 +3885,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -3235,23 +3913,73 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-10-03 07:41:43" + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" }, { "name": "sebastian/version", - "version": "1.0.6", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, + "require": { + "php": ">=5.6" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -3270,7 +3998,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21 13:59:46" + "time": "2016-10-03T07:35:21+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -3348,29 +4076,29 @@ "phpcs", "standards" ], - "time": "2017-05-22 02:43:20" + "time": "2017-05-22T02:43:20+00:00" }, { "name": "symfony/browser-kit", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "e49a78bcf09ba2e6d03e63e80211f889c037add5" + "reference": "490f27762705c8489bd042fe3e9377a191dba9b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/e49a78bcf09ba2e6d03e63e80211f889c037add5", - "reference": "e49a78bcf09ba2e6d03e63e80211f889c037add5", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/490f27762705c8489bd042fe3e9377a191dba9b4", + "reference": "490f27762705c8489bd042fe3e9377a191dba9b4", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/dom-crawler": "~2.1|~3.0.0" + "php": "^5.5.9|>=7.0.8", + "symfony/dom-crawler": "~2.8|~3.0|~4.0" }, "require-dev": { - "symfony/css-selector": "^2.0.5|~3.0.0", - "symfony/process": "~2.3.34|^2.7.6|~3.0.0" + "symfony/css-selector": "~2.8|~3.0|~4.0", + "symfony/process": "~2.8|~3.0|~4.0" }, "suggest": { "symfony/process": "" @@ -3378,7 +4106,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -3405,29 +4133,29 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2018-01-03 07:36:31" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/css-selector", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "c5b39674eacd34adedbef78227c57109caa9e318" + "reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/c5b39674eacd34adedbef78227c57109caa9e318", - "reference": "c5b39674eacd34adedbef78227c57109caa9e318", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/e66394bc7610e69279bfdb3ab11b4fe65403f556", + "reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -3458,28 +4186,28 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2018-01-03 07:36:31" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/dom-crawler", - "version": "v2.8.34", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "31ff8f1d7a3de4b43b35ff821e6e223d81a8988b" + "reference": "09bd97b844b3151fab82f2fdd62db9c464b3910a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/31ff8f1d7a3de4b43b35ff821e6e223d81a8988b", - "reference": "31ff8f1d7a3de4b43b35ff821e6e223d81a8988b", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/09bd97b844b3151fab82f2fdd62db9c464b3910a", + "reference": "09bd97b844b3151fab82f2fdd62db9c464b3910a", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/css-selector": "~2.8|~3.0.0" + "symfony/css-selector": "~2.8|~3.0|~4.0" }, "suggest": { "symfony/css-selector": "" @@ -3487,7 +4215,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -3514,38 +4242,39 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2018-01-03 07:36:31" + "time": "2018-01-03T07:37:34+00:00" }, { - "name": "symfony/process", - "version": "v2.8.34", + "name": "webmozart/assert", + "version": "1.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "905efe90024caa75a2fc93f54e14b26f2a099d96" + "url": "https://github.com/webmozart/assert.git", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/905efe90024caa75a2fc93f54e14b26f2a099d96", - "reference": "905efe90024caa75a2fc93f54e14b26f2a099d96", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "1.3-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Webmozart\\Assert\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3553,17 +4282,17 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], - "description": "Symfony Process Component", - "homepage": "https://symfony.com", - "time": "2018-01-29 08:54:45" + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-11-23T20:04:58+00:00" } ], "aliases": [], @@ -3572,10 +4301,10 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.4" + "php": ">=5.6" }, "platform-dev": [], "platform-overrides": { - "php": "5.4.7" + "php": "5.6" } } diff --git a/phpBB/config/default/container/services.yml b/phpBB/config/default/container/services.yml index 9bb1d673f41..950b8ae295a 100644 --- a/phpBB/config/default/container/services.yml +++ b/phpBB/config/default/container/services.yml @@ -8,6 +8,7 @@ imports: - { resource: services_cron.yml } - { resource: services_db.yml } - { resource: services_event.yml } + - { resource: services_extensions.yml } - { resource: services_feed.yml } - { resource: services_files.yml } - { resource: services_filesystem.yml } @@ -24,6 +25,7 @@ imports: - { resource: services_profilefield.yml } - { resource: services_report.yml } - { resource: services_routing.yml } + - { resource: services_storage.yml } - { resource: services_text_formatter.yml } - { resource: services_text_reparser.yml } - { resource: services_twig.yml } @@ -98,25 +100,12 @@ services: - '%core.root_path%' - '@template' - ext.manager: - class: phpbb\extension\manager - arguments: - - '@service_container' - - '@dbal.conn' - - '@config' - - '@filesystem' - - '%tables.ext%' - - '%core.root_path%' - - '%core.php_ext%' - - '@cache' - file_downloader: class: phpbb\file_downloader file_locator: class: phpbb\routing\file_locator arguments: - - '@filesystem' - '%core.root_path%' group_helper: @@ -140,7 +129,6 @@ services: class: phpbb\path_helper arguments: - '@symfony_request' - - '@filesystem' - '@request' - '%core.root_path%' - '%core.php_ext%' diff --git a/phpBB/config/default/container/services_avatar.yml b/phpBB/config/default/container/services_avatar.yml index 6cc38516ae9..93a8cd0b62d 100644 --- a/phpBB/config/default/container/services_avatar.yml +++ b/phpBB/config/default/container/services_avatar.yml @@ -61,11 +61,11 @@ services: - '@config' - '%core.root_path%' - '%core.php_ext%' - - '@filesystem' + - '@storage.avatar' - '@path_helper' - '@dispatcher' - '@files.factory' - - '@cache.driver' + - '@php_ini' calls: - [set_name, [avatar.driver.upload]] tags: diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml index a327b74ac42..c2c3cdecce5 100644 --- a/phpBB/config/default/container/services_console.yml +++ b/phpBB/config/default/container/services_console.yml @@ -140,6 +140,33 @@ services: tags: - { name: console.command } + console.command.extension.install: + class: phpbb\console\command\extension\install + arguments: + - '@user' + - '@ext.composer.manager' + - '@language' + tags: + - { name: console.command } + + console.command.extension.list_available: + class: phpbb\console\command\extension\list_available + arguments: + - '@user' + - '@ext.composer.manager' + - '@language' + tags: + - { name: console.command } + + console.command.extension.manage: + class: phpbb\console\command\extension\manage + arguments: + - '@user' + - '@ext.composer.manager' + - '@language' + tags: + - { name: console.command } + console.command.extension.purge: class: phpbb\console\command\extension\purge arguments: @@ -149,6 +176,15 @@ services: tags: - { name: console.command } + console.command.extension.remove: + class: phpbb\console\command\extension\remove + arguments: + - '@user' + - '@ext.composer.manager' + - '@language' + tags: + - { name: console.command } + console.command.extension.show: class: phpbb\console\command\extension\show arguments: @@ -158,6 +194,15 @@ services: tags: - { name: console.command } + console.command.extension.update: + class: phpbb\console\command\extension\update + arguments: + - '@user' + - '@ext.composer.manager' + - '@language' + tags: + - { name: console.command } + console.command.fixup.recalculate_email_hash: class: phpbb\console\command\fixup\recalculate_email_hash arguments: diff --git a/phpBB/config/default/container/services_content.yml b/phpBB/config/default/container/services_content.yml index 602fd25f4e6..63e370f9b57 100644 --- a/phpBB/config/default/container/services_content.yml +++ b/phpBB/config/default/container/services_content.yml @@ -68,5 +68,3 @@ services: viewonline_helper: class: phpbb\viewonline_helper - arguments: - - '@filesystem' diff --git a/phpBB/config/default/container/services_cron.yml b/phpBB/config/default/container/services_cron.yml index d7f63885362..70f70e355df 100644 --- a/phpBB/config/default/container/services_cron.yml +++ b/phpBB/config/default/container/services_cron.yml @@ -3,6 +3,7 @@ services: class: phpbb\cron\manager arguments: - '@cron.task_collection' + - '@routing.helper' - '%core.root_path%' - '%core.php_ext%' @@ -13,6 +14,18 @@ services: - '@config' - '@dbal.conn' + cron.controller: + class: phpbb\cron\controller\cron + + cron.event_listener: + class: phpbb\cron\event\cron_runner_listener + arguments: + - '@cron.lock_db' + - '@cron.manager' + - '@request' + tags: + - { name: kernel.event_subscriber } + # ----- Cron tasks ----- cron.task_collection: class: phpbb\di\service_collection diff --git a/phpBB/config/default/container/services_extensions.yml b/phpBB/config/default/container/services_extensions.yml new file mode 100644 index 00000000000..53e36f0fda0 --- /dev/null +++ b/phpBB/config/default/container/services_extensions.yml @@ -0,0 +1,47 @@ +services: + ext.manager: + class: phpbb\extension\manager + arguments: + - '@service_container' + - '@dbal.conn' + - '@config' + - '%tables.ext%' + - '%core.root_path%' + - '%core.php_ext%' + - '@cache' + + ext.composer.installer: + class: phpbb\composer\installer + arguments: + - '%core.root_path%' + - '@filesystem' + - '@request' + - '@config' + + ext.composer.manager: + class: phpbb\composer\extension_manager + arguments: + - '@ext.composer.installer' + - '@cache.driver' + - '@ext.manager' + - '@filesystem' + - phpbb-extension + - EXTENSIONS_ + - '%core.root_path%' + - '@config' + + style.composer.manager: + class: phpbb\composer\manager + arguments: + - '@ext.composer.installer' + - '@cache.driver' + - phpbb-style + - STYLES_ + + lang.composer.manager: + class: phpbb\composer\manager + arguments: + - '@ext.composer.installer' + - '@cache.driver' + - phpbb-language + - LANGUAGES_ diff --git a/phpBB/config/default/container/services_files.yml b/phpBB/config/default/container/services_files.yml index ba1fdb4c9a1..96682d67139 100644 --- a/phpBB/config/default/container/services_files.yml +++ b/phpBB/config/default/container/services_files.yml @@ -16,6 +16,16 @@ services: - '@mimetype.guesser' - '@plupload' + files.filespec_storage: + class: phpbb\files\filespec_storage + shared: false + arguments: + - '@language' + - '@php_ini' + - '@upload_imagesize' + - '@mimetype.guesser' + - '@plupload' + files.upload: class: phpbb\files\upload shared: false @@ -36,6 +46,16 @@ services: - '@plupload' - '@request' + files.types.form_storage: + class: phpbb\files\types\form_storage + shared: false + arguments: + - '@files.factory' + - '@language' + - '@php_ini' + - '@plupload' + - '@request' + files.types.local: class: phpbb\files\types\local shared: false @@ -55,3 +75,14 @@ services: - '@php_ini' - '@request' - '%core.root_path%' + + files.types.remote_storage: + class: phpbb\files\types\remote_storage + shared: false + arguments: + - '@config' + - '@files.factory' + - '@language' + - '@php_ini' + - '@request' + - '%core.root_path%' diff --git a/phpBB/config/default/container/services_routing.yml b/phpBB/config/default/container/services_routing.yml index 3048145a2f7..cb397eab852 100644 --- a/phpBB/config/default/container/services_routing.yml +++ b/phpBB/config/default/container/services_routing.yml @@ -12,8 +12,6 @@ services: class: Symfony\Component\HttpKernel\EventListener\RouterListener arguments: - '@router' - - null - - null - '@request_stack' tags: - { name: kernel.event_subscriber } @@ -25,7 +23,6 @@ services: - '@router' - '@symfony_request' - '@request' - - '@filesystem' - '%core.root_path%' - '%core.php_ext%' diff --git a/phpBB/config/default/container/services_storage.yml b/phpBB/config/default/container/services_storage.yml new file mode 100644 index 00000000000..3593b8264a5 --- /dev/null +++ b/phpBB/config/default/container/services_storage.yml @@ -0,0 +1,59 @@ +services: + +# Storages + storage.avatar: + class: phpbb\storage\storage + arguments: + - '@storage.adapter.factory' + - 'avatar' + tags: + - { name: storage } + +# Factory + storage.adapter.factory: + class: phpbb\storage\adapter_factory + arguments: + - '@config' + - '@storage.adapter_collection' + - '@storage.provider_collection' + +# Collections + storage.storage_collection: + class: phpbb\di\service_collection + arguments: + - '@service_container' + tags: + - { name: service_collection, tag: storage } + + storage.adapter_collection: + class: phpbb\di\service_collection + arguments: + - '@service_container' + tags: + - { name: service_collection, tag: storage.adapter, class_name_aware: true } + + storage.provider_collection: + class: phpbb\di\service_collection + arguments: + - '@service_container' + tags: + - { name: service_collection, tag: storage.provider, class_name_aware: true } + +# Adapters + storage.adapter.local: + class: phpbb\storage\adapter\local + shared: false + arguments: + - '@filesystem' + - '@upload_imagesize' + - '@mimetype.guesser' + - '%core.root_path%' + tags: + - { name: storage.adapter } + +# Providers + storage.provider.local: + class: phpbb\storage\provider\local + arguments: + tags: + - { name: storage.provider } diff --git a/phpBB/config/default/container/services_twig.yml b/phpBB/config/default/container/services_twig.yml index a9b5b6d4cdf..c7ce82632ab 100644 --- a/phpBB/config/default/container/services_twig.yml +++ b/phpBB/config/default/container/services_twig.yml @@ -15,6 +15,7 @@ services: - [] calls: - [setLexer, ['@template.twig.lexer']] + - [addGlobal, ['config', '@config']] template.twig.lexer: class: phpbb\template\twig\lexer @@ -24,8 +25,6 @@ services: template.twig.loader: class: phpbb\template\twig\loader - arguments: - - '@filesystem' template.twig.extensions.collection: class: phpbb\di\service_collection diff --git a/phpBB/config/default/routing/cron.yml b/phpBB/config/default/routing/cron.yml new file mode 100644 index 00000000000..5a634166fa6 --- /dev/null +++ b/phpBB/config/default/routing/cron.yml @@ -0,0 +1,3 @@ +phpbb_cron_run: + path: /{cron_type} + defaults: { _controller: cron.controller:handle } diff --git a/phpBB/config/default/routing/routing.yml b/phpBB/config/default/routing/routing.yml index f381f024ade..199c5229b06 100644 --- a/phpBB/config/default/routing/routing.yml +++ b/phpBB/config/default/routing/routing.yml @@ -8,6 +8,10 @@ # instantiate the 'foo_service' service and call the 'method' method. # +phpbb_cron_routing: + resource: cron.yml + prefix: /cron + phpbb_feed_routing: resource: feed.yml prefix: /feed diff --git a/phpBB/config/development/config.yml b/phpBB/config/development/config.yml index f39eb52e736..1e144d68d6c 100644 --- a/phpBB/config/development/config.yml +++ b/phpBB/config/development/config.yml @@ -11,3 +11,7 @@ core: debug: true auto_reload: true enable_debug_extension: true + + extensions: + composer_debug: true + composer_verbose: true diff --git a/phpBB/config/installer/container/services.yml b/phpBB/config/installer/container/services.yml index 7203c0ab10d..080b8a48e38 100644 --- a/phpBB/config/installer/container/services.yml +++ b/phpBB/config/installer/container/services.yml @@ -31,7 +31,6 @@ services: file_locator: class: phpbb\routing\file_locator arguments: - - '@filesystem' - '%core.root_path%' kernel_exception_subscriber: @@ -50,7 +49,6 @@ services: class: phpbb\path_helper arguments: - '@symfony_request' - - '@filesystem' - '@request' - '%core.root_path%' - '%core.php_ext%' diff --git a/phpBB/cron.php b/phpBB/cron.php index 2f519947aa5..58261429a28 100644 --- a/phpBB/cron.php +++ b/phpBB/cron.php @@ -11,10 +11,11 @@ * */ +use Symfony\Component\HttpFoundation\RedirectResponse; + /** */ define('IN_PHPBB', true); -define('IN_CRON', true); $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './'; $phpEx = substr(strrchr(__FILE__, '.'), 1); include($phpbb_root_path . 'common.' . $phpEx); @@ -23,62 +24,14 @@ $user->session_begin(false); $auth->acl($user->data); -function output_image() -{ - // Output transparent gif - header('Cache-Control: no-cache'); - header('Content-type: image/gif'); - header('Content-length: 43'); - - echo base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='); - - // Flush here to prevent browser from showing the page as loading while - // running cron. - flush(); -} - -// Thanks to various fatal errors and lack of try/finally, it is quite easy to leave -// the cron lock locked, especially when working on cron-related code. -// -// Attempt to alleviate the problem by doing setup outside of the lock as much as possible. - $cron_type = $request->variable('cron_type', ''); -// Comment this line out for debugging so the page does not return an image. -output_image(); - -/* @var $cron_lock \phpbb\lock\db */ -$cron_lock = $phpbb_container->get('cron.lock_db'); -if ($cron_lock->acquire()) -{ - /* @var $cron \phpbb\cron\manager */ - $cron = $phpbb_container->get('cron.manager'); - - $task = $cron->find_task($cron_type); - if ($task) - { - /** - * This event enables you to catch the task before it runs - * - * @event core.cron_run_before - * @var \phpbb\cron\task\wrapper task Current Cron task - * @since 3.1.8-RC1 - */ - $vars = array( - 'task', - ); - extract($phpbb_dispatcher->trigger_event('core.cron_run_before', compact($vars))); - - if ($task->is_parametrized()) - { - $task->parse_parameters($request); - } - if ($task->is_ready()) - { - $task->run(); - } - } - $cron_lock->release(); -} +$get_params_array = $request->get_super_global(\phpbb\request\request_interface::GET); -garbage_collection(); +/** @var \phpbb\controller\helper $controller_helper */ +$controller_helper = $phpbb_container->get('controller.helper'); +$response = new RedirectResponse( + $controller_helper->route('phpbb_cron_run', $get_params_array), + 301 +); +$response->send(); diff --git a/phpBB/develop/adjust_avatars.php b/phpBB/develop/adjust_avatars.php index dc4ae88f371..a6b326109dd 100644 --- a/phpBB/develop/adjust_avatars.php +++ b/phpBB/develop/adjust_avatars.php @@ -19,7 +19,7 @@ $user->setup(); $echos = 0; - + if (!isset($config['avatar_salt'])) { $cache->purge(); @@ -30,6 +30,11 @@ die('database not up to date'); } +if (!isset($config['storage\\avatar\\config\\path']) || $config['storage\\avatar\\config\\path'] !== 'phpbb\\storage\\provider\\local') +{ + die('use local provider'); +} + // let's start with the users using a group_avatar. $sql = 'SELECT group_id, group_avatar FROM ' . GROUPS_TABLE . ' @@ -46,16 +51,16 @@ { $new_avatar_name = adjust_avatar($row['group_avatar'], 'g' . $row['group_id']); $group_avatars[] = $new_avatar_name; - + // failure is probably due to the avatar name already being adjusted if ($new_avatar_name !== false) { $sql = 'UPDATE ' . USERS_TABLE . " SET user_avatar = '" . $db->sql_escape($new_avatar_name) . "' - WHERE user_avatar = '" . $db->sql_escape($row['group_avatar']) . "' + WHERE user_avatar = '" . $db->sql_escape($row['group_avatar']) . "' AND user_avatar_type = " . AVATAR_UPLOAD; $db->sql_query($sql); - + $sql = 'UPDATE ' . GROUPS_TABLE . " SET group_avatar = '" . $db->sql_escape($new_avatar_name) . "' WHERE group_id = {$row['group_id']}"; @@ -80,8 +85,8 @@ $db->sql_freeresult($result); $sql = 'SELECT user_id, username, user_avatar, user_avatar_type - FROM ' . USERS_TABLE . ' - WHERE user_avatar_type = ' . AVATAR_UPLOAD . ' + FROM ' . USERS_TABLE . ' + WHERE user_avatar_type = ' . AVATAR_UPLOAD . ' AND ' . $db->sql_in_set('user_avatar', $group_avatars, true, true); $result = $db->sql_query($sql); @@ -108,7 +113,7 @@ $db->sql_query($sql); echo '
Failed updating user ' . $row['user_id'] . "\n"; } - + if ($echos > 200) { echo '
' . "\n"; @@ -131,8 +136,8 @@ function adjust_avatar($old_name, $midfix) { global $config, $phpbb_root_path; - - $avatar_path = $phpbb_root_path . $config['avatar_path']; + + $avatar_path = $phpbb_root_path . $config['storage\\avatar\\config\\path']; $extension = strtolower(substr(strrchr($old_name, '.'), 1)); $new_name = $config['avatar_salt'] . '_' . $midfix . '.' . $extension; diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 6e0a0820450..2dcb6e4a348 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -44,7 +44,7 @@ $phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); $phpbb_class_loader->register(); -$finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path); +$finder = new \phpbb\finder($phpbb_root_path); $classes = $finder->core_path('phpbb/') ->directory('/db/migration/data') ->get_classes(); diff --git a/phpBB/develop/mysql_upgrader.php b/phpBB/develop/mysql_upgrader.php index 276c010e848..a1e4b76d9cb 100644 --- a/phpBB/develop/mysql_upgrader.php +++ b/phpBB/develop/mysql_upgrader.php @@ -62,7 +62,7 @@ @set_time_limit(0); -$finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path); +$finder = new \phpbb\finder($phpbb_root_path); $classes = $finder->core_path('phpbb/') ->directory('/db/migration/data') ->get_classes(); diff --git a/phpBB/docs/CREDITS.txt b/phpBB/docs/CREDITS.txt index 4c8974d7c9b..4b6fe9e6302 100644 --- a/phpBB/docs/CREDITS.txt +++ b/phpBB/docs/CREDITS.txt @@ -83,10 +83,10 @@ prosilver by subBlue Design, Tom Beddard, (c) 2004 phpBB Limited phpBB contains code from the following applications: -LGPL licenced: +LGPL licensed: Smarty (c) 2001, 2002 by ispi of Lincoln, Inc, http://smarty.php.net/ -GPL licenced: +GPL licensed: phpMyAdmin (c) 2001, 2003 phpMyAdmin Devel team, http://www.phpmyadmin.net/ Jabber Class (c) 2006 Flyspray.org, http://www.flyspray.org/ Chora (c) 2000-2006, The Horde Project. http://horde.org/chora/ @@ -100,6 +100,6 @@ Pear (c) 2001-2004 PHP Group, http://pear.php.net Text_Diff-0.2.1 http://pear.php.net/package/Text_Diff -MIT licenced: +MIT licensed: Symfony2 (c) 2004-2011 Fabien Potencier, https://symfony.com/ Cookie Consent (c) 2015 Silktide Ltd, https://cookieconsent.insites.com diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index 8fb9036ad82..4a0c6c8593d 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -4,7 +4,7 @@ - + phpBB • Readme @@ -21,7 +21,7 @@
-

phpBB 3.2.x Readme

+

phpBB 3.3.x Readme

Skip

@@ -323,7 +323,7 @@

Readme

-

phpBB 3.2.x takes advantage of new features added in PHP 5.4. We recommend that you upgrade to the latest stable release of PHP to run phpBB. The minimum version required is PHP 5.4.7 and the maximum supported version is the latest stable version of PHP.

+

phpBB 3.2.x takes advantage of new features added in PHP 5.5.9. We recommend that you upgrade to the latest stable release of PHP to run phpBB. The minimum version required is PHP 5.5.9 and the maximum supported version is the latest stable version of PHP.

Please remember that running any application on a development (unstable, e.g. a beta release) version of PHP can lead to strange/unexpected results which may appear to be bugs in the application. Therefore, we recommend you upgrade to the newest stable version of PHP before running phpBB. If you are running a development version of PHP please check any bugs you find on a system running a stable release before submitting.

diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index 569ffe680ce..ff324a6c1a0 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -264,7 +264,6 @@

PHPBB_USE_BOARD_URL_PATH

  • {T_SUPER_TEMPLATE_PATH} - styles/xxx/template
  • {T_IMAGES_PATH} - images/
  • {T_SMILIES_PATH} - $config['smilies_path']/
  • -
  • {T_AVATAR_PATH} - $config['avatar_path']/
  • {T_AVATAR_GALLERY_PATH} - $config['avatar_gallery_path']/
  • {T_ICONS_PATH} - $config['icons_path']/
  • {T_RANKS_PATH} - $config['ranks_path']/
  • @@ -1211,7 +1210,7 @@

    Other functions, operators, statements and keywords:

    <td class="gensmall">TEST</td>
    -

    Try to match text class types with existing useage, e.g. don't use the nav class where viewtopic uses gensmall for example.

    +

    Try to match text class types with existing usage, e.g. don't use the nav class where viewtopic uses gensmall for example.

    Row colours/classes are now defined by the template, use an IF S_ROW_COUNT switch, see viewtopic or viewforum for an example.

    @@ -1223,7 +1222,7 @@

    Other functions, operators, statements and keywords:

    The separate catXXXX and thXXX classes are gone. When defining a header cell just use <th> rather than <th class="thHead"> etc. Similarly for cat, don't use <td class="catLeft"> use <td class="cat"> etc.

    -

    Try to retain consistency of basic layout and class useage, i.e. _EXPLAIN text should generally be placed below the title it explains, e.g. {L_POST_USERNAME}<br /><span class="gensmall">{L_POST_USERNAME_EXPLAIN}</span> is the typical way of handling this ... there may be exceptions and this isn't a hard and fast rule.

    +

    Try to retain consistency of basic layout and class usage, i.e. _EXPLAIN text should generally be placed below the title it explains, e.g. {L_POST_USERNAME}<br /><span class="gensmall">{L_POST_USERNAME_EXPLAIN}</span> is the typical way of handling this ... there may be exceptions and this isn't a hard and fast rule.

    Try to keep template conditional and other statements tabbed in line with the block to which they refer.

    @@ -1767,7 +1766,7 @@

    What are Unicode, UCS and UTF-8?

    The Universal Character Set (UCS) described in ISO/IEC 10646 consists of a large amount of characters. Each of them has a unique name and a code point which is an integer number. Unicode - which is an industry standard - complements the Universal Character Set with further information about the characters' properties and alternative character encodings. More information on Unicode can be found on the Unicode Consortium's website. One of the Unicode encodings is the 8-bit Unicode Transformation Format (UTF-8). It encodes characters with up to four bytes aiming for maximum compatibility with the American Standard Code for Information Interchange which is a 7-bit encoding of a relatively small subset of the UCS.

    phpBB's use of Unicode

    -

    Unfortunately PHP does not faciliate the use of Unicode prior to version 6. Most functions simply treat strings as sequences of bytes assuming that each character takes up exactly one byte. This behaviour still allows for storing UTF-8 encoded text in PHP strings but many operations on strings have unexpected results. To circumvent this problem we have created some alternative functions to PHP's native string operations which use code points instead of bytes. These functions can be found in /includes/utf/utf_tools.php. They are also covered in the phpBB3 Sourcecode Documentation. A lot of native PHP functions still work with UTF-8 as long as you stick to certain restrictions. For example explode still works as long as the first and the last character of the delimiter string are ASCII characters.

    +

    Unfortunately PHP does not facilitate the use of Unicode prior to version 6. Most functions simply treat strings as sequences of bytes assuming that each character takes up exactly one byte. This behaviour still allows for storing UTF-8 encoded text in PHP strings but many operations on strings have unexpected results. To circumvent this problem we have created some alternative functions to PHP's native string operations which use code points instead of bytes. These functions can be found in /includes/utf/utf_tools.php. They are also covered in the phpBB3 Sourcecode Documentation. A lot of native PHP functions still work with UTF-8 as long as you stick to certain restrictions. For example explode still works as long as the first and the last character of the delimiter string are ASCII characters.

    phpBB only uses the ASCII and the UTF-8 character encodings. Still all Strings are UTF-8 encoded because ASCII is a subset of UTF-8. The only exceptions to this rule are code sections which deal with external systems which use other encodings and character sets. Such external data should be converted to UTF-8 using the utf8_recode() function supplied with phpBB. It supports a variety of other character sets and encodings, a full list can be found below.

    @@ -1848,7 +1847,7 @@

    Language Tag:

    The IETF recently published RFC 4646 for tags used to identify languages, which in combination with RFC 4647 obseletes the older RFC 3006 and older-still RFC 1766. RFC 4646 uses ISO 639-1/ISO 639-2, ISO 3166-1 alpha-2, ISO 15924 and UN M.49 to define a language tag. Each complete tag is composed of subtags which are not case sensitive and can also be empty.

    -

    Ordering of the subtags in the case that they are all non-empty is: language-script-region-variant-extension-privateuse. Should any subtag be empty, its corresponding hyphen would also be ommited. Thus, the language tag for English will be en and not en-----.

    +

    Ordering of the subtags in the case that they are all non-empty is: language-script-region-variant-extension-privateuse. Should any subtag be empty, its corresponding hyphen would also be omitted. Thus, the language tag for English will be en and not en-----.

    Most language tags consist of a two- or three-letter language subtag (from ISO 639-1/ISO 639-2). Sometimes, this is followed by a two-letter or three-digit region subtag (from ISO 3166-1 alpha-2 or UN M.49). Some examples are:

    @@ -1902,7 +1901,7 @@

    Language Tag:

    The ultimate aim of a language tag is to convey the needed useful distingushing information, whilst keeping it as short as possible. So for example, use en, fr and ja as opposed to en-GB, fr-FR and ja-JP, since we know English, French and Japanese are the native language of Great Britain, France and Japan respectively.

    -

    Next is the ISO 15924 language script code and when one should or shouldn't use it. For example, whilst en-Latn is syntaxically correct for describing English written with Latin script, real world English writing is more-or-less exclusively in the Latin script. For such languages like English that are written in a single script, the IANA Language Subtag Registry has a "Suppress-Script" field meaning the script code should be ommitted unless a specific language tag requires a specific script code. Some languages are written in more than one script and in such cases, the script code is encouraged since an end-user may be able to read their language in one script, but not the other. Some examples are:

    +

    Next is the ISO 15924 language script code and when one should or shouldn't use it. For example, whilst en-Latn is syntaxically correct for describing English written with Latin script, real world English writing is more-or-less exclusively in the Latin script. For such languages like English that are written in a single script, the IANA Language Subtag Registry has a "Suppress-Script" field meaning the script code should be omitted unless a specific language tag requires a specific script code. Some languages are written in more than one script and in such cases, the script code is encouraged since an end-user may be able to read their language in one script, but not the other. Some examples are:

    @@ -1967,7 +1966,7 @@

    Language Tag:

    Examples of using a language subtag in combination with a script subtag
    -

    Usage of the three-digit UN M.49 code over the two-letter ISO 3166-1 alpha-2 code should hapen if a macro-geographical entity is required and/or the ISO 3166-1 alpha-2 is ambiguous.

    +

    Usage of the three-digit UN M.49 code over the two-letter ISO 3166-1 alpha-2 code should happen if a macro-geographical entity is required and/or the ISO 3166-1 alpha-2 is ambiguous.

    Examples of English using marco-geographical regions:

    diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index f2b87ce7f1a..5dfd2245b53 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -164,13 +164,13 @@ acp_group_options_before === * Location: adm/style/acp_groups.html * Since: 3.1.0-b4 -* Purpose: Add addtional options to group settings (before GROUP_FOUNDER_MANAGE) +* Purpose: Add additional options to group settings (before GROUP_FOUNDER_MANAGE) acp_group_options_after === * Location: adm/style/acp_groups.html * Since: 3.1.0-b4 -* Purpose: Add addtional options to group settings (after GROUP_RECEIVE_PM) +* Purpose: Add additional options to group settings (after GROUP_RECEIVE_PM) acp_groups_find_username_append === diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 9ee489cef40..c7540c5380d 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -99,6 +99,11 @@ /* @var $phpbb_avatar_manager \phpbb\avatar\manager */ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager'); + if (@is_file($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php')) + { + require_once($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php'); + } + $filename = $request->variable('avatar', ''); $avatar_group = false; $exit = false; diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index f89f5535ebf..03af1e62651 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -82,34 +82,25 @@ function main($id, $mode) $display_vars = array( 'title' => 'ACP_BOARD_FEATURES', 'vars' => array( - 'legend1' => 'ACP_BOARD_FEATURES', - 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'allow_topic_notify' => array('lang' => 'ALLOW_TOPIC_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'allow_forum_notify' => array('lang' => 'ALLOW_FORUM_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'allow_pm_report' => array('lang' => 'ALLOW_PM_REPORT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'legend1' => 'ACP_BOARD_FEATURES', + 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'allow_topic_notify' => array('lang' => 'ALLOW_TOPIC_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_forum_notify' => array('lang' => 'ALLOW_FORUM_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_pm_report' => array('lang' => 'ALLOW_PM_REPORT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_board_notifications' => array('lang' => 'ALLOW_BOARD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'display_last_subject' => array('lang' => 'DISPLAY_LAST_SUBJECT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'allow_quick_reply' => array('lang' => 'ALLOW_QUICK_REPLY', 'validate' => 'bool', 'type' => 'custom', 'method' => 'quick_reply', 'explain' => true), - - 'legend2' => 'ACP_LOAD_SETTINGS', - 'load_birthdays' => array('lang' => 'YES_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'load_cpf_pm' => array('lang' => 'LOAD_CPF_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'display_last_subject' => array('lang' => 'DISPLAY_LAST_SUBJECT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'allow_quick_reply' => array('lang' => 'ALLOW_QUICK_REPLY', 'validate' => 'bool', 'type' => 'custom', 'method' => 'quick_reply', 'explain' => true), - 'legend3' => 'ACP_SUBMIT_CHANGES', + 'legend2' => 'ACP_SUBMIT_CHANGES', ) ); break; diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index 6f65dc9fa06..bfd20662746 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -24,23 +24,35 @@ class acp_extensions { - var $u_action; - var $tpl_name; - var $page_title; + public $u_action; + private $db; + + /** @var phpbb\config\config */ private $config; + + /** @var \phpbb\template\twig\twig */ private $template; private $user; private $log; + + /** @var \phpbb\request\request */ private $request; private $phpbb_dispatcher; + + /** @var \phpbb\extension\manager */ private $ext_manager; + private $u_catalog_action; + + /** @var string */ + private $phpbb_root_path; - function main() + function main($id, $mode) { // Start the page - global $config, $user, $template, $request, $phpbb_extension_manager, $phpbb_root_path, $phpbb_log, $phpbb_dispatcher; + global $config, $user, $template, $request, $phpbb_extension_manager, $db, $phpbb_log, $phpbb_dispatcher, $phpbb_root_path; + $this->db = $db; $this->config = $config; $this->template = $template; $this->user = $user; @@ -48,8 +60,24 @@ function main() $this->log = $phpbb_log; $this->phpbb_dispatcher = $phpbb_dispatcher; $this->ext_manager = $phpbb_extension_manager; + $this->phpbb_root_path = $phpbb_root_path; + + $this->user->add_lang(['install', 'acp/extensions', 'migrator']); - $this->user->add_lang(array('install', 'acp/extensions', 'migrator')); + switch ($mode) + { + case 'catalog': + $this->catalog_mode($id, $mode); + break; + default: + $this->main_mode($id, $mode); + break; + } + } + + public function main_mode($id, $mode) + { + global $phpbb_extension_manager, $phpbb_container, $phpbb_admin_path, $phpEx; $this->page_title = 'ACP_EXTENSIONS'; @@ -110,6 +138,8 @@ function main() } } + $this->u_catalog_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=catalog"); + // What are we doing? switch ($action) { @@ -133,7 +163,7 @@ function main() $this->config->set('extension_force_unstable', false); trigger_error($this->user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } - break; + break; case 'list': default: @@ -143,15 +173,27 @@ function main() trigger_error($this->user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } - $this->list_enabled_exts(); - $this->list_disabled_exts(); - $this->list_available_exts(); + /** @var \phpbb\composer\manager $composer_manager */ + $composer_manager = $phpbb_container->get('ext.composer.manager'); + + $managed_packages = []; + if ($composer_manager->check_requirements()) + { + $managed_packages = $composer_manager->get_managed_packages(); + } + + $this->list_enabled_exts($phpbb_extension_manager, $managed_packages); + $this->list_disabled_exts($phpbb_extension_manager, $managed_packages); + $this->list_available_exts($phpbb_extension_manager, $managed_packages); $this->template->assign_vars(array( 'U_VERSIONCHECK_FORCE' => $this->u_action . '&action=list&versioncheck_force=1', 'FORCE_UNSTABLE' => $this->config['extension_force_unstable'], 'U_ACTION' => $this->u_action, + 'MANAGED_EXTENSIONS' => $managed_packages, + 'U_CATALOG_ACTION' => $this->u_catalog_action, )); + $this->request->disable_super_globals(); $this->tpl_name = 'acp_ext_list'; break; @@ -223,7 +265,7 @@ function main() 'name' => 'adm', 'ext_path' => 'adm/style/', ), - ), array($phpbb_root_path . 'adm/style')); + ), array($this->phpbb_root_path . 'adm/style')); $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_ENABLE', time(), array($ext_name)); } @@ -391,11 +433,340 @@ function main() } /** - * Lists all the enabled extensions and dumps to the template - * - * @return null - */ - public function list_enabled_exts() + * Handles the catalog mode of the extensions list + * + * @param string $id + * @param string $mode + */ + public function catalog_mode($id, $mode) + { + global $phpbb_container; + + $action = $this->request->variable('action', 'list'); + + /** @var \phpbb\language\language $language */ + $language = $phpbb_container->get('language'); + + /** @var \phpbb\composer\manager $composer_manager */ + $composer_manager = $phpbb_container->get('ext.composer.manager'); + + /** @var \phpbb\extension\manager $extensions_manager */ + $extensions_manager = $phpbb_container->get('ext.manager'); + + if (!$composer_manager->check_requirements()) + { + $this->page_title = 'ACP_EXTENSIONS_CATALOG'; + $this->tpl_name = 'message_body'; + + $this->template->assign_vars([ + 'MESSAGE_TITLE' => $language->lang('EXTENSIONS_CATALOG_NOT_AVAILABLE'), + 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE'), + ]); + + return; + } + + switch ($action) + { + case 'install': + $this->page_title = 'ACP_EXTENSIONS_INSTALL'; + + $extension = $this->request->variable('extension', ''); + + if (empty($extension)) + { + redirect($this->u_action); + } + + $formatter = new \phpbb\composer\io\html_output_formatter([ + 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow') + ]); + + $composer_io = new \phpbb\composer\io\web_io($language, '', $phpbb_container->getParameter('extensions.composer.output'), $formatter); + + try + { + $composer_manager->install((array) $extension, $composer_io); + } + catch (\phpbb\exception\runtime_exception $e) + { + $this->display_composer_exception($language, $e, $composer_io); + return; + } + $this->tpl_name = 'detailed_message_body'; + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_INSTALL'), + 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_INSTALLED') . adm_back_link($this->u_action), + 'MESSAGE_DETAIL' => $composer_io->getOutput(), + 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'), + 'S_USER_NOTICE' => true, + ) + ); + + break; + case 'remove': + $this->page_title = 'ACP_EXTENSIONS_REMOVE'; + + $extension = $this->request->variable('extension', ''); + + if (empty($extension)) + { + redirect($this->u_action); + } + + $formatter = new \phpbb\composer\io\html_output_formatter([ + 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow') + ]); + + $composer_io = new \phpbb\composer\io\web_io($language, '', $phpbb_container->getParameter('extensions.composer.output'), $formatter); + + try + { + $composer_manager->remove((array) $extension, $composer_io); + } + catch (\phpbb\exception\runtime_exception $e) + { + $this->display_composer_exception($language, $e, $composer_io); + return; + } + $this->tpl_name = 'detailed_message_body'; + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_REMOVE'), + 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_REMOVED') . adm_back_link($this->u_action), + 'MESSAGE_DETAIL' => $composer_io->getOutput(), + 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'), + 'S_USER_NOTICE' => true, + ) + ); + + break; + case 'update': + $this->page_title = 'ACP_EXTENSIONS_UPDATE'; + + $extension = $this->request->variable('extension', ''); + + if (empty($extension)) + { + redirect($this->u_action); + } + + $formatter = new \phpbb\composer\io\html_output_formatter([ + 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow') + ]); + + $composer_io = new \phpbb\composer\io\web_io($language, '', $phpbb_container->getParameter('extensions.composer.output'), $formatter); + + try + { + $composer_manager->update((array) $extension, $composer_io); + } + catch (\phpbb\exception\runtime_exception $e) + { + $this->display_composer_exception($language, $e, $composer_io); + return; + } + $this->tpl_name = 'detailed_message_body'; + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_UPDATE'), + 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_UPDATED') . adm_back_link($this->u_action), + 'MESSAGE_DETAIL' => $composer_io->getOutput(), + 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'), + 'S_USER_NOTICE' => true, + ) + ); + + break; + case 'manage': + $this->page_title = 'ACP_EXTENSIONS_MANAGE'; + + $extension = $this->request->variable('extension', ''); + + if (empty($extension)) + { + redirect($this->u_action); + } + + $formatter = new \phpbb\composer\io\html_output_formatter([ + 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow') + ]); + + $composer_io = new \phpbb\composer\io\web_io($language, '', $phpbb_container->getParameter('extensions.composer.output'), $formatter); + + try + { + $composer_manager->start_managing($extension, $composer_io); + } + catch (\phpbb\exception\runtime_exception $e) + { + $this->display_composer_exception($language, $e, $composer_io); + return; + } + $this->tpl_name = 'detailed_message_body'; + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_MANAGE'), + 'MESSAGE_TEXT' => $language->lang('EXTENSION_MANAGED_SUCCESS', $extension) . adm_back_link($this->u_action), + 'MESSAGE_DETAIL' => $composer_io->getOutput(), + 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'), + 'S_USER_NOTICE' => true, + ) + ); + + break; + case 'list': + default: + if (!$this->config['exts_composer_packagist'] && $this->request->is_set('enable_packagist') && confirm_box(true)) + { + $this->config->set('exts_composer_packagist', true); + $composer_manager->reset_cache(); + + trigger_error($language->lang('CONFIG_UPDATED') . adm_back_link($this->u_action)); + } + + $submit = $this->request->is_set('update'); + if ($submit) + { + if (!check_form_key('catalog_settings')) + { + trigger_error($language->lang('FORM_INVALID') . adm_back_link($this->u_action), E_USER_WARNING); + } + + $enable_packagist = $this->request->variable('enable_packagist', false); + $enable_on_install = $this->request->variable('enable_on_install', false); + $purge_on_remove = $this->request->variable('purge_on_remove', false); + $minimum_stability = $this->request->variable('minimum_stability', 'stable'); + $repositories = array_unique( + array_filter( + array_map( + 'trim', + explode("\n", $this->request->variable('repositories', '')) + ) + ) + ); + + $previous_minimum_stability = $this->config['exts_composer_minimum_stability']; + $previous_repositories = $this->config['exts_composer_repositories']; + $previous_enable_packagist = $this->config['exts_composer_packagist']; + + $this->config->set('exts_composer_enable_on_install', $enable_on_install); + $this->config->set('exts_composer_purge_on_remove', $purge_on_remove); + $this->config->set('exts_composer_minimum_stability', $minimum_stability); + $this->config->set('exts_composer_repositories', json_encode($repositories, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + + if ($minimum_stability != $previous_minimum_stability + || $repositories != $previous_repositories + || $enable_packagist != $previous_enable_packagist) + { + $composer_manager->reset_cache(); + } + + if (!$this->config['exts_composer_packagist'] && $enable_packagist) + { + $s_hidden_fields = build_hidden_fields(array( + 'enable_packagist' => $enable_packagist + )); + + confirm_box(false, $language->lang('ENABLE_PACKAGIST_CONFIRM'), $s_hidden_fields); + } + else + { + $this->config->set('exts_composer_packagist', $enable_packagist); + trigger_error($language->lang('CONFIG_UPDATED') . adm_back_link($this->u_action)); + } + } + + /** @var \phpbb\composer\extension_manager $manager */ + $manager = $phpbb_container->get('ext.composer.manager'); + + /** @var \phpbb\pagination $pagination */ + $pagination = $phpbb_container->get('pagination'); + + $start = $this->request->variable('start', 0); + $base_url = $this->u_action; + + $available_extensions = $manager->get_available_packages(); + $managed_packages = $manager->get_managed_packages(); + + $extensions = array_slice($available_extensions, $start, 20); + + $pagination->generate_template_pagination($base_url, 'pagination', 'start', count($available_extensions), 20, $start); + + $this->page_title = 'ACP_EXTENSIONS_CATALOG'; + $this->tpl_name = 'acp_ext_catalog'; + + $this->template->assign_vars([ + 'extensions' => $extensions, + 'managed_extensions' => array_keys($managed_packages), + 'installed_extensions' => array_keys($extensions_manager->all_available()), + 'U_ACTION' => $this->u_action, + 'settings' => [ + 'enable_packagist' => $this->config['exts_composer_packagist'], + 'enable_on_install' => $this->config['exts_composer_enable_on_install'], + 'purge_on_remove' => $this->config['exts_composer_purge_on_remove'], + 'minimum_stability' => $this->config['exts_composer_minimum_stability'], + 'stabilities' => array_keys(\Composer\Package\BasePackage::$stabilities), + 'repositories' => json_decode($this->config['exts_composer_repositories'], true), + ], + ]); + + add_form_key('catalog_settings'); + + break; + } + } + + /** + * Display an exception raised by the composer manager + * + * @param \phpbb\language\language $language + * @param \phpbb\exception\runtime_exception $e + * @param \phpbb\composer\io\web_io $composer_io + */ + private function display_composer_exception(\phpbb\language\language $language, \phpbb\exception\runtime_exception $e, \phpbb\composer\io\web_io $composer_io) + { + $this->tpl_name = 'detailed_message_body'; + + if ($e->getPrevious()) + { + $message_title = $language->lang_array($e->getMessage(), $e->get_parameters()); + + if ($e->getPrevious() instanceof \phpbb\exception\exception_interface) + { + $message_text = $language->lang_array($e->getPrevious()->getMessage(), $e->getPrevious()->get_parameters()) . adm_back_link($this->u_action); + } + else + { + $message_text = $e->getPrevious()->getMessage() . adm_back_link($this->u_action); + } + } + else + { + $message_title = $language->lang('INFORMATION'); + $message_text = $language->lang_array($e->getMessage(), $e->get_parameters()) . adm_back_link($this->u_action); + } + + $this->template->assign_vars(array( + 'MESSAGE_TITLE' => $message_title, + 'MESSAGE_TEXT' => $message_text, + 'MESSAGE_DETAIL' => $composer_io->getOutput(), + 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'), + 'S_USER_ERROR' => true, + ) + ); + } + + /** + * Lists all the enabled extensions and dumps to the template + * + * @param \phpbb\extension\manager $phpbb_extension_manager An instance of the extension manager + * @param array $managed_packages List of managed packages + * + * @return null + */ + public function list_enabled_exts(\phpbb\extension\manager $phpbb_extension_manager, array $managed_packages) { $enabled_extension_meta_data = array(); @@ -409,6 +780,7 @@ public function list_enabled_exts() $enabled_extension_meta_data[$name] = array( 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), 'META_VERSION' => $meta['version'], + 'META_NAME' => $md_manager->get_metadata('name'), ); if (isset($meta['extra']['version-check'])) @@ -458,15 +830,29 @@ public function list_enabled_exts() $this->output_actions('enabled', array( 'DISABLE' => $this->u_action . '&action=disable_pre&ext_name=' . urlencode($name), )); + + if (isset($managed_packages[$block_vars['META_NAME']])) + { + $this->output_actions('enabled', [ + 'UPDATE' => $this->u_catalog_action . '&action=update&extension=' . urlencode($block_vars['META_NAME']), + 'REMOVE' => [ + 'url' => $this->u_catalog_action . '&action=remove&extension=' . urlencode($block_vars['META_NAME']), + 'color' => '#BC2A4D;', + ] + ]); + } } } /** - * Lists all the disabled extensions and dumps to the template - * - * @return null - */ - public function list_disabled_exts() + * Lists all the disabled extensions and dumps to the template + * + * @param \phpbb\extension\manager $phpbb_extension_manager An instance of the extension manager + * @param array $managed_packages List of managed packages + * + * @return null + */ + public function list_disabled_exts(\phpbb\extension\manager $phpbb_extension_manager, array $managed_packages) { $disabled_extension_meta_data = array(); @@ -480,6 +866,7 @@ public function list_disabled_exts() $disabled_extension_meta_data[$name] = array( 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), 'META_VERSION' => $meta['version'], + 'META_NAME' => $md_manager->get_metadata('name'), ); if (isset($meta['extra']['version-check'])) @@ -527,15 +914,29 @@ public function list_disabled_exts() 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), 'DELETE_DATA' => $this->u_action . '&action=delete_data_pre&ext_name=' . urlencode($name), )); + + if (isset($managed_packages[$block_vars['META_NAME']])) + { + $this->output_actions('disabled', [ + 'UPDATE' => $this->u_catalog_action . '&action=update&extension=' . urlencode($block_vars['META_NAME']), + 'REMOVE' => [ + 'url' => $this->u_catalog_action . '&action=remove&extension=' . urlencode($block_vars['META_NAME']), + 'color' => '#BC2A4D;', + ] + ]); + } } } /** - * Lists all the available extensions and dumps to the template - * - * @return null - */ - public function list_available_exts() + * Lists all the available extensions and dumps to the template + * + * @param \phpbb\extension\manager $phpbb_extension_manager An instance of the extension manager + * @param array $managed_packages List of managed packages + * + * @return null + */ + public function list_available_exts(\phpbb\extension\manager $phpbb_extension_manager, array $managed_packages) { $uninstalled = array_diff_key($this->ext_manager->all_available(), $this->ext_manager->all_configured()); @@ -551,6 +952,7 @@ public function list_available_exts() $available_extension_meta_data[$name] = array( 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), 'META_VERSION' => $meta['version'], + 'META_NAME' => $md_manager->get_metadata('name'), ); if (isset($meta['extra']['version-check'])) @@ -604,13 +1006,26 @@ public function list_available_exts() */ private function output_actions($block, $actions) { - foreach ($actions as $lang => $url) + foreach ($actions as $lang => $options) { - $this->template->assign_block_vars($block . '.actions', array( + $url = $options; + if (is_array($options)) + { + $url = $options['url']; + } + + $vars = array( 'L_ACTION' => $this->user->lang('EXTENSION_' . $lang), 'L_ACTION_EXPLAIN' => (isset($this->user->lang['EXTENSION_' . $lang . '_EXPLAIN'])) ? $this->user->lang('EXTENSION_' . $lang . '_EXPLAIN') : '', 'U_ACTION' => $url, - )); + ); + + if (isset($options['color'])) + { + $vars['COLOR'] = $options['color']; + } + + $this->template->assign_block_vars($block . '.actions', $vars); } } diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index 8f169d15a79..99675e2b295 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -502,26 +502,8 @@ function main($id, $mode) $upload_dir_size = get_formatted_filesize($config['upload_dir_size']); - $avatar_dir_size = 0; - - if ($avatar_dir = @opendir($phpbb_root_path . $config['avatar_path'])) - { - while (($file = readdir($avatar_dir)) !== false) - { - if ($file[0] != '.' && $file != 'CVS' && strpos($file, 'index.') === false) - { - $avatar_dir_size += filesize($phpbb_root_path . $config['avatar_path'] . '/' . $file); - } - } - closedir($avatar_dir); - - $avatar_dir_size = get_formatted_filesize($avatar_dir_size); - } - else - { - // Couldn't open Avatar dir. - $avatar_dir_size = $user->lang['NOT_AVAILABLE']; - } + // Couldn't open Avatar dir. + $avatar_dir_size = $user->lang['NOT_AVAILABLE']; if ($posts_per_day > $total_posts) { diff --git a/phpBB/includes/acp/acp_storage.php b/phpBB/includes/acp/acp_storage.php new file mode 100644 index 00000000000..b2647843f1f --- /dev/null +++ b/phpBB/includes/acp/acp_storage.php @@ -0,0 +1,318 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +class acp_storage +{ + /** @var \phpbb\config $config */ + protected $config; + + /** @var \phpbb\language\language $lang */ + protected $lang; + + /** @var \phpbb\request\request */ + protected $request; + + /** @var \phpbb\template\template */ + protected $template; + + /** @var \phpbb\user */ + protected $user; + + /** @var \phpbb\di\service_collection */ + protected $provider_collection; + + /** @var \phpbb\di\service_collection */ + protected $storage_collection; + + /** @var string */ + public $page_title; + + /** @var string */ + public $tpl_name; + + /** @var string */ + public $u_action; + + /** + * @param string $id + * @param string $mode + */ + public function main($id, $mode) + { + global $phpbb_container, $phpbb_dispatcher; + + $this->config = $phpbb_container->get('config'); + $this->lang = $phpbb_container->get('language'); + $this->request = $phpbb_container->get('request'); + $this->template = $phpbb_container->get('template'); + $this->user = $phpbb_container->get('user'); + $this->provider_collection = $phpbb_container->get('storage.provider_collection'); + $this->storage_collection = $phpbb_container->get('storage.storage_collection'); + + // Add necesary language files + $this->lang->add_lang(['acp/storage']); + + /** + * Add language strings + * + * @event core.acp_storage_load + * @since 3.3.0-a1 + */ + $phpbb_dispatcher->dispatch('core.acp_storage_load'); + + $this->overview($id, $mode); + } + + /** + * @param string $id + * @param string $mode + */ + public function overview($id, $mode) + { + $form_key = 'acp_storage'; + add_form_key($form_key); + + // Template from adm/style + $this->tpl_name = 'acp_storage'; + + // Set page title + $this->page_title = 'STORAGE_TITLE'; + + if ($this->request->is_set_post('submit')) + { + $modified_storages = []; + $messages = []; + + if (!check_form_key($form_key)) + { + $messages[] = $this->lang->lang('FORM_INVALID'); + } + + foreach ($this->storage_collection as $storage) + { + $storage_name = $storage->get_name(); + + $options = $this->get_provider_options($this->get_current_provider($storage_name)); + + $modified = false; + + // Check if provider have been modified + if ($this->get_new_provider($storage_name) != $this->get_current_provider($storage_name)) + { + $modified = true; + } + + // Check if options have been modified + if (!$modified) + { + foreach (array_keys($options) as $definition) + { + if ($this->get_new_definition($storage_name, $definition) != $this->get_current_definition($storage_name, $definition)) + { + $modified = true; + break; + } + } + } + + // If the storage have been modified, validate options + if ($modified) + { + $modified_storages[] = $storage_name; + $this->validate_data($storage_name, $messages); + } + } + + if (!empty($modified_storages)) + { + if (empty($messages)) + { + foreach ($modified_storages as $storage_name) + { + $this->update_storage_config($storage_name); + } + + trigger_error($this->lang->lang('STORAGE_UPDATE_SUCCESSFUL') . adm_back_link($this->u_action), E_USER_NOTICE); + } + else + { + trigger_error(implode('
    ', $messages) . adm_back_link($this->u_action), E_USER_WARNING); + } + } + + // If there is no errors + trigger_error($this->lang->lang('STORAGE_NO_CHANGES') . adm_back_link($this->u_action), E_USER_WARNING); + } + + $this->template->assign_vars(array( + 'STORAGES' => $this->storage_collection, + 'PROVIDERS' => $this->provider_collection, + )); + } + + /** + * Get the current provider from config + * + * @param string $key Storage name + * @return string The current provider + */ + protected function get_current_provider($storage_name) + { + return $this->config['storage\\' . $storage_name . '\\provider']; + } + + /** + * Get the new provider from the request + * + * @param string $key Storage name + * @return string The new provider + */ + protected function get_new_provider($storage_name) + { + return $this->request->variable([$storage_name, 'provider'], ''); + } + + /** + * Get adapter definitions from a provider + * + * @param string $provider Provider class + * @return array Adapter definitions + */ + protected function get_provider_options($provider) + { + return $this->provider_collection->get_by_class($provider)->get_options(); + } + + /** + * Get the current value of the definition of a storage from config + * + * @param string $storage_name Storage name + * @param string $definition Definition + * @return string Definition value + */ + protected function get_current_definition($storage_name, $definition) + { + return $this->config['storage\\' . $storage_name . '\\config\\' . $definition]; + } + + /** + * Get the new value of the definition of a storage from the request + * + * @param string $storage_name Storage name + * @param string $definition Definition + * @return string Definition value + */ + protected function get_new_definition($storage_name, $definition) + { + return $this->request->variable([$storage_name, $definition], ''); + } + + /** + * Validates data + * + * @param string $storage_name Storage name + * @param array $messages Reference to messages array + */ + protected function validate_data($storage_name, &$messages) + { + $storage_title = $this->lang->lang('STORAGE_' . strtoupper($storage_name) . '_TITLE'); + + // Check if provider exists + try + { + $new_provider = $this->provider_collection->get_by_class($this->get_new_provider($storage_name)); + } + catch (\Exception $e) + { + $messages[] = $this->lang->lang('STORAGE_PROVIDER_NOT_EXISTS', $storage_title); + return; + } + + // Check if provider is available + if (!$new_provider->is_available()) + { + $messages[] = $this->lang->lang('STORAGE_PROVIDER_NOT_AVAILABLE', $storage_title); + return; + } + + // Check options + $new_options = $this->get_provider_options($this->get_new_provider($storage_name)); + + foreach ($new_options as $definition_key => $definition_value) + { + $provider = $this->provider_collection->get_by_class($this->get_new_provider($storage_name)); + $definition_title = $this->lang->lang('STORAGE_ADAPTER_' . strtoupper($provider->get_name()) . '_OPTION_' . strtoupper($definition_key)); + + $value = $this->get_new_definition($storage_name, $definition_key); + + switch ($definition_value['type']) + { + case 'email': + if (!filter_var($value, FILTER_VALIDATE_EMAIL)) + { + $messages[] = $this->lang->lang('STORAGE_FORM_TYPE_EMAIL_INCORRECT_FORMAT', $definition_title, $storage_title); + } + case 'text': + case 'password': + $maxlength = isset($definition_value['maxlength']) ? $definition_value['maxlength'] : 255; + if (strlen($value) > $maxlength) + { + $messages[] = $this->lang->lang('STORAGE_FORM_TYPE_TEXT_TOO_LONG', $definition_title, $storage_title); + } + break; + case 'radio': + case 'select': + if (!in_array($value, array_values($definition_value['options']))) + { + $messages[] = $this->lang->lang('STORAGE_FORM_TYPE_SELECT_NOT_AVAILABLE', $definition_title, $storage_title); + } + break; + } + } + } + + /** + * Updates an storage with the info provided in the form + * + * @param string $storage_name Storage name + */ + protected function update_storage_config($storage_name) + { + $current_options = $this->get_provider_options($this->get_current_provider($storage_name)); + + // Remove old storage config + foreach (array_keys($current_options) as $definition) + { + $this->config->delete('storage\\' . $storage_name . '\\config\\' . $definition); + } + + // Update provider + $this->config->set('storage\\' . $storage_name . '\\provider', $this->get_new_provider($storage_name)); + + // Set new storage config + $new_options = $this->get_provider_options($this->get_new_provider($storage_name)); + + foreach (array_keys($new_options) as $definition) + { + $this->config->set('storage\\' . $storage_name . '\\config\\' . $definition, $this->get_new_definition($storage_name, $definition)); + } + } +} diff --git a/phpBB/includes/acp/info/acp_extensions.php b/phpBB/includes/acp/info/acp_extensions.php index 9adcd543b92..f555d0fa8c0 100644 --- a/phpBB/includes/acp/info/acp_extensions.php +++ b/phpBB/includes/acp/info/acp_extensions.php @@ -20,6 +20,7 @@ function module() 'title' => 'ACP_EXTENSION_MANAGEMENT', 'modes' => array( 'main' => array('title' => 'ACP_EXTENSIONS', 'auth' => 'acl_a_extensions', 'cat' => array('ACP_EXTENSION_MANAGEMENT')), + 'catalog' => array('title' => 'ACP_EXTENSIONS_CATALOG', 'auth' => 'acl_a_extensions', 'cat' => array('ACP_EXTENSION_MANAGEMENT')), ), ); } diff --git a/phpBB/includes/acp/info/acp_storage.php b/phpBB/includes/acp/info/acp_storage.php new file mode 100644 index 00000000000..facec03c66b --- /dev/null +++ b/phpBB/includes/acp/info/acp_storage.php @@ -0,0 +1,34 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +class acp_storage_info +{ + function module() + { + return array( + 'filename' => 'acp_storage', + 'title' => 'ACP_STORAGE_SETTINGS', + 'modes' => array( + 'settings' => array('title' => 'ACP_STORAGE_SETTINGS', 'auth' => 'acl_a_storage', 'cat' => array('ACP_SERVER_CONFIGURATION')), + ), + ); + } + + function install() + { + } + + function uninstall() + { + } +} diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index 239e5c8ad6b..076fd4dc040 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -156,9 +156,7 @@ function bbcode_cache_init() $phpbb_container->get('path_helper'), $phpbb_container->getParameter('core.cache_dir'), $phpbb_container->get('ext.manager'), - new \phpbb\template\twig\loader( - $phpbb_filesystem - ) + new \phpbb\template\twig\loader() ), $phpbb_container->getParameter('core.cache_dir'), $phpbb_container->get('user'), diff --git a/phpBB/includes/compatibility_globals.php b/phpBB/includes/compatibility_globals.php index 0f403896a7d..464c5535328 100644 --- a/phpBB/includes/compatibility_globals.php +++ b/phpBB/includes/compatibility_globals.php @@ -18,6 +18,13 @@ exit; } +// +// Deprecated globals +// +define('ATTACHMENT_CATEGORY_WM', 2); // Windows Media Files - Streaming - @deprecated 3.2 +define('ATTACHMENT_CATEGORY_RM', 3); // Real Media Files - Streaming - @deprecated 3.2 +define('ATTACHMENT_CATEGORY_QUICKTIME', 6); // Quicktime/Mov files - @deprecated 3.2 + /** * Sets compatibility globals in the global scope * diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 7eeb36595df..6460a1ae7c1 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -28,7 +28,7 @@ */ // phpBB Version -@define('PHPBB_VERSION', '3.2.3-dev'); +@define('PHPBB_VERSION', '3.3.0-a1-dev'); // QA-related // define('PHPBB_QA', 1); @@ -171,11 +171,8 @@ // Categories - Attachments define('ATTACHMENT_CATEGORY_NONE', 0); define('ATTACHMENT_CATEGORY_IMAGE', 1); // Inline Images -define('ATTACHMENT_CATEGORY_WM', 2); // Windows Media Files - Streaming - @deprecated 3.2 -define('ATTACHMENT_CATEGORY_RM', 3); // Real Media Files - Streaming - @deprecated 3.2 define('ATTACHMENT_CATEGORY_THUMB', 4); // Not used within the database, only while displaying posts define('ATTACHMENT_CATEGORY_FLASH', 5); // Flash/SWF files -define('ATTACHMENT_CATEGORY_QUICKTIME', 6); // Quicktime/Mov files - @deprecated 3.2 // BBCode UID length define('BBCODE_UID_LEN', 8); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 4aae84705ba..d61f3bc6533 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -51,18 +51,6 @@ function phpbb_load_extensions_autoloaders($phpbb_root_path) } } -/** -* Casts a variable to the given type. -* -* @deprecated -*/ -function set_var(&$result, $var, $type, $multibyte = false) -{ - // no need for dependency injection here, if you have the object, call the method yourself! - $type_cast_helper = new \phpbb\request\type_cast_helper(); - $type_cast_helper->set_var($result, $var, $type, $multibyte); -} - /** * Generates an alphanumeric random string of given length * @@ -3497,15 +3485,7 @@ function phpbb_filter_root_path($errfile) if (empty($root_path)) { - if ($phpbb_filesystem) - { - $root_path = $phpbb_filesystem->realpath(dirname(__FILE__) . '/../'); - } - else - { - $filesystem = new \phpbb\filesystem\filesystem(); - $root_path = $filesystem->realpath(dirname(__FILE__) . '/../'); - } + $root_path = \phpbb\filesystem\helper::realpath(dirname(__FILE__) . '/../'); } return str_replace(array($root_path, '\\'), array('[ROOT]', '/'), $errfile); @@ -4342,6 +4322,9 @@ function page_header($page_title = '', $display_online_list = false, $item_id = $controller_helper = $phpbb_container->get('controller.helper'); $notification_mark_hash = generate_link_hash('mark_all_notifications_read'); + $phpbb_version_parts = explode('.', PHPBB_VERSION, 3); + $phpbb_major = $phpbb_version_parts[0] . '.' . $phpbb_version_parts[1]; + // The following assigns all _common_ variables that may be used at any point in a template. $template->assign_vars(array( 'SITENAME' => $config['sitename'], @@ -4375,6 +4358,8 @@ function page_header($page_title = '', $display_online_list = false, $item_id = 'SESSION_ID' => $user->session_id, 'ROOT_PATH' => $web_path, 'BOARD_URL' => $board_url, + 'PHPBB_VERSION' => PHPBB_VERSION, + 'PHPBB_MAJOR' => $phpbb_major, 'L_LOGIN_LOGOUT' => $l_login_logout, 'L_INDEX' => ($config['board_index_text'] !== '') ? $config['board_index_text'] : $user->lang['FORUM_INDEX'], @@ -4450,7 +4435,6 @@ function page_header($page_title = '', $display_online_list = false, $item_id = 'T_SUPER_TEMPLATE_PATH' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/template', 'T_IMAGES_PATH' => "{$web_path}images/", 'T_SMILIES_PATH' => "{$web_path}{$config['smilies_path']}/", - 'T_AVATAR_PATH' => "{$web_path}{$config['avatar_path']}/", 'T_AVATAR_GALLERY_PATH' => "{$web_path}{$config['avatar_gallery_path']}/", 'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/", 'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/", @@ -4468,7 +4452,6 @@ function page_header($page_title = '', $display_online_list = false, $item_id = 'T_SUPER_TEMPLATE_NAME' => rawurlencode((isset($user->style['style_parent_tree']) && $user->style['style_parent_tree']) ? $user->style['style_parent_tree'] : $user->style['style_path']), 'T_IMAGES' => 'images', 'T_SMILIES' => $config['smilies_path'], - 'T_AVATAR' => $config['avatar_path'], 'T_AVATAR_GALLERY' => $config['avatar_gallery_path'], 'T_ICONS' => $config['icons_path'], 'T_RANKS' => $config['ranks_path'], diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index 8bf42aa36ed..b3bde79339c 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -66,6 +66,9 @@ function adm_page_header($page_title) } } + $phpbb_version_parts = explode('.', PHPBB_VERSION, 3); + $phpbb_major = $phpbb_version_parts[0] . '.' . $phpbb_version_parts[1]; + $template->assign_vars(array( 'PAGE_TITLE' => $page_title, 'USERNAME' => $user->data['username'], @@ -75,6 +78,8 @@ function adm_page_header($page_title) 'SESSION_ID' => $user->session_id, 'ROOT_PATH' => $phpbb_root_path, 'ADMIN_ROOT_PATH' => $phpbb_admin_path, + 'PHPBB_VERSION' => PHPBB_VERSION, + 'PHPBB_MAJOR' => $phpbb_major, 'U_LOGOUT' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout'), 'U_ADM_LOGOUT' => append_sid("{$phpbb_admin_path}index.$phpEx", 'action=admlogout'), @@ -83,7 +88,6 @@ function adm_page_header($page_title) 'T_IMAGES_PATH' => "{$phpbb_root_path}images/", 'T_SMILIES_PATH' => "{$phpbb_root_path}{$config['smilies_path']}/", - 'T_AVATAR_PATH' => "{$phpbb_root_path}{$config['avatar_path']}/", 'T_AVATAR_GALLERY_PATH' => "{$phpbb_root_path}{$config['avatar_gallery_path']}/", 'T_ICONS_PATH' => "{$phpbb_root_path}{$config['icons_path']}/", 'T_RANKS_PATH' => "{$phpbb_root_path}{$config['ranks_path']}/", diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 2fb83770fe6..8e7048ef0f3 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -1160,28 +1160,6 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = return count($post_ids); } -/** -* Delete Attachments -* -* @deprecated 3.2.0-a1 (To be removed: 3.4.0) -* -* @param string $mode can be: post|message|topic|attach|user -* @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids -* @param bool $resync set this to false if you are deleting posts or topics -*/ -function delete_attachments($mode, $ids, $resync = true) -{ - global $phpbb_container; - - /** @var \phpbb\attachment\manager $attachment_manager */ - $attachment_manager = $phpbb_container->get('attachment.manager'); - $num_deleted = $attachment_manager->delete($mode, $ids, $resync); - - unset($attachment_manager); - - return $num_deleted; -} - /** * Deletes shadow topics pointing to a specified forum. * @@ -1293,23 +1271,6 @@ function update_posted_info(&$topic_ids) $db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary); } -/** -* Delete attached file -* -* @deprecated 3.2.0-a1 (To be removed: 3.4.0) -*/ -function phpbb_unlink($filename, $mode = 'file', $entry_removed = false) -{ - global $phpbb_container; - - /** @var \phpbb\attachment\manager $attachment_manager */ - $attachment_manager = $phpbb_container->get('attachment.manager'); - $unlink = $attachment_manager->unlink($filename, $mode, $entry_removed); - unset($attachment_manager); - - return $unlink; -} - /** * All-encompasing sync function * diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php index 4fe7e71117c..6ae72076e7a 100644 --- a/phpBB/includes/functions_compatibility.php +++ b/phpBB/includes/functions_compatibility.php @@ -22,7 +22,7 @@ /** * Get user avatar * -* @deprecated 3.1.0-a1 (To be removed: 3.3.0) +* @deprecated 3.1.0-a1 (To be removed: 4.0.0) * * @param string $avatar Users assigned avatar name * @param int $avatar_type Type of avatar @@ -50,7 +50,7 @@ function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $ /** * Hash the password * -* @deprecated 3.1.0-a2 (To be removed: 3.3.0) +* @deprecated 3.1.0-a2 (To be removed: 4.0.0) * * @param string $password Password to be hashed * @@ -68,7 +68,7 @@ function phpbb_hash($password) /** * Check for correct password * -* @deprecated 3.1.0-a2 (To be removed: 3.3.0) +* @deprecated 3.1.0-a2 (To be removed: 4.0.0) * * @param string $password The password in plain text * @param string $hash The stored password hash @@ -87,45 +87,16 @@ function phpbb_check_hash($password, $hash) /** * Eliminates useless . and .. components from specified path. * -* Deprecated, use filesystem class instead +* Deprecated, use storage helper class instead * * @param string $path Path to clean * @return string Cleaned path * -* @deprecated 3.1.0 (To be removed: 3.3.0) +* @deprecated 3.1.0 (To be removed: 4.0.0) */ function phpbb_clean_path($path) { - global $phpbb_path_helper, $phpbb_container; - - if (!$phpbb_path_helper && $phpbb_container) - { - /* @var $phpbb_path_helper \phpbb\path_helper */ - $phpbb_path_helper = $phpbb_container->get('path_helper'); - } - else if (!$phpbb_path_helper) - { - global $phpbb_root_path, $phpEx; - - // The container is not yet loaded, use a new instance - if (!class_exists('\phpbb\path_helper')) - { - require($phpbb_root_path . 'phpbb/path_helper.' . $phpEx); - } - - $request = new phpbb\request\request(); - $phpbb_path_helper = new phpbb\path_helper( - new phpbb\symfony_request( - $request - ), - new phpbb\filesystem\filesystem(), - $request, - $phpbb_root_path, - $phpEx - ); - } - - return $phpbb_path_helper->clean_path($path); + return \phpbb\filesystem\helper::clean_path($path); } /** @@ -136,7 +107,7 @@ function phpbb_clean_path($path) * * @return string Returns the options for timezone selector only * -* @deprecated 3.1.0 (To be removed: 3.3.0) +* @deprecated 3.1.0 (To be removed: 4.0.0) */ function tz_select($default = '', $truncate = false) { @@ -150,7 +121,7 @@ function tz_select($default = '', $truncate = false) * via admin_permissions. Changes of usernames and group names * must be carried through for the moderators table. * -* @deprecated 3.1.0 (To be removed: 3.3.0) +* @deprecated 3.1.0 (To be removed: 4.0.0) * @return null */ function cache_moderators() @@ -162,7 +133,7 @@ function cache_moderators() /** * Removes moderators and administrators from foe lists. * -* @deprecated 3.1.0 (To be removed: 3.3.0) +* @deprecated 3.1.0 (To be removed: 4.0.0) * @param array|bool $group_id If an array, remove all members of this group from foe lists, or false to ignore * @param array|bool $user_id If an array, remove this user from foe lists, or false to ignore * @return null @@ -182,7 +153,7 @@ function update_foes($group_id = false, $user_id = false) * @param string &$rank_img the rank image as full img tag is stored here after execution * @param string &$rank_img_src the rank image source is stored here after execution * -* @deprecated 3.1.0-RC5 (To be removed: 3.3.0) +* @deprecated 3.1.0-RC5 (To be removed: 4.0.0) * * Note: since we do not want to break backwards-compatibility, this function will only properly assign ranks to guests if you call it for them with user_posts == false */ @@ -232,7 +203,7 @@ function get_remote_file($host, $directory, $filename, &$errstr, &$errno, $port * * @return int|bool Returns the log_id, if the entry was added to the database, false otherwise. * - * @deprecated 3.1.0 (To be removed: 3.3.0) + * @deprecated 3.1.0 (To be removed: 4.0.0) */ function add_log() { @@ -280,7 +251,7 @@ function add_log() * * @return null * - * @deprecated 3.1.0 (To be removed: 3.3.0) + * @deprecated 3.1.0 (To be removed: 4.0.0) */ function set_config($config_name, $config_value, $is_dynamic = false, \phpbb\config\config $set_config = null) { @@ -310,7 +281,7 @@ function set_config($config_name, $config_value, $is_dynamic = false, \phpbb\con * * @return null * - * @deprecated 3.1.0 (To be removed: 3.3.0) + * @deprecated 3.1.0 (To be removed: 4.0.0) */ function set_config_count($config_name, $increment, $is_dynamic = false, \phpbb\config\config $set_config = null) { @@ -331,7 +302,7 @@ function set_config_count($config_name, $increment, $is_dynamic = false, \phpbb\ * See {@link \phpbb\request\request_interface::variable \phpbb\request\request_interface::variable} for * documentation of this function's use. * - * @deprecated 3.1.0 (To be removed: 3.3.0) + * @deprecated 3.1.0 (To be removed: 4.0.0) * @param mixed $var_name The form variable's name from which data shall be retrieved. * If the value is an array this may be an array of indizes which will give * direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a") @@ -389,7 +360,7 @@ function request_var($var_name, $default, $multibyte = false, $cookie = false, $ /** * Get tables of a database * - * @deprecated 3.1.0 (To be removed: 3.3.0) + * @deprecated 3.1.0 (To be removed: 4.0.0) */ function get_tables(&$db) { @@ -463,25 +434,21 @@ function phpbb_is_writable($file) * @param string $path Path to check absoluteness of * @return boolean * - * @deprecated 3.2.0-dev use \phpbb\filesystem\filesystem::is_absolute_path() instead + * @deprecated 3.2.0-dev use \phpbb\filesystem\helper::is_absolute_path() instead */ function phpbb_is_absolute($path) { - global $phpbb_filesystem; - - return $phpbb_filesystem->is_absolute_path($path); + return \phpbb\filesystem\helper::is_absolute_path($path); } /** * A wrapper for realpath * - * @deprecated 3.2.0-dev use \phpbb\filesystem\filesystem::realpath() instead + * @deprecated 3.2.0-dev use \phpbb\filesystem\helper::realpath() instead */ function phpbb_realpath($path) { - global $phpbb_filesystem; - - return $phpbb_filesystem->realpath($path); + return \phpbb\filesystem\helper::realpath($path); } /** @@ -492,7 +459,7 @@ function phpbb_realpath($path) * @param $number int|float The number we want to get the plural case for. Float numbers are floored. * @return int The plural-case we need to use for the number plural-rule combination * - * @deprecated 3.2.0-dev (To be removed: 3.3.0) + * @deprecated 3.2.0-dev (To be removed: 4.0.0) */ function phpbb_get_plural_form($rule, $number) { @@ -511,3 +478,93 @@ function phpbb_pcre_utf8_support() { return true; } + +/** + * Casts a variable to the given type. + * + * @deprecated 3.1 (To be removed 4.0.0) + */ +function set_var(&$result, $var, $type, $multibyte = false) +{ + // no need for dependency injection here, if you have the object, call the method yourself! + $type_cast_helper = new \phpbb\request\type_cast_helper(); + $type_cast_helper->set_var($result, $var, $type, $multibyte); +} + +/** + * Delete Attachments + * + * @deprecated 3.2.0-a1 (To be removed: 4.0.0) + * + * @param string $mode can be: post|message|topic|attach|user + * @param mixed $ids can be: post_ids, message_ids, topic_ids, attach_ids, user_ids + * @param bool $resync set this to false if you are deleting posts or topics + */ +function delete_attachments($mode, $ids, $resync = true) +{ + global $phpbb_container; + + /** @var \phpbb\attachment\manager $attachment_manager */ + $attachment_manager = $phpbb_container->get('attachment.manager'); + $num_deleted = $attachment_manager->delete($mode, $ids, $resync); + + unset($attachment_manager); + + return $num_deleted; +} + +/** + * Delete attached file + * + * @deprecated 3.2.0-a1 (To be removed: 4.0.0) + */ +function phpbb_unlink($filename, $mode = 'file', $entry_removed = false) +{ + global $phpbb_container; + + /** @var \phpbb\attachment\manager $attachment_manager */ + $attachment_manager = $phpbb_container->get('attachment.manager'); + $unlink = $attachment_manager->unlink($filename, $mode, $entry_removed); + unset($attachment_manager); + + return $unlink; +} + +/** + * Display reasons + * + * @deprecated 3.2.0-dev (To be removed: 4.0.0) + */ +function display_reasons($reason_id = 0) +{ + global $phpbb_container; + + $phpbb_container->get('phpbb.report.report_reason_list_provider')->display_reasons($reason_id); +} + +/** + * Upload Attachment - filedata is generated here + * Uses upload class + * + * @deprecated 3.2.0-a1 (To be removed: 4.0.0) + * + * @param string $form_name The form name of the file upload input + * @param int $forum_id The id of the forum + * @param bool $local Whether the file is local or not + * @param string $local_storage The path to the local file + * @param bool $is_message Whether it is a PM or not + * @param array $local_filedata A filespec object created for the local file + * + * @return array File data array + */ +function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false) +{ + global $phpbb_container; + + /** @var \phpbb\attachment\manager $attachment_manager */ + $attachment_manager = $phpbb_container->get('attachment.manager'); + $file = $attachment_manager->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata); + unset($attachment_manager); + + return $file; +} diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 4c1a90d5b57..117266b2499 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1148,18 +1148,6 @@ function display_custom_bbcodes() $phpbb_dispatcher->dispatch('core.display_custom_bbcodes'); } -/** -* Display reasons -* -* @deprecated 3.2.0-dev -*/ -function display_reasons($reason_id = 0) -{ - global $phpbb_container; - - $phpbb_container->get('phpbb.report.report_reason_list_provider')->display_reasons($reason_id); -} - /** * Display user activity (action forum/topic) */ diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index 7be12baa136..b6414c40dcd 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -25,30 +25,27 @@ */ function send_avatar_to_browser($file, $browser) { - global $config, $phpbb_root_path; + global $config, $phpbb_container; - $prefix = $config['avatar_salt'] . '_'; - $image_dir = $config['avatar_path']; + $storage = $phpbb_container->get('storage.avatar'); - // Adjust image_dir path (no trailing slash) - if (substr($image_dir, -1, 1) == '/' || substr($image_dir, -1, 1) == '\\') - { - $image_dir = substr($image_dir, 0, -1) . '/'; - } - $image_dir = str_replace(array('../', '..\\', './', '.\\'), '', $image_dir); + $prefix = $config['avatar_salt'] . '_'; + $file_path = $prefix . $file; - if ($image_dir && ($image_dir[0] == '/' || $image_dir[0] == '\\')) + if ($storage->exists($file_path) && !headers_sent()) { - $image_dir = ''; - } - $file_path = $phpbb_root_path . $image_dir . '/' . $prefix . $file; + $file_info = $storage->file_info($file_path); - if ((@file_exists($file_path) && @is_readable($file_path)) && !headers_sent()) - { header('Cache-Control: public'); - $image_data = @getimagesize($file_path); - header('Content-Type: ' . image_type_to_mime_type($image_data[2])); + try + { + header('Content-Type: ' . $file_info->mimetype); + } + catch (\phpbb\storage\exception\exception $e) + { + // Just don't send this header + } if ((strpos(strtolower($browser), 'msie') !== false) && !phpbb_is_greater_ie_version($browser, 7)) { @@ -69,24 +66,26 @@ function send_avatar_to_browser($file, $browser) header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT'); } - $size = @filesize($file_path); - if ($size) + try { - header("Content-Length: $size"); + header('Content-Length: ' . $file_info->size); } - - if (@readfile($file_path) == false) + catch (\phpbb\storage\exception\exception $e) { - $fp = @fopen($file_path, 'rb'); + // Just don't send this header + } - if ($fp !== false) - { - while (!feof($fp)) - { - echo fread($fp, 8192); - } - fclose($fp); - } + try + { + $fp = $storage->read_stream($file_path); + $output = fopen('php://output', 'w+b'); + stream_copy_to_stream($fp, $output); + fclose($fp); + fclose($output); + } + catch (\Exception $e) + { + // Send nothing } flush(); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index a85a3b67c5c..803d28458c2 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -700,9 +700,7 @@ protected function setup_template() $phpbb_container->get('path_helper'), $phpbb_container->getParameter('core.template.cache_path'), $phpbb_container->get('ext.manager'), - new \phpbb\template\twig\loader( - $phpbb_container->get('filesystem') - ), + new \phpbb\template\twig\loader(), $phpbb_dispatcher, array() ); diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index 3563a646e85..9cc6fc23a6c 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -933,6 +933,14 @@ function assign_tpl_vars($module_url) 'U_TITLE' => $u_title ); + if (isset($this->module_cache['parents'][$item_ary['id']]) || $item_ary['id'] == $this->p_id) + { + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $item_ary['lang'], + 'U_VIEW_FORUM' => $u_title, + )); + } + $template->assign_block_vars($use_tabular_offset, array_merge($tpl_ary, array_change_key_case($item_ary, CASE_UPPER))); } diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 78c66ac6b8d..b95926acb42 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -395,34 +395,6 @@ function posting_gen_topic_types($forum_id, $cur_topic_type = POST_NORMAL) // // Attachment related functions // - -/** -* Upload Attachment - filedata is generated here -* Uses upload class -* -* @deprecated 3.2.0-a1 (To be removed: 3.4.0) -* -* @param string $form_name The form name of the file upload input -* @param int $forum_id The id of the forum -* @param bool $local Whether the file is local or not -* @param string $local_storage The path to the local file -* @param bool $is_message Whether it is a PM or not -* @param array $local_filedata A filespec object created for the local file -* -* @return array File data array -*/ -function upload_attachment($form_name, $forum_id, $local = false, $local_storage = '', $is_message = false, $local_filedata = false) -{ - global $phpbb_container; - - /** @var \phpbb\attachment\manager $attachment_manager */ - $attachment_manager = $phpbb_container->get('attachment.manager'); - $file = $attachment_manager->upload($form_name, $forum_id, $local, $local_storage, $is_message, $local_filedata); - unset($attachment_manager); - - return $file; -} - /** * Calculate the needed size for Thumbnail */ diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 245d263720e..e5720facfb4 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -2179,7 +2179,9 @@ function phpbb_style_is_active($style_id) */ function avatar_delete($mode, $row, $clean_db = false) { - global $phpbb_root_path, $config; + global $config, $phpbb_container; + + $storage = $phpbb_container->get('storage.avatar'); // Check if the users avatar is actually *not* a group avatar if ($mode == 'user') @@ -2196,11 +2198,16 @@ function avatar_delete($mode, $row, $clean_db = false) } $filename = get_avatar_filename($row[$mode . '_avatar']); - if (file_exists($phpbb_root_path . $config['avatar_path'] . '/' . $filename)) + try { - @unlink($phpbb_root_path . $config['avatar_path'] . '/' . $filename); + $storage->delete($filename); + return true; } + catch (\phpbb\storage\exception\exception $e) + { + // Fail is covered by return statement below + } return false; } @@ -2520,7 +2527,9 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow */ function group_correct_avatar($group_id, $old_entry) { - global $config, $db, $phpbb_root_path; + global $config, $db, $phpbb_container; + + $storage = $phpbb_container->get('storage.avatar'); $group_id = (int) $group_id; $ext = substr(strrchr($old_entry, '.'), 1); @@ -2528,14 +2537,19 @@ function group_correct_avatar($group_id, $old_entry) $new_filename = $config['avatar_salt'] . "_g$group_id.$ext"; $new_entry = 'g' . $group_id . '_' . substr(time(), -5) . ".$ext"; - $avatar_path = $phpbb_root_path . $config['avatar_path']; - if (@rename($avatar_path . '/'. $old_filename, $avatar_path . '/' . $new_filename)) + try { + $this->storage->rename($old_filename, $new_filename); + $sql = 'UPDATE ' . GROUPS_TABLE . ' SET group_avatar = \'' . $db->sql_escape($new_entry) . "' WHERE group_id = $group_id"; $db->sql_query($sql); } + catch (\phpbb\storage\exception\exception $e) + { + // If rename fail, dont execute the query + } } diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index 1fb026167a9..5f7a784b3af 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -434,8 +434,8 @@ function main($id, $mode) 'GROUP_DESC_DISP' => generate_text_for_display($group_row['group_desc'], $group_row['group_desc_uid'], $group_row['group_desc_bitfield'], $group_row['group_desc_options']), 'GROUP_TYPE' => $group_row['group_type'], - 'AVATAR' => (empty($avatar) ? '' : $avatar), - 'AVATAR_IMAGE' => (empty($avatar) ? '' : $avatar), + 'AVATAR' => (empty($avatar) ? '' : $avatar), + 'AVATAR_IMAGE' => (empty($avatar) ? '' : $avatar), 'AVATAR_WIDTH' => (isset($group_row['group_avatar_width'])) ? $group_row['group_avatar_width'] : '', 'AVATAR_HEIGHT' => (isset($group_row['group_avatar_height'])) ? $group_row['group_avatar_height'] : '', )); diff --git a/phpBB/install/convert/convertor.php b/phpBB/install/convert/convertor.php index 5118651b711..619fc73275f 100644 --- a/phpBB/install/convert/convertor.php +++ b/phpBB/install/convert/convertor.php @@ -281,7 +281,7 @@ function convert_data($converter) $bad_folders = array(); $local_paths = array( - 'avatar_path' => path($config['avatar_path']), + 'avatar_path' => path($config['storage\\avatar\\config\\path']), 'avatar_gallery_path' => path($config['avatar_gallery_path']), 'icons_path' => path($config['icons_path']), 'ranks_path' => path($config['ranks_path']), diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index a453e5f7ffc..d0885dc620f 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -38,7 +38,7 @@ $convertor_data = array( 'forum_name' => 'phpBB 2.0.x', 'version' => '1.0.3', - 'phpbb_version' => '3.2.2', + 'phpbb_version' => '3.3.0-a1-dev', 'author' => 'phpBB Limited', 'dbms' => $dbms, 'dbhost' => $dbhost, diff --git a/phpBB/install/phpbbcli.php b/phpBB/install/phpbbcli.php index 17b8444aa55..4b86f64e2ac 100755 --- a/phpBB/install/phpbbcli.php +++ b/phpBB/install/phpbbcli.php @@ -23,7 +23,7 @@ define('IN_PHPBB', true); define('IN_INSTALL', true); define('PHPBB_ENVIRONMENT', 'production'); -define('PHPBB_VERSION', '3.2.2-RC1'); +define('PHPBB_VERSION', '3.3.0-a1-dev'); $phpbb_root_path = __DIR__ . '/../'; $phpEx = substr(strrchr(__FILE__, '.'), 1); diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 4dfe5e94aa0..58a7ff4f63f 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -55,7 +55,6 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_max_height' INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_max_width', '90'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_min_height', '20'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_min_width', '20'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_path', 'images/avatars/upload'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_salt', 'phpbb_avatar'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact', 'contact@yourdomain.tld'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact_name', ''); @@ -280,9 +279,17 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0 INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.2.3-dev'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.0-a1-dev'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_repositories', '[]'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_packagist', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_json_file', 'composer-ext.json'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_vendor_dir', 'vendor-ext/'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_enable_on_install', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_purge_on_remove', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\avatar\provider', 'phpbb\storage\provider\local'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\avatar\config\path', 'images/avatars/upload'); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('cache_last_gc', '0', 1); INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('cron_lock', '0', 1); @@ -402,6 +409,7 @@ INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_reasons', 1); INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_roles', 1); INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_search', 1); INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_server', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_storage', 1); INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_styles', 1); INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_switchperm', 1); INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_uauth', 1); diff --git a/phpBB/install/startup.php b/phpBB/install/startup.php index 9a4f9bfe39b..50758f5b985 100644 --- a/phpBB/install/startup.php +++ b/phpBB/install/startup.php @@ -120,6 +120,7 @@ function installer_msg_handler($errno, $msg_text, $errfile, $errline) $phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; // Include files +phpbb_require_updated('includes/compatibility_globals.' . $phpEx, $phpbb_root_path); phpbb_require_updated('includes/functions.' . $phpEx, $phpbb_root_path); phpbb_require_updated('includes/functions_content.' . $phpEx, $phpbb_root_path); phpbb_include_updated('includes/functions_compatibility.' . $phpEx, $phpbb_root_path); diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index 0d5f6fee25a..c6f62869de6 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -88,6 +88,11 @@ 'ACP_EXTENSION_GROUPS' => 'Manage attachment extension groups', 'ACP_EXTENSION_MANAGEMENT' => 'Extension management', 'ACP_EXTENSIONS' => 'Manage extensions', + 'ACP_EXTENSIONS_CATALOG' => 'Extensions catalog', + 'ACP_EXTENSIONS_INSTALL' => 'Install extensions', + 'ACP_EXTENSIONS_REMOVE' => 'Remove extensions', + 'ACP_EXTENSIONS_UPDATE' => 'Update extensions', + 'ACP_EXTENSIONS_MANAGE' => 'Manage extension automatically', 'ACP_FORUM_BASED_PERMISSIONS' => 'Forum based permissions', 'ACP_FORUM_LOGS' => 'Forum logs', @@ -173,6 +178,9 @@ 'ACP_SERVER_SETTINGS' => 'Server settings', 'ACP_SIGNATURE_SETTINGS' => 'Signature settings', 'ACP_SMILIES' => 'Smilies', + + 'ACP_STORAGE_SETTINGS' => 'Storage settings', + 'ACP_STYLE_MANAGEMENT' => 'Style management', 'ACP_STYLES' => 'Styles', 'ACP_STYLES_CACHE' => 'Purge Cache', @@ -240,6 +248,17 @@ 'EXCEPTION' => 'Exception', 'COLOUR_SWATCH' => 'Web-safe colour swatch', + + 'COMPOSER_UNSUPPORTED_OPERATION' => 'Operation unsupported for the package type “%s”.', + 'COMPOSER_UPDATING_DEPENDENCIES' => 'Updating packages', + 'COMPOSER_LOADING_REPOSITORIES' => 'Loading remote repositories with package information', + 'COMPOSER_ERROR_CONFLICT' => 'Your requirements could not be resolved to an installable set of packages.', + 'COMPOSER_REPOSITORY_UNAVAILABLE' => 'An error occurred while fetching the repository %s.', + 'COMPOSER_INSTALLING_PACKAGE' => ' - Installing %1$s (%2$s)', + 'COMPOSER_DELETING' => ' - Deleting %s', + 'COMPOSER_UPDATE_NOTHING' => 'Nothing to update', + 'COMPOSER_OUTPUT' => 'Composer output', + 'CONFIG_UPDATED' => 'Configuration updated successfully.', 'CRON_LOCK_ERROR' => 'Could not obtain cron lock.', 'CRON_NO_SUCH_TASK' => 'Could not find cron task “%s”.', @@ -372,7 +391,7 @@ 'DATABASE_SERVER_INFO' => 'Database server', 'DATABASE_SIZE' => 'Database size', - // Enviroment configuration checks, mbstring related + // Environment configuration checks, mbstring related 'ERROR_MBSTRING_FUNC_OVERLOAD' => 'Function overloading is improperly configured', 'ERROR_MBSTRING_FUNC_OVERLOAD_EXPLAIN' => 'mbstring.func_overload must be set to either 0 or 4. You can check the current value on the PHP information page.', 'ERROR_MBSTRING_ENCODING_TRANSLATION' => 'Transparent character encoding is improperly configured', diff --git a/phpBB/language/en/acp/extensions.php b/phpBB/language/en/acp/extensions.php index a96a7a2a2bb..c6eb147b86e 100644 --- a/phpBB/language/en/acp/extensions.php +++ b/phpBB/language/en/acp/extensions.php @@ -35,6 +35,22 @@ // in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine $lang = array_merge($lang, array( + + 'EXTENSION_ALREADY_INSTALLED' => 'The “%s” extension has already been installed.', + 'EXTENSION_ALREADY_INSTALLED_MANUALLY' => 'The “%s” extension has already been installed manually.', + 'EXTENSION_ALREADY_MANAGED' => 'The “%s” extension is already managed.', + 'EXTENSION_CANNOT_MANAGE_FILESYSTEM_ERROR' => 'The “%s” extension cannot be managed because the existing files could not be removed from the filesystem.', + 'EXTENSION_CANNOT_MANAGE_INSTALL_ERROR' => 'The “%s” extension could not be installed. The prior installation of this extension has been restored.', + 'EXTENSION_MANAGED_WITH_CLEAN_ERROR' => 'The “%1$s” extension has been installed but an error occurred and the old files could not be removed. You might want to delete the “%2$s” files manually.', + 'EXTENSION_MANAGED_WITH_ENABLE_ERROR' => 'The “%s” extension has been installed but an error occurred while enabling it.', + 'EXTENSION_NOT_INSTALLED' => 'The “%s” extension is not installed.', + + 'ENABLING_EXTENSIONS' => 'Enabling extensions', + 'DISABLING_EXTENSIONS' => 'Disabling extensions', + + 'EXTENSIONS_CATALOG' => 'Extensions Catalog', + 'EXTENSIONS_CATALOG_EXPLAIN' => 'Here you can browse all of the extensions available for your phpBB board. Extensions can easily be installed or removed with just a click. Adjust the settings to allow instant enabling and purging of extensions.', + 'EXTENSION' => 'Extension', 'EXTENSIONS' => 'Extensions', 'EXTENSIONS_ADMIN' => 'Extensions Manager', @@ -43,7 +59,6 @@ 'EXTENSION_NOT_AVAILABLE' => 'The selected extension is not available for this board, please verify your phpBB and PHP versions are allowed (see the details page).', 'EXTENSION_DIR_INVALID' => 'The selected extension has an invalid directory structure and cannot be enabled.', 'EXTENSION_NOT_ENABLEABLE' => 'The selected extension cannot be enabled, please verify the extension’s requirements.', - 'EXTENSION_NOT_INSTALLED' => 'The extension %s is not available. Please check that you have installed it correctly.', 'DETAILS' => 'Details', @@ -53,6 +68,8 @@ 'EXTENSION_DELETE_DATA' => 'Delete data', 'EXTENSION_DISABLE' => 'Disable', 'EXTENSION_ENABLE' => 'Enable', + 'EXTENSION_UPDATE' => 'Update', + 'EXTENSION_REMOVE' => 'Remove', 'EXTENSION_DELETE_DATA_EXPLAIN' => 'Deleting an extension’s data removes all of its data and settings. The extension files are retained so it can be enabled again.', 'EXTENSION_DISABLE_EXPLAIN' => 'Disabling an extension retains its files, data and settings but removes any functionality added by the extension.', @@ -94,6 +111,9 @@ 'EXTENSION_ENABLE_CONFIRM' => 'Are you sure that you wish to enable the “%s” extension?', 'EXTENSION_FORCE_UNSTABLE_CONFIRM' => 'Are you sure that you wish to force the use of unstable version?', + 'INSTALLED' => 'Installed', + 'INSTALLED_MANUALLY' => 'Installed manually', + 'RETURN_TO_EXTENSION_LIST' => 'Return to the extension list', 'EXT_DETAILS' => 'Extension Details', @@ -130,4 +150,32 @@ 'META_FIELD_NOT_SET' => 'Required meta field %s has not been set.', 'META_FIELD_INVALID' => 'Meta field %s is invalid.', + + 'EXTENSIONS_CATALOG_SETTINGS' => 'Extensions catalog settings', + 'ENABLE_ON_INSTALL' => 'Enable extensions while installing', + 'PURGE_ON_REMOVE' => 'Purge extensions while removing', + 'ENABLE_PACKAGIST' => 'Search packagist', + 'ENABLE_PACKAGIST_EXPLAIN' => 'Search packagist for phpBB extensions. Beware that packagist may contain extensions not validated by the phpBB Extension Customisations Team.', + 'ENABLE_PACKAGIST_CONFIRM' => 'Are you sure you want to search packagist?', + 'COMPOSER_REPOSITORIES' => 'Repositories', + 'COMPOSER_REPOSITORIES_EXPLAIN' => 'Add URLs to Composer repositories of phpBB extensions to search here, one per line (must be the base url of the packages.json file).', + 'NO_EXTENSION_AVAILABLE' => 'There are no extension available for your board', + + 'EXTENSION_MANAGED_SUCCESS' => 'The extension %s is now being managed automatically.', + 'EXTENSIONS_INSTALLED' => 'Extensions successfully installed.', + 'EXTENSIONS_REMOVED' => 'Extensions successfully removed.', + 'EXTENSIONS_UPDATED' => 'Extensions successfully updated.', + + 'EXTENSIONS_CATALOG_NOT_AVAILABLE' => 'The extensions catalog is not available', + 'EXTENSIONS_COMPOSER_NOT_WRITABLE' => 'In order to use the catalog, the following files and directories must be writable: ext/ vendor-ext/ composer-ext.json and composer-ext.lock', + + 'STABILITY_STABLE' => 'stable', + 'STABILITY_RC' => 'RC', + 'STABILITY_BETA' => 'beta', + 'STABILITY_ALPHA' => 'alpha', + 'STABILITY_DEV' => 'dev', + + 'COMPOSER_MINIMUM_STABILITY' => 'Minimum stability', + 'COMPOSER_MINIMUM_STABILITY_EXPLAIN' => 'Always use stable versions on a live forum. Non-stable versions may still be in development and could cause unexpected problems with your forum and should only be used for development purposes in local or staging environments.', + )); diff --git a/phpBB/language/en/acp/permissions_phpbb.php b/phpBB/language/en/acp/permissions_phpbb.php index 64740b311b8..9ab088c3e2c 100644 --- a/phpBB/language/en/acp/permissions_phpbb.php +++ b/phpBB/language/en/acp/permissions_phpbb.php @@ -200,6 +200,7 @@ 'ACL_A_ROLES' => 'Can manage roles', 'ACL_A_SWITCHPERM' => 'Can use others permissions', + 'ACL_A_STORAGE' => 'Can manage storages', 'ACL_A_STYLES' => 'Can manage styles', 'ACL_A_EXTENSIONS' => 'Can manage extensions', 'ACL_A_VIEWLOGS' => 'Can view logs', diff --git a/phpBB/language/en/acp/storage.php b/phpBB/language/en/acp/storage.php new file mode 100644 index 00000000000..638df2177e9 --- /dev/null +++ b/phpBB/language/en/acp/storage.php @@ -0,0 +1,64 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +* DO NOT CHANGE +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +if (empty($lang) || !is_array($lang)) +{ + $lang = array(); +} + +// DEVELOPERS PLEASE NOTE +// +// All language files should use UTF-8 as their encoding and the files must not contain a BOM. +// +// Placeholders can now contain order information, e.g. instead of +// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows +// translators to re-order the output of data while ensuring it remains correct +// +// You do not need this where single placeholders are used, e.g. 'Message %d' is fine +// equally where a string contains only two placeholders which are used to wrap text +// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine + +$lang = array_merge($lang, array( + + // Template + 'STORAGE_TITLE' => 'Storage Settings', + 'STORAGE_TITLE_EXPLAIN' => 'Change storage providers for the file storage types of phpBB. Choose local or remote providers to store files added to or created by phpBB.', + 'STORAGE_SELECT' => 'Select storage', + 'STORAGE_SELECT_DESC' => 'Select a storage from the list.', + + // Storage names + 'STORAGE_ATTACHMENT_TITLE' => 'Attachments storage', + 'STORAGE_AVATAR_TITLE' => 'Avatars storage', + 'STORAGE_BACKUP_TITLE' => 'Backup storage', + + // Local adapter + 'STORAGE_ADAPTER_LOCAL_NAME' => 'Local', + 'STORAGE_ADAPTER_LOCAL_OPTION_PATH' => 'Path', + + // Form validation + 'STORAGE_UPDATE_SUCCESSFUL' => 'All storage types were successfully updated.', + 'STORAGE_NO_CHANGES' => 'No changes have been applied.', + 'STORAGE_PROVIDER_NOT_EXISTS' => 'Provider selected for %s doesn’t exist.', + 'STORAGE_PROVIDER_NOT_AVAILABLE' => 'Provider selected for %s is not available.', + 'STORAGE_FORM_TYPE_EMAIL_INCORRECT_FORMAT' => 'Incorrect email for %s of %s.', + 'STORAGE_FORM_TYPE_TEXT_TOO_LONG' => 'Text is too long for %s of %s.', + 'STORAGE_FORM_TYPE_SELECT_NOT_AVAILABLE' => 'Selected value is not available for %s of %s.', +)); diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php index 505d12e8ffd..bc3f9fc2d79 100644 --- a/phpBB/language/en/cli.php +++ b/phpBB/language/en/cli.php @@ -164,6 +164,18 @@ 1 => 'Re-cleaning complete. %d username was cleaned.', 2 => 'Re-cleaning complete. %d usernames were cleaned.', ], + + 'CLI_DESCRIPTION_EXTENSION_MANAGE' => 'Manages an extension', + 'CLI_DESCRIPTION_EXTENSION_MANAGE_ARGUMENT' => 'Extension to manage', + 'CLI_DESCRIPTION_EXTENSION_INSTALL' => 'Install the specified extension(s).', + 'CLI_DESCRIPTION_EXTENSION_INSTALL_OPTION_ENABLE' => 'Enable extension(s) after installation', + 'CLI_DESCRIPTION_EXTENSION_INSTALL_ARGUMENT' => 'Extension(s) to install, e.g.: vendor/package', + 'CLI_DESCRIPTION_EXTENSION_LIST_AVAILABLE' => 'List extensions available for installation.', + 'CLI_DESCRIPTION_EXTENSION_REMOVE' => 'Remove the specified extension(s).', + 'CLI_DESCRIPTION_EXTENSION_REMOVE_OPTION_PURGE' => 'Purge extension(s) when removing them', + 'CLI_DESCRIPTION_EXTENSION_REMOVE_ARGUMENT' => 'Extension(s) to remove, e.g.: vendor/package', + 'CLI_DESCRIPTION_EXTENSION_UPDATE' => 'Update the specified extension(s).', + 'CLI_DESCRIPTION_EXTENSION_UPDATE_ARGUMENT' => 'Extension(s) to update, e.g.: vendor/package', )); // Additional help for commands. diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 5140919dadb..865c9b0158e 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -157,6 +157,7 @@ 'BYTES_SHORT' => 'B', 'CANCEL' => 'Cancel', + 'CANNOT_RENAME_FILE' => 'Cannot rename %s', 'CHANGE' => 'Change', 'CHANGE_FONT_SIZE' => 'Change font size', 'CHANGING_PREFERENCES' => 'Changing board preferences', @@ -372,7 +373,7 @@ 'LDAP_SEARCH_FAILED' => 'An error occurred while searching the LDAP directory.', 'LEGEND' => 'Legend', 'LIVE_SEARCHES_NOT_ALLOWED' => 'Live searches are not allowed.', - 'LOADING' => 'Loading', + 'LOADING' => 'Loading...', 'LOCATION' => 'Location', 'LOCK_POST' => 'Lock post', 'LOCK_POST_EXPLAIN' => 'Prevent editing', @@ -484,7 +485,7 @@ 'NOTIFICATION_TOPIC_IN_QUEUE' => 'Topic approval request by %1$s:', 'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.', 'NOTIFICATION_ADMIN_ACTIVATE_USER' => 'Activation required for deactivated or newly registered user: “%1$s”', - // Used in conjuction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST. + // Used in conjunction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST. 'NOTIFICATION_MANY_OTHERS' => 'others', 'NOTIFICATION_X_OTHERS' => array( 2 => '%d others', @@ -731,6 +732,19 @@ 'SUBJECT' => 'Subject', 'SUBMIT' => 'Submit', + 'STORAGE_ADAPTER_NOT_AVAILABLE' => 'Selected storage is not available.', + 'STORAGE_FILE_EXISTS' => 'File already exists.', + 'STORAGE_FILE_NO_EXIST' => 'File does not exist.', + 'STORAGE_CANNOT_WRITE_FILE' => 'Can not write to file.', + 'STORAGE_CANNOT_READ_FILE' => 'Can not read file.', + 'STORAGE_CANNOT_DELETE' => 'Can not delete file or folder.', + 'STORAGE_CANNOT_RENAME' => 'Can not rename file or folder.', + 'STORAGE_CANNOT_COPY' => 'Can not copy file or folder.', + 'STORAGE_CANNOT_COPY_RESOURCE' => 'Can not copy resource.', + 'STORAGE_CANNOT_CREATE_DIR' => 'Can not create directory.', + 'STORAGE_CANNOT_OPEN_FILE' => 'Can not open file.', + 'STORAGE_CANNOT_CREATE_FILE' => 'Can not create file.', + 'TB' => 'TB', 'TERMS_USE' => 'Terms of use', 'TEST_CONNECTION' => 'Test connection', diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php index 9bceeccde7b..3faec8a499d 100644 --- a/phpBB/language/en/install.php +++ b/phpBB/language/en/install.php @@ -220,7 +220,7 @@ 'UPDATE_INCOMPLETE_MORE' => 'Please read the information below in order to fix this error.', 'UPDATE_INCOMPLETE_EXPLAIN' => '

    Incomplete update

    -

    We noticed that the last update of your phpBB installation hasn’t been completed. Visit the database updater, ensure Update database only is selected and click on Submit. Don\'t forget to delete the "install"-directory after you have updated the database sucessfully.

    ', +

    We noticed that the last update of your phpBB installation hasn’t been completed. Visit the database updater, ensure Update database only is selected and click on Submit. Don\'t forget to delete the "install"-directory after you have updated the database successfully.

    ', // // Server data @@ -565,7 +565,7 @@ // Finish conversion 'CONVERT_COMPLETE' => 'Conversion completed', - 'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 3.2. You can now login and access your board. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the Documentation and the support forums.', + 'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 3.3. You can now login and access your board. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the Documentation and the support forums.', 'CONV_ERROR_ATTACH_FTP_DIR' => 'FTP upload for attachments is enabled at the old board. Please disable the FTP upload option and make sure a valid upload directory is specified, then copy all attachment files to this new web accessible directory. Once you have done this, restart the convertor.', 'CONV_ERROR_CONFIG_EMPTY' => 'There is no configuration information available for the conversion.', diff --git a/phpBB/mcp.php b/phpBB/mcp.php index c4a8a66c18d..c5599b7851d 100644 --- a/phpBB/mcp.php +++ b/phpBB/mcp.php @@ -308,6 +308,11 @@ ); extract($phpbb_dispatcher->trigger_event('core.modify_mcp_modules_display_option', compact($vars))); +$template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $user->lang('MCP'), + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}mcp.$phpEx"), +)); + // Load and execute the relevant module $module->load_active(); diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 977857da598..a191ee25fb4 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -364,6 +364,11 @@ } } + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $page_title, + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=team"), + )); + $template->assign_vars(array( 'PM_IMG' => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE'])) ); @@ -461,6 +466,11 @@ break; } + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $page_title, + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&action=$action&u=$user_id"), + )); + // Send vars to the template $template->assign_vars(array( 'IM_CONTACT' => $row[$sql_field], @@ -788,6 +798,15 @@ $page_title = sprintf($user->lang['VIEWING_PROFILE'], $member['username']); $template_html = 'memberlist_view.html'; + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $user->lang('MEMBERLIST'), + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}memberlist.$phpEx"), + )); + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $member['username'], + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=viewprofile&u=$user_id"), + )); + break; case 'contactadmin': @@ -837,6 +856,41 @@ $template_html = $form->get_template_file(); $form->render($template); + if ($user_id) + { + $navlink_name = $user->lang('SEND_EMAIL'); + $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&u=$user_id"); + } + else if ($topic_id) + { + $sql = 'SELECT f.parent_id, f.forum_parents, f.left_id, f.right_id, f.forum_type, f.forum_name, f.forum_id, f.forum_desc, f.forum_desc_uid, f.forum_desc_bitfield, f.forum_desc_options, f.forum_options, t.topic_title + FROM ' . FORUMS_TABLE . ' as f, + ' . TOPICS_TABLE . ' as t + WHERE t.forum_id = f.forum_id'; + $result = $db->sql_query($sql); + $topic_data = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + generate_forum_nav($topic_data); + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $topic_data['topic_title'], + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id"), + )); + + $navlink_name = $user->lang('EMAIL_TOPIC'); + $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&t=$topic_id"); + } + else if ($mode === 'contactadmin') + { + $navlink_name = $user->lang('CONTACT_ADMIN'); + $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contactadmin"); + } + + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $navlink_name, + 'U_VIEW_FORUM' => $navlink_url, + )); + break; case 'livesearch': @@ -874,6 +928,11 @@ $page_title = $user->lang['MEMBERLIST']; $template_html = 'memberlist_body.html'; + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $page_title, + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}memberlist.$phpEx"), + )); + /* @var $pagination \phpbb\pagination */ $pagination = $phpbb_container->get('pagination'); @@ -1179,6 +1238,11 @@ unset($module); } + $template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $group_helper->get_name($group_row['group_name']), + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&g=$group_id"), + )); + $template->assign_vars(array( 'GROUP_DESC' => generate_text_for_display($group_row['group_desc'], $group_row['group_desc_uid'], $group_row['group_desc_bitfield'], $group_row['group_desc_options']), 'GROUP_NAME' => $group_helper->get_name($group_row['group_name']), diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index 8809a0c6b4b..6b974e7c80d 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -274,7 +274,7 @@ public function login($username, $password) $storage->set_user_id($row['user_id']); /** - * Event is triggered after user is successfuly logged in via OAuth. + * Event is triggered after user is successfully logged in via OAuth. * * @event core.auth_oauth_login_after * @var array row User row diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php index 3e4e7ff98ba..cbd8da90e26 100644 --- a/phpBB/phpbb/avatar/driver/gravatar.php +++ b/phpBB/phpbb/avatar/driver/gravatar.php @@ -40,7 +40,7 @@ public function get_data($row) */ public function get_custom_html($user, $row, $alt = '') { - return ''; diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 77b44754ac2..92fa59e6b6b 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -13,15 +13,18 @@ namespace phpbb\avatar\driver; +use bantu\IniGetWrapper\IniGetWrapper; +use \phpbb\storage\exception\exception as storage_exception; + /** * Handles avatars uploaded to the board */ class upload extends \phpbb\avatar\driver\driver { /** - * @var \phpbb\filesystem\filesystem_interface + * @var \phpbb\storage\storage */ - protected $filesystem; + protected $storage; /** * @var \phpbb\event\dispatcher_interface @@ -33,28 +36,33 @@ class upload extends \phpbb\avatar\driver\driver */ protected $files_factory; + /** + * @var IniGetWrapper + */ + protected $php_ini; + /** * Construct a driver object * * @param \phpbb\config\config $config phpBB configuration * @param string $phpbb_root_path Path to the phpBB root * @param string $php_ext PHP file extension - * @param \phpbb\filesystem\filesystem_interface $filesystem phpBB filesystem helper + * @param \phpbb\storage\storage phpBB avatar storage * @param \phpbb\path_helper $path_helper phpBB path helper * @param \phpbb\event\dispatcher_interface $dispatcher phpBB Event dispatcher object * @param \phpbb\files\factory $files_factory File classes factory - * @param \phpbb\cache\driver\driver_interface $cache Cache driver + * @param IniGetWrapper $php_ini ini_get() wrapper */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\storage\storage $storage, \phpbb\path_helper $path_helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, IniGetWrapper $php_ini) { $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; - $this->filesystem = $filesystem; + $this->storage = $storage; $this->path_helper = $path_helper; $this->dispatcher = $dispatcher; $this->files_factory = $files_factory; - $this->cache = $cache; + $this->php_ini = $php_ini; } /** @@ -116,7 +124,7 @@ public function process_form($request, $template, $user, $row, &$error) if (!empty($upload_file['name'])) { - $file = $upload->handle_upload('files.types.form', 'avatar_upload_file'); + $file = $upload->handle_upload('files.types.form_storage', 'avatar_upload_file'); } else if (!empty($this->config['allow_avatar_remote_upload']) && !empty($url)) { @@ -156,7 +164,7 @@ public function process_form($request, $template, $user, $row, &$error) return false; } - $file = $upload->handle_upload('files.types.remote', $url); + $file = $upload->handle_upload('files.types.remote_storage', $url); } else { @@ -169,26 +177,11 @@ public function process_form($request, $template, $user, $row, &$error) // If there was an error during upload, then abort operation if (count($file->error)) { - $file->remove(); + $file->remove($this->storage); $error = $file->error; return false; } - // Calculate new destination - $destination = $this->config['avatar_path']; - - // Adjust destination path (no trailing slash) - if (substr($destination, -1, 1) == '/' || substr($destination, -1, 1) == '\\') - { - $destination = substr($destination, 0, -1); - } - - $destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination); - if ($destination && ($destination[0] == '/' || $destination[0] == "\\")) - { - $destination = ''; - } - $filedata = array( 'filename' => $file->get('filename'), 'filesize' => $file->get('filesize'), @@ -204,7 +197,6 @@ public function process_form($request, $template, $user, $row, &$error) * @event core.avatar_driver_upload_move_file_before * @var array filedata Array containing uploaded file data * @var \phpbb\files\filespec file Instance of filespec class - * @var string destination Destination directory where the file is going to be moved * @var string prefix Prefix for the avatar filename * @var array row Array with avatar row data * @var array error Array of errors, if filled in by this event file will not be moved @@ -215,7 +207,6 @@ public function process_form($request, $template, $user, $row, &$error) $vars = array( 'filedata', 'file', - 'destination', 'prefix', 'row', 'error', @@ -227,14 +218,14 @@ public function process_form($request, $template, $user, $row, &$error) if (!count($error)) { // Move file and overwrite any existing image - $file->move_file($destination, true); + $file->move_file($this->storage, true); } // If there was an error during move, then clean up leftovers $error = array_merge($error, $file->error); if (count($error)) { - $file->remove(); + $file->remove($this->storage); return false; } @@ -260,7 +251,6 @@ public function prepare_form_acp($user) return array( 'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), - 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true), ); } @@ -271,37 +261,35 @@ public function delete($row) { $error = array(); - $destination = $this->config['avatar_path']; $prefix = $this->config['avatar_salt'] . '_'; $ext = substr(strrchr($row['avatar'], '.'), 1); - $filename = $this->phpbb_root_path . $destination . '/' . $prefix . $row['id'] . '.' . $ext; + $filename = $prefix . $row['id'] . '.' . $ext; /** * Before deleting an existing avatar * * @event core.avatar_driver_upload_delete_before - * @var string destination Destination directory where the file is going to be deleted * @var string prefix Prefix for the avatar filename * @var array row Array with avatar row data * @var array error Array of errors, if filled in by this event file will not be deleted * @since 3.1.6-RC1 + * @changed 3.3.0-a1 Remove destination */ $vars = array( - 'destination', 'prefix', 'row', 'error', ); extract($this->dispatcher->trigger_event('core.avatar_driver_upload_delete_before', compact($vars))); - if (!count($error) && $this->filesystem->exists($filename)) + if (!count($error) && $this->storage->exists($filename)) { try { - $this->filesystem->remove($filename); + $this->storage->delete($filename); return true; } - catch (\phpbb\filesystem\exception\filesystem_exception $e) + catch (storage_exception $e) { // Fail is covered by return statement below } @@ -319,12 +307,12 @@ public function get_template_name() } /** - * Check if user is able to upload an avatar + * Check if user is able to upload an avatar to a temporary folder * * @return bool True if user can upload, false if not */ protected function can_upload() { - return ($this->filesystem->exists($this->phpbb_root_path . $this->config['avatar_path']) && $this->filesystem->is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')); + return $this->php_ini->getBool('file_uploads'); } } diff --git a/phpBB/phpbb/class_loader.php b/phpBB/phpbb/class_loader.php index cfdcc2af0b1..a4b69311ca5 100644 --- a/phpBB/phpbb/class_loader.php +++ b/phpBB/phpbb/class_loader.php @@ -64,7 +64,7 @@ public function __construct($namespace, $path, $php_ext = 'php', \phpbb\cache\dr /** * Provide the class loader with a cache to store paths. If set to null, the - * the class loader will resolve paths by checking for the existance of every + * the class loader will resolve paths by checking for the existence of every * directory in the class name every time. * * @param \phpbb\cache\driver\driver_interface $cache An implementation of the phpBB cache interface. diff --git a/phpBB/phpbb/composer/exception/managed_with_clean_error_exception_exception.php b/phpBB/phpbb/composer/exception/managed_with_clean_error_exception_exception.php new file mode 100644 index 00000000000..2339fa40964 --- /dev/null +++ b/phpBB/phpbb/composer/exception/managed_with_clean_error_exception_exception.php @@ -0,0 +1,35 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\exception; + +/** + * Packaged managed with success but error occurred when cleaning the filesystem + */ +class managed_with_clean_error_exception extends managed_with_error_exception +{ + /** + * Constructor + * + * @param string $prefix The language string prefix + * @param string $message The Exception message to throw (must be a language variable). + * @param array $parameters The parameters to use with the language var. + * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining. + * @param integer $code The Exception code. + */ + public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0) + { + parent::__construct($prefix . $message, $parameters, $previous, $code); + } + +} diff --git a/phpBB/phpbb/composer/exception/managed_with_enable_error_exception.php b/phpBB/phpbb/composer/exception/managed_with_enable_error_exception.php new file mode 100644 index 00000000000..7ef7a42df36 --- /dev/null +++ b/phpBB/phpbb/composer/exception/managed_with_enable_error_exception.php @@ -0,0 +1,35 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\exception; + +/** + * Packaged managed with success but error occurred when re-enabling the extension + */ +class managed_with_enable_error_exception extends managed_with_error_exception +{ + /** + * Constructor + * + * @param string $prefix The language string prefix + * @param string $message The Exception message to throw (must be a language variable). + * @param array $parameters The parameters to use with the language var. + * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining. + * @param integer $code The Exception code. + */ + public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0) + { + parent::__construct($prefix . $message, $parameters, $previous, $code); + } + +} diff --git a/phpBB/phpbb/composer/exception/managed_with_error_exception.php b/phpBB/phpbb/composer/exception/managed_with_error_exception.php new file mode 100644 index 00000000000..9e7c67580e6 --- /dev/null +++ b/phpBB/phpbb/composer/exception/managed_with_error_exception.php @@ -0,0 +1,35 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\exception; + +/** + * Packaged managed with success but errored at some point + */ +class managed_with_error_exception extends runtime_exception +{ + /** + * Constructor + * + * @param string $prefix The language string prefix + * @param string $message The Exception message to throw (must be a language variable). + * @param array $parameters The parameters to use with the language var. + * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining. + * @param integer $code The Exception code. + */ + public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0) + { + parent::__construct($prefix . $message, $parameters, $previous, $code); + } + +} diff --git a/phpBB/phpbb/composer/exception/runtime_exception.php b/phpBB/phpbb/composer/exception/runtime_exception.php new file mode 100644 index 00000000000..eb927593185 --- /dev/null +++ b/phpBB/phpbb/composer/exception/runtime_exception.php @@ -0,0 +1,37 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\exception; + +use phpbb\exception\runtime_exception as base; + +/** + * Base class for exceptions thrown when managing packages through composer + */ +class runtime_exception extends base +{ + /** + * Constructor + * + * @param string $prefix The language string prefix + * @param string $message The Exception message to throw (must be a language variable). + * @param array $parameters The parameters to use with the language var. + * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining. + * @param integer $code The Exception code. + */ + public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0) + { + parent::__construct($prefix . $message, $parameters, $previous, $code); + } + +} diff --git a/phpBB/phpbb/composer/extension_manager.php b/phpBB/phpbb/composer/extension_manager.php new file mode 100644 index 00000000000..96250e9dd3f --- /dev/null +++ b/phpBB/phpbb/composer/extension_manager.php @@ -0,0 +1,316 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer; + +use Composer\IO\IOInterface; +use phpbb\cache\driver\driver_interface; +use phpbb\composer\exception\managed_with_clean_error_exception; +use phpbb\composer\exception\managed_with_enable_error_exception; +use phpbb\composer\exception\runtime_exception; +use phpbb\config\config; +use phpbb\extension\manager as ext_manager; +use phpbb\filesystem\exception\filesystem_exception; +use phpbb\filesystem\filesystem; + +/** + * Class to safely manage extensions through composer. + */ +class extension_manager extends manager +{ + /** + * @var \phpbb\extension\manager + */ + protected $extension_manager; + + /** + * @var \phpbb\filesystem\filesystem + */ + protected $filesystem; + + /** + * @var array + */ + private $enabled_extensions; + + /** + * @var bool Enables extensions when installing them? + */ + private $enable_on_install = false; + + /** + * @var bool Purges extensions data when removing them? + */ + private $purge_on_remove = true; + + /** + * @param installer $installer Installer object + * @param driver_interface $cache Cache object + * @param ext_manager $extension_manager phpBB extension manager + * @param filesystem $filesystem Filesystem object + * @param string $package_type Composer type of managed packages + * @param string $exception_prefix Exception prefix to use + * @param string $root_path phpBB root path + * @param config $config Config object + */ + public function __construct(installer $installer, driver_interface $cache, ext_manager $extension_manager, filesystem $filesystem, $package_type, $exception_prefix, $root_path, config $config = null) + { + $this->extension_manager = $extension_manager; + $this->filesystem = $filesystem; + $this->root_path = $root_path; + + if ($config) + { + $this->enable_on_install = (bool) $config['exts_composer_enable_on_install']; + $this->purge_on_remove = (bool) $config['exts_composer_purge_on_remove']; + } + + parent::__construct($installer, $cache, $package_type, $exception_prefix); + } + + /** + * {@inheritdoc} + */ + public function pre_install(array $packages, IOInterface $io = null) + { + $installed_manually = array_intersect(array_keys($this->extension_manager->all_available()), array_keys($packages)); + if (count($installed_manually) !== 0) + { + throw new runtime_exception($this->exception_prefix, 'ALREADY_INSTALLED_MANUALLY', [implode('|', array_keys($installed_manually))]); + } + } + + /** + * {@inheritdoc} + */ + public function post_install(array $packages, IOInterface $io = null) + { + if ($this->enable_on_install) + { + $io->writeError([['ENABLING_EXTENSIONS', [], 1]], true); + foreach ($packages as $package => $version) + { + try + { + $this->extension_manager->enable($package); + } + catch (\phpbb\exception\runtime_exception $e) + { + $io->writeError([[$e->getMessage(), $e->get_parameters(), 4]], true); + } + catch (\Exception $e) + { + $io->writeError([[$e->getMessage(), [], 4]], true); + } + } + } + } + + /** + * {@inheritdoc} + */ + protected function pre_update(array $packages, IOInterface $io = null) + { + $io->writeError([['DISABLING_EXTENSIONS', [], 1]], true); + $this->enabled_extensions = []; + foreach ($packages as $package => $version) + { + try + { + if ($this->extension_manager->is_enabled($package)) + { + $this->enabled_extensions[] = $package; + $this->extension_manager->disable($package); + } + } + catch (\phpbb\exception\runtime_exception $e) + { + $io->writeError([[$e->getMessage(), $e->get_parameters(), 4]], true); + } + catch (\Exception $e) + { + $io->writeError([[$e->getMessage(), [], 4]], true); + } + } + } + + /** + * {@inheritdoc} + */ + protected function post_update(array $packages, IOInterface $io = null) + { + $io->writeError([['ENABLING_EXTENSIONS', [], 1]], true); + foreach ($this->enabled_extensions as $package) + { + try + { + $this->extension_manager->enable($package); + } + catch (\phpbb\exception\runtime_exception $e) + { + $io->writeError([[$e->getMessage(), $e->get_parameters(), 4]], true); + } + catch (\Exception $e) + { + $io->writeError([[$e->getMessage(), [], 4]], true); + } + } + } + + /** + * {@inheritdoc} + */ + public function remove(array $packages, IOInterface $io = null) + { + $packages = $this->normalize_version($packages); + + $not_installed = array_diff(array_keys($packages), array_keys($this->extension_manager->all_available())); + if (count($not_installed) !== 0) + { + throw new runtime_exception($this->exception_prefix, 'NOT_INSTALLED', [implode('|', array_keys($not_installed))]); + } + + parent::remove($packages, $io); + } + + /** + * {@inheritdoc} + */ + public function pre_remove(array $packages, IOInterface $io = null) + { + if ($this->purge_on_remove) + { + $io->writeError([['DISABLING_EXTENSIONS', [], 1]], true); + } + + foreach ($packages as $package => $version) + { + try + { + if ($this->extension_manager->is_enabled($package)) + { + if ($this->purge_on_remove) + { + $this->extension_manager->purge($package); + } + else + { + $this->extension_manager->disable($package); + } + } + } + catch (\phpbb\exception\runtime_exception $e) + { + $io->writeError([[$e->getMessage(), $e->get_parameters(), 4]], true); + } + catch (\Exception $e) + { + $io->writeError([[$e->getMessage(), [], 4]], true); + } + } + } + + /** + * {@inheritdoc} + */ + public function start_managing($package, $io) + { + if (!$this->extension_manager->is_available($package)) + { + throw new runtime_exception($this->exception_prefix, 'NOT_INSTALLED', [$package]); + } + + if ($this->is_managed($package)) + { + throw new runtime_exception($this->exception_prefix, 'ALREADY_MANAGED', [$package]); + } + + $enabled = false; + if ($this->extension_manager->is_enabled($package)) + { + $enabled = true; + $io->writeError([['DISABLING_EXTENSIONS', [], 1]], true); + $this->extension_manager->disable($package); + } + + $ext_path = $this->extension_manager->get_extension_path($package, true); + $backup_path = rtrim($ext_path, '/') . '__backup__'; + + try + { + $this->filesystem->rename($ext_path, $backup_path); + } + catch (filesystem_exception $e) + { + throw new runtime_exception($this->exception_prefix, 'CANNOT_MANAGE_FILESYSTEM_ERROR', [$package], $e); + } + + try + { + $this->install((array) $package, $io); + $this->filesystem->remove($backup_path); + } + catch (runtime_exception $e) + { + $this->filesystem->rename($backup_path, $ext_path); + throw new runtime_exception($this->exception_prefix, 'CANNOT_MANAGE_INSTALL_ERROR', [$package], $e); + } + catch (filesystem_exception $e) + { + throw new managed_with_clean_error_exception($this->exception_prefix, 'MANAGED_WITH_CLEAN_ERROR', [$package, $backup_path], $e); + } + + if ($enabled) + { + try + { + $io->writeError([['ENABLING_EXTENSIONS', [], 1]], true); + $this->extension_manager->enable($package); + } + catch (\Exception $e) + { + throw new managed_with_enable_error_exception($this->exception_prefix, 'MANAGED_WITH_ENABLE_ERROR', [$package], $e); + } + } + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return parent::check_requirements() && $this->filesystem->is_writable($this->root_path . 'ext/'); + } + + /** + * Enable the extensions when installing + * + * Warning: Only the explicitly required extensions will be enabled + * + * @param bool $enable + */ + public function set_enable_on_install($enable) + { + $this->enable_on_install = $enable; + } + + /** + * Purge the extension when disabling it + * + * @param bool $purge + */ + public function set_purge_on_remove($purge) + { + $this->purge_on_remove = $purge; + } +} diff --git a/phpBB/phpbb/composer/installer.php b/phpBB/phpbb/composer/installer.php new file mode 100644 index 00000000000..3a03e29ef5f --- /dev/null +++ b/phpBB/phpbb/composer/installer.php @@ -0,0 +1,711 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer; + +use Composer\Composer; +use Composer\Factory; +use Composer\IO\IOInterface; +use Composer\IO\NullIO; +use Composer\Json\JsonFile; +use Composer\Package\BasePackage; +use Composer\Package\CompletePackage; +use Composer\Repository\ComposerRepository; +use Composer\Semver\Constraint\ConstraintInterface; +use Composer\Util\RemoteFilesystem; +use phpbb\composer\io\null_io; +use phpbb\config\config; +use phpbb\exception\runtime_exception; +use phpbb\filesystem\filesystem; +use phpbb\request\request; +use Seld\JsonLint\ParsingException; +use phpbb\filesystem\helper as filesystem_helper; + +/** + * Class to install packages through composer while freezing core dependencies. + */ +class installer +{ + const PHPBB_TYPES = 'phpbb-extension,phpbb-style,phpbb-language'; + + /** + * @var array Repositories to look packages from + */ + protected $repositories = []; + + /** + * @var bool Indicates whether packagist usage is allowed or not + */ + protected $packagist = false; + + /** + * @var string Composer filename used to manage the packages + */ + protected $composer_filename = 'composer-ext.json'; + + /** + * @var string Directory where to install packages vendors + */ + protected $packages_vendor_dir = 'vendor-ext/'; + + /** + * @var string Minimum stability + */ + protected $minimum_stability = 'stable'; + + /** + * @var string phpBB root path + */ + protected $root_path; + + /** + * @var string Stores the original working directory in case it has been changed through move_to_root() + */ + private $original_cwd; + + /** + * @var array Stores the content of the ext json file before generate_ext_json_file() overrides it + */ + private $ext_json_file_backup; + + /** + * @var request phpBB request object + */ + private $request; + + /** + * @param string $root_path phpBB root path + * @param filesystem $filesystem Filesystem object + * @param request $request phpBB request object + * @param config $config Config object + */ + public function __construct($root_path, filesystem $filesystem, request $request, config $config = null) + { + if ($config) + { + $repositories = json_decode($config['exts_composer_repositories'], true); + + if (is_array($repositories) && !empty($repositories)) + { + $this->repositories = (array) $repositories; + } + + $this->packagist = (bool) $config['exts_composer_packagist']; + $this->composer_filename = $config['exts_composer_json_file']; + $this->packages_vendor_dir = $config['exts_composer_vendor_dir']; + $this->minimum_stability = $config['exts_composer_minimum_stability']; + } + + $this->root_path = $root_path; + $this->request = $request; + + putenv('COMPOSER_HOME=' . filesystem_helper::realpath($root_path) . '/store/composer'); + } + + /** + * Update the current installed set of packages + * + * @param array $packages Packages to install. + * Each entry may be a name or an array associating a version constraint to a name + * @param array $whitelist White-listed packages (packages that can be installed/updated/removed) + * @param IOInterface $io IO object used for the output + * + * @throws runtime_exception + */ + public function install(array $packages, $whitelist, IOInterface $io = null) + { + $this->wrap(function() use ($packages, $whitelist, $io) { + $this->do_install($packages, $whitelist, $io); + }); + } + + /** + * Update the current installed set of packages + * + * /!\ Doesn't change the current working directory + * + * @param array $packages Packages to install. + * Each entry may be a name or an array associating a version constraint to a name + * @param array $whitelist White-listed packages (packages that can be installed/updated/removed) + * @param IOInterface $io IO object used for the output + * + * @throws runtime_exception + */ + protected function do_install(array $packages, $whitelist, IOInterface $io = null) + { + if (!$io) + { + $io = new null_io(); + } + + $this->generate_ext_json_file($packages); + + $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false); + $install = \Composer\Installer::create($io, $composer); + + $composer->getDownloadManager()->setOutputProgress(false); + + $install + ->setVerbose(true) + ->setPreferSource(false) + ->setPreferDist(true) + ->setDevMode(false) + ->setUpdate(true) + ->setUpdateWhitelist($whitelist) + ->setWhitelistDependencies(false) + ->setIgnorePlatformRequirements(false) + ->setOptimizeAutoloader(true) + ->setDumpAutoloader(true) + ->setPreferStable(true) + ->setRunScripts(false) + ->setDryRun(false); + + try + { + $result = $install->run(); + } + catch (\Exception $e) + { + $this->restore_ext_json_file(); + + throw new runtime_exception('COMPOSER_CANNOT_INSTALL', [], $e); + } + + if ($result !== 0) + { + $this->restore_ext_json_file(); + + throw new runtime_exception($io->get_composer_error(), []); + } + } + + /** + * Returns the list of currently installed packages + * + * @param string|array $types Returns only the packages with the given type(s) + * + * @return array The installed packages associated to their version. + * + * @throws runtime_exception + */ + public function get_installed_packages($types) + { + return $this->wrap(function() use ($types) { + return $this->do_get_installed_packages($types); + }); + } + + /** + * Returns the list of currently installed packages + * + * /!\ Doesn't change the current working directory + * + * @param string|array $types Returns only the packages with the given type(s) + * + * @return array The installed packages associated to their version. + */ + protected function do_get_installed_packages($types) + { + $types = (array) $types; + + try + { + $io = new NullIO(); + $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false); + + $installed = []; + + /** @var \Composer\Package\Link[] $required_links */ + $required_links = $composer->getPackage()->getRequires(); + $installed_packages = $composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages(); + + foreach ($installed_packages as $package) + { + if (in_array($package->getType(), $types, true)) + { + $version = array_key_exists($package->getName(), $required_links) ? + $required_links[$package->getName()]->getPrettyConstraint() : '*'; + $installed[$package->getName()] = $version; + } + } + + return $installed; + } + catch (\Exception $e) + { + return []; + } + } + + /** + * Gets the list of the available packages of the configured type in the configured repositories + * + * /!\ Doesn't change the current working directory + * + * @param string $type Returns only the packages with the given type + * + * @return array The name of the available packages, associated to their definition. Ordered by name. + * + * @throws runtime_exception + */ + public function get_available_packages($type) + { + return $this->wrap(function() use ($type) { + return $this->do_get_available_packages($type); + }); + } + + /** + * Gets the list of the available packages of the configured type in the configured repositories + * + * @param string $type Returns only the packages with the given type + * + * @return array The name of the available packages, associated to their definition. Ordered by name. + */ + protected function do_get_available_packages($type) + { + try + { + $this->generate_ext_json_file($this->do_get_installed_packages(explode(',', self::PHPBB_TYPES))); + + $io = new NullIO(); + $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false); + + /** @var ConstraintInterface $core_constraint */ + $core_constraint = $composer->getPackage()->getRequires()['phpbb/phpbb']->getConstraint(); + $core_stability = $composer->getPackage()->getMinimumStability(); + + $available = []; + + $compatible_packages = []; + $repositories = $composer->getRepositoryManager()->getRepositories(); + + /** @var \Composer\Repository\RepositoryInterface $repository */ + foreach ($repositories as $repository) + { + try + { + if ($repository instanceof ComposerRepository && $repository->hasProviders()) + { + // Special case for packagist which exposes an api to retrieve all packages of a given type. + // For the others composer repositories with providers we can't do anything. It would be too slow. + + $r = new \ReflectionObject($repository); + $repo_url = $r->getProperty('url'); + $repo_url->setAccessible(true); + + if ($repo_url->getValue($repository) === 'http://packagist.org') + { + $url = 'https://packagist.org/packages/list.json?type=' . $type; + $rfs = new RemoteFilesystem($io); + $hostname = parse_url($url, PHP_URL_HOST) ?: $url; + $json = $rfs->getContents($hostname, $url, false); + + /** @var \Composer\Package\PackageInterface $package */ + foreach (JsonFile::parseJson($json, $url)['packageNames'] as $package) + { + $versions = $repository->findPackages($package); + $compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $core_stability, $package, $versions); + } + } + } + else + { + // Pre-filter repo packages by their type + $packages = []; + /** @var \Composer\Package\PackageInterface $package */ + foreach ($repository->getPackages() as $package) + { + if ($package->getType() === $type) + { + $packages[$package->getName()][] = $package; + } + } + + // Filter the compatibles versions + foreach ($packages as $package => $versions) + { + $compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $core_stability, $package, $versions); + } + } + } + catch (\Exception $e) + { + // If a repo fails, just skip it. + continue; + } + } + + foreach ($compatible_packages as $name => $versions) + { + // Determine the highest version of the package + /** @var CompletePackage $highest_version */ + $highest_version = null; + + /** @var CompletePackage $version */ + foreach ($versions as $version) + { + if (!$highest_version || version_compare($version->getVersion(), $highest_version->getVersion(), '>')) + { + $highest_version = $version; + } + } + + // Generates the entry + $available[$name] = []; + $available[$name]['name'] = $highest_version->getPrettyName(); + $available[$name]['display_name'] = $highest_version->getExtra()['display-name']; + $available[$name]['composer_name'] = $highest_version->getName(); + $available[$name]['version'] = $highest_version->getPrettyVersion(); + + if ($version instanceof CompletePackage) + { + $available[$name]['description'] = $highest_version->getDescription(); + $available[$name]['url'] = $highest_version->getHomepage(); + $available[$name]['authors'] = $highest_version->getAuthors(); + } + else + { + $available[$name]['description'] = ''; + $available[$name]['url'] = ''; + $available[$name]['authors'] = []; + } + } + + usort($available, function($a, $b) + { + return strcasecmp($a['display_name'], $b['display_name']); + }); + + return $available; + } + catch (\Exception $e) + { + return []; + } + } + + /** + * Checks the requirements of the manager and returns true if it can be used. + * + * @return bool + */ + public function check_requirements() + { + $filesystem = new \phpbb\filesystem\filesystem(); + + return $filesystem->is_writable([ + $this->root_path . $this->composer_filename, + $this->root_path . $this->packages_vendor_dir, + $this->root_path . substr($this->composer_filename, 0, -5) . '.lock', + ]); + } + + /** + * Updates $compatible_packages with the versions of $versions compatibles with the $core_constraint + * + * @param array $compatible_packages List of compatibles versions + * @param ConstraintInterface $core_constraint Constraint against the phpBB version + * @param string $core_stability Core stability + * @param string $package_name Considered package + * @param array $versions List of available versions + * + * @return array + */ + private function get_compatible_versions(array $compatible_packages, ConstraintInterface $core_constraint, $core_stability, $package_name, array $versions) + { + $core_stability_value = BasePackage::$stabilities[$core_stability]; + + /** @var \Composer\Package\PackageInterface $version */ + foreach ($versions as $version) + { + try + { + if (BasePackage::$stabilities[$version->getStability()] > $core_stability_value) + { + continue; + } + + if (array_key_exists('phpbb/phpbb', $version->getRequires())) + { + /** @var ConstraintInterface $package_constraint */ + $package_constraint = $version->getRequires()['phpbb/phpbb']->getConstraint(); + + if (!$package_constraint->matches($core_constraint)) + { + continue; + } + } + + $compatible_packages[$package_name][] = $version; + } + catch (\Exception $e) + { + // Do nothing (to log when a true debug logger is available) + } + } + + return $compatible_packages; + } + + /** + * Generates and write the json file used to install the set of packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + */ + protected function generate_ext_json_file(array $packages) + { + $io = new NullIO(); + + $composer = Factory::create($io, null, false); + + $core_packages = $this->get_core_packages($composer); + $ext_json_data = [ + 'require' => array_merge( + ['php' => $this->get_core_php_requirement($composer)], + $core_packages, + $this->get_extra_dependencies(), + $packages), + 'replace' => $core_packages, + 'repositories' => $this->get_composer_repositories(), + 'config' => [ + 'vendor-dir'=> $this->packages_vendor_dir, + ], + 'minimum-stability' => $this->minimum_stability, + ]; + + $this->ext_json_file_backup = null; + $json_file = new JsonFile($this->get_composer_ext_json_filename()); + + try + { + $ext_json_file_backup = $json_file->read(); + } + catch (ParsingException $e) + { + $ext_json_file_backup = '{}'; + + $lockFile = new JsonFile(substr($this->get_composer_ext_json_filename(), 0, -5) . '.lock'); + $lockFile->write([]); + } + + $json_file->write($ext_json_data); + $this->ext_json_file_backup = $ext_json_file_backup; + } + + /** + * Restore the json file overridden by generate_ext_json_file() + */ + protected function restore_ext_json_file() + { + if ($this->ext_json_file_backup) + { + try + { + $json_file = new JsonFile($this->get_composer_ext_json_filename()); + $json_file->write($this->ext_json_file_backup); + } + catch (\Exception $e) + { + } + + $this->ext_json_file_backup = null; + } + } + + /** + * Get the core installed packages + * + * @param Composer $composer Composer object to load the dependencies + * @return array The core packages with their version + */ + protected function get_core_packages(Composer $composer) + { + $core_deps = []; + $packages = $composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages(); + + foreach ($packages as $package) + { + $core_deps[$package->getName()] = $package->getPrettyVersion(); + } + + $core_deps['phpbb/phpbb'] = PHPBB_VERSION; + + return $core_deps; + } + + /** + * Get the PHP version required by the core + * + * @param Composer $composer Composer object to load the dependencies + * @return string The PHP version required by the core + */ + protected function get_core_php_requirement(Composer $composer) + { + return $composer->getLocker()->getLockData()['platform']['php']; + } + + /** + * Generate the repositories entry of the packages json file + * + * @return array repositories entry + */ + protected function get_composer_repositories() + { + $repositories = []; + + if (!$this->packagist) + { + $repositories[]['packagist'] = false; + } + + foreach ($this->repositories as $repository) + { + if (preg_match('#^' . get_preg_expression('url') . '$#iu', $repository)) + { + $repositories[] = [ + 'type' => 'composer', + 'url' => $repository, + ]; + } + } + + return $repositories; + } + + /** + * Get the name of the json file used for the packages. + * + * @return string The json filename + */ + protected function get_composer_ext_json_filename() + { + return $this->composer_filename; + } + + /** + * Get extra dependencies required to install the packages + * + * @return array Array of composer dependencies + */ + protected function get_extra_dependencies() + { + return []; + } + + /** + * Sets the customs repositories + * + * @param array $repositories An array of composer repositories to use + */ + public function set_repositories(array $repositories) + { + $this->repositories = $repositories; + } + + /** + * Allow or disallow packagist + * + * @param boolean $packagist + */ + public function set_packagist($packagist) + { + $this->packagist = $packagist; + } + + /** + * Sets the name of the managed packages' json file + * + * @param string $composer_filename + */ + public function set_composer_filename($composer_filename) + { + $this->composer_filename = $composer_filename; + } + + /** + * Sets the location of the managed packages' vendors + * + * @param string $packages_vendor_dir + */ + public function set_packages_vendor_dir($packages_vendor_dir) + { + $this->packages_vendor_dir = $packages_vendor_dir; + } + + /** + * Sets the phpBB root path + * + * @param string $root_path + */ + public function set_root_path($root_path) + { + $this->root_path = $root_path; + } + + /** + * Change the current directory to phpBB root + */ + protected function move_to_root() + { + if ($this->original_cwd === null) + { + $this->original_cwd = getcwd(); + chdir($this->root_path); + } + } + + /** + * Restore the current working directory if move_to_root() have been called + */ + protected function restore_cwd() + { + if ($this->original_cwd) + { + chdir($this->original_cwd); + $this->original_cwd = null; + } + } + + /** + * Wraps a callable in order to adjust the context needed by composer + * + * @param callable $callable + * + * @return mixed + */ + protected function wrap(callable $callable) + { + // The composer installers works with a path relative to the current directory + $this->move_to_root(); + + // The composer installers uses some super globals + $super_globals = $this->request->super_globals_disabled(); + $this->request->enable_super_globals(); + + try + { + return $callable(); + } + finally + { + $this->restore_cwd(); + + if ($super_globals) + { + $this->request->disable_super_globals(); + } + } + } +} diff --git a/phpBB/phpbb/composer/io/console_io.php b/phpBB/phpbb/composer/io/console_io.php new file mode 100644 index 00000000000..5239b050bb1 --- /dev/null +++ b/phpBB/phpbb/composer/io/console_io.php @@ -0,0 +1,40 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\io; + +use Composer\IO\ConsoleIO; +use phpbb\language\language; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class console_io extends ConsoleIO implements io_interface +{ + use translate_composer_trait; + + /** + * Constructor. + * + * @param InputInterface $input The input instance + * @param OutputInterface $output The output instance + * @param HelperSet $helperSet The helperSet instance + * @param language $language Language object + */ + public function __construct(InputInterface $input, OutputInterface $output, HelperSet $helperSet, language $language) + { + $this->language = $language; + + parent::__construct($input, $output, $helperSet); + } +} diff --git a/phpBB/phpbb/composer/io/html_output_formatter.php b/phpBB/phpbb/composer/io/html_output_formatter.php new file mode 100644 index 00000000000..588be30a21e --- /dev/null +++ b/phpBB/phpbb/composer/io/html_output_formatter.php @@ -0,0 +1,86 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\io; + +class html_output_formatter extends \Composer\Console\HtmlOutputFormatter +{ + protected static $availableForegroundColors = [ + 30 => 'black', + 31 => 'red', + 32 => 'green', + 33 => 'orange', + 34 => 'blue', + 35 => 'magenta', + 36 => 'cyan', + 37 => 'white', + ]; + + protected static $availableBackgroundColors = [ + 40 => 'black', + 41 => 'red', + 42 => 'green', + 43 => 'yellow', + 44 => 'blue', + 45 => 'magenta', + 46 => 'cyan', + 47 => 'white', + ]; + + protected static $availableOptions + = [ + 1 => 'bold', + 4 => 'underscore', + ]; + + /** + * {@inheritdoc} + */ + public function format($message) + { + $formatted = parent::format($message); + + return preg_replace_callback("{[\033\e]\[([0-9;]+)m(.*?)[\033\e]\[[0-9;]+m}s", [$this, 'formatHtml'], $formatted); + } + + protected function formatHtml($matches) + { + $out = '' . $matches[2] . ''; + } +} diff --git a/phpBB/phpbb/composer/io/io_interface.php b/phpBB/phpbb/composer/io/io_interface.php new file mode 100644 index 00000000000..a1d41122cb1 --- /dev/null +++ b/phpBB/phpbb/composer/io/io_interface.php @@ -0,0 +1,26 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\io; + +use Composer\IO\IOInterface; + +interface io_interface extends IOInterface +{ + /** + * Returns the composer errors that occurred since the last tcall of the method. + * + * @return string + */ + public function get_composer_error(); +} diff --git a/phpBB/phpbb/composer/io/null_io.php b/phpBB/phpbb/composer/io/null_io.php new file mode 100644 index 00000000000..9a667ca097b --- /dev/null +++ b/phpBB/phpbb/composer/io/null_io.php @@ -0,0 +1,27 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\io; + +use Composer\IO\NullIO; + +class null_io extends NullIO implements io_interface +{ + /** + * {@inheritdoc} + */ + public function get_composer_error() + { + return ''; + } +} diff --git a/phpBB/phpbb/composer/io/translate_composer_trait.php b/phpBB/phpbb/composer/io/translate_composer_trait.php new file mode 100644 index 00000000000..444cf38e6b8 --- /dev/null +++ b/phpBB/phpbb/composer/io/translate_composer_trait.php @@ -0,0 +1,245 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\io; + +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Trait to translate the composer Output + */ +trait translate_composer_trait +{ + /** + * @var \phpbb\language\language + */ + protected $language; + + /** + * @var array + */ + protected $composer_error = []; + + /** + * {@inheritdoc} + */ + public function write($messages, $newline = true, $verbosity = self::NORMAL) + { + $messages = (array) $messages; + $translated_messages = []; + + foreach ($messages as $message) + { + $level = 0; + if (is_array($message)) + { + $lang_key = $message[0]; + $parameters = $message[1]; + if (count($message) > 2) + { + $level = $message[2]; + } + } + else + { + $lang_key = $message; + $parameters = []; + } + + $message = trim($this->strip_format($lang_key), "\n\r"); + + if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_DEBUG) + { + // Do nothing + } + else if (strpos($message, 'Deleting ') === 0) + { + $elements = explode(' ', $message); + $lang_key = 'COMPOSER_DELETING'; + $parameters = [$elements[1]]; + } + + $translated_message = $this->language->lang_array($lang_key, $parameters); + + switch ($level) + { + case 1: + $translated_message = '' . $translated_message . ''; + break; + case 2: + $translated_message = '' . $translated_message . ''; + break; + case 3: + $translated_message = '' . $translated_message . ''; + break; + case 4: + $translated_message = '' . $translated_message . ''; + break; + } + + $translated_messages[] = $translated_message; + } + + parent::write($translated_messages, $newline); + } + + /** + * {@inheritdoc} + */ + public function writeError($messages, $newline = true, $verbosity = self::NORMAL) + { + $messages = (array) $messages; + $translated_messages = []; + + foreach ($messages as $message) + { + $level = 0; + if (is_array($message)) + { + $lang_key = $message[0]; + $parameters = $message[1]; + if (count($message) > 2) + { + $level = $message[2]; + } + } + else + { + $lang_key = $message; + $parameters = []; + } + + $message = trim($this->strip_format($lang_key), "\n\r"); + + if ($message === 'Your requirements could not be resolved to an installable set of packages.') + { + $this->composer_error[] = ['COMPOSER_ERROR_CONFLICT', []]; + + if ($this->output->getVerbosity() < OutputInterface::VERBOSITY_DEBUG) + { + continue; + } + } + else if (strpos($message, ' Problem ') === 0) + { + if ($this->output->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) + { + continue; + } + + $lang_key = "\n" . htmlentities($message) . "\n"; + $level = 4; + } + else if ($message === 'Updating dependencies') + { + $lang_key = 'COMPOSER_UPDATING_DEPENDENCIES'; + $level = 1; + } + else if ($message === 'Loading composer repositories with package information') + { + $lang_key = 'COMPOSER_LOADING_REPOSITORIES'; + $level = 1; + } + else if (strpos($message, 'could not be fully loaded, package information was loaded from the local cache and may be out of date') !== false) + { + $end_repo = strpos($message, 'could not be fully loaded, package information was loaded from the local cache and may be out of date'); + $repo = substr($message, 0, $end_repo - 1); + + $lang_key = 'COMPOSER_REPOSITORY_UNAVAILABLE'; + $parameters = [$repo]; + $level = 3; + } + else if (strpos($message, 'file could not be downloaded') !== false) + { + continue; + } + else if (strpos($message, ' - Installing ') === 0) + { + $elements = explode(' ', $message); + $lang_key = 'COMPOSER_INSTALLING_PACKAGE'; + $parameters = [$elements[4], trim($elements[5], '()')]; + } + else if ($message === 'Nothing to install or update') + { + $lang_key = 'COMPOSER_UPDATE_NOTHING'; + $level = 3; + } + else if ($message === ' Downloading') + { + continue; + } + else if ($message === ' Loading from cache') + { + continue; + } + else if ($message === 'Writing lock file') + { + continue; + } + else if ($message === ' Extracting archive') + { + continue; + } + else if (empty($message)) + { + continue; + } + + $translated_message = $this->language->lang_array($lang_key, $parameters); + + switch ($level) + { + case 1: + $translated_message = '' . $translated_message . ''; + break; + case 2: + $translated_message = '' . $translated_message . ''; + break; + case 3: + $translated_message = '' . $translated_message . ''; + break; + case 4: + $translated_message = '' . $translated_message . ''; + break; + } + + $translated_messages[] = $translated_message; + } + + parent::writeError($translated_messages, $newline); + } + + public function get_composer_error() + { + $error = ''; + foreach ($this->composer_error as $error_line) + { + $error .= $this->language->lang_array($error_line[0], $error_line[1]); + $error .= "\n"; + } + + $this->composer_error = []; + + return $error; + } + + protected function strip_format($message) + { + return str_replace([ + '', '', + '', '', + '', '', + '', '', + ], '', $message); + } +} diff --git a/phpBB/phpbb/composer/io/web_io.php b/phpBB/phpbb/composer/io/web_io.php new file mode 100644 index 00000000000..4eab3d099ae --- /dev/null +++ b/phpBB/phpbb/composer/io/web_io.php @@ -0,0 +1,37 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer\io; + +use Composer\IO\BufferIO; +use phpbb\language\language; +use Symfony\Component\Console\Formatter\OutputFormatterInterface; +use Symfony\Component\Console\Output\StreamOutput; + +class web_io extends BufferIO implements io_interface +{ + use translate_composer_trait; + + /** + * @param language $language Language object + * @param string $input Input string + * @param int $verbosity Verbosity level + * @param OutputFormatterInterface $formatter Output formatter + */ + public function __construct(language $language, $input = '', $verbosity = StreamOutput::VERBOSITY_NORMAL, OutputFormatterInterface $formatter = null) + { + $this->language = $language; + + parent::__construct($input, $verbosity, $formatter); + } +} diff --git a/phpBB/phpbb/composer/manager.php b/phpBB/phpbb/composer/manager.php new file mode 100644 index 00000000000..43ea8a25035 --- /dev/null +++ b/phpBB/phpbb/composer/manager.php @@ -0,0 +1,332 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer; + +use Composer\IO\IOInterface; +use phpbb\cache\driver\driver_interface; +use phpbb\composer\exception\runtime_exception; + +/** + * Class to manage packages through composer. + */ +class manager implements manager_interface +{ + /** + * @var installer Composer packages installer + */ + protected $installer; + + /** + * @var driver_interface Cache instance + */ + protected $cache; + + /** + * @var string Type of packages (phpbb-packages per example) + */ + protected $package_type; + + /** + * @var string Prefix used for the exception's language string + */ + protected $exception_prefix; + + /** + * @var array Caches the managed packages list (for the current type) + */ + private $managed_packages; + + /** + * @var array Caches the managed packages list (for all phpBB types) + */ + private $all_managed_packages; + + /** + * @var array Caches the available packages list + */ + private $available_packages; + + /** + * @param installer $installer Installer object + * @param driver_interface $cache Cache object + * @param string $package_type Composer type of managed packages + * @param string $exception_prefix Exception prefix to use + */ + public function __construct(installer $installer, driver_interface $cache, $package_type, $exception_prefix) + { + $this->installer = $installer; + $this->cache = $cache; + $this->package_type = $package_type; + $this->exception_prefix = $exception_prefix; + } + + /** + * {@inheritdoc} + */ + public function install(array $packages, IOInterface $io = null) + { + $packages = $this->normalize_version($packages); + + $already_managed = array_intersect(array_keys($this->get_managed_packages()), array_keys($packages)); + if (count($already_managed) !== 0) + { + throw new runtime_exception($this->exception_prefix, 'ALREADY_INSTALLED', [implode('|', $already_managed)]); + } + + $this->pre_install($packages, $io); + + $managed_packages = array_merge($this->get_all_managed_packages(), $packages); + ksort($managed_packages); + + $this->installer->install($managed_packages, array_keys($packages), $io); + + $this->post_install($packages, $io); + + $this->managed_packages = null; + } + + /** + * Hook called before installing the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function pre_install(array $packages, IOInterface $io = null) + { + } + + /** + * Hook called after installing the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function post_install(array $packages, IOInterface $io = null) + { + } + + /** + * {@inheritdoc} + */ + public function update(array $packages, IOInterface $io = null) + { + $packages = $this->normalize_version($packages); + + $not_managed = array_diff_key($packages, $this->get_managed_packages()); + if (count($not_managed) !== 0) + { + throw new runtime_exception($this->exception_prefix, 'NOT_MANAGED', [implode('|', array_keys($not_managed))]); + } + + $this->pre_update($packages, $io); + + $managed_packages = array_merge($this->get_all_managed_packages(), $packages); + ksort($managed_packages); + + $this->installer->install($managed_packages, array_keys($packages), $io); + + $this->post_update($packages, $io); + } + + /** + * Hook called before updating the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function pre_update(array $packages, IOInterface $io = null) + { + } + + /** + * Hook called after updating the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function post_update(array $packages, IOInterface $io = null) + { + } + + /** + * {@inheritdoc} + */ + public function remove(array $packages, IOInterface $io = null) + { + $packages = $this->normalize_version($packages); + + $not_managed = array_diff_key($packages, $this->get_managed_packages()); + if (count($not_managed) !== 0) + { + throw new runtime_exception($this->exception_prefix, 'NOT_MANAGED', [implode('|', array_keys($not_managed))]); + } + + $this->pre_remove($packages, $io); + + $managed_packages = array_diff_key($this->get_all_managed_packages(), $packages); + ksort($managed_packages); + + $this->installer->install($managed_packages, array_keys($packages), $io); + + $this->post_remove($packages, $io); + + $this->managed_packages = null; + } + + /** + * Hook called before removing the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function pre_remove(array $packages, IOInterface $io = null) + { + } + + /** + * Hook called after removing the packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + */ + protected function post_remove(array $packages, IOInterface $io = null) + { + } + + /** + * {@inheritdoc} + */ + public function is_managed($package) + { + return array_key_exists($package, $this->get_managed_packages()); + } + + /** + * {@inheritdoc} + */ + public function get_managed_packages() + { + if ($this->managed_packages === null) + { + $this->managed_packages = $this->installer->get_installed_packages($this->package_type); + } + + return $this->managed_packages; + } + + /** + * {@inheritdoc} + */ + public function get_all_managed_packages() + { + if ($this->all_managed_packages === null) + { + $this->all_managed_packages = $this->installer->get_installed_packages(explode(',', installer::PHPBB_TYPES)); + } + + return $this->all_managed_packages; + } + + /** + * {@inheritdoc} + */ + public function get_available_packages() + { + if ($this->available_packages === null) + { + $this->available_packages = $this->cache->get('_composer_' . $this->package_type . '_available'); + + if (!$this->available_packages) + { + $this->available_packages = $this->installer->get_available_packages($this->package_type); + $this->cache->put('_composer_' . $this->package_type . '_available', $this->available_packages, 24*60*60); + } + } + + return $this->available_packages; + } + + /** + * {@inheritdoc} + */ + public function reset_cache() + { + $this->cache->destroy('_composer_' . $this->package_type . '_available'); + + $this->available_packages = null; + $this->managed_packages = null; + $this->all_managed_packages = null; + } + + /** + * {@inheritdoc} + */ + public function start_managing($package, $io) + { + throw new \phpbb\exception\runtime_exception('COMPOSER_UNSUPPORTED_OPERATION', (array) $this->package_type); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + return $this->installer->check_requirements(); + } + + /** + * Normalize a packages/version array. Every entry can have 3 different forms: + * - $package => $version + * - $indice => $package:$version + * - $indice => $package + * They are converted to he form: + * - $package => $version ($version is set to '*' for the third form) + * + * @param array $packages + * + * @return array + */ + protected function normalize_version(array $packages) + { + $normalized_packages = []; + + foreach ($packages as $package => $version) + { + if (is_numeric($package)) + { + if (strpos($version, ':') !== false) + { + $parts = explode(':', $version); + $normalized_packages[$parts[0]] = $parts[1]; + } + else + { + $normalized_packages[$version] = '*'; + } + } + else + { + $normalized_packages[$package] = $version; + } + } + + return $normalized_packages; + } +} diff --git a/phpBB/phpbb/composer/manager_interface.php b/phpBB/phpbb/composer/manager_interface.php new file mode 100644 index 00000000000..3cb401f2b6d --- /dev/null +++ b/phpBB/phpbb/composer/manager_interface.php @@ -0,0 +1,110 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\composer; + +use Composer\IO\IOInterface; +use phpbb\composer\exception\runtime_exception; + +/** + * Class to manage packages through composer. + */ +interface manager_interface +{ + /** + * Installs (if necessary) a set of packages + * + * @param array $packages Packages to install. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + * + * @throws runtime_exception + */ + public function install(array $packages, IOInterface $io = null); + + /** + * Updates or installs a set of packages + * + * @param array $packages Packages to update. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + * + * @throws runtime_exception + */ + public function update(array $packages, IOInterface $io = null); + + /** + * Removes a set of packages + * + * @param array $packages Packages to remove. + * Each entry may be a name or an array associating a version constraint to a name + * @param IOInterface $io IO object used for the output + * + * @throws runtime_exception + */ + public function remove(array $packages, IOInterface $io = null); + + /** + * Tells whether or not a package is managed by Composer. + * + * @param string $packages Package name + * + * @return bool + */ + public function is_managed($packages); + + /** + * Returns the list of managed packages for the current type + * + * @return array The managed packages associated to their version. + */ + public function get_managed_packages(); + + /** + * Returns the list of managed packages for all phpBB types + * + * @return array The managed packages associated to their version. + */ + public function get_all_managed_packages(); + + /** + * Returns the list of available packages + * + * @return array The name of the available packages, associated to their definition. Ordered by name. + */ + public function get_available_packages(); + + /** + * Reset the cache + */ + public function reset_cache(); + + /** + * Start managing a manually installed package + * + * Remove a package installed manually and reinstall it using composer. + * + * @param string $package Package to manage + * @param IOInterface $io IO object used for the output + * + * @throws runtime_exception + */ + public function start_managing($package, $io); + + /** + * Checks the requirements of the manager and returns true if it can be used. + * + * @return bool + */ + public function check_requirements(); +} diff --git a/phpBB/phpbb/config/config.php b/phpBB/phpbb/config/config.php index aaad333006f..c619cae2fd0 100644 --- a/phpBB/phpbb/config/config.php +++ b/phpBB/phpbb/config/config.php @@ -147,6 +147,25 @@ public function set_atomic($key, $old_value, $new_value, $use_cache = true) return false; } + /** + * Checks configuration option's value only if the new_value matches the + * current configuration value and the configuration value does exist.Called + * only after set_atomic has been called. + * + * @param string $key The configuration option's name + * @param string $new_value New configuration value + * @throws \phpbb\exception\http_exception when config value is set and not equal to new_value. + * @return bool True if the value was changed, false otherwise. + */ + public function ensure_lock($key, $new_value) + { + if (isset($this->config[$key]) && $this->config[$key] == $new_value) + { + return true; + } + throw new \phpbb\exception\http_exception(500, 'Failure while aqcuiring locks.'); + } + /** * Increments an integer configuration value. * diff --git a/phpBB/phpbb/console/command/cron/run.php b/phpBB/phpbb/console/command/cron/run.php index dea64930073..df8bcf44f92 100644 --- a/phpBB/phpbb/console/command/cron/run.php +++ b/phpBB/phpbb/console/command/cron/run.php @@ -73,7 +73,7 @@ protected function configure() * @param InputInterface $input The input stream used to get the argument and verboe option. * @param OutputInterface $output The output stream, used for printing verbose-mode and error information. * - * @return int 0 if all is ok, 1 if a lock error occured and 2 if no task matching the argument was found. + * @return int 0 if all is ok, 1 if a lock error occurred and 2 if no task matching the argument was found. */ protected function execute(InputInterface $input, OutputInterface $output) { diff --git a/phpBB/phpbb/console/command/extension/install.php b/phpBB/phpbb/console/command/extension/install.php new file mode 100644 index 00000000000..bbed53be306 --- /dev/null +++ b/phpBB/phpbb/console/command/extension/install.php @@ -0,0 +1,103 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\console\command\extension; + +use phpbb\composer\extension_manager; +use phpbb\composer\io\console_io; +use phpbb\language\language; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +class install extends \phpbb\console\command\command +{ + /** + * @var extension_manager Composer extensions manager + */ + protected $manager; + + /** + * @var \phpbb\language\language + */ + protected $language; + + public function __construct(\phpbb\user $user, extension_manager $manager, language $language) + { + $this->manager = $manager; + $this->language = $language; + + $language->add_lang('acp/extensions'); + + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('extension:install') + ->setDescription($this->language->lang('CLI_DESCRIPTION_EXTENSION_INSTALL')) + ->addOption( + 'enable', + null, + InputOption::VALUE_NONE, + $this->language->lang('CLI_DESCRIPTION_EXTENSION_INSTALL_OPTION_ENABLE')) + ->addArgument( + 'extensions', + InputArgument::IS_ARRAY | InputArgument::REQUIRED, + $this->language->lang('CLI_DESCRIPTION_EXTENSION_INSTALL_ARGUMENT')) + ; + } + + /** + * Executes the command extension:install + * + * @param InputInterface $input + * @param OutputInterface $output + * @return integer + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('black', 'yellow')); + + $io = new SymfonyStyle($input, $output); + + if (!$this->manager->check_requirements()) + { + $io->error($this->language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE')); + return 1; + } + + $composer_io = new console_io($input, $output, $this->getHelperSet(), $this->language); + $extensions = $input->getArgument('extensions'); + + if ($input->getOption('enable')) + { + $this->manager->set_enable_on_install(true); + } + + $this->manager->install($extensions, $composer_io); + + $io->success($this->language->lang('EXTENSIONS_INSTALLED')); + + return 0; + } +} diff --git a/phpBB/phpbb/console/command/extension/list_available.php b/phpBB/phpbb/console/command/extension/list_available.php new file mode 100644 index 00000000000..7f9efe67715 --- /dev/null +++ b/phpBB/phpbb/console/command/extension/list_available.php @@ -0,0 +1,73 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\console\command\extension; + +use phpbb\composer\manager_interface; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +class list_available extends \phpbb\console\command\command +{ + /** + * @var manager_interface Composer extensions manager + */ + protected $manager; + + public function __construct(\phpbb\user $user, manager_interface $manager) + { + $this->manager = $manager; + + $user->add_lang('acp/extensions'); + + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('extension:list-available') + ->setDescription($this->user->lang('CLI_DESCRIPTION_EXTENSION_LIST_AVAILABLE')) + ; + } + + /** + * Executes the command extension:install + * + * @param InputInterface $input + * @param OutputInterface $output + * @return integer + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + + $extensions = []; + + foreach ($this->manager->get_available_packages() as $package) + { + $extensions[] = '' . $package['name'] . ' (' . $package['version'] . ') ' . $package['url'] . + ($package['description'] ? "\n" . $package['description'] : ''); + } + + $io->listing($extensions); + + return 0; + } +} diff --git a/phpBB/phpbb/console/command/extension/manage.php b/phpBB/phpbb/console/command/extension/manage.php new file mode 100644 index 00000000000..cd8bbc1a7de --- /dev/null +++ b/phpBB/phpbb/console/command/extension/manage.php @@ -0,0 +1,99 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\console\command\extension; + +use phpbb\composer\exception\managed_with_error_exception; +use phpbb\composer\io\console_io; +use phpbb\composer\manager_interface; +use phpbb\language\language; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +class manage extends \phpbb\console\command\command +{ + /** + * @var manager_interface Composer extensions manager + */ + protected $manager; + + /** + * @var \phpbb\language\language + */ + protected $language; + + public function __construct(\phpbb\user $user, manager_interface $manager, language $language) + { + $this->manager = $manager; + $this->language = $language; + + $language->add_lang('acp/extensions'); + + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('extension:manage') + ->setDescription($this->language->lang('CLI_DESCRIPTION_EXTENSION_MANAGE')) + ->addArgument( + 'extension', + InputArgument::REQUIRED, + $this->language->lang('CLI_DESCRIPTION_EXTENSION_MANAGE_ARGUMENT')) + ; + } + + /** + * Executes the command extension:install + * + * @param InputInterface $input + * @param OutputInterface $output + * @return integer + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + + if (!$this->manager->check_requirements()) + { + $io->error($this->language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE')); + return 1; + } + + $composer_io = new console_io($input, $output, $this->getHelperSet(), $this->language); + + $extension = $input->getArgument('extension'); + + try + { + $this->manager->start_managing($extension, $composer_io); + } + catch (managed_with_error_exception $e) + { + $io->warning($this->language->lang_array($e->getMessage(), $e->get_parameters())); + return 1; + } + + $io->success($this->language->lang('EXTENSION_MANAGED_SUCCESS', $extension)); + + return 0; + } +} diff --git a/phpBB/phpbb/console/command/extension/remove.php b/phpBB/phpbb/console/command/extension/remove.php new file mode 100644 index 00000000000..69d2a62dd97 --- /dev/null +++ b/phpBB/phpbb/console/command/extension/remove.php @@ -0,0 +1,103 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\console\command\extension; + +use phpbb\composer\extension_manager; +use phpbb\composer\io\console_io; +use phpbb\language\language; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +class remove extends \phpbb\console\command\command +{ + /** + * @var extension_manager Composer extensions manager + */ + protected $manager; + + /** + * @var \phpbb\language\language + */ + protected $language; + + public function __construct(\phpbb\user $user, extension_manager $manager, language $language) + { + $this->manager = $manager; + $this->language = $language; + + $language->add_lang('acp/extensions'); + + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('extension:remove') + ->setDescription($this->language->lang('CLI_DESCRIPTION_EXTENSION_REMOVE')) + ->addOption( + 'purge', + null, + InputOption::VALUE_NONE, + $this->language->lang('CLI_DESCRIPTION_EXTENSION_REMOVE_OPTION_PURGE')) + ->addArgument( + 'extensions', + InputArgument::IS_ARRAY | InputArgument::REQUIRED, + $this->language->lang('CLI_DESCRIPTION_EXTENSION_REMOVE_ARGUMENT')) + ; + } + + /** + * Executes the command extension:install + * + * @param InputInterface $input + * @param OutputInterface $output + * @return integer + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('black', 'yellow')); + + $io = new SymfonyStyle($input, $output); + + if (!$this->manager->check_requirements()) + { + $io->error($this->language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE')); + return 1; + } + + $composer_io = new console_io($input, $output, $this->getHelperSet(), $this->language); + $extensions = $input->getArgument('extensions'); + + if ($input->getOption('purge')) + { + $this->manager->set_purge_on_remove(true); + } + + $this->manager->remove($extensions, $composer_io); + + $io->success($this->language->lang('EXTENSIONS_REMOVED')); + + return 0; + } +} diff --git a/phpBB/phpbb/console/command/extension/update.php b/phpBB/phpbb/console/command/extension/update.php new file mode 100644 index 00000000000..f1479c8b0d7 --- /dev/null +++ b/phpBB/phpbb/console/command/extension/update.php @@ -0,0 +1,90 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\console\command\extension; + +use phpbb\composer\io\console_io; +use phpbb\composer\manager_interface; +use phpbb\language\language; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +class update extends \phpbb\console\command\command +{ + /** + * @var manager_interface Composer extensions manager + */ + protected $manager; + + /** + * @var \phpbb\language\language + */ + protected $language; + + public function __construct(\phpbb\user $user, manager_interface $manager, language $language) + { + $this->manager = $manager; + $this->language = $language; + + parent::__construct($user); + } + + /** + * Sets the command name and description + * + * @return null + */ + protected function configure() + { + $this + ->setName('extension:update') + ->setDescription($this->user->lang('CLI_DESCRIPTION_EXTENSION_UPDATE')) + ->addArgument( + 'extensions', + InputArgument::IS_ARRAY | InputArgument::REQUIRED, + $this->user->lang('CLI_DESCRIPTION_EXTENSION_UPDATE_ARGUMENT')) + ; + } + + /** + * Executes the command extension:install + * + * @param InputInterface $input + * @param OutputInterface $output + * @return integer + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('black', 'yellow')); + + $io = new SymfonyStyle($input, $output); + + if (!$this->manager->check_requirements()) + { + $io->error($this->language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE')); + return 1; + } + + $composer_io = new console_io($input, $output, $this->getHelperSet(), $this->language); + $extensions = $input->getArgument('extensions'); + + $this->manager->update($extensions, $composer_io); + + $io->success($this->language->lang('EXTENSIONS_UPDATED')); + + return 0; + } +} diff --git a/phpBB/phpbb/console/command/update/check.php b/phpBB/phpbb/console/command/update/check.php index 9ced651e8b6..85c6cf73797 100644 --- a/phpBB/phpbb/console/command/update/check.php +++ b/phpBB/phpbb/console/command/update/check.php @@ -77,7 +77,7 @@ protected function configure() * * @param InputInterface $input Input stream, used to get the options. * @param OutputInterface $output Output stream, used to print messages. - * @return int 0 if the board is up to date, 1 if it is not and 2 if an error occured. + * @return int 0 if the board is up to date, 1 if it is not and 2 if an error occurred. * @throws \RuntimeException */ protected function execute(InputInterface $input, OutputInterface $output) diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index f023e0742c0..704ec6badba 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -684,7 +684,7 @@ public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, * @param $time int Timestamp when the action is performed * @param $reason string Reason why the visibilty was changed. * @param $force_update_all bool Force to update all posts within the topic - * @return array Changed topic data, empty array if an error occured. + * @return array Changed topic data, empty array if an error occurred. */ public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false) { diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index 664b4f4e0f3..58a4a492f80 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -121,7 +121,7 @@ public function route($route, array $params = array(), $is_amp = true, $session_ * @param int $code The error code (e.g. 404, 500, 503, etc.) * @return Response A Response instance * - * @deprecated 3.1.3 (To be removed: 3.3.0) Use exceptions instead. + * @deprecated 3.1.3 (To be removed: 4.0.0) Use exceptions instead. */ public function error($message, $code = 500) { diff --git a/phpBB/phpbb/cron/controller/cron.php b/phpBB/phpbb/cron/controller/cron.php new file mode 100644 index 00000000000..6f0e35e4cda --- /dev/null +++ b/phpBB/phpbb/cron/controller/cron.php @@ -0,0 +1,40 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\cron\controller; + +use Symfony\Component\HttpFoundation\Response; + +/** + * Controller for running cron jobs + */ +class cron +{ + /** + * Handles CRON requests + * + * @param string $cron_type + * + * @return Response + */ + public function handle($cron_type) + { + $response = new Response(); + $response->headers->set('Cache-Control', 'no-cache'); + $response->headers->set('Content-type', 'image/gif'); + $response->headers->set('Content-length', '43'); + $response->setContent(base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==')); + + return $response; + } +} diff --git a/phpBB/phpbb/cron/event/cron_runner_listener.php b/phpBB/phpbb/cron/event/cron_runner_listener.php new file mode 100644 index 00000000000..9e9ecf0d472 --- /dev/null +++ b/phpBB/phpbb/cron/event/cron_runner_listener.php @@ -0,0 +1,103 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\cron\event; + +use phpbb\cron\manager; +use phpbb\lock\db; +use phpbb\request\request_interface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\Event\PostResponseEvent; + +/** + * Event listener that executes cron tasks, after the response was served + */ +class cron_runner_listener implements EventSubscriberInterface +{ + /** + * @var \phpbb\lock\db + */ + private $cron_lock; + + /** + * @var \phpbb\cron\manager + */ + private $cron_manager; + + /** + * @var \phpbb\request\request_interface + */ + private $request; + + /** + * Constructor + * + * @param db $lock + * @param manager $manager + * @param request_interface $request + */ + public function __construct(db $lock, manager $manager, request_interface $request) + { + $this->cron_lock = $lock; + $this->cron_manager = $manager; + $this->request = $request; + } + + /** + * Runs the cron job after the response was sent + * + * @param PostResponseEvent $event The event + */ + public function on_kernel_terminate(PostResponseEvent $event) + { + $request = $event->getRequest(); + $controller_name = $request->get('_route'); + + if ($controller_name !== 'phpbb_cron_run') + { + return; + } + + $cron_type = $request->get('cron_type'); + + if ($this->cron_lock->acquire()) + { + $task = $this->cron_manager->find_task($cron_type); + if ($task) + { + if ($task->is_parametrized()) + { + $task->parse_parameters($this->request); + } + + if ($task->is_ready()) + { + $task->run(); + } + + $this->cron_lock->release(); + } + } + } + + /** + * {@inheritdoc} + */ + static public function getSubscribedEvents() + { + return array( + KernelEvents::TERMINATE => 'on_kernel_terminate', + ); + } +} diff --git a/phpBB/phpbb/cron/manager.php b/phpBB/phpbb/cron/manager.php index 9bd30a0a5be..59ee6930749 100644 --- a/phpBB/phpbb/cron/manager.php +++ b/phpBB/phpbb/cron/manager.php @@ -13,6 +13,9 @@ namespace phpbb\cron; +use phpbb\cron\task\wrapper; +use phpbb\routing\helper; + /** * Cron manager class. * @@ -20,6 +23,11 @@ */ class manager { + /** + * @var helper + */ + protected $routing_helper; + /** * Set of \phpbb\cron\task\wrapper objects. * Array holding all tasks that have been found. @@ -28,18 +36,27 @@ class manager */ protected $tasks = array(); + /** + * @var string + */ protected $phpbb_root_path; + + /** + * @var string + */ protected $php_ext; /** * Constructor. Loads all available tasks. * * @param array|\Traversable $tasks Provides an iterable set of task names + * @param helper $routing_helper Routing helper * @param string $phpbb_root_path Relative path to phpBB root * @param string $php_ext PHP file extension */ - public function __construct($tasks, $phpbb_root_path, $php_ext) + public function __construct($tasks, helper $routing_helper, $phpbb_root_path, $php_ext) { + $this->routing_helper = $routing_helper; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -142,6 +159,6 @@ public function get_tasks() */ public function wrap_task(\phpbb\cron\task\task $task) { - return new \phpbb\cron\task\wrapper($task, $this->phpbb_root_path, $this->php_ext); + return new wrapper($task, $this->routing_helper, $this->phpbb_root_path, $this->php_ext); } } diff --git a/phpBB/phpbb/cron/task/wrapper.php b/phpBB/phpbb/cron/task/wrapper.php index 8a4a8b1f0c9..4dc3a7fb95d 100644 --- a/phpBB/phpbb/cron/task/wrapper.php +++ b/phpBB/phpbb/cron/task/wrapper.php @@ -13,14 +13,32 @@ namespace phpbb\cron\task; +use phpbb\routing\helper; + /** * Cron task wrapper class. * Enhances cron tasks with convenience methods that work identically for all tasks. */ class wrapper { + /** + * @var helper + */ + protected $routing_helper; + + /** + * @var task + */ protected $task; + + /** + * @var string + */ protected $phpbb_root_path; + + /** + * @var string + */ protected $php_ext; /** @@ -28,13 +46,15 @@ class wrapper * * Wraps a task $task, which must implement cron_task interface. * - * @param \phpbb\cron\task\task $task The cron task to wrap. - * @param string $phpbb_root_path Relative path to phpBB root - * @param string $php_ext PHP file extension + * @param task $task The cron task to wrap. + * @param helper $routing_helper Routing helper for route generation + * @param string $phpbb_root_path Relative path to phpBB root + * @param string $php_ext PHP file extension */ - public function __construct(\phpbb\cron\task\task $task, $phpbb_root_path, $php_ext) + public function __construct(task $task, helper $routing_helper, $phpbb_root_path, $php_ext) { $this->task = $task; + $this->routing_helper = $routing_helper; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } @@ -49,7 +69,7 @@ public function __construct(\phpbb\cron\task\task $task, $phpbb_root_path, $php_ */ public function is_parametrized() { - return $this->task instanceof \phpbb\cron\task\parametrized; + return $this->task instanceof parametrized; } /** @@ -76,22 +96,13 @@ public function is_ready() */ public function get_url() { - $name = $this->get_name(); + $params['cron_type'] = $this->get_name(); if ($this->is_parametrized()) { - $params = $this->task->get_parameters(); - $extra = ''; - foreach ($params as $key => $value) - { - $extra .= '&' . $key . '=' . urlencode($value); - } + $params = array_merge($params, $this->task->get_parameters()); } - else - { - $extra = ''; - } - $url = append_sid($this->phpbb_root_path . 'cron.' . $this->php_ext, 'cron_type=' . $name . $extra); - return $url; + + return $this->routing_helper->route('phpbb_cron_run', $params); } /** diff --git a/phpBB/phpbb/db/driver/mysql.php b/phpBB/phpbb/db/driver/mysql.php index a94e88b331f..5eabe0f9ef3 100644 --- a/phpBB/phpbb/db/driver/mysql.php +++ b/phpBB/phpbb/db/driver/mysql.php @@ -390,7 +390,7 @@ function _sql_report($mode, $query = '') { static $test_prof; - // current detection method, might just switch to see the existance of INFORMATION_SCHEMA.PROFILING + // current detection method, might just switch to see the existence of INFORMATION_SCHEMA.PROFILING if ($test_prof === null) { $test_prof = false; diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php index d43e2015260..57962fdf207 100644 --- a/phpBB/phpbb/db/driver/mysqli.php +++ b/phpBB/phpbb/db/driver/mysqli.php @@ -373,7 +373,7 @@ function _sql_report($mode, $query = '') { static $test_prof; - // current detection method, might just switch to see the existance of INFORMATION_SCHEMA.PROFILING + // current detection method, might just switch to see the existence of INFORMATION_SCHEMA.PROFILING if ($test_prof === null) { $test_prof = false; diff --git a/phpBB/phpbb/db/extractor/mysql_extractor.php b/phpBB/phpbb/db/extractor/mysql_extractor.php index 34e309c19e0..534e8b7653a 100644 --- a/phpBB/phpbb/db/extractor/mysql_extractor.php +++ b/phpBB/phpbb/db/extractor/mysql_extractor.php @@ -300,7 +300,7 @@ protected function new_write_table($table_name) } /** - * Extracts database table structure (for MySQL verisons older than 3.23.20) + * Extracts database table structure (for MySQL versions older than 3.23.20) * * @param string $table_name name of the database table * @return null diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php index 10343438b37..247ccc7a763 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php @@ -117,7 +117,7 @@ public function update_custom_profile_fields() } else { - // equivelant to "none", which is the "Display in user control panel" option + // equivalent to "none", which is the "Display in user control panel" option $sql_ary['field_show_profile'] = 1; } diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php index b1e7486e241..877cdc2fa39 100644 --- a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php +++ b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php @@ -132,7 +132,7 @@ public function update_topics_post_counts() /* * Using sql_case here to avoid "BIGINT UNSIGNED value is out of range" errors. * As we update all topics in 2 queries, one broken topic would stop the conversion - * for all topics and the surpressed error will cause the admin to not even notice it. + * for all topics and the suppressed error will cause the admin to not even notice it. */ $sql = 'UPDATE ' . $this->table_prefix . 'topics SET topic_posts_approved = topic_replies + 1, diff --git a/phpBB/phpbb/db/migration/data/v330/acp_storage_module.php b/phpBB/phpbb/db/migration/data/v330/acp_storage_module.php new file mode 100644 index 00000000000..d5491a625e5 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v330/acp_storage_module.php @@ -0,0 +1,33 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v330; + +class acp_storage_module extends \phpbb\db\migration\migration +{ + public function update_data() + { + return array( + array('module.add', array( + 'acp', + 'ACP_SERVER_CONFIGURATION', + array( + 'module_basename' => 'acp_storage', + 'module_langname' => 'ACP_STORAGE_SETTINGS', + 'module_mode' => 'settings', + 'module_auth' => 'acl_a_storage', + ), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v330/add_storage_permission.php b/phpBB/phpbb/db/migration/data/v330/add_storage_permission.php new file mode 100644 index 00000000000..0836462f030 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v330/add_storage_permission.php @@ -0,0 +1,28 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v330; + +class add_storage_permission extends \phpbb\db\migration\migration +{ + public function update_data() + { + return array( + // Add permission + array('permission.add', array('a_storage')), + + // Set permissions + array('permission.permission_set', array('ROLE_ADMIN_FULL', 'a_storage')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v330/extensions_composer.php b/phpBB/phpbb/db/migration/data/v330/extensions_composer.php new file mode 100644 index 00000000000..7e12150e56d --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v330/extensions_composer.php @@ -0,0 +1,39 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v330; + +class extensions_composer extends \phpbb\db\migration\migration +{ + public function update_data() + { + return array( + array('config.add', array('exts_composer_repositories', json_encode([ + 'https://www.phpbb.com/customise/db/composer/', + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES))), + array('config.add', array('exts_composer_packagist', false)), + array('config.add', array('exts_composer_json_file', 'composer-ext.json')), + array('config.add', array('exts_composer_vendor_dir', 'vendor-ext/')), + array('config.add', array('exts_composer_enable_on_install', false)), + array('config.add', array('exts_composer_purge_on_remove', true)), + array('module.add', array( + 'acp', + 'ACP_EXTENSION_MANAGEMENT', + array( + 'module_basename' => 'acp_extensions', + 'modes' => array('catalog'), + ), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v330/storage_avatar.php b/phpBB/phpbb/db/migration/data/v330/storage_avatar.php new file mode 100644 index 00000000000..077904daa61 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v330/storage_avatar.php @@ -0,0 +1,26 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v330; + +class storage_avatar extends \phpbb\db\migration\migration +{ + public function update_data() + { + return array( + array('config.add', array('storage\\avatar\\provider', \phpbb\storage\provider\local::class)), + array('config.add', array('storage\\avatar\\config\\path', $this->config['avatar_path'])), + array('config.remove', array('avatar_path')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 7d2720c8619..0e5cddbd393 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -504,7 +504,7 @@ protected function get_categories_list() * Get parent module id * * @param string|int $parent_id The parent module_id|module_langname - * @param int|string|array $data The module_id, module_langname for existance checking or module data array for adding + * @param int|string|array $data The module_id, module_langname for existence checking or module data array for adding * @param bool $throw_exception The flag indicating if exception should be thrown on error * @return mixed The int parent module_id, an array of int parent module_id values or false * @throws \phpbb\db\migration\exception diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index a425df56e87..0929160413f 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -784,7 +784,7 @@ protected function get_callable_from_step(array $step, $last_result = 0, $revers { return array( $parameters[0], - array($last_result), + isset($parameters[1]) ? array_merge($parameters[1], array($last_result)) : array($last_result), ); } break; diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index cbedf9a5c4f..29f816a8698 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -194,7 +194,7 @@ function sql_create_table($table_name, $table_data) $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; } - // create sequence DDL based off of the existance of auto incrementing columns + // create sequence DDL based off of the existence of auto incrementing columns if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) { $create_sequence = $column_name; diff --git a/phpBB/phpbb/db/tools/postgres.php b/phpBB/phpbb/db/tools/postgres.php index 077d6e06f99..276ac135be6 100644 --- a/phpBB/phpbb/db/tools/postgres.php +++ b/phpBB/phpbb/db/tools/postgres.php @@ -141,7 +141,7 @@ function sql_create_table($table_name, $table_data) $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; } - // create sequence DDL based off of the existance of auto incrementing columns + // create sequence DDL based off of the existence of auto incrementing columns if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) { $create_sequence = $column_name; diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index d21d34b8a99..ccba63a5d30 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -335,7 +335,7 @@ function sql_create_table($table_name, $table_data) $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; } - // create sequence DDL based off of the existance of auto incrementing columns + // create sequence DDL based off of the existence of auto incrementing columns if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) { $create_sequence = $column_name; diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index ac1a1a1733e..d267b11820b 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -13,7 +13,6 @@ namespace phpbb\di; -use phpbb\filesystem\filesystem; use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\FileLocator; @@ -25,6 +24,7 @@ use Symfony\Component\Filesystem\Exception\IOException; use Symfony\Component\Finder\Finder; use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; +use phpbb\filesystem\helper as filesystem_helper; class container_builder { @@ -180,8 +180,7 @@ public function get_container() $this->register_ext_compiler_pass(); } - $filesystem = new filesystem(); - $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path()))); + $loader = new YamlFileLoader($this->container, new FileLocator(filesystem_helper::realpath($this->get_config_path()))); $loader->load($this->container->getParameter('core.environment') . '/config.yml'); $this->inject_custom_parameters(); @@ -415,6 +414,12 @@ protected function load_extensions() $ext_container->register('cache.driver', '\\phpbb\\cache\\driver\\dummy'); $ext_container->compile(); + $config = $ext_container->get('config'); + if (@is_file($this->phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php')) + { + require_once($this->phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php'); + } + $extensions = $ext_container->get('ext.manager')->all_enabled(); // Load each extension found diff --git a/phpBB/phpbb/di/extension/container_configuration.php b/phpBB/phpbb/di/extension/container_configuration.php index 4585d6509e0..3870670ac00 100644 --- a/phpBB/phpbb/di/extension/container_configuration.php +++ b/phpBB/phpbb/di/extension/container_configuration.php @@ -45,6 +45,13 @@ public function getConfigTreeBuilder() ->booleanNode('enable_debug_extension')->defaultValue(false)->end() ->end() ->end() + ->arrayNode('extensions') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('composer_debug')->defaultValue(false)->end() + ->booleanNode('composer_verbose')->defaultValue(false)->end() + ->end() + ->end() ->end() ; return $treeBuilder; diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php index 67150f0103d..75a037871f9 100644 --- a/phpBB/phpbb/di/extension/core.php +++ b/phpBB/phpbb/di/extension/core.php @@ -15,9 +15,11 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use phpbb\filesystem\helper as filesystem_helper; /** * Container core extension @@ -52,8 +54,7 @@ public function __construct($config_path) */ public function load(array $configs, ContainerBuilder $container) { - $filesystem = new \phpbb\filesystem\filesystem(); - $loader = new YamlFileLoader($container, new FileLocator($filesystem->realpath($this->config_path))); + $loader = new YamlFileLoader($container, new FileLocator(filesystem_helper::realpath($this->config_path))); $loader->load($container->getParameter('core.environment') . '/container/environment.yml'); $config = $this->getConfiguration($configs, $container); @@ -92,6 +93,18 @@ public function load(array $configs, ContainerBuilder $container) $definition->addTag('twig.extension'); } + $composer_output = OutputInterface::VERBOSITY_NORMAL; + if ($config['extensions']['composer_verbose']) + { + $composer_output = OutputInterface::VERBOSITY_VERBOSE; + } + if ($config['extensions']['composer_debug']) + { + $composer_output = OutputInterface::VERBOSITY_DEBUG; + } + + $container->setParameter('extensions.composer.output', $composer_output); + // Set the debug options foreach ($config['debug'] as $name => $value) { diff --git a/phpBB/phpbb/di/service_collection.php b/phpBB/phpbb/di/service_collection.php index 8e9175e2042..8c1c172e365 100644 --- a/phpBB/phpbb/di/service_collection.php +++ b/phpBB/phpbb/di/service_collection.php @@ -103,4 +103,35 @@ public function get_service_classes() { return $this->service_classes; } + + /** + * Returns the service associated to a class + * + * @return mixed + * @throw \RuntimeException if the + */ + public function get_by_class($class) + { + $service_id = null; + + foreach ($this->service_classes as $id => $service_class) + { + if ($service_class === $class) + { + if ($service_id !== null) + { + throw new \RuntimeException('More than one service definitions found for class "'.$class.'" in collection.'); + } + + $service_id = $id; + } + } + + if ($service_id === null) + { + throw new \RuntimeException('No service found for class "'.$class.'" in collection.'); + } + + return $this->offsetGet($service_id); + } } diff --git a/phpBB/phpbb/extension/di/extension_base.php b/phpBB/phpbb/extension/di/extension_base.php index ba74615e702..97033e7ddb8 100644 --- a/phpBB/phpbb/extension/di/extension_base.php +++ b/phpBB/phpbb/extension/di/extension_base.php @@ -18,6 +18,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use phpbb\filesystem\helper as filesystem_helper; /** * Container core extension @@ -94,8 +95,7 @@ protected function load_services(ContainerBuilder $container) if ($services_directory && $services_file) { - $filesystem = new \phpbb\filesystem\filesystem(); - $loader = new YamlFileLoader($container, new FileLocator($filesystem->realpath($services_directory))); + $loader = new YamlFileLoader($container, new FileLocator(filesystem_helper::realpath($services_directory))); $loader->load($services_file); } } diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 4b4109bd85a..a98e9c27c0f 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -40,14 +40,13 @@ class manager * @param ContainerInterface $container A container * @param \phpbb\db\driver\driver_interface $db A database connection * @param \phpbb\config\config $config Config object - * @param \phpbb\filesystem\filesystem_interface $filesystem * @param string $extension_table The name of the table holding extensions * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $php_ext php file extension, defaults to php * @param \phpbb\cache\service $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\service $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\service $cache = null, $cache_name = '_ext') { $this->cache = $cache; $this->cache_name = $cache_name; @@ -55,7 +54,6 @@ public function __construct(ContainerInterface $container, \phpbb\db\driver\driv $this->container = $container; $this->db = $db; $this->extension_table = $extension_table; - $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -619,7 +617,7 @@ public function is_purged($name) */ public function get_finder($use_all_available = false) { - $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); + $finder = new \phpbb\finder($this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); if ($use_all_available) { $finder->set_extensions(array_keys($this->all_available())); diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php index ea9ee97b9d3..ee7fe177f5f 100644 --- a/phpBB/phpbb/feed/topics_active.php +++ b/phpBB/phpbb/feed/topics_active.php @@ -17,7 +17,7 @@ * Active Topics feed * * This will give you the last {$this->num_items} topics - * with replies made withing the last {$this->sort_days} days + * with replies made within the last {$this->sort_days} days * including the last post. */ class topics_active extends topic_base diff --git a/phpBB/phpbb/files/filespec_storage.php b/phpBB/phpbb/files/filespec_storage.php new file mode 100644 index 00000000000..b370b66a4ed --- /dev/null +++ b/phpBB/phpbb/files/filespec_storage.php @@ -0,0 +1,512 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files; + +use phpbb\language\language; + +/** + * Responsible for holding all file relevant information, as well as doing file-specific operations. + * The {@link fileupload fileupload class} can be used to upload several files, each of them being this object to operate further on. + */ +class filespec_storage +{ + /** @var string File name */ + protected $filename = ''; + + /** @var string Real name of file */ + protected $realname = ''; + + /** @var string Upload name of file */ + protected $uploadname = ''; + + /** @var string Mimetype of file */ + protected $mimetype = ''; + + /** @var string File extension */ + protected $extension = ''; + + /** @var int File size */ + protected $filesize = 0; + + /** @var int Width of file */ + protected $width = 0; + + /** @var int Height of file */ + protected $height = 0; + + /** @var array Image info including type and size */ + protected $image_info = array(); + + /** @var string Destination file name */ + protected $destination_file = ''; + + /** @var string Destination file path */ + protected $destination_path = ''; + + /** @var bool Whether file was moved */ + protected $file_moved = false; + + /** @var bool Whether file is local */ + protected $local = false; + + /** @var bool Class initialization flag */ + protected $class_initialized = false; + + /** @var array Error array */ + public $error = array(); + + /** @var upload Instance of upload class */ + public $upload; + + /** @var \bantu\IniGetWrapper\IniGetWrapper ini_get() wrapper class */ + protected $php_ini; + + /** @var \FastImageSize\FastImageSize */ + protected $imagesize; + + /** @var language Language class */ + protected $language; + + /** @var \phpbb\plupload\plupload The plupload object */ + protected $plupload; + + /** @var \phpbb\mimetype\guesser phpBB Mimetype guesser */ + protected $mimetype_guesser; + + /** + * File upload class + * + * @param language $language Language + * @param \bantu\IniGetWrapper\IniGetWrapper $php_ini ini_get() wrapper + * @param \FastImageSize\FastImageSize $imagesize Imagesize class + * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser + * @param \phpbb\plupload\plupload $plupload Plupload + */ + public function __construct(language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, \FastImageSize\FastImageSize $imagesize, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null) + { + $this->language = $language; + $this->php_ini = $php_ini; + $this->imagesize = $imagesize; + $this->plupload = $plupload; + $this->mimetype_guesser = $mimetype_guesser; + } + + /** + * Set upload ary + * + * @param array $upload_ary Upload ary + * + * @return filespec This instance of the filespec class + */ + public function set_upload_ary($upload_ary) + { + if (!isset($upload_ary) || !count($upload_ary)) + { + return $this; + } + + $this->class_initialized = true; + $this->filename = $upload_ary['tmp_name']; + $this->filesize = $upload_ary['size']; + $name = $upload_ary['name']; + $name = trim(utf8_basename($name)); + $this->realname = $this->uploadname = $name; + $this->mimetype = $upload_ary['type']; + + // Opera adds the name to the mime type + $this->mimetype = (strpos($this->mimetype, '; name') !== false) ? str_replace(strstr($this->mimetype, '; name'), '', $this->mimetype) : $this->mimetype; + + if (!$this->mimetype) + { + $this->mimetype = 'application/octet-stream'; + } + + $this->extension = strtolower(self::get_extension($this->realname)); + + // Try to get real filesize from temporary folder (not always working) ;) + $this->filesize = ($this->get_filesize($this->filename)) ?: $this->filesize; + + $this->width = $this->height = 0; + $this->file_moved = false; + + $this->local = (isset($upload_ary['local_mode'])) ? true : false; + + return $this; + } + + /** + * Set the upload namespace + * + * @param upload $namespace Instance of upload class + * + * @return filespec This instance of the filespec class + */ + public function set_upload_namespace($namespace) + { + $this->upload = $namespace; + + return $this; + } + + /** + * Check if class members were not properly initialised yet + * + * @return bool True if there was an init error, false if not + */ + public function init_error() + { + return !$this->class_initialized; + } + + /** + * Set error in error array + * + * @param mixed $error Content for error array + * + * @return \phpbb\files\filespec This instance of the filespec class + */ + public function set_error($error) + { + $this->error[] = $error; + + return $this; + } + + /** + * Cleans destination filename + * + * @param string $mode Either real, unique, or unique_ext. Real creates a + * realname, filtering some characters, lowering every + * character. Unique creates a unique filename. + * @param string $prefix Prefix applied to filename + * @param string $user_id The user_id is only needed for when cleaning a user's avatar + */ + public function clean_filename($mode = 'unique', $prefix = '', $user_id = '') + { + if ($this->init_error()) + { + return; + } + + switch ($mode) + { + case 'real': + // Remove every extension from filename (to not let the mime bug being exposed) + if (strpos($this->realname, '.') !== false) + { + $this->realname = substr($this->realname, 0, strpos($this->realname, '.')); + } + + // Replace any chars which may cause us problems with _ + $bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|'); + + $this->realname = rawurlencode(str_replace($bad_chars, '_', strtolower($this->realname))); + $this->realname = preg_replace("/%(\w{2})/", '_', $this->realname); + + $this->realname = $prefix . $this->realname . '.' . $this->extension; + break; + + case 'unique': + $this->realname = $prefix . md5(unique_id()); + break; + + case 'avatar': + $this->extension = strtolower($this->extension); + $this->realname = $prefix . $user_id . '.' . $this->extension; + + break; + + case 'unique_ext': + default: + $this->realname = $prefix . md5(unique_id()) . '.' . $this->extension; + } + } + + /** + * Get property from file object + * + * @param string $property Name of property + * + * @return mixed Content of property + */ + public function get($property) + { + if ($this->init_error() || !isset($this->$property)) + { + return false; + } + + return $this->$property; + } + + /** + * Check if file is an image (mime type) + * + * @return bool true if it is an image, false if not + */ + public function is_image() + { + return (strpos($this->mimetype, 'image/') === 0); + } + + /** + * Check if the file got correctly uploaded + * + * @return bool true if it is a valid upload, false if not + */ + public function is_uploaded() + { + $is_plupload = $this->plupload && $this->plupload->is_active(); + + if (!$this->local && !$is_plupload && !is_uploaded_file($this->filename)) + { + return false; + } + + if (($this->local || $is_plupload) && !file_exists($this->filename)) + { + return false; + } + + return true; + } + + /** + * Remove file + */ + public function remove($storage) + { + if ($this->file_moved) + { + $storage->delete($this->destination_file); + } + } + + /** + * Get file extension + * + * @param string $filename Filename that needs to be checked + * + * @return string Extension of the supplied filename + */ + static public function get_extension($filename) + { + $filename = utf8_basename($filename); + + if (strpos($filename, '.') === false) + { + return ''; + } + + $filename = explode('.', $filename); + return array_pop($filename); + } + + /** + * Get mime type + * + * @param string $filename Filename that needs to be checked + * @return string Mime type of supplied filename + */ + public function get_mimetype($filename) + { + if ($this->mimetype_guesser !== null) + { + $mimetype = $this->mimetype_guesser->guess($filename, $this->uploadname); + + if ($mimetype !== 'application/octet-stream') + { + $this->mimetype = $mimetype; + } + } + + return $this->mimetype; + } + + /** + * Get file size + * + * @param string $filename File name of file to check + * + * @return int File size + */ + public function get_filesize($filename) + { + return @filesize($filename); + } + + + /** + * Check the first 256 bytes for forbidden content + * + * @param array $disallowed_content Array containg disallowed content + * + * @return bool False if disallowed content found, true if not + */ + public function check_content($disallowed_content) + { + if (empty($disallowed_content)) + { + return true; + } + + $fp = @fopen($this->filename, 'rb'); + + if ($fp !== false) + { + $ie_mime_relevant = fread($fp, 256); + fclose($fp); + foreach ($disallowed_content as $forbidden) + { + if (stripos($ie_mime_relevant, '<' . $forbidden) !== false) + { + return false; + } + } + } + return true; + } + + /** + * Move file to destination folder + * + * @param bool $overwrite If set to true, an already existing file will be overwritten + * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped + * + * @return bool True if file was moved, false if not + * @access public + */ + public function move_file($storage, $overwrite = false, $skip_image_check = false) + { + if (count($this->error)) + { + return false; + } + + $this->destination_file = utf8_basename($this->realname); + + // Try to get real filesize from destination folder + $this->filesize = ($this->get_filesize($this->filename)) ?: $this->filesize; + + // Get mimetype of supplied file + $this->mimetype = $this->get_mimetype($this->filename); + + if ($this->is_image() && !$skip_image_check) + { + $this->width = $this->height = 0; + + $this->image_info = $this->imagesize->getImageSize($this->filename, $this->mimetype); + + if ($this->image_info !== false) + { + $this->width = $this->image_info['width']; + $this->height = $this->image_info['height']; + + // Check image type + $types = upload::image_types(); + + if (!isset($types[$this->image_info['type']]) || !in_array($this->extension, $types[$this->image_info['type']])) + { + if (!isset($types[$this->image_info['type']])) + { + $this->error[] = $this->language->lang('IMAGE_FILETYPE_INVALID', $this->image_info['type'], $this->mimetype); + } + else + { + $this->error[] = $this->language->lang('IMAGE_FILETYPE_MISMATCH', $types[$this->image_info['type']][0], $this->extension); + } + } + + // Make sure the dimensions match a valid image + if (empty($this->width) || empty($this->height)) + { + $this->error[] = $this->language->lang('ATTACHED_IMAGE_NOT_IMAGE'); + } + } + else + { + $this->error[] = $this->language->lang('UNABLE_GET_IMAGE_SIZE'); + } + } + + if ($overwrite && $storage->exists($this->destination_file)) + { + $storage->delete($this->destination_file); + } + + try + { + $fp = fopen($this->filename, 'rb'); + $storage->write_stream($this->destination_file, $fp); + fclose($fp); + } + catch (\phpbb\storage\exception\exception $e) + { + $this->error[] = $this->language->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file); + $this->file_moved = false; + } + + // Remove temporary filename + @unlink($this->filename); + + if (count($this->error)) + { + return false; + } + + $this->file_moved = true; + $this->additional_checks(); + unset($this->upload); + + return true; + } + + /** + * Performing additional checks + * + * @return bool False if issue was found, true if not + */ + public function additional_checks() + { + if (!$this->file_moved) + { + return false; + } + + // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form + if ($this->upload->max_filesize && ($this->get('filesize') > $this->upload->max_filesize || $this->filesize == 0)) + { + $max_filesize = get_formatted_filesize($this->upload->max_filesize, false); + + $this->error[] = $this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit']); + + return false; + } + + if (!$this->upload->valid_dimensions($this)) + { + $this->error[] = $this->language->lang($this->upload->error_prefix . 'WRONG_SIZE', + $this->language->lang('PIXELS', (int) $this->upload->min_width), + $this->language->lang('PIXELS', (int) $this->upload->min_height), + $this->language->lang('PIXELS', (int) $this->upload->max_width), + $this->language->lang('PIXELS', (int) $this->upload->max_height), + $this->language->lang('PIXELS', (int) $this->width), + $this->language->lang('PIXELS', (int) $this->height)); + + return false; + } + + return true; + } +} diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php index 2c3beb6e022..a9154761913 100644 --- a/phpBB/phpbb/files/types/form.php +++ b/phpBB/phpbb/files/types/form.php @@ -25,21 +25,12 @@ class form extends base /** @var factory Files factory */ protected $factory; - /** @var language */ - protected $language; - - /** @var IniGetWrapper */ - protected $php_ini; - /** @var plupload */ protected $plupload; /** @var request_interface */ protected $request; - /** @var \phpbb\files\upload */ - protected $upload; - /** * Construct a form upload type * diff --git a/phpBB/phpbb/files/types/form_storage.php b/phpBB/phpbb/files/types/form_storage.php new file mode 100644 index 00000000000..3024dc83e77 --- /dev/null +++ b/phpBB/phpbb/files/types/form_storage.php @@ -0,0 +1,128 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files\types; + +use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\files\factory; +use phpbb\files\filespec; +use phpbb\language\language; +use phpbb\plupload\plupload; +use phpbb\request\request_interface; + +class form_storage extends base +{ + /** @var factory Files factory */ + protected $factory; + + /** @var plupload */ + protected $plupload; + + /** @var request_interface */ + protected $request; + + /** + * Construct a form upload type + * + * @param factory $factory Files factory + * @param language $language Language class + * @param IniGetWrapper $php_ini ini_get() wrapper + * @param plupload $plupload Plupload + * @param request_interface $request Request object + */ + public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, plupload $plupload, request_interface $request) + { + $this->factory = $factory; + $this->language = $language; + $this->php_ini = $php_ini; + $this->plupload = $plupload; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public function upload() + { + $args = func_get_args(); + return $this->form_upload($args[0]); + } + + /** + * Form upload method + * Upload file from users harddisk + * + * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) + * + * @return filespec $file Object "filespec" is returned, all further operations can be done with this object + */ + protected function form_upload($form_name) + { + $upload = $this->request->file($form_name); + unset($upload['local_mode']); + + $result = $this->plupload->handle_upload($form_name); + if (is_array($result)) + { + $upload = array_merge($upload, $result); + } + + /** @var filespec $file */ + $file = $this->factory->get('filespec_storage') + ->set_upload_ary($upload) + ->set_upload_namespace($this->upload); + + if ($file->init_error()) + { + $file->error[] = ''; + return $file; + } + + // Error array filled? + if (isset($upload['error'])) + { + $error = $this->upload->assign_internal_error($upload['error']); + + if ($error !== false) + { + $file->error[] = $error; + return $file; + } + } + + // Check if empty file got uploaded (not catched by is_uploaded_file) + if (isset($upload['size']) && $upload['size'] == 0) + { + $file->error[] = $this->language->lang($this->upload->error_prefix . 'EMPTY_FILEUPLOAD'); + return $file; + } + + // PHP Upload file size check + $file = $this->check_upload_size($file); + if (count($file->error)) + { + return $file; + } + + // Not correctly uploaded + if (!$file->is_uploaded()) + { + $file->error[] = $this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED'); + return $file; + } + + $this->upload->common_checks($file); + + return $file; + } +} diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php index 4dfe4f75060..67948ea6df4 100644 --- a/phpBB/phpbb/files/types/local.php +++ b/phpBB/phpbb/files/types/local.php @@ -24,18 +24,9 @@ class local extends base /** @var factory Files factory */ protected $factory; - /** @var language */ - protected $language; - - /** @var IniGetWrapper */ - protected $php_ini; - /** @var request_interface */ protected $request; - /** @var \phpbb\files\upload */ - protected $upload; - /** * Construct a form upload type * diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 1fdba0ca329..e64e360b6a5 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -28,18 +28,9 @@ class remote extends base /** @var factory Files factory */ protected $factory; - /** @var language */ - protected $language; - - /** @var IniGetWrapper */ - protected $php_ini; - /** @var request_interface */ protected $request; - /** @var \phpbb\files\upload */ - protected $upload; - /** @var string phpBB root path */ protected $phpbb_root_path; diff --git a/phpBB/phpbb/files/types/remote_storage.php b/phpBB/phpbb/files/types/remote_storage.php new file mode 100644 index 00000000000..3e6953703ea --- /dev/null +++ b/phpBB/phpbb/files/types/remote_storage.php @@ -0,0 +1,197 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\files\types; + +use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\config\config; +use phpbb\files\factory; +use phpbb\files\filespec; +use phpbb\language\language; +use phpbb\request\request_interface; + +class remote_storage extends base +{ + /** @var config phpBB config */ + protected $config; + + /** @var factory Files factory */ + protected $factory; + + /** @var request_interface */ + protected $request; + + /** @var string phpBB root path */ + protected $phpbb_root_path; + + /** + * Construct a form upload type + * + * @param config $config phpBB config + * @param factory $factory Files factory + * @param language $language Language class + * @param IniGetWrapper $php_ini ini_get() wrapper + * @param request_interface $request Request object + * @param string $phpbb_root_path phpBB root path + */ + public function __construct(config $config, factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) + { + $this->config = $config; + $this->factory = $factory; + $this->language = $language; + $this->php_ini = $php_ini; + $this->request = $request; + $this->phpbb_root_path = $phpbb_root_path; + } + + /** + * {@inheritdoc} + */ + public function upload() + { + $args = func_get_args(); + return $this->remote_upload($args[0]); + } + + /** + * Remote upload method + * Uploads file from given url + * + * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif + * @return filespec $file Object "filespec" is returned, all further operations can be done with this object + */ + protected function remote_upload($upload_url) + { + $upload_ary = array(); + $upload_ary['local_mode'] = true; + + if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->upload->allowed_extensions) . ')$#i', $upload_url, $match)) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'URL_INVALID')); + } + + $url = parse_url($upload_url); + + $upload_ary['type'] = 'application/octet-stream'; + + $url['path'] = explode('.', $url['path']); + $ext = array_pop($url['path']); + + $url['path'] = implode('', $url['path']); + $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); + + $remote_max_filesize = $this->get_max_file_size(); + + $guzzle_options = [ + 'timeout' => $this->upload->upload_timeout, + 'connect_timeout' => $this->upload->upload_timeout, + 'verify' => !empty($this->config['remote_upload_verify']) ? (bool) $this->config['remote_upload_verify'] : false, + ]; + $client = new \GuzzleHttp\Client($guzzle_options); + + try + { + $response = $client->get($upload_url, $guzzle_options); + } + catch (\GuzzleHttp\Exception\ClientException $clientException) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); + } + catch (\GuzzleHttp\Exception\RequestException $requestException) + { + if (strpos($requestException->getMessage(), 'cURL error 28') !== false || preg_match('/408|504/', $requestException->getCode())) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); + } + else + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } + } + catch (\Exception $e) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } + + $content_length = $response->getBody()->getSize(); + if ($remote_max_filesize && $content_length > $remote_max_filesize) + { + $max_filesize = get_formatted_filesize($remote_max_filesize, false); + + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); + } + + if ($content_length === 0) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); + } + + $data = $response->getBody(); + + $filename = tempnam(sys_get_temp_dir(), unique_id() . '-'); + + if (!($fp = @fopen($filename, 'wb'))) + { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'NOT_UPLOADED'); + } + + $upload_ary['size'] = fwrite($fp, $data); + fclose($fp); + unset($data); + + $upload_ary['tmp_name'] = $filename; + + /** @var filespec $file */ + $file = $this->factory->get('filespec_storage') + ->set_upload_ary($upload_ary) + ->set_upload_namespace($this->upload); + $this->upload->common_checks($file); + + return $file; + } + + /** + * Get maximum file size for remote uploads + * + * @return int Maximum file size + */ + protected function get_max_file_size() + { + $max_file_size = $this->upload->max_filesize; + if (!$max_file_size) + { + $max_file_size = $this->php_ini->getString('upload_max_filesize'); + + if (!empty($max_file_size)) + { + $unit = strtolower(substr($max_file_size, -1, 1)); + $max_file_size = (int) $max_file_size; + + switch ($unit) + { + case 'g': + $max_file_size *= 1024; + // no break + case 'm': + $max_file_size *= 1024; + // no break + case 'k': + $max_file_size *= 1024; + // no break + } + } + } + + return $max_file_size; + } +} diff --git a/phpBB/phpbb/filesystem.php b/phpBB/phpbb/filesystem.php index af56d78845b..6ac94593313 100644 --- a/phpBB/phpbb/filesystem.php +++ b/phpBB/phpbb/filesystem.php @@ -14,7 +14,7 @@ namespace phpbb; /** - * @deprecated 3.2.0-dev (To be removed 3.3.0) use \phpbb\filesystem\filesystem instead + * @deprecated 3.2.0-dev (To be removed 4.0.0) use \phpbb\filesystem\filesystem instead */ class filesystem extends \phpbb\filesystem\filesystem { diff --git a/phpBB/phpbb/filesystem/exception/filesystem_exception.php b/phpBB/phpbb/filesystem/exception/filesystem_exception.php index d68fa9adf34..ddff8046e52 100644 --- a/phpBB/phpbb/filesystem/exception/filesystem_exception.php +++ b/phpBB/phpbb/filesystem/exception/filesystem_exception.php @@ -13,7 +13,9 @@ namespace phpbb\filesystem\exception; -class filesystem_exception extends \phpbb\exception\runtime_exception +use phpbb\exception\runtime_exception; + +class filesystem_exception extends runtime_exception { /** * Constructor @@ -24,7 +26,7 @@ class filesystem_exception extends \phpbb\exception\runtime_exception * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining. * @param integer $code The Exception code. */ - public function __construct($message = "", $filename = '', $parameters = array(), \Exception $previous = null, $code = 0) + public function __construct($message = '', $filename = '', $parameters = array(), \Exception $previous = null, $code = 0) { parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code); } @@ -36,7 +38,7 @@ public function __construct($message = "", $filename = '', $parameters = array() */ public function get_filename() { - $parameters = parent::get_parameters(); + $parameters = $this->get_parameters(); return $parameters['filename']; } } diff --git a/phpBB/phpbb/filesystem/filesystem.php b/phpBB/phpbb/filesystem/filesystem.php index 3f39448f059..7754a4107be 100644 --- a/phpBB/phpbb/filesystem/filesystem.php +++ b/phpBB/phpbb/filesystem/filesystem.php @@ -13,6 +13,7 @@ namespace phpbb\filesystem; +use Symfony\Component\Filesystem\Exception\IOException; use phpbb\filesystem\exception\filesystem_exception; /** @@ -60,7 +61,7 @@ public function chgrp($files, $group, $recursive = false) { $this->symfony_filesystem->chgrp($files, $group, $recursive); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { // Try to recover filename // By the time this is written that is at the end of the message @@ -146,7 +147,7 @@ public function chown($files, $user, $recursive = false) { $this->symfony_filesystem->chown($files, $user, $recursive); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { // Try to recover filename // By the time this is written that is at the end of the message @@ -162,26 +163,7 @@ public function chown($files, $user, $recursive = false) */ public function clean_path($path) { - $exploded = explode('/', $path); - $filtered = array(); - foreach ($exploded as $part) - { - if ($part === '.' && !empty($filtered)) - { - continue; - } - - if ($part === '..' && !empty($filtered) && $filtered[count($filtered) - 1] !== '.' && $filtered[count($filtered) - 1] !== '..') - { - array_pop($filtered); - } - else - { - $filtered[] = $part; - } - } - $path = implode('/', $filtered); - return $path; + return helper::clean_path($path); } /** @@ -193,7 +175,7 @@ public function copy($origin_file, $target_file, $override = false) { $this->symfony_filesystem->copy($origin_file, $target_file, $override); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { throw new filesystem_exception('CANNOT_COPY_FILES', '', array(), $e); } @@ -208,7 +190,7 @@ public function dump_file($filename, $content) { $this->symfony_filesystem->dumpFile($filename, $content); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { throw new filesystem_exception('CANNOT_DUMP_FILE', $filename, array(), $e); } @@ -227,7 +209,7 @@ public function exists($files) */ public function is_absolute_path($path) { - return (isset($path[0]) && $path[0] === '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false; + return helper::is_absolute_path($path); } /** @@ -305,7 +287,7 @@ public function is_writable($files, $recursive = false) */ public function make_path_relative($end_path, $start_path) { - return $this->symfony_filesystem->makePathRelative($end_path, $start_path); + return helper::make_path_relative($end_path, $start_path); } /** @@ -317,7 +299,7 @@ public function mirror($origin_dir, $target_dir, \Traversable $iterator = null, { $this->symfony_filesystem->mirror($origin_dir, $target_dir, $iterator, $options); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { $msg = $e->getMessage(); $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); @@ -335,7 +317,7 @@ public function mkdir($dirs, $mode = 0777) { $this->symfony_filesystem->mkdir($dirs, $mode); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { $msg = $e->getMessage(); $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); @@ -486,27 +468,7 @@ public function phpbb_chmod($files, $perms = null, $recursive = false, $force_ch */ public function realpath($path) { - if (!function_exists('realpath')) - { - return $this->phpbb_own_realpath($path); - } - - $realpath = realpath($path); - - // Strangely there are provider not disabling realpath but returning strange values. :o - // We at least try to cope with them. - if ((!$this->is_absolute_path($path) && $realpath === $path) || $realpath === false) - { - return $this->phpbb_own_realpath($path); - } - - // Check for DIRECTORY_SEPARATOR at the end (and remove it!) - if (substr($realpath, -1) === DIRECTORY_SEPARATOR) - { - $realpath = substr($realpath, 0, -1); - } - - return $realpath; + return helper::realpath($path); } /** @@ -518,7 +480,7 @@ public function remove($files) { $this->symfony_filesystem->remove($files); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { // Try to recover filename // By the time this is written that is at the end of the message @@ -538,7 +500,7 @@ public function rename($origin, $target, $overwrite = false) { $this->symfony_filesystem->rename($origin, $target, $overwrite); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { $msg = $e->getMessage(); $filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"')); @@ -556,7 +518,7 @@ public function symlink($origin_dir, $target_dir, $copy_on_windows = false) { $this->symfony_filesystem->symlink($origin_dir, $target_dir, $copy_on_windows); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { throw new filesystem_exception('CANNOT_CREATE_SYMLINK', $origin_dir, array(), $e); } @@ -571,7 +533,7 @@ public function touch($files, $time = null, $access_time = null) { $this->symfony_filesystem->touch($files, $time, $access_time); } - catch (\Symfony\Component\Filesystem\Exception\IOException $e) + catch (IOException $e) { // Try to recover filename // By the time this is written that is at the end of the message @@ -639,6 +601,8 @@ protected function phpbb_is_writable($file) /** * Try to resolve real path when PHP's realpath failes to do so * + * @deprecated 3.3.0-a1 (To be removed: 4.0.0) + * * @param string $path * @return bool|string */ @@ -764,6 +728,8 @@ protected function to_iterator($files) /** * Try to resolve symlinks in path * + * @deprecated 3.3.0-a1 (To be removed: 4.0.0) + * * @param string $path The path to resolve * @param string $prefix The path prefix (on windows the drive letter) * @param bool $absolute Whether or not the path is absolute @@ -774,143 +740,6 @@ protected function to_iterator($files) */ protected function resolve_path($path, $prefix = '', $absolute = false, $return_array = false) { - if ($return_array) - { - $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); - } - - trim ($path, '/'); - $path_parts = explode('/', $path); - $resolved = array(); - $resolved_path = $prefix; - $file_found = false; - - foreach ($path_parts as $path_part) - { - if ($file_found) - { - return false; - } - - if (empty($path_part) || ($path_part === '.' && ($absolute || !empty($resolved)))) - { - continue; - } - else if ($absolute && $path_part === '..') - { - if (empty($resolved)) - { - // No directories above root - return false; - } - - array_pop($resolved); - $resolved_path = false; - } - else if ($path_part === '..' && !empty($resolved) && !in_array($resolved[count($resolved) - 1], array('.', '..'))) - { - array_pop($resolved); - $resolved_path = false; - } - else - { - if ($resolved_path === false) - { - if (empty($resolved)) - { - $resolved_path = ($absolute) ? $prefix . '/' . $path_part : $path_part; - } - else - { - $tmp_array = $resolved; - if ($absolute) - { - array_unshift($tmp_array, $prefix); - } - - $resolved_path = implode('/', $tmp_array); - } - } - - $current_path = $resolved_path . '/' . $path_part; - - // Resolve symlinks - if (is_link($current_path)) - { - if (!function_exists('readlink')) - { - return false; - } - - $link = readlink($current_path); - - // Is link has an absolute path in it? - if ($this->is_absolute_path($link)) - { - if (defined('PHP_WINDOWS_VERSION_MAJOR')) - { - $prefix = $link[0] . ':'; - $link = substr($link, 2); - } - else - { - $prefix = ''; - } - - $resolved = $this->resolve_path($link, $prefix, true, true); - $absolute = true; - } - else - { - $resolved = $this->resolve_path($resolved_path . '/' . $link, $prefix, $absolute, true); - } - - if (!$resolved) - { - return false; - } - - $resolved_path = false; - } - else if (is_dir($current_path . '/')) - { - $resolved[] = $path_part; - $resolved_path = $current_path; - } - else if (is_file($current_path)) - { - $resolved[] = $path_part; - $resolved_path = $current_path; - $file_found = true; - } - else - { - return false; - } - } - } - - // If at the end of the path there were a .. or . - // we need to build the path again. - // Only doing this when a string is expected in return - if ($resolved_path === false && $return_array === false) - { - if (empty($resolved)) - { - $resolved_path = ($absolute) ? $prefix . '/' : './'; - } - else - { - $tmp_array = $resolved; - if ($absolute) - { - array_unshift($tmp_array, $prefix); - } - - $resolved_path = implode('/', $tmp_array); - } - } - - return ($return_array) ? $resolved : $resolved_path; + return helper::resolve_path($path, $prefix, $absolute, $return_array); } } diff --git a/phpBB/phpbb/filesystem/filesystem_interface.php b/phpBB/phpbb/filesystem/filesystem_interface.php index 1093be24996..139cd27ef6a 100644 --- a/phpBB/phpbb/filesystem/filesystem_interface.php +++ b/phpBB/phpbb/filesystem/filesystem_interface.php @@ -89,6 +89,8 @@ public function chown($files, $user, $recursive = false); /** * Eliminates useless . and .. components from specified path. * + * @deprecated 3.3.0-a1 (To be removed: 4.0.0) + * * @param string $path Path to clean * * @return string Cleaned path @@ -132,6 +134,8 @@ public function exists($files); /** * Checks if a path is absolute or not * + * @deprecated 3.3.0-a1 (To be removed: 4.0.0) + * * @param string $path Path to check * * @return bool true if the path is absolute, false otherwise @@ -161,6 +165,8 @@ public function is_writable($files, $recursive = false); /** * Given an existing path, convert it to a path relative to a given starting path * + * @deprecated 3.3.0-a1 (To be removed: 4.0.0) + * * @param string $end_path Absolute path of target * @param string $start_path Absolute path where traversal begins * @@ -204,7 +210,7 @@ public function mkdir($dirs, $mode = 0777); * This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions. * The function determines owner and group from common.php file and sets the same to the provided file. * The function uses bit fields to build the permissions. - * The function sets the appropiate execute bit on directories. + * The function sets the appropriate execute bit on directories. * * Supported constants representing bit fields are: * @@ -228,6 +234,8 @@ public function phpbb_chmod($file, $perms = null, $recursive = false, $force_chm /** * A wrapper for PHP's realpath * + * @deprecated 3.3.0-a1 (To be removed: 4.0.0) + * * Try to resolve realpath when PHP's realpath is not available, or * known to be buggy. * diff --git a/phpBB/phpbb/filesystem/helper.php b/phpBB/phpbb/filesystem/helper.php new file mode 100644 index 00000000000..0bb20eb32d3 --- /dev/null +++ b/phpBB/phpbb/filesystem/helper.php @@ -0,0 +1,385 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\filesystem; + +use Symfony\Component\Filesystem\Filesystem as symfony_filesystem; + +class helper +{ + /** + * @var \Symfony\Component\Filesystem\Filesystem + */ + protected static $symfony_filesystem; + + /** + * Eliminates useless . and .. components from specified path. + * + * @param string $path Path to clean + * + * @return string Cleaned path + */ + public static function clean_path($path) + { + $exploded = explode('/', $path); + $filtered = array(); + foreach ($exploded as $part) + { + if ($part === '.' && !empty($filtered)) + { + continue; + } + + if ($part === '..' && !empty($filtered) && $filtered[count($filtered) - 1] !== '.' && $filtered[count($filtered) - 1] !== '..') + { + array_pop($filtered); + } + else + { + $filtered[] = $part; + } + } + $path = implode('/', $filtered); + return $path; + } + + /** + * Checks if a path is absolute or not + * + * @param string $path Path to check + * + * @return bool true if the path is absolute, false otherwise + */ + public static function is_absolute_path($path) + { + return (isset($path[0]) && $path[0] === '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false; + } + + /** + * Try to resolve real path when PHP's realpath failes to do so + * + * @param string $path + * @return bool|string + */ + protected static function phpbb_own_realpath($path) + { + // Replace all directory separators with '/' + $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); + + $is_absolute_path = false; + $path_prefix = ''; + + if (self::is_absolute_path($path)) + { + $is_absolute_path = true; + } + else + { + if (function_exists('getcwd')) + { + $working_directory = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()); + } + + // + // From this point on we really just guessing + // If chdir were called we screwed + // + else if (function_exists('debug_backtrace')) + { + $call_stack = debug_backtrace(0); + $working_directory = str_replace(DIRECTORY_SEPARATOR, '/', dirname($call_stack[count($call_stack) - 1]['file'])); + } + else + { + // + // Assuming that the working directory is phpBB root + // we could use this as a fallback, when phpBB will use controllers + // everywhere this will be a safe assumption + // + //$dir_parts = explode(DIRECTORY_SEPARATOR, __DIR__); + //$namespace_parts = explode('\\', trim(__NAMESPACE__, '\\')); + + //$namespace_part_count = count($namespace_parts); + + // Check if we still loading from root + //if (array_slice($dir_parts, -$namespace_part_count) === $namespace_parts) + //{ + // $working_directory = implode('/', array_slice($dir_parts, 0, -$namespace_part_count)); + //} + //else + //{ + // $working_directory = false; + //} + + $working_directory = false; + } + + if ($working_directory !== false) + { + $is_absolute_path = true; + $path = $working_directory . '/' . $path; + } + } + + if ($is_absolute_path) + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) + { + $path_prefix = $path[0] . ':'; + $path = substr($path, 2); + } + else + { + $path_prefix = ''; + } + } + + $resolved_path = self::resolve_path($path, $path_prefix, $is_absolute_path); + if ($resolved_path === false) + { + return false; + } + + if (!@file_exists($resolved_path) || (!@is_dir($resolved_path . '/') && !is_file($resolved_path))) + { + return false; + } + + // Return OS specific directory separators + $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved_path); + + // Check for DIRECTORY_SEPARATOR at the end (and remove it!) + if (substr($resolved, -1) === DIRECTORY_SEPARATOR) + { + return substr($resolved, 0, -1); + } + + return $resolved; + } + + /** + * A wrapper for PHP's realpath + * + * Try to resolve realpath when PHP's realpath is not available, or + * known to be buggy. + * + * @param string $path Path to resolve + * + * @return string Resolved path + */ + public static function realpath($path) + { + if (!function_exists('realpath')) + { + return self::phpbb_own_realpath($path); + } + + $realpath = realpath($path); + + // Strangely there are provider not disabling realpath but returning strange values. :o + // We at least try to cope with them. + if ((!self::is_absolute_path($path) && $realpath === $path) || $realpath === false) + { + return self::phpbb_own_realpath($path); + } + + // Check for DIRECTORY_SEPARATOR at the end (and remove it!) + if (substr($realpath, -1) === DIRECTORY_SEPARATOR) + { + $realpath = substr($realpath, 0, -1); + } + + return $realpath; + } + + /** + * Given an existing path, convert it to a path relative to a given starting path + * + * @param string $end_path Absolute path of target + * @param string $start_path Absolute path where traversal begins + * + * @return string Path of target relative to starting path + */ + public static function make_path_relative($end_path, $start_path) + { + return self::get_symfony_filesystem()->makePathRelative($end_path, $start_path); + } + + /** + * Try to resolve symlinks in path + * + * @param string $path The path to resolve + * @param string $prefix The path prefix (on windows the drive letter) + * @param bool $absolute Whether or not the path is absolute + * @param bool $return_array Whether or not to return path parts + * + * @return string|array|bool returns the resolved path or an array of parts of the path if $return_array is true + * or false if path cannot be resolved + */ + public static function resolve_path($path, $prefix = '', $absolute = false, $return_array = false) + { + if ($return_array) + { + $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); + } + + trim($path, '/'); + $path_parts = explode('/', $path); + $resolved = array(); + $resolved_path = $prefix; + $file_found = false; + + foreach ($path_parts as $path_part) + { + if ($file_found) + { + return false; + } + + if (empty($path_part) || ($path_part === '.' && ($absolute || !empty($resolved)))) + { + continue; + } + else if ($absolute && $path_part === '..') + { + if (empty($resolved)) + { + // No directories above root + return false; + } + + array_pop($resolved); + $resolved_path = false; + } + else if ($path_part === '..' && !empty($resolved) && !in_array($resolved[count($resolved) - 1], array('.', '..'))) + { + array_pop($resolved); + $resolved_path = false; + } + else + { + if ($resolved_path === false) + { + if (empty($resolved)) + { + $resolved_path = ($absolute) ? $prefix . '/' . $path_part : $path_part; + } + else + { + $tmp_array = $resolved; + if ($absolute) + { + array_unshift($tmp_array, $prefix); + } + + $resolved_path = implode('/', $tmp_array); + } + } + + $current_path = $resolved_path . '/' . $path_part; + + // Resolve symlinks + if (is_link($current_path)) + { + if (!function_exists('readlink')) + { + return false; + } + + $link = readlink($current_path); + + // Is link has an absolute path in it? + if (self::is_absolute_path($link)) + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) + { + $prefix = $link[0] . ':'; + $link = substr($link, 2); + } + else + { + $prefix = ''; + } + + $resolved = self::resolve_path($link, $prefix, true, true); + $absolute = true; + } + else + { + $resolved = self::resolve_path($resolved_path . '/' . $link, $prefix, $absolute, true); + } + + if (!$resolved) + { + return false; + } + + $resolved_path = false; + } + else if (is_dir($current_path . '/')) + { + $resolved[] = $path_part; + $resolved_path = $current_path; + } + else if (is_file($current_path)) + { + $resolved[] = $path_part; + $resolved_path = $current_path; + $file_found = true; + } + else + { + return false; + } + } + } + + // If at the end of the path there were a .. or . + // we need to build the path again. + // Only doing this when a string is expected in return + if ($resolved_path === false && $return_array === false) + { + if (empty($resolved)) + { + $resolved_path = ($absolute) ? $prefix . '/' : './'; + } + else + { + $tmp_array = $resolved; + if ($absolute) + { + array_unshift($tmp_array, $prefix); + } + + $resolved_path = implode('/', $tmp_array); + } + } + + return $return_array ? $resolved : $resolved_path; + } + + /** + * Get an instance of symfony's filesystem object. + * + * @return \Symfony\Component\Filesystem\Filesystem Symfony filesystem + */ + protected static function get_symfony_filesystem() + { + if (self::$symfony_filesystem === null) + { + self::$symfony_filesystem = new symfony_filesystem(); + } + + return self::$symfony_filesystem; + } +} diff --git a/phpBB/phpbb/finder.php b/phpBB/phpbb/finder.php index 1f1d9318805..19056318f8e 100644 --- a/phpBB/phpbb/finder.php +++ b/phpBB/phpbb/finder.php @@ -13,13 +13,14 @@ namespace phpbb; +use phpbb\filesystem\helper as filesystem_helper; + /** * The finder provides a simple way to locate files in the core and a set of extensions */ class finder { protected $extensions; - protected $filesystem; protected $phpbb_root_path; protected $cache; protected $php_ext; @@ -48,16 +49,14 @@ class finder /** * Creates a new finder instance with its dependencies * - * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem instance * @param string $phpbb_root_path Path to the phpbb root directory * @param \phpbb\cache\service $cache A cache instance or null * @param string $php_ext php file extension * @param string $cache_name The name of the cache variable, defaults to * _ext_finder */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path = '', \phpbb\cache\service $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') + public function __construct($phpbb_root_path = '', \phpbb\cache\service $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') { - $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; $this->cache = $cache; $this->php_ext = $php_ext; @@ -80,7 +79,7 @@ public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, /** * Set the array of extensions * - * @param array $extensions A list of extensions that should be searched aswell + * @param array $extensions A list of extensions that should be searched as well * @param bool $replace_list Should the list be emptied before adding the extensions * @return \phpbb\finder This object for chaining calls */ @@ -237,14 +236,14 @@ public function core_directory($core_directory) } /** - * Removes occurances of /./ and makes sure path ends without trailing slash + * Removes occurrences of /./ and makes sure path ends without trailing slash * * @param string $directory A directory pattern * @return string A cleaned up directory pattern */ protected function sanitise_directory($directory) { - $directory = $this->filesystem->clean_path($directory); + $directory = filesystem_helper::clean_path($directory); $dir_len = strlen($directory); if ($dir_len > 1 && $directory[$dir_len - 1] === '/') diff --git a/phpBB/phpbb/help/controller/bbcode.php b/phpBB/phpbb/help/controller/bbcode.php index e16f99023d2..c3cf53fd76a 100644 --- a/phpBB/phpbb/help/controller/bbcode.php +++ b/phpBB/phpbb/help/controller/bbcode.php @@ -25,6 +25,11 @@ public function display() { $this->language->add_lang('help/bbcode'); + $this->template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $this->language->lang('BBCODE_GUIDE'), + 'U_VIEW_FORUM' => $this->helper->route('phpbb_help_bbcode_controller'), + )); + $this->manager->add_block( 'HELP_BBCODE_BLOCK_INTRO', false, diff --git a/phpBB/phpbb/help/controller/faq.php b/phpBB/phpbb/help/controller/faq.php index 5e45cfe667a..117723c793c 100644 --- a/phpBB/phpbb/help/controller/faq.php +++ b/phpBB/phpbb/help/controller/faq.php @@ -25,6 +25,11 @@ public function display() { $this->language->add_lang('help/faq'); + $this->template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $this->language->lang('FAQ_EXPLAIN'), + 'U_VIEW_FORUM' => $this->helper->route('phpbb_help_faq_controller'), + )); + $this->manager->add_block( 'HELP_FAQ_BLOCK_LOGIN', false, diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index 9e372fecdef..655760270a2 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -181,7 +181,7 @@ protected function build_container() $this->request->disable_super_globals(); } - // Get compatibilty globals and constants + // Get compatibility globals and constants $this->update_helper->include_file('includes/compatibility_globals.' . $this->php_ext); register_compatibility_globals(); diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php index 21af652f9d2..3885ce7a3f7 100644 --- a/phpBB/phpbb/install/helper/database.php +++ b/phpBB/phpbb/install/helper/database.php @@ -14,6 +14,7 @@ namespace phpbb\install\helper; use phpbb\install\exception\invalid_dbms_exception; +use phpbb\filesystem\helper as filesystem_helper; /** * Database related general functionality for installer @@ -329,7 +330,7 @@ public function check_database_connection($dbms, $dbhost, $dbport, $dbuser, $dbp // Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea if ($dbms_info['SCHEMA'] === 'sqlite' - && stripos($this->filesystem->realpath($dbhost), $this->filesystem->realpath($this->phpbb_root_path) === 0)) + && stripos(filesystem_helper::realpath($dbhost), filesystem_helper::realpath($this->phpbb_root_path) === 0)) { $errors[] = array( 'title' =>'INST_ERR_DB_FORUM_PATH', diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php index 440748901cb..3df9a91936e 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php @@ -31,7 +31,7 @@ public function send_response($no_more_output = false); * @param string $name Name of the input variable to obtain * @param mixed $default A default value that is returned if the variable was not set. * This function will always return a value of the same type as the default. - * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters + * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks * * @return mixed Value of the input variable diff --git a/phpBB/phpbb/install/installer_configuration.php b/phpBB/phpbb/install/installer_configuration.php index 805140338c2..dfafc40b4b2 100644 --- a/phpBB/phpbb/install/installer_configuration.php +++ b/phpBB/phpbb/install/installer_configuration.php @@ -48,9 +48,9 @@ public function getConfigTreeBuilder() ->cannotBeEmpty() ->end() ->scalarNode('description') - ->defaultValue('My amazing new phpBB board') - ->cannotBeEmpty() - ->end() + ->defaultValue('My amazing new phpBB board') + ->cannotBeEmpty() + ->end() ->end() ->end() ->arrayNode('database') @@ -128,12 +128,11 @@ public function getConfigTreeBuilder() ->integerNode('server_port') ->defaultValue(80) ->min(1) - ->cannotBeEmpty() ->end() ->scalarNode('script_path') ->defaultValue('/') ->cannotBeEmpty() - ->end() + ->end() ->end() ->end() ->arrayNode('extensions') diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema.php b/phpBB/phpbb/install/module/install_database/task/create_schema.php index a5635d5dbe6..fb97caa59a8 100644 --- a/phpBB/phpbb/install/module/install_database/task/create_schema.php +++ b/phpBB/phpbb/install/module/install_database/task/create_schema.php @@ -183,7 +183,7 @@ public function run() include ($this->phpbb_root_path . 'includes/constants.' . $this->php_ext); } - $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, null, $this->php_ext); + $finder = new \phpbb\finder($this->phpbb_root_path, null, $this->php_ext); $migrator_classes = $finder->core_path('phpbb/db/migration/data/')->get_classes(); $factory = new \phpbb\db\tools\factory(); $db_tools = $factory->get($this->db, true); diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema_file.php b/phpBB/phpbb/install/module/install_database/task/create_schema_file.php index b6d6ece17f7..81db66e11ee 100644 --- a/phpBB/phpbb/install/module/install_database/task/create_schema_file.php +++ b/phpBB/phpbb/install/module/install_database/task/create_schema_file.php @@ -117,7 +117,7 @@ public function run() include ($this->phpbb_root_path . 'includes/constants.' . $this->php_ext); } - $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, null, $this->php_ext); + $finder = new \phpbb\finder($this->phpbb_root_path, null, $this->php_ext); $migrator_classes = $finder->core_path('phpbb/db/migration/data/')->get_classes(); $factory = new \phpbb\db\tools\factory(); $db_tools = $factory->get($this->db, true); diff --git a/phpBB/phpbb/lock/db.php b/phpBB/phpbb/lock/db.php index 85ba9a7aa35..eea919f8f79 100644 --- a/phpBB/phpbb/lock/db.php +++ b/phpBB/phpbb/lock/db.php @@ -110,6 +110,13 @@ public function acquire() // process we failed to acquire the lock. $this->locked = $this->config->set_atomic($this->config_name, $lock_value, $this->unique_id, false); + if ($this->locked == true) + { + if ($this->config->ensure_lock($this->config_name, $this->unique_id)) + { + return true; + } + } return $this->locked; } diff --git a/phpBB/phpbb/lock/flock.php b/phpBB/phpbb/lock/flock.php index df88e1490a1..af051afb563 100644 --- a/phpBB/phpbb/lock/flock.php +++ b/phpBB/phpbb/lock/flock.php @@ -101,7 +101,10 @@ public function acquire() if ($this->lock_fp) { - @flock($this->lock_fp, LOCK_EX); + if (!@flock($this->lock_fp, LOCK_EX)) + { + throw new \phpbb\exception\http_exception(500, 'Failure while aqcuiring locks.'); + } } return (bool) $this->lock_fp; diff --git a/phpBB/phpbb/mimetype/guesser.php b/phpBB/phpbb/mimetype/guesser.php index 8baa77089b3..f8cbffe8f53 100644 --- a/phpBB/phpbb/mimetype/guesser.php +++ b/phpBB/phpbb/mimetype/guesser.php @@ -76,7 +76,7 @@ protected function register_guessers($mimetype_guessers) * should be used first and vice versa. usort() orders the array values * from low to high depending on what the comparison function returns * to it. Return value should be smaller than 0 if value a is smaller - * than value b. This has been reversed in the comparision function in + * than value b. This has been reversed in the comparison function in * order to sort the guessers from high to low. * Method has been set to public in order to allow proper testing. * diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index e4b111e4da9..1e8afec3f9d 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -94,7 +94,7 @@ public function find_users_for_notification($post, $options = array()) * * @param array $post Post data from submit_post * @param array $notify_users Notify users list - * Formated from find_users_for_notification() + * Formatted from find_users_for_notification() * @return array Whatever you want to send to create_insert_array(). */ public function pre_create_insert_array($post, $notify_users) diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php index f8a3fdec6ff..f0bbf3f6b09 100644 --- a/phpBB/phpbb/notification/type/approve_topic.php +++ b/phpBB/phpbb/notification/type/approve_topic.php @@ -94,7 +94,7 @@ public function find_users_for_notification($post, $options = array()) * * @param array $post Post data from submit_post * @param array $notify_users Notify users list - * Formated from find_users_for_notification() + * Formatted from find_users_for_notification() * @return array Whatever you want to send to create_insert_array(). */ public function pre_create_insert_array($post, $notify_users) diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 77ed7f2b09a..e4600add11d 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -336,7 +336,7 @@ public function get_avatar() } /** - * Get the reference of the notifcation (fall back) + * Get the reference of the notification (fall back) * * @return string */ @@ -356,7 +356,7 @@ public function get_forum() } /** - * Get the reason for the notifcation (fall back) + * Get the reason for the notification (fall back) * * @return string */ diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index 254f4c07b38..f0e938d3cea 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -352,7 +352,7 @@ public function trim_user_ary($users) * * @param array $post Post data from submit_post * @param array $notify_users Notify users list - * Formated from find_users_for_notification() + * Formatted from find_users_for_notification() * @return array Whatever you want to send to create_insert_array(). */ public function pre_create_insert_array($post, $notify_users) diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php index 5c42afa8c87..2535cdaed62 100644 --- a/phpBB/phpbb/notification/type/topic.php +++ b/phpBB/phpbb/notification/type/topic.php @@ -256,7 +256,7 @@ public function users_to_query() * * @param array $post Post data from submit_post * @param array $notify_users Notify users list - * Formated from find_users_for_notification() + * Formatted from find_users_for_notification() * @return array Whatever you want to send to create_insert_array(). */ public function pre_create_insert_array($post, $notify_users) diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php index f9f832bdda4..ed77335ce56 100644 --- a/phpBB/phpbb/notification/type/type_interface.php +++ b/phpBB/phpbb/notification/type/type_interface.php @@ -170,7 +170,7 @@ public function get_email_template_variables(); * * @param array $type_data The type specific data * @param array $notify_users Notify users list - * Formated from find_users_for_notification() + * Formatted from find_users_for_notification() * @return array Whatever you want to send to create_insert_array(). */ public function pre_create_insert_array($type_data, $notify_users); diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php index fad76a9fe55..54e6dce4be1 100644 --- a/phpBB/phpbb/passwords/manager.php +++ b/phpBB/phpbb/passwords/manager.php @@ -250,7 +250,7 @@ public function hash($password, $type = '') /** * Check supplied password against hash and set convert_flag if password - * needs to be converted to different format (preferrably newer one) + * needs to be converted to different format (preferably newer one) * * @param string $password Password that should be checked * @param string $hash Stored hash diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index 5b6db35f23b..e58704937f4 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -13,6 +13,8 @@ namespace phpbb; +use phpbb\filesystem\helper as filesystem_helper; + /** * A class with various functions that are related to paths, files and the filesystem */ @@ -21,9 +23,6 @@ class path_helper /** @var \phpbb\symfony_request */ protected $symfony_request; - /** @var \phpbb\filesystem\filesystem_interface */ - protected $filesystem; - /** @var \phpbb\request\request_interface */ protected $request; @@ -43,16 +42,14 @@ class path_helper * Constructor * * @param \phpbb\symfony_request $symfony_request - * @param \phpbb\filesystem\filesystem_interface $filesystem * @param \phpbb\request\request_interface $request * @param string $phpbb_root_path Relative path to phpBB root * @param string $php_ext PHP file extension * @param mixed $adm_relative_path Relative path admin path to adm/ root */ - public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null) + public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null) { $this->symfony_request = $symfony_request; - $this->filesystem = $filesystem; $this->request = $request; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -117,7 +114,7 @@ public function update_web_root_path($path) $path = substr($path, 8); } - return $this->filesystem->clean_path($web_root_path . $path); + return filesystem_helper::clean_path($web_root_path . $path); } return $path; @@ -163,7 +160,7 @@ public function get_web_root_path() // We do not need to escape $path_info, $request_uri and $script_name because we can not find their content in the result. // Path info (e.g. /foo/bar) - $path_info = $this->filesystem->clean_path($this->symfony_request->getPathInfo()); + $path_info = filesystem_helper::clean_path($this->symfony_request->getPathInfo()); // Full request URI (e.g. phpBB/app.php/foo/bar) $request_uri = $this->symfony_request->getRequestUri(); @@ -178,7 +175,7 @@ public function get_web_root_path() */ if ($path_info === '/' && preg_match('/app\.' . $this->php_ext . '\/$/', $request_uri)) { - return $this->web_root_path = $this->filesystem->clean_path('./../' . $this->phpbb_root_path); + return $this->web_root_path = filesystem_helper::clean_path('./../' . $this->phpbb_root_path); } /* @@ -235,7 +232,7 @@ public function get_web_root_path() } // Prepend ../ to the phpbb_root_path as many times as / exists in path_info - $this->web_root_path = $this->filesystem->clean_path( + $this->web_root_path = filesystem_helper::clean_path( './' . str_repeat('../', $corrections) . $this->phpbb_root_path ); return $this->web_root_path; @@ -326,7 +323,7 @@ public function clean_url($url) // Add length of URL delimiter to position $path = substr($url, $delimiter_position + 3); - return $scheme . $this->filesystem->clean_path($path); + return $scheme . filesystem_helper::clean_path($path); } /** diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php index 7697884b6a2..ac9a99b5916 100644 --- a/phpBB/phpbb/permissions.php +++ b/phpBB/phpbb/permissions.php @@ -349,6 +349,7 @@ public function get_permission_lang($permission) 'a_roles' => array('lang' => 'ACL_A_ROLES', 'cat' => 'permissions'), 'a_switchperm' => array('lang' => 'ACL_A_SWITCHPERM', 'cat' => 'permissions'), + 'a_storage' => array('lang' => 'ACL_A_STORAGE', 'cat' => 'misc'), 'a_styles' => array('lang' => 'ACL_A_STYLES', 'cat' => 'misc'), 'a_extensions' => array('lang' => 'ACL_A_EXTENSIONS', 'cat' => 'misc'), 'a_viewlogs' => array('lang' => 'ACL_A_VIEWLOGS', 'cat' => 'misc'), diff --git a/phpBB/phpbb/report/report_handler.php b/phpBB/phpbb/report/report_handler.php index 854318c5594..97acc1763ea 100644 --- a/phpBB/phpbb/report/report_handler.php +++ b/phpBB/phpbb/report/report_handler.php @@ -51,7 +51,7 @@ abstract class report_handler implements report_handler_interface protected $report_data; /** - * Construtor + * Constructor * * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\event\dispatcher_interface $dispatcher diff --git a/phpBB/phpbb/request/request.php b/phpBB/phpbb/request/request.php index 00be8fd3813..331cd3b1ec7 100644 --- a/phpBB/phpbb/request/request.php +++ b/phpBB/phpbb/request/request.php @@ -181,7 +181,7 @@ public function overwrite($var_name, $value, $super_global = \phpbb\request\requ * then specifying array("var", 1) as the name will return "a". * @param mixed $default A default value that is returned if the variable was not set. * This function will always return a value of the same type as the default. - * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters + * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks * @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global * Specifies which super global should be used @@ -205,7 +205,7 @@ public function variable($var_name, $default, $multibyte = false, $super_global * then specifying array("var", 1) as the name will return "a". * @param mixed $default A default value that is returned if the variable was not set. * This function will always return a value of the same type as the default. - * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters + * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks * @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global * Specifies which super global should be used @@ -397,7 +397,7 @@ public function variable_names($super_global = \phpbb\request\request_interface: * then specifying array("var", 1) as the name will return "a". * @param mixed $default A default value that is returned if the variable was not set. * This function will always return a value of the same type as the default. - * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters + * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks * @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global * Specifies which super global should be used diff --git a/phpBB/phpbb/request/request_interface.php b/phpBB/phpbb/request/request_interface.php index 3bfa8bb424f..54dd8cef155 100644 --- a/phpBB/phpbb/request/request_interface.php +++ b/phpBB/phpbb/request/request_interface.php @@ -54,7 +54,7 @@ public function overwrite($var_name, $value, $super_global = \phpbb\request\requ * then specifying array("var", 1) as the name will return "a". * @param mixed $default A default value that is returned if the variable was not set. * This function will always return a value of the same type as the default. - * @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters + * @param bool $multibyte If $default is a string this parameter has to be true if the variable may contain any UTF-8 characters * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks * @param \phpbb\request\request_interface::POST|GET|REQUEST|COOKIE $super_global * Specifies which super global should be used diff --git a/phpBB/phpbb/routing/file_locator.php b/phpBB/phpbb/routing/file_locator.php index 64efcc6c763..bd2c1850bb7 100644 --- a/phpBB/phpbb/routing/file_locator.php +++ b/phpBB/phpbb/routing/file_locator.php @@ -13,19 +13,19 @@ namespace phpbb\routing; -use phpbb\filesystem\filesystem_interface; use Symfony\Component\Config\FileLocator; +use phpbb\filesystem\helper as filesystem_helper; class file_locator extends FileLocator { - public function __construct(filesystem_interface $filesystem, $paths = []) + public function __construct($paths = []) { $paths = (array) $paths; $absolute_paths = []; foreach ($paths as $path) { - $absolute_paths[] = $filesystem->realpath($path); + $absolute_paths[] = filesystem_helper::realpath($path); } parent::__construct($absolute_paths); diff --git a/phpBB/phpbb/routing/helper.php b/phpBB/phpbb/routing/helper.php index c15608dce58..3d38105aa38 100644 --- a/phpBB/phpbb/routing/helper.php +++ b/phpBB/phpbb/routing/helper.php @@ -15,6 +15,7 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RequestContext; +use phpbb\filesystem\helper as filesystem_helper; /** * Controller helper class, contains methods that do things for controllers @@ -43,11 +44,6 @@ class helper */ protected $request; - /** - * @var \phpbb\filesystem The filesystem object - */ - protected $filesystem; - /** * phpBB root path * @var string @@ -67,17 +63,15 @@ class helper * @param \phpbb\routing\router $router phpBB router * @param \phpbb\symfony_request $symfony_request Symfony Request object * @param \phpbb\request\request_interface $request phpBB request object - * @param \phpbb\filesystem\filesystem $filesystem The filesystem object * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP file extension */ - public function __construct(\phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem\filesystem $filesystem, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext) { $this->config = $config; $this->router = $router; $this->symfony_request = $symfony_request; $this->request = $request; - $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } @@ -140,7 +134,7 @@ public function route($route, array $params = array(), $is_amp = true, $session_ } } - $base_url = $this->request->escape($this->filesystem->clean_path($base_url), true); + $base_url = $this->request->escape(filesystem_helper::clean_path($base_url), true); $context->setBaseUrl($base_url); diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index 137ed7433d5..4e881e5f0c3 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -150,7 +150,7 @@ public function get_word_length() /** * Checks for correct MySQL version and stores min/max word length in the config * - * @return string|bool Language key of the error/incompatiblity occurred + * @return string|bool Language key of the error/incompatibility occurred */ public function init() { diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 4172e2cc4f7..f97d2c4244b 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -339,7 +339,7 @@ public function split_keywords($keywords, $terms) $this->db->sql_freeresult($result); } - // Handle +, - without preceeding whitespace character + // Handle +, - without preceding whitespace character $match = array('#(\S)\+#', '#(\S)-#'); $replace = array('$1 +', '$1 +'); diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php index 2f387e791e3..6241f21fcf2 100644 --- a/phpBB/phpbb/search/fulltext_postgres.php +++ b/phpBB/phpbb/search/fulltext_postgres.php @@ -173,7 +173,7 @@ public function supports_phrase_search() /** * Checks for correct PostgreSQL version and stores min/max word length in the config * - * @return string|bool Language key of the error/incompatiblity occurred + * @return string|bool Language key of the error/incompatibility occurred */ public function init() { diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index e2eeb5f7f34..06d1596b850 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -18,7 +18,7 @@ define('SPHINX_CONNECT_WAIT_TIME', 300); /** -* Fulltext search based on the sphinx search deamon +* Fulltext search based on the sphinx search daemon */ class fulltext_sphinx { @@ -210,7 +210,7 @@ public function get_common_words() /** * Checks permissions and paths, if everything is correct it generates the config file * - * @return string|bool Language key of the error/incompatiblity encountered, or false if successful + * @return string|bool Language key of the error/incompatibility encountered, or false if successful */ public function init() { diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index de9345ca859..cd60bd80727 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -13,6 +13,8 @@ namespace phpbb; +use phpbb\filesystem\helper as filesystem_helper; + /** * Session class */ @@ -38,7 +40,7 @@ class session */ static function extract_current_page($root_path) { - global $request, $symfony_request, $phpbb_filesystem; + global $request, $symfony_request; $page_array = array(); @@ -85,7 +87,7 @@ static function extract_current_page($root_path) $page_name = (substr($script_name, -1, 1) == '/') ? '' : basename($script_name); $page_name = urlencode(htmlspecialchars($page_name)); - $symfony_request_path = $phpbb_filesystem->clean_path($symfony_request->getPathInfo()); + $symfony_request_path = filesystem_helper::clean_path($symfony_request->getPathInfo()); if ($symfony_request_path !== '/') { $page_name .= str_replace('%2F', '/', urlencode($symfony_request_path)); @@ -99,8 +101,8 @@ static function extract_current_page($root_path) else { // current directory within the phpBB root (for example: adm) - $root_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath($root_path))); - $page_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath('./'))); + $root_dirs = explode('/', str_replace('\\', '/', filesystem_helper::realpath($root_path))); + $page_dirs = explode('/', str_replace('\\', '/', filesystem_helper::realpath('./'))); } $intersection = array_intersect_assoc($root_dirs, $page_dirs); @@ -250,7 +252,7 @@ function session_begin($update_session_page = true) $ips = explode(' ', $this->forwarded_for); foreach ($ips as $ip) { - // check IPv4 first, the IPv6 is hopefully only going to be used very seldomly + // check IPv4 first, the IPv6 is hopefully only going to be used very seldom if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip)) { // contains invalid data, don't use the forwarded for header @@ -478,7 +480,7 @@ function session_begin($update_session_page = true) } else { - // Added logging temporarly to help debug bugs... + // Added logging temporarily to help debug bugs... if (defined('DEBUG') && $this->data['user_id'] != ANONYMOUS) { if ($referer_valid) @@ -1331,7 +1333,7 @@ protected function check_ban_for_current_session($config) * Only IPv4 (rbldns does not support AAAA records/IPv6 lookups) * * @author satmd (from the php manual) - * @param string $mode register/post - spamcop for example is ommitted for posting + * @param string $mode register/post - spamcop for example is omitted for posting * @param string|false $ip the IPv4 address to check * * @return false if ip is not blacklisted, else an array([checked server], [lookup]) @@ -1390,7 +1392,7 @@ function check_dnsbl($mode, $ip = false) /** * Check if URI is blacklisted - * This should be called only where absolutly necessary, for example on the submitted website field + * This should be called only where absolutely necessary, for example on the submitted website field * This function is not in use at the moment and is only included for testing purposes, it may not work at all! * This means it is untested at the moment and therefore commented out * diff --git a/phpBB/phpbb/storage/adapter/adapter_interface.php b/phpBB/phpbb/storage/adapter/adapter_interface.php new file mode 100644 index 00000000000..afc78a7f83c --- /dev/null +++ b/phpBB/phpbb/storage/adapter/adapter_interface.php @@ -0,0 +1,88 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage\adapter; + +interface adapter_interface +{ + /** + * Set adapter parameters + * + * @param array options Storage-specific options. + */ + public function configure($options); + + /** + * Dumps content into a file. + * + * @param string path The file to be written to. + * @param string content The data to write into the file. + * + * @throws \phpbb\storage\exception\exception When the file already exists + * When the file cannot be written + */ + public function put_contents($path, $content); + + /** + * Read the contents of a file + * + * @param string $path The file to read + * + * @throws \phpbb\storage\exception\exception When the file doesn't exist + * When cannot read file contents + * + * @return string Returns file contents + * + */ + public function get_contents($path); + + /** + * Checks the existence of files or directories. + * + * @param string $path file/directory to check + * + * @return bool Returns true if the file/directory exist, false otherwise. + */ + public function exists($path); + + /** + * Removes files or directories. + * + * @param string $path file/directory to remove + * + * @throws \phpbb\storage\exception\exception When removal fails. + */ + public function delete($path); + + /** + * Rename a file or a directory. + * + * @param string $path_orig The original file/direcotry + * @param string $path_dest The target file/directory + * + * @throws \phpbb\storage\exception\exception When target exists + * When file/directory cannot be renamed + */ + public function rename($path_orig, $path_dest); + + /** + * Copies a file. + * + * @param string $path_orig The original filename + * @param string $path_dest The target filename + * + * @throws \phpbb\storage\exception\exception When target exists + * When the file cannot be copied + */ + public function copy($path_orig, $path_dest); +} diff --git a/phpBB/phpbb/storage/adapter/local.php b/phpBB/phpbb/storage/adapter/local.php new file mode 100644 index 00000000000..1ef2516f4f7 --- /dev/null +++ b/phpBB/phpbb/storage/adapter/local.php @@ -0,0 +1,334 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage\adapter; + +use phpbb\storage\stream_interface; +use phpbb\storage\exception\exception; +use phpbb\filesystem\exception\filesystem_exception; +use phpbb\filesystem\filesystem; +use phpbb\filesystem\helper as filesystem_helper; +use phpbb\mimetype\guesser; +use FastImageSize\FastImageSize; + +/** + * @internal Experimental + */ +class local implements adapter_interface, stream_interface +{ + /** + * Filesystem component + * + * @var \phpbb\filesystem\filesystem + */ + protected $filesystem; + + /** + * FastImageSize + * + * @var \FastImageSize\FastImageSize + */ + protected $imagesize; + + /** + * Mimetype Guesser component + * + * @var \phpbb\mimetype\guesser + */ + protected $mimetype_guesser; + + /** + * @var string path + */ + protected $phpbb_root_path; + + /** + * @var string path + */ + protected $root_path; + + /** + * Constructor + */ + public function __construct(filesystem $filesystem, FastImageSize $imagesize, guesser $mimetype_guesser, $phpbb_root_path) + { + $this->filesystem = $filesystem; + $this->imagesize = $imagesize; + $this->mimetype_guesser = $mimetype_guesser; + $this->phpbb_root_path = $phpbb_root_path; + } + + /** + * {@inheritdoc} + */ + public function configure($options) + { + $this->root_path = $this->phpbb_root_path . $options['path']; + + if (substr($this->root_path, -1, 1) !== DIRECTORY_SEPARATOR) + { + $this->root_path = $this->root_path . DIRECTORY_SEPARATOR; + } + } + + /** + * {@inheritdoc} + */ + public function put_contents($path, $content) + { + $this->ensure_directory_exists($path); + + if ($this->exists($path)) + { + throw new exception('STORAGE_FILE_EXISTS', $path); + } + + try + { + $this->filesystem->dump_file($this->root_path . $path, $content); + } + catch (filesystem_exception $e) + { + throw new exception('STORAGE_CANNOT_WRITE_FILE', $path, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function get_contents($path) + { + if (!$this->exists($path)) + { + throw new exception('STORAGE_FILE_NO_EXIST', $path); + } + + $content = @file_get_contents($this->root_path . $path); + + if ($content === false) + { + throw new exception('STORAGE_CANNOT_READ_FILE', $path); + } + + return $content; + } + + /** + * {@inheritdoc} + */ + public function exists($path) + { + return $this->filesystem->exists($this->root_path . $path); + } + + /** + * {@inheritdoc} + */ + public function delete($path) + { + try + { + $this->filesystem->remove($this->root_path . $path); + } + catch (filesystem_exception $e) + { + throw new exception('STORAGE_CANNOT_DELETE', $path, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function rename($path_orig, $path_dest) + { + $this->ensure_directory_exists($path_dest); + + try + { + $this->filesystem->rename($this->root_path . $path_orig, $this->root_path . $path_dest, false); + } + catch (filesystem_exception $e) + { + throw new exception('STORAGE_CANNOT_RENAME', $path_orig, array(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function copy($path_orig, $path_dest) + { + $this->ensure_directory_exists($path_dest); + + try + { + $this->filesystem->copy($this->root_path . $path_orig, $this->root_path . $path_dest, false); + } + catch (filesystem_exception $e) + { + throw new exception('STORAGE_CANNOT_COPY', $path_orig, array(), $e); + } + } + + /** + * Creates a directory recursively. + * + * @param string $path The directory path + * + * @throws \phpbb\storage\exception\exception On any directory creation failure + */ + protected function create_dir($path) + { + try + { + $this->filesystem->mkdir($this->root_path . $path); + } + catch (filesystem_exception $e) + { + throw new exception('STORAGE_CANNOT_CREATE_DIR', $path, array(), $e); + } + } + + /** + * Ensures that the directory of a file exists. + * + * @param string $path The file path + */ + protected function ensure_directory_exists($path) + { + $path = dirname($this->root_path . $path); + $path = filesystem_helper::make_path_relative($path, $this->root_path); + + if (!$this->exists($path)) + { + $this->create_dir($path); + } + } + + /** + * {@inheritdoc} + */ + public function read_stream($path) + { + $stream = @fopen($this->root_path . $path, 'rb'); + + if (!$stream) + { + throw new exception('STORAGE_CANNOT_OPEN_FILE', $path); + } + + return $stream; + } + + /** + * {@inheritdoc} + */ + public function write_stream($path, $resource) + { + if ($this->exists($path)) + { + throw new exception('STORAGE_FILE_EXISTS', $path); + } + + $stream = @fopen($this->root_path . $path, 'w+b'); + + if (!$stream) + { + throw new exception('STORAGE_CANNOT_CREATE_FILE', $path); + } + + if (stream_copy_to_stream($resource, $stream) === false) + { + fclose($stream); + throw new exception('STORAGE_CANNOT_COPY_RESOURCE'); + } + } + + /** + * Get file size. + * + * @param string $path The file + * + * @throws \phpbb\storage\exception\exception When cannot get size + * + * @return array Properties + */ + public function file_size($path) + { + $size = filesize($this->root_path . $path); + + if ($size === null) + { + throw new exception('STORAGE_CANNOT_GET_FILESIZE'); + } + + return ['size' => $size]; + } + + /** + * Get file mimetype. + * + * @param string $path The file + * + * @return array Properties + */ + public function file_mimetype($path) + { + return ['mimetype' => $this->mimetype_guesser->guess($this->root_path . $path)]; + } + + /** + * Get image dimensions. + * + * @param string $path The file + * + * @return array Properties + */ + protected function image_dimensions($path) + { + $size = $this->imagesize->getImageSize($this->root_path . $path); + + // For not supported types like swf + if ($size === false) + { + $imsize = getimagesize($this->root_path . $path); + $size = ['width' => $imsize[0], 'height' => $imsize[1]]; + } + + return ['image_width' => $size['width'], 'image_height' => $size['height']]; + } + + /** + * Get image width. + * + * @param string $path The file + * + * @return array Properties + */ + public function file_image_width($path) + { + return $this->image_dimensions($path); + } + + /** + * Get image height. + * + * @param string $path The file + * + * @return array Properties + */ + public function file_image_height($path) + { + return $this->image_dimensions($path); + } +} diff --git a/phpBB/phpbb/storage/adapter_factory.php b/phpBB/phpbb/storage/adapter_factory.php new file mode 100644 index 00000000000..6be702c0c8b --- /dev/null +++ b/phpBB/phpbb/storage/adapter_factory.php @@ -0,0 +1,93 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage; + +use phpbb\config\config; +use phpbb\di\service_collection; +use phpbb\storage\exception\exception; + +class adapter_factory +{ + /** + * @var \phpbb\config\config + */ + protected $config; + + /** + * @var \phpbb\di\service_collection + */ + protected $adapters; + + /** + * @var \phpbb\di\service_collection + */ + protected $providers; + + /** + * Constructor + * + * @param \phpbb\config\config $config + * @param \phpbb\di\service_collection $adapters + * @param \phpbb\di\service_collection $providers + */ + public function __construct(config $config, service_collection $adapters, service_collection $providers) + { + $this->config = $config; + $this->adapters = $adapters; + $this->providers = $providers; + } + + /** + * Obtains a configured adapters for a given storage + * + * @param string $storage_name + * + * @return \phpbb\storage\adapter\adapter_interface + */ + public function get($storage_name) + { + $provider_class = $this->config['storage\\' . $storage_name . '\\provider']; + $provider = $this->providers->get_by_class($provider_class); + + if (!$provider->is_available()) + { + throw new exception('STORAGE_ADAPTER_NOT_AVAILABLE'); + } + + $adapter = $this->adapters->get_by_class($provider->get_adapter_class()); + $adapter->configure($this->build_options($storage_name, $provider->get_options())); + + return $adapter; + } + + /** + * Obtains configuration for a given storage + * + * @param string $storage_name + * @param array $definitions + * + * @return array Returns storage configuration values + */ + public function build_options($storage_name, array $definitions) + { + $options = []; + + foreach (array_keys($definitions) as $definition) + { + $options[$definition] = $this->config['storage\\' . $storage_name . '\\config\\' . $definition]; + } + + return $options; + } +} diff --git a/phpBB/phpbb/storage/exception/exception.php b/phpBB/phpbb/storage/exception/exception.php new file mode 100644 index 00000000000..4eca403cc10 --- /dev/null +++ b/phpBB/phpbb/storage/exception/exception.php @@ -0,0 +1,44 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage\exception; + +use phpbb\exception\runtime_exception; + +class exception extends runtime_exception +{ + /** + * Constructor + * + * @param string $message The Exception message to throw (must be a language variable). + * @param string $filename The file that caused the error. + * @param array $parameters The parameters to use with the language var. + * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining. + * @param integer $code The Exception code. + */ + public function __construct($message = '', $filename = '', $parameters = [], \Exception $previous = null, $code = 0) + { + parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code); + } + + /** + * Returns the filename that triggered the error + * + * @return string + */ + public function get_filename() + { + $parameters = $this->get_parameters(); + return $parameters['filename']; + } +} diff --git a/phpBB/phpbb/storage/file_info.php b/phpBB/phpbb/storage/file_info.php new file mode 100644 index 00000000000..ae2bd5169dc --- /dev/null +++ b/phpBB/phpbb/storage/file_info.php @@ -0,0 +1,85 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage; + +use phpbb\storage\exception\exception; +use phpbb\storage\adapter\adapter_interface; + +class file_info +{ + /** + * @var \phpbb\storage\adapter\adapter_interface + */ + protected $adapter; + + /** + * Path of the file + * + * @var string + */ + protected $path; + + /** + * Stores the properties of $path file, so dont have to be consulted multiple times. + * For example, when you need the width of an image, using getimagesize() you get + * both dimensions, so you store both here, and when you get the height, you dont have + * to call getimagesize() again. + * + * @var array + */ + protected $properties; + + /** + * Constructor + * + * @param \Symfony\Component\DependencyInjection\ContainerInterface $adapter + * @param string $path + */ + public function __construct(adapter_interface $adapter, $path) + { + $this->adapter = $adapter; + $this->path = $path; + $this->properties = []; + } + + /** + * Load propertys lazily. + * + * @param string name The property name. + * + * @return string Returns the property value + */ + public function get($name) + { + if (!isset($this->properties[$name])) + { + if (!method_exists($this->adapter, 'file_' . $name)) + { + throw new exception('STORAGE_METHOD_NOT_IMPLEMENTED'); + } + + $this->properties = array_merge($this->properties, call_user_func([$this->adapter, 'file_' . $name], $this->path)); + } + + return $this->properties[$name]; + } + + /** + * Alias of \phpbb\storage\file_info->get() + */ + public function __get($name) + { + return $this->get($name); + } +} diff --git a/phpBB/phpbb/storage/provider/local.php b/phpBB/phpbb/storage/provider/local.php new file mode 100644 index 00000000000..7ec94d3d2ef --- /dev/null +++ b/phpBB/phpbb/storage/provider/local.php @@ -0,0 +1,49 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage\provider; + +class local implements provider_interface +{ + /** + * {@inheritdoc} + */ + public function get_name() + { + return 'local'; + } + + /** + * {@inheritdoc} + */ + public function get_adapter_class() + { + return \phpbb\storage\adapter\local::class; + } + + /** + * {@inheritdoc} + */ + public function get_options() + { + return ['path' => array('type' => 'text')]; + } + + /** + * {@inheritdoc} + */ + public function is_available() + { + return true; + } +} diff --git a/phpBB/phpbb/storage/provider/provider_interface.php b/phpBB/phpbb/storage/provider/provider_interface.php new file mode 100644 index 00000000000..a61845bcccc --- /dev/null +++ b/phpBB/phpbb/storage/provider/provider_interface.php @@ -0,0 +1,45 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage\provider; + +interface provider_interface +{ + /** + * Gets adapter name. + * + * @return string + */ + public function get_name(); + + /** + * Gets adapter class. + * + * @return \phpbb\storage\adapter\adapter_interface + */ + public function get_adapter_class(); + + /** + * Gets adapter options. + * + * @return array Configuration keys + */ + public function get_options(); + + /** + * Return true if the adapter is available. + * + * @return bool + */ + public function is_available(); +} diff --git a/phpBB/phpbb/storage/storage.php b/phpBB/phpbb/storage/storage.php new file mode 100644 index 00000000000..bc089117d49 --- /dev/null +++ b/phpBB/phpbb/storage/storage.php @@ -0,0 +1,219 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage; + +/** + * @internal Experimental + */ +class storage +{ + /** + * @var string + */ + protected $storage_name; + + /** + * @var \phpbb\storage\adapter_factory + */ + protected $factory; + + /** + * @var \phpbb\storage\adapter\adapter_interface + */ + protected $adapter; + + /** + * Constructor + * + * @param \phpbb\storage\adapter_factory $factory + * @param string $storage_name + */ + public function __construct(adapter_factory $factory, $storage_name) + { + $this->factory = $factory; + $this->storage_name = $storage_name; + } + + /** + * Returns storage name + * + * @return string + */ + public function get_name() + { + return $this->storage_name; + } + + /** + * Returns an adapter instance + * + * @return \phpbb\storage\adapter\adapter_interface + */ + protected function get_adapter() + { + if ($this->adapter === null) + { + $this->adapter = $this->factory->get($this->storage_name); + } + + return $this->adapter; + } + + /** + * Dumps content into a file. + * + * @param string path The file to be written to. + * @param string content The data to write into the file. + * + * @throws \phpbb\storage\exception\exception When the file already exists + * When the file cannot be written + */ + public function put_contents($path, $content) + { + $this->get_adapter()->put_contents($path, $content); + } + + /** + * Read the contents of a file + * + * @param string $path The file to read + * + * @throws \phpbb\storage\exception\exception When the file doesn't exist + * When cannot read file contents + * + * @return string Returns file contents + * + */ + public function get_contents($path) + { + return $this->get_adapter()->get_contents($path); + } + + /** + * Checks the existence of files or directories. + * + * @param string $path file/directory to check + * + * @return bool Returns true if the file/directory exist, false otherwise. + */ + public function exists($path) + { + return $this->get_adapter()->exists($path); + } + + /** + * Removes files or directories. + * + * @param string $path file/directory to remove + * + * @throws \phpbb\storage\exception\exception When removal fails. + */ + public function delete($path) + { + $this->get_adapter()->delete($path); + } + + /** + * Rename a file or a directory. + * + * @param string $path_orig The original file/direcotry + * @param string $path_dest The target file/directory + * + * @throws \phpbb\storage\exception\exception When target exists + * When file/directory cannot be renamed + */ + public function rename($path_orig, $path_dest) + { + $this->get_adapter()->rename($path_orig, $path_dest); + } + + /** + * Copies a file. + * + * @param string $path_orig The original filename + * @param string $path_dest The target filename + * + * @throws \phpbb\storage\exception\exception When target exists + * When the file cannot be copied + */ + public function copy($path_orig, $path_dest) + { + $this->get_adapter()->copy($path_orig, $path_dest); + } + + /** + * Reads a file as a stream. + * + * @param string $path File to read + * + * @throws \phpbb\storage\exception\exception When unable to open file + + * @return resource Returns a file pointer + */ + public function read_stream($path) + { + $stream = null; + $adapter = $this->get_adapter(); + + if ($adapter instanceof stream_interface) + { + $stream = $adapter->read_stream($path); + } + else + { + // Simulate the stream + $stream = fopen('php://temp', 'w+b'); + fwrite($stream, $adapter->get_contents($path)); + rewind($stream); + } + + return $stream; + } + + /** + * Writes a new file using a stream. + * + * @param string $path The target file + * @param resource $resource The resource + * When target file cannot be created + */ + public function write_stream($path, $resource) + { + $adapter = $this->get_adapter(); + + if ($adapter instanceof stream_interface) + { + $adapter->write_stream($path, $resource); + } + else + { + // Simulate the stream + $adapter->put_contents($path, stream_get_contents($resource)); + } + } + + /** + * Get file info. + * + * @param string $path The file + * + * @throws \phpbb\storage\exception\not_implemented When the adapter doesnt implement the method + * + * @return \phpbb\storage\file_info Returns file_info object + */ + public function file_info($path) + { + return new file_info($this->adapter, $path); + } +} diff --git a/phpBB/phpbb/storage/stream_interface.php b/phpBB/phpbb/storage/stream_interface.php new file mode 100644 index 00000000000..0ba866777a3 --- /dev/null +++ b/phpBB/phpbb/storage/stream_interface.php @@ -0,0 +1,39 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\storage; + +interface stream_interface +{ + /** + * Reads a file as a stream. + * + * @param string $path File to read + * + * @throws \phpbb\storage\exception\exception When unable to open file + * + * @return resource Returns a file pointer + */ + public function read_stream($path); + + /** + * Writes a new file using a stream. + * + * @param string $path The target file + * @param resource $resource The resource + * + * @throws \phpbb\storage\exception\exception When target file exists + * When target file cannot be created + */ + public function write_stream($path, $resource); +} diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index cb00f165497..fb70fbb24e2 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -13,6 +13,8 @@ namespace phpbb\template; +use phpbb\filesystem\helper as filesystem_helper; + class asset { protected $components = array(); @@ -20,20 +22,15 @@ class asset /** @var \phpbb\path_helper **/ protected $path_helper; - /** @var \phpbb\filesystem\filesystem */ - protected $filesystem; - /** * Constructor * * @param string $url URL * @param \phpbb\path_helper $path_helper Path helper object - * @param \phpbb\filesystem\filesystem $filesystem */ - public function __construct($url, \phpbb\path_helper $path_helper, \phpbb\filesystem\filesystem $filesystem) + public function __construct($url, \phpbb\path_helper $path_helper) { $this->path_helper = $path_helper; - $this->filesystem = $filesystem; $this->set_url($url); } @@ -158,7 +155,7 @@ public function get_path() public function set_path($path, $urlencode = false) { // Since 1.7.0 Twig returns the real path of the file. We need it to be relative. - $real_root_path = $this->filesystem->realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR; + $real_root_path = filesystem_helper::realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR; // If the asset is under the phpBB root path we need to remove its path and then prepend $phpbb_root_path if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) @@ -168,7 +165,7 @@ public function set_path($path, $urlencode = false) else { // Else we make the path relative to the current working directory - $real_root_path = $this->filesystem->realpath('.') . DIRECTORY_SEPARATOR; + $real_root_path = filesystem_helper::realpath('.') . DIRECTORY_SEPARATOR; if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) { $path = str_replace('\\', '/', substr($path, strlen($real_root_path))); diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index de583d3224b..a45c61dbedc 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -87,7 +87,7 @@ public function append_var($varname, $varval) } /** - * Retreive a single scalar value from a single key. + * Retrieve a single scalar value from a single key. * * @param string $varname Variable name * @return mixed Variable value, or null if not set @@ -149,7 +149,7 @@ protected function set_num_rows(&$loop_data) { // If the key name is lowercase and the data is an array, // it could be a template loop. So we set the S_NUM_ROWS there - // aswell. + // as well. if ($sub_block_name === strtolower($sub_block_name) && is_array($sub_block)) { $this->set_num_rows($sub_block); diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php index df83d5bc43f..6634c28d02f 100644 --- a/phpBB/phpbb/template/template.php +++ b/phpBB/phpbb/template/template.php @@ -136,7 +136,7 @@ public function append_var($varname, $varval); public function retrieve_vars(array $vararray); /** - * Retreive a single scalar value from a single key. + * Retrieve a single scalar value from a single key. * * @param string $varname Variable name * @return mixed Variable value, or null if not set diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 1aa77174707..9374a891717 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -85,6 +85,8 @@ public function getFunctions() { return array( new \Twig_SimpleFunction('lang', array($this, 'lang')), + new \Twig_SimpleFunction('lang_defined', array($this, 'lang_defined')), + new \Twig_SimpleFunction('get_class', 'get_class'), ); } @@ -136,7 +138,7 @@ public function getOperators() * * @return mixed The sliced variable */ - function loop_subset(\Twig_Environment $env, $item, $start, $end = null, $preserveKeys = false) + public function loop_subset(\Twig_Environment $env, $item, $start, $end = null, $preserveKeys = false) { // We do almost the same thing as Twig's slice (array_slice), except when $end is positive if ($end >= 1) @@ -165,7 +167,7 @@ function loop_subset(\Twig_Environment $env, $item, $start, $end = null, $preser * * @return string */ - function lang() + public function lang() { $args = func_get_args(); $key = $args[0]; @@ -182,4 +184,14 @@ function lang() return call_user_func_array(array($this->language, 'lang'), $args); } + + /** + * Check if a language variable exists + * + * @return bool + */ + public function lang_defined($key) + { + return call_user_func_array([$this->language, 'is_set'], [$key]); + } } diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php index c13e3ee2985..3273520d865 100644 --- a/phpBB/phpbb/template/twig/loader.php +++ b/phpBB/phpbb/template/twig/loader.php @@ -13,6 +13,8 @@ namespace phpbb\template\twig; +use phpbb\filesystem\helper as filesystem_helper; + /** * Twig Template loader */ @@ -20,22 +22,14 @@ class loader extends \Twig_Loader_Filesystem { protected $safe_directories = array(); - /** - * @var \phpbb\filesystem\filesystem_interface - */ - protected $filesystem; - /** * Constructor * - * @param \phpbb\filesystem\filesystem_interface $filesystem * @param string|array $paths */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $paths = array()) + public function __construct($paths = array()) { - $this->filesystem = $filesystem; - - parent::__construct($paths, $this->filesystem->realpath(dirname(__FILE__))); + parent::__construct($paths, __DIR__); } /** @@ -67,7 +61,7 @@ public function setSafeDirectories($directories = array()) */ public function addSafeDirectory($directory) { - $directory = $this->filesystem->realpath($directory); + $directory = filesystem_helper::realpath($directory); if ($directory !== false) { @@ -107,7 +101,7 @@ protected function validateName($name) */ public function addPath($path, $namespace = self::MAIN_NAMESPACE) { - return parent::addPath($this->filesystem->realpath($path), $namespace); + return parent::addPath(filesystem_helper::realpath($path), $namespace); } /** @@ -147,7 +141,7 @@ protected function findTemplate($name) // can now check if we're within a "safe" directory // Find the real path of the directory the file is in - $directory = $this->filesystem->realpath(dirname($file)); + $directory = filesystem_helper::realpath(dirname($file)); if ($directory === false) { diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index 5899dff2f5d..7afe31dcb8c 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -324,7 +324,7 @@ function setup($lang_set = false, $style_id = false) } // Disable board if the install/ directory is still present - // For the brave development army we do not care about this, else we need to comment out this everytime we develop locally + // For the brave development army we do not care about this, else we need to comment out this every time we develop locally if (!defined('DEBUG') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install')) { // Adjust the message slightly according to the permissions @@ -443,7 +443,7 @@ function lang() * @return int|bool The plural-case we need to use for the number plural-rule combination, false if $force_rule * was invalid. * - * @deprecated: 3.2.0-dev (To be removed: 3.3.0) + * @deprecated: 3.2.0-dev (To be removed: 4.0.0) */ function get_plural_form($number, $force_rule = false) { @@ -454,8 +454,8 @@ function get_plural_form($number, $force_rule = false) * Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion) * * @param mixed $lang_set specifies the language entries to include - * @param bool $use_db internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 3.3.0) - * @param bool $use_help internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 3.3.0) + * @param bool $use_db internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 4.0.0) + * @param bool $use_help internal variable for recursion, do not use @deprecated 3.2.0-dev (To be removed: 4.0.0) * @param string $ext_name The extension to load language from, or empty for core files * * Examples: @@ -470,7 +470,7 @@ function get_plural_form($number, $force_rule = false) * Note: $use_db and $use_help should be removed. The old function was kept for BC purposes, * so the BC logic is handled here. * - * @deprecated: 3.2.0-dev (To be removed: 3.3.0) + * @deprecated: 3.2.0-dev (To be removed: 4.0.0) */ function add_lang($lang_set, $use_db = false, $use_help = false, $ext_name = '') { @@ -511,7 +511,7 @@ function add_lang($lang_set, $use_db = false, $use_help = false, $ext_name = '') /** * BC function for loading language files * - * @deprecated 3.2.0-dev (To be removed: 3.3.0) + * @deprecated 3.2.0-dev (To be removed: 4.0.0) */ private function set_lang($lang_set, $use_help, $ext_name) { @@ -547,7 +547,7 @@ private function set_lang($lang_set, $use_help, $ext_name) * * Note: $use_db and $use_help should be removed. Kept for BC purposes. * - * @deprecated: 3.2.0-dev (To be removed: 3.3.0) + * @deprecated: 3.2.0-dev (To be removed: 4.0.0) */ function add_lang_ext($ext_name, $lang_set, $use_db = false, $use_help = false) { @@ -749,7 +749,7 @@ function optionset($key, $value, $data = false) } /** - * Funtion to make the user leave the NEWLY_REGISTERED system group. + * Function to make the user leave the NEWLY_REGISTERED system group. * @access public */ function leave_newly_registered() diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php index 294f5208d52..b3ae4fe2df7 100644 --- a/phpBB/phpbb/user_loader.php +++ b/phpBB/phpbb/user_loader.php @@ -121,7 +121,7 @@ public function load_user_by_username($username) /** * Get a user row from our users cache * - * @param int $user_id User ID of the user you want to retreive + * @param int $user_id User ID of the user you want to retrieve * @param bool $query Should we query the database if this user has not yet been loaded? * Typically this should be left as false and you should make sure * you load users ahead of time with load_users() @@ -148,7 +148,7 @@ public function get_user($user_id, $query = false) /** * Get username * - * @param int $user_id User ID of the user you want to retreive the username for + * @param int $user_id User ID of the user you want to retrieve the username for * @param string $mode The mode to load (same as get_username_string). One of the following: * profile (for getting an url to the profile) * username (for obtaining the username) @@ -202,7 +202,7 @@ public function get_avatar($user_id, $query = false, $lazy = false) /** * Get rank * - * @param int $user_id User ID of the user you want to retreive the rank for + * @param int $user_id User ID of the user you want to retrieve the rank for * @param bool $query Should we query the database if this user has not yet been loaded? * Typically this should be left as false and you should make sure * you load users ahead of time with load_users() diff --git a/phpBB/phpbb/viewonline_helper.php b/phpBB/phpbb/viewonline_helper.php index 89915f2228c..8df1f484d8f 100644 --- a/phpBB/phpbb/viewonline_helper.php +++ b/phpBB/phpbb/viewonline_helper.php @@ -13,20 +13,18 @@ namespace phpbb; +use phpbb\filesystem\helper as filesystem_helper; + /** * Class to handle viewonline related tasks */ class viewonline_helper { - /** @var \phpbb\filesystem\filesystem_interface */ - protected $filesystem; - /** - * @param \phpbb\filesystem\filesystem_interface $filesystem phpBB's filesystem service + * */ - public function __construct(\phpbb\filesystem\filesystem_interface $filesystem) + public function __construct() { - $this->filesystem = $filesystem; } /** @@ -37,7 +35,7 @@ public function __construct(\phpbb\filesystem\filesystem_interface $filesystem) */ public function get_user_page($session_page) { - $session_page = $this->filesystem->clean_path($session_page); + $session_page = filesystem_helper::clean_path($session_page); if (strpos($session_page, './') === 0) { $session_page = substr($session_page, 2); diff --git a/phpBB/search.php b/phpBB/search.php index 97a8f320d47..8e3d6b4d22a 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -129,6 +129,11 @@ /* @var $pagination \phpbb\pagination */ $pagination = $phpbb_container->get('pagination'); +$template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $user->lang('SEARCH'), + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}search.$phpEx"), +)); + /** * This event allows you to alter the above parameters, such as keywords and submit * diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index 00d07fee6c1..27bc483267f 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -21,8 +21,8 @@ # General Information about this style name = prosilver copyright = © phpBB Limited, 2007 -style_version = 3.2.2 -phpbb_version = 3.2.2 +style_version = 3.3.0-a1-dev +phpbb_version = 3.3.0-a1-dev # Defining a different template bitfield # template_bitfield = //g= diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 6903ad2261f..c1b886e701d 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -100,7 +100,7 @@ phpbb.addAjaxCallback('mark_topics_read', function(res, updateTopicLinks) { // This callback will mark all notifications read phpbb.addAjaxCallback('notification.mark_all_read', function(res) { if (typeof res.success !== 'undefined') { - phpbb.markNotifications($('#notification_list li.bg2'), 0); + phpbb.markNotifications($('[data-notification-unread="true"]'), 0); phpbb.closeDarkenWrapper(3000); } }); @@ -108,8 +108,8 @@ phpbb.addAjaxCallback('notification.mark_all_read', function(res) { // This callback will mark a notification read phpbb.addAjaxCallback('notification.mark_read', function(res) { if (typeof res.success !== 'undefined') { - var unreadCount = Number($('#notification_list_button strong').html()) - 1; - phpbb.markNotifications($(this).parent('li.bg2'), unreadCount); + var unreadCount = Number($('#notification-button strong').html()) - 1; + phpbb.markNotifications($(this).parent('[data-notification-unread="true"]'), unreadCount); } }); @@ -131,11 +131,11 @@ phpbb.markNotifications = function($popup, unreadCount) { }); // Update the unread count. - $('strong', '#notification_list_button').html(unreadCount); + $('strong', '#notification-button').html(unreadCount); // Remove the Mark all read link and hide notification count if there are no unread notifications. if (!unreadCount) { $('#mark_all_notifications').remove(); - $('#notification_list_button > strong').addClass('hidden'); + $('#notification-button > strong').addClass('hidden'); } // Update page title diff --git a/phpBB/styles/prosilver/template/captcha_default.html b/phpBB/styles/prosilver/template/captcha_default.html index 02899bcafdf..6df124b443c 100644 --- a/phpBB/styles/prosilver/template/captcha_default.html +++ b/phpBB/styles/prosilver/template/captcha_default.html @@ -12,7 +12,7 @@

    {L_CONFIRMATION}

    {L_CONFIRM_CODE}
    - +
    {L_CONFIRM_CODE_EXPLAIN}
    diff --git a/phpBB/styles/prosilver/template/confirm_body.html b/phpBB/styles/prosilver/template/confirm_body.html index aaea5cfd05e..180ccaac592 100644 --- a/phpBB/styles/prosilver/template/confirm_body.html +++ b/phpBB/styles/prosilver/template/confirm_body.html @@ -4,8 +4,8 @@

    {MESSAGE_TITLE}

    {MESSAGE_TEXT}

    -   - +   +
    @@ -22,8 +22,8 @@

    {MESSAGE_TITLE}

    {S_HIDDEN_FIELDS} -   - +   +
    diff --git a/phpBB/styles/prosilver/template/confirm_delete_body.html b/phpBB/styles/prosilver/template/confirm_delete_body.html index 98974963c04..ecf96d49333 100644 --- a/phpBB/styles/prosilver/template/confirm_delete_body.html +++ b/phpBB/styles/prosilver/template/confirm_delete_body.html @@ -18,8 +18,8 @@
    -   - +   +
    @@ -58,8 +58,8 @@

    {MESSAGE_TITLE}

    {S_HIDDEN_FIELDS} -   - +   +
    diff --git a/phpBB/styles/prosilver/template/display_options.html b/phpBB/styles/prosilver/template/display_options.html index a426d08845c..1bcaf40087d 100644 --- a/phpBB/styles/prosilver/template/display_options.html +++ b/phpBB/styles/prosilver/template/display_options.html @@ -11,7 +11,7 @@
    - + @@ -19,7 +19,7 @@
    - + diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 3f59709ac64..2d7971206ef 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -462,7 +462,7 @@ function parseDocument($container) { $linksLast = $linksNotSkip.filter(filterLast), // The items that will be hidden last persistent = $this.attr('id') === 'nav-main', // Does this list already have a menu (such as quick-links)? html = '', - slack = 3; // Vertical slack space (in pixels). Determines how sensitive the script is in determining whether a line-break has occured. + slack = 3; // Vertical slack space (in pixels). Determines how sensitive the script is in determining whether a line-break has occurred. // Add a hidden drop-down menu to each links list (except those that already have one) if (!persistent) { diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index eab6528ca4b..b8fc209cb5a 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -48,17 +48,21 @@ {forumrow.FORUM_NAME} -
    {forumrow.FORUM_DESC} + {forumrow.FORUM_DESC} -
    {forumrow.L_MODERATOR_STR}{L_COLON} {forumrow.MODERATORS} + {forumrow.L_MODERATOR_STR}{L_COLON} {forumrow.MODERATORS} -
    {forumrow.L_SUBFORUM_STR}{L_COLON} + + {forumrow.L_SUBFORUM_STR}{L_COLON} - - {forumrow.subforum.SUBFORUM_NAME}{L_COMMA_SEPARATOR} + + + {forumrow.subforum.SUBFORUM_NAME}{L_COMMA_SEPARATOR} + + diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html index b292c40eb25..14c7e6b78b4 100644 --- a/phpBB/styles/prosilver/template/index_body.html +++ b/phpBB/styles/prosilver/template/index_body.html @@ -27,7 +27,7 @@

    {L_LOGIN_LOGOUT} | - + {S_LOGIN_REDIRECT} diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html index ef080357172..b948d6238ae 100644 --- a/phpBB/styles/prosilver/template/login_body.html +++ b/phpBB/styles/prosilver/template/login_body.html @@ -35,7 +35,7 @@

    {L_REGISTER}

    {L_LOGIN_INFO}

    {L_TERMS_USE} | {L_PRIVACY}


    -

    {L_REGISTER}

    +

    {L_REGISTER}

    diff --git a/phpBB/styles/prosilver/template/login_body_oauth.html b/phpBB/styles/prosilver/template/login_body_oauth.html index 156485d2119..a6a2e700522 100644 --- a/phpBB/styles/prosilver/template/login_body_oauth.html +++ b/phpBB/styles/prosilver/template/login_body_oauth.html @@ -2,7 +2,7 @@
     
    -
    {oauth.SERVICE_NAME}
    +
    {oauth.SERVICE_NAME}
    diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html index 7fa9736a968..a1239c4349d 100644 --- a/phpBB/styles/prosilver/template/login_forum.html +++ b/phpBB/styles/prosilver/template/login_forum.html @@ -27,7 +27,7 @@ {S_LOGIN_REDIRECT}
     
    -
    {S_HIDDEN_FIELDS}
    +
    {S_HIDDEN_FIELDS}
    diff --git a/phpBB/styles/prosilver/template/mcp_approve.html b/phpBB/styles/prosilver/template/mcp_approve.html index f7874ab90b3..2acc4753aba 100644 --- a/phpBB/styles/prosilver/template/mcp_approve.html +++ b/phpBB/styles/prosilver/template/mcp_approve.html @@ -19,8 +19,8 @@

    {MESSAGE_TITLE}

    -   - +   +
    @@ -66,8 +66,8 @@

    {MESSAGE_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  +
    diff --git a/phpBB/styles/prosilver/template/mcp_ban.html b/phpBB/styles/prosilver/template/mcp_ban.html index 5b798d9b6c8..cbee56a4520 100644 --- a/phpBB/styles/prosilver/template/mcp_ban.html +++ b/phpBB/styles/prosilver/template/mcp_ban.html @@ -85,8 +85,8 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    @@ -122,8 +122,8 @@

    {L_UNBAN_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  +
    diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index f6c518e1df4..a41fea82949 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -142,7 +142,7 @@

    {L_FORUM}{L_COLON} {FORUM_NAME}

    - + {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/template/mcp_front.html b/phpBB/styles/prosilver/template/mcp_front.html index 90793d072b7..f84faeee656 100644 --- a/phpBB/styles/prosilver/template/mcp_front.html +++ b/phpBB/styles/prosilver/template/mcp_front.html @@ -53,8 +53,8 @@

    {L_LATEST_UNAPPROVED}

    {S_HIDDEN_FIELDS} -   - +   +
    diff --git a/phpBB/styles/prosilver/template/mcp_logs.html b/phpBB/styles/prosilver/template/mcp_logs.html index 03216b4f387..d693ca0fed2 100644 --- a/phpBB/styles/prosilver/template/mcp_logs.html +++ b/phpBB/styles/prosilver/template/mcp_logs.html @@ -8,7 +8,7 @@

    {L_TITLE}

    - {L_SEARCH_KEYWORDS}{L_COLON}   + {L_SEARCH_KEYWORDS}{L_COLON}  
    -   - +   + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/mcp_notes_user.html b/phpBB/styles/prosilver/template/mcp_notes_user.html index 62d0562a46b..6d318dda977 100644 --- a/phpBB/styles/prosilver/template/mcp_notes_user.html +++ b/phpBB/styles/prosilver/template/mcp_notes_user.html @@ -42,8 +42,8 @@

    {L_ADD_FEEDBACK}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    @@ -51,7 +51,7 @@

    {L_ADD_FEEDBACK}

    - {L_SEARCH_KEYWORDS}{L_COLON}   + {L_SEARCH_KEYWORDS}{L_COLON}  
    -   - +   + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/mcp_warn_post.html b/phpBB/styles/prosilver/template/mcp_warn_post.html index 5e394806583..6c5b67f5012 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_post.html +++ b/phpBB/styles/prosilver/template/mcp_warn_post.html @@ -69,8 +69,8 @@

    {L_ADD_WARNING}

    -   - +   + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/mcp_warn_user.html b/phpBB/styles/prosilver/template/mcp_warn_user.html index f4dbf2819e0..8f7391e7b83 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_user.html +++ b/phpBB/styles/prosilver/template/mcp_warn_user.html @@ -53,8 +53,8 @@

    {L_ADD_WARNING}

    -   - +   + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index 255e6746e11..4c47a5d511b 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -125,7 +125,7 @@

    {PAGE_TITLE}{L_COLON} - + @@ -139,7 +139,7 @@

    {PAGE_TITLE}{L_COLON} - + diff --git a/phpBB/styles/prosilver/template/memberlist_email.html b/phpBB/styles/prosilver/template/memberlist_email.html index d9752bed00e..8c29496a00a 100644 --- a/phpBB/styles/prosilver/template/memberlist_email.html +++ b/phpBB/styles/prosilver/template/memberlist_email.html @@ -95,7 +95,7 @@

    {L_EMAIL_TOPIC}

    - +
    diff --git a/phpBB/styles/prosilver/template/memberlist_im.html b/phpBB/styles/prosilver/template/memberlist_im.html index 874607d9135..f91454aacb7 100644 --- a/phpBB/styles/prosilver/template/memberlist_im.html +++ b/phpBB/styles/prosilver/template/memberlist_im.html @@ -26,7 +26,7 @@

    {L_SEND_IM}

     
    -
    +
    diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index b1c7a81709f..ecdb9fa2810 100644 --- a/phpBB/styles/prosilver/template/memberlist_search.html +++ b/phpBB/styles/prosilver/template/memberlist_search.html @@ -76,8 +76,8 @@

    {L_FIND_USERNAME}


    -   - +   + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/memberlist_team.html b/phpBB/styles/prosilver/template/memberlist_team.html index 59041fbac0a..9dca281b733 100644 --- a/phpBB/styles/prosilver/template/memberlist_team.html +++ b/phpBB/styles/prosilver/template/memberlist_team.html @@ -8,7 +8,7 @@

    {PAGE_TITLE}

    - +
    diff --git a/phpBB/styles/prosilver/template/memberlist_view.html b/phpBB/styles/prosilver/template/memberlist_view.html index a7439bc7595..09797e19d8b 100644 --- a/phpBB/styles/prosilver/template/memberlist_view.html +++ b/phpBB/styles/prosilver/template/memberlist_view.html @@ -5,7 +5,7 @@

    {PAGE_TITLE}

    -
    +
    @@ -19,9 +19,11 @@

    {PAGE_TITLE}

    -
    {L_USERNAME}{L_COLON}
    +
    + {L_USERNAME}{L_COLON} +
    - {USERNAME} + {USERNAME} {L_ONLINE} [ {L_EDIT_PROFILE} ] [ {L_USER_ADMIN} ] [ {L_USER_BAN} ] @@ -35,7 +37,7 @@

    {PAGE_TITLE}

    {L_USER_IS_INACTIVE}{L_COLON}
    {USER_INACTIVE_REASON}
    {L_AGE}{L_COLON}
    {AGE}
    -
    {L_USERGROUPS}{L_COLON}
    +
    {L_USERGROUPS}{L_COLON}
    diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html index b8080a6be37..ce3f76ae4e8 100644 --- a/phpBB/styles/prosilver/template/navbar_header.html +++ b/phpBB/styles/prosilver/template/navbar_header.html @@ -151,7 +151,7 @@
    @@ -18,7 +18,7 @@
    - +
    @@ -37,8 +37,8 @@
    @@ -61,8 +61,8 @@ {attach_row.FILENAME} -   - +   + diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index d963c98e08c..49fff3fb082 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -94,10 +94,10 @@ {S_HIDDEN_ADDRESS_FIELD} {S_HIDDEN_FIELDS} -   -   - onclick="document.getElementById('postform').action += '#preview';" />  -   +   +   + onclick="document.getElementById('postform').action += '#preview';" />  +   diff --git a/phpBB/styles/prosilver/template/posting_layout.html b/phpBB/styles/prosilver/template/posting_layout.html index bca9195f0e1..985f92b23d4 100644 --- a/phpBB/styles/prosilver/template/posting_layout.html +++ b/phpBB/styles/prosilver/template/posting_layout.html @@ -51,7 +51,7 @@

    {L_SELECT_DESTINATION_FORUM}

     
    -
    +
    diff --git a/phpBB/styles/prosilver/template/posting_pm_header.html b/phpBB/styles/prosilver/template/posting_pm_header.html index 032d8c6a6f3..02c7d805582 100644 --- a/phpBB/styles/prosilver/template/posting_pm_header.html +++ b/phpBB/styles/prosilver/template/posting_pm_header.html @@ -13,8 +13,8 @@
    - - + + {L_FIND_USERNAME} @@ -31,7 +31,7 @@
    diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html index 943774c6ec3..57f902df622 100644 --- a/phpBB/styles/prosilver/template/ucp_agreement.html +++ b/phpBB/styles/prosilver/template/ucp_agreement.html @@ -46,10 +46,10 @@

    {SITENAME} - {L_REGISTRATION}

    - {L_COPPA_NO}  {L_COPPA_YES} + {L_COPPA_NO}  {L_COPPA_YES} -   - +   + {S_HIDDEN_FIELDS} {S_FORM_TOKEN} @@ -66,7 +66,7 @@

    {SITENAME} - {L_REGISTRATION}

    {SITENAME} - {AGREEMENT_TITLE}

    {AGREEMENT_TEXT}


    -

    {L_BACK}

    +

    {L_BACK}

    diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index 696f621116c..c13ef0713a7 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -73,7 +73,7 @@

    {L_TITLE}

    - + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html index 18316613b01..27124197cd3 100644 --- a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html +++ b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html @@ -10,7 +10,7 @@

    {oauth.SERVICE_NAME}

     
    -
    +
    @@ -18,7 +18,7 @@

    {oauth.SERVICE_NAME}

     
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options.html b/phpBB/styles/prosilver/template/ucp_avatar_options.html index 2cf9488ed00..8987fecc728 100644 --- a/phpBB/styles/prosilver/template/ucp_avatar_options.html +++ b/phpBB/styles/prosilver/template/ucp_avatar_options.html @@ -39,8 +39,8 @@

    {avatar_drivers.L_TITLE}

    -   - +   +
    diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options_local.html b/phpBB/styles/prosilver/template/ucp_avatar_options_local.html index e431b7425e0..ee17902ed53 100644 --- a/phpBB/styles/prosilver/template/ucp_avatar_options_local.html +++ b/phpBB/styles/prosilver/template/ucp_avatar_options_local.html @@ -4,7 +4,7 @@ - +
    - + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_groups_membership.html b/phpBB/styles/prosilver/template/ucp_groups_membership.html index e824a7b8679..e25e6363913 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_membership.html +++ b/phpBB/styles/prosilver/template/ucp_groups_membership.html @@ -149,7 +149,7 @@

    {L_USERGROUPS}

    - + {S_FORM_TOKEN}
    @@ -162,7 +162,7 @@

    {L_USERGROUPS}

      - + {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/template/ucp_header.html b/phpBB/styles/prosilver/template/ucp_header.html index 98d2eee1a0c..9ebb404dd9d 100644 --- a/phpBB/styles/prosilver/template/ucp_header.html +++ b/phpBB/styles/prosilver/template/ucp_header.html @@ -69,11 +69,11 @@

    {L_UCP}

    {L_FRIENDS}
    -
    {friends_online.USERNAME_FULL}
    +
    {friends_online.USERNAME_FULL}
    -
    {friends_offline.USERNAME_FULL}
    +
    {friends_offline.USERNAME_FULL}
    diff --git a/phpBB/styles/prosilver/template/ucp_login_link.html b/phpBB/styles/prosilver/template/ucp_login_link.html index be173318cb5..10d2d377ec1 100644 --- a/phpBB/styles/prosilver/template/ucp_login_link.html +++ b/phpBB/styles/prosilver/template/ucp_login_link.html @@ -18,7 +18,7 @@

    {L_REGISTER}

     
    -
    {S_HIDDEN_FIELDS}
    +
    {S_HIDDEN_FIELDS}
    @@ -46,7 +46,7 @@

    {L_LOGIN}

    {S_LOGIN_REDIRECT}
     
    -
    {S_HIDDEN_FIELDS}
    +
    {S_HIDDEN_FIELDS}
    diff --git a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html index 25647afe1ac..d14ae234257 100644 --- a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html +++ b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html @@ -114,7 +114,7 @@

    {L_TITLE}

    - + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_main_drafts.html b/phpBB/styles/prosilver/template/ucp_main_drafts.html index 52ad5b503bf..25eb5ce2d1a 100644 --- a/phpBB/styles/prosilver/template/ucp_main_drafts.html +++ b/phpBB/styles/prosilver/template/ucp_main_drafts.html @@ -16,8 +16,8 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    @@ -66,7 +66,7 @@

    {L_TITLE}

    - + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_main_subscribed.html b/phpBB/styles/prosilver/template/ucp_main_subscribed.html index d8de7fd0930..ec1500ffac4 100644 --- a/phpBB/styles/prosilver/template/ucp_main_subscribed.html +++ b/phpBB/styles/prosilver/template/ucp_main_subscribed.html @@ -160,7 +160,7 @@

    {L_TITLE}

    - + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_notifications.html b/phpBB/styles/prosilver/template/ucp_notifications.html index 55e30477d22..0bee0e5fd3a 100644 --- a/phpBB/styles/prosilver/template/ucp_notifications.html +++ b/phpBB/styles/prosilver/template/ucp_notifications.html @@ -52,7 +52,7 @@

    {TITLE}

    -
    +
    • @@ -109,7 +109,7 @@

      {TITLE}

      {S_HIDDEN_FIELDS} - + {S_FORM_TOKEN}
      diff --git a/phpBB/styles/prosilver/template/ucp_pm_options.html b/phpBB/styles/prosilver/template/ucp_pm_options.html index 247be8b6fd3..4c971243b16 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_options.html +++ b/phpBB/styles/prosilver/template/ucp_pm_options.html @@ -14,7 +14,7 @@

      {L_DEFINED_RULES}

        -
      1. {L_IF} {rule.CHECK} {rule.RULE} {rule.STRING} | {rule.ACTION}{L_COLON} {rule.FOLDER}
      2. +
      3. {L_IF} {rule.CHECK} {rule.RULE} {rule.STRING} | {rule.ACTION}{L_COLON} {rule.FOLDER}
      4. {L_NO_RULES_DEFINED}
      5. @@ -28,22 +28,22 @@

        {L_ADD_NEW_RULE}

        for="check_option">{L_IF}{L_COLON}
        - {CHECK_CURRENT} + {CHECK_CURRENT}
        -
        -
        {RULE_CURRENT}
        +
        +
        {RULE_CURRENT}
        -
        +
        @@ -53,7 +53,7 @@

        {L_ADD_NEW_RULE}

        {L_NO_GROUPS} - + {COND_CURRENT} @@ -68,8 +68,8 @@

        {L_ADD_NEW_RULE}

        -
        -
        {ACTION_CURRENT}
        +
        +
        {ACTION_CURRENT}
        @@ -82,7 +82,7 @@

        {L_FOLDER_OPTIONS}

        -
        {L_MAX_FOLDER_REACHED}
        +
        {L_MAX_FOLDER_REACHED}

        @@ -94,7 +94,7 @@

        {L_FOLDER_OPTIONS}

        -
        +

        @@ -102,7 +102,7 @@

        {L_FOLDER_OPTIONS}

        -
        +
        @@ -119,7 +119,7 @@

        {L_FOLDER_OPTIONS}


        {L_DEFAULT_ACTION_EXPLAIN}
        {DEFAULT_ACTION}
        -
        +
        diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html index a290313df77..f4556c4555b 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html @@ -24,8 +24,8 @@

        {L_OPTIONS}

    -   -   +   +   {S_FORM_TOKEN}
    @@ -100,8 +100,8 @@

    {L_OPTIONS}

    -

    - +

    +
    diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index 2ed0189c219..1e1e08f3680 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -22,147 +22,147 @@ -
    -
    - -
    -
    -
    - - {AUTHOR_AVATAR} - -
    - {MESSAGE_AUTHOR_FULL} -
    - - -
    {RANK_TITLE}
    {RANK_IMG}
    - - -
    {L_POSTS}{L_COLON} {AUTHOR_POSTS}{AUTHOR_POSTS}
    -
    {L_JOINED}{L_COLON} {AUTHOR_JOINED}
    - - - - -
    {custom_fields.PROFILE_FIELD_NAME}{L_COLON} {custom_fields.PROFILE_FIELD_VALUE}
    - - - - - - -
    - {L_CONTACT}{L_COLON} -
    - - -
    - -
    -

    {SUBJECT}

    - - - - - - - - -

    - {L_SENT_AT}{L_COLON} {SENT_DATE} -
    {L_PM_FROM}{L_COLON} {MESSAGE_AUTHOR_FULL} -
    {L_TO}{L_COLON} {to_recipient.NAME_FULL}{to_recipient.NAME}  -
    {L_BCC}{L_COLON} {bcc_recipient.NAME_FULL}{bcc_recipient.NAME}  -

    - - -
    {MESSAGE}
    - - -
    -
    - {L_ATTACHMENTS} -
    - -
    {attachment.DISPLAY_ATTACHMENT}
    - -
    - - -
    {L_DOWNLOAD_NOTICE}
    - + +
    {EDITED_MESSAGE} +
    {L_REASON}{L_COLON} {EDIT_REASON} +
    + - -
    {EDITED_MESSAGE} -
    {L_REASON}{L_COLON} {EDIT_REASON} + +
    {SIGNATURE}
    +
    - - -
    {SIGNATURE}
    - -
    - - +
    @@ -171,7 +171,7 @@

    {SUBJECT}

    -   +   {L_VIEW_PREVIOUS_PM} @@ -182,7 +182,7 @@

    {SUBJECT}

    {L_VIEW_NEXT_PM}
    - + diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index 4cd9f6655b3..46e96799267 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -79,8 +79,8 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_prefs_post.html b/phpBB/styles/prosilver/template/ucp_prefs_post.html index 169d41bf722..97a5da0a853 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_post.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_post.html @@ -44,8 +44,8 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_prefs_view.html b/phpBB/styles/prosilver/template/ucp_prefs_view.html index 4b7142fbea9..e28679aa96b 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_view.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_view.html @@ -89,8 +89,8 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html index 65909b7068e..3f63c5b3c0b 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html +++ b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html @@ -34,7 +34,7 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS} + {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html index 69eda8c42c2..c5dc0f88a6d 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html +++ b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html @@ -42,8 +42,8 @@

    {L_TITLE} [ - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html index f62d3cf37d5..8d7c6728a77 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html +++ b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html @@ -50,8 +50,8 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_profile_signature.html b/phpBB/styles/prosilver/template/ucp_profile_signature.html index 614f6f440da..41bd3ee2c67 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_signature.html +++ b/phpBB/styles/prosilver/template/ucp_profile_signature.html @@ -41,9 +41,9 @@

    {L_OPTIONS}

    {S_HIDDEN_FIELDS} -   -   - +   +   + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index 38413addba5..0b9897abf6b 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -96,8 +96,8 @@

    {L_COPPA_COMPLIANCE}

    {S_HIDDEN_FIELDS} -   - +   + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_remind.html b/phpBB/styles/prosilver/template/ucp_remind.html index 0ab1251d9ea..57d5d5a2604 100644 --- a/phpBB/styles/prosilver/template/ucp_remind.html +++ b/phpBB/styles/prosilver/template/ucp_remind.html @@ -19,7 +19,7 @@

    {L_SEND_PASSWORD}

     
    -
    {S_HIDDEN_FIELDS} 
    +
    {S_HIDDEN_FIELDS} 
    {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/template/ucp_resend.html b/phpBB/styles/prosilver/template/ucp_resend.html index 7713efe5215..48827d811bb 100644 --- a/phpBB/styles/prosilver/template/ucp_resend.html +++ b/phpBB/styles/prosilver/template/ucp_resend.html @@ -20,7 +20,7 @@

    {L_UCP_RESEND}

     
    -
    {S_HIDDEN_FIELDS}{S_FORM_TOKEN} 
    +
    {S_HIDDEN_FIELDS}{S_FORM_TOKEN} 
    diff --git a/phpBB/styles/prosilver/template/ucp_zebra_foes.html b/phpBB/styles/prosilver/template/ucp_zebra_foes.html index 2a0f6e0dea3..efd7a0613d8 100644 --- a/phpBB/styles/prosilver/template/ucp_zebra_foes.html +++ b/phpBB/styles/prosilver/template/ucp_zebra_foes.html @@ -32,8 +32,8 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_zebra_friends.html b/phpBB/styles/prosilver/template/ucp_zebra_friends.html index e584d876b8b..1478fb9546f 100644 --- a/phpBB/styles/prosilver/template/ucp_zebra_friends.html +++ b/phpBB/styles/prosilver/template/ucp_zebra_friends.html @@ -34,8 +34,8 @@

    {L_TITLE}

    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS}  + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index b5e12cdde4d..2113c6d7c5f 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -111,7 +111,7 @@

    {L_LOGIN_LOGOUT}{POLL_
     
    -
    +
    @@ -136,7 +136,7 @@

    {POLL_ data-url="{postrow.U_MINI_POST}"> -
    +
    style="display: none;"> @@ -149,7 +149,7 @@

    {POLL_

    - {postrow.POST_AUTHOR_FULL}{postrow.POST_AUTHOR_FULL} + {postrow.POST_AUTHOR_FULL}{postrow.POST_AUTHOR_FULL} {L_ONLINE} @@ -298,8 +298,8 @@

    class="first">class="first"> - + - + {S_FORM_TOKEN}

    diff --git a/phpBB/styles/prosilver/theme/base.css b/phpBB/styles/prosilver/theme/base.css index 98c57d92644..f4daeee1e50 100644 --- a/phpBB/styles/prosilver/theme/base.css +++ b/phpBB/styles/prosilver/theme/base.css @@ -1,6 +1,6 @@ -/* -------------------------------------------------------------- +/* -------------------------------------------------------------- /* $Base --------------------------------------------------------------- */ +/* -------------------------------------------------------------- */ /** { -webkit-box-sizing: border-box; @@ -12,19 +12,25 @@ -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -}*/ +} +*/ -/* Define your base font-size here; most elements will inherit this. _NO__DOTCOMMA__AFTER__*/ +/* + * 1. Define your base font-size here (16px), most elements will inherit this. + * 2. 24px (This is now our magic number; all subsequent margin-bottoms and + * line-heights want to be a multiple of this number in order to maintain + * vertical rhythm.) +*/ html { - font-size: 1em; /* Assuming 16px... */ - line-height: 1.5; /* 24px (This is now our magic number; all subsequent margin-bottoms and line-heights want to be a multiple of this number in order to maintain vertical rhythm.) _NO__DOTCOMMA__AFTER__*/ + font-size: 16px; /* [1] */ + line-height: 1.5; /* [2] */ -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - color: #333333; background-color: #ffffff; + color: #333333; } input, @@ -36,26 +42,31 @@ textarea { line-height: inherit; } -figure { margin: 0 } -img { vertical-align: middle } +figure { + margin: 0; +} + +img { + vertical-align: middle; +} hr { - margin-top: 20px; - margin-bottom: 20px; border: 0; border-top: 1px solid #e5e5e5; + margin-top: 20px; + margin-bottom: 20px; } a { - color: #428bca; text-decoration: none; + color: #428bca; } a:hover, a:focus, a:active { - color: #2a6496; text-decoration: underline; + color: #2a6496; } blockquote, @@ -69,7 +80,10 @@ h5, h6, figure, p, -pre { margin: 0 } +pre { + margin: 0; +} + button { background: transparent; border: 0; @@ -81,8 +95,7 @@ button { * results in a loss of the default `button` focus styles. */ button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; + outline: 1px dotted 5px auto -webkit-focus-ring-color; } fieldset { @@ -91,12 +104,15 @@ fieldset { padding: 0; } -iframe { border: 0 } +iframe { + border: 0; +} + ol, ul { - list-style: none; margin: 0; padding: 0; + list-style: none; } /** @@ -104,7 +120,9 @@ ul { * This prevents an unwanted focus outline from appearing around elements that * might still respond to pointer events. */ -[tabindex="-1"]:focus { outline: none !important } +[tabindex="-1"]:focus { + outline: none !important; +} /** * Remove double underline from recent version of firefox @@ -112,4 +130,3 @@ ul { abbr[title] { text-decoration: none; } - diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index 79b769b1e70..bcf271b0c82 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -1,5 +1,8 @@ -/* RTL definitions ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Bidi +/* -------------------------------------------------------------- */ +/* stylelint-disable selector-max-compound-selectors */ +/* stylelint-disable selector-no-qualifying-type */ /** * common.css @@ -18,8 +21,8 @@ } .rtl div.rules ul { - margin-left: 0; margin-right: 20px; + margin-left: 0; } /* Main blocks @@ -51,48 +54,52 @@ } /* Horizontal lists -----------------------------------------*/ +---------------------------------------- */ .rtl ul.linklist > li { float: right; margin-right: 0; margin-left: 7px; } -.rtl ul.linklist > li.rightside, .rtl p.rightside, .rtl a.rightside { +.rtl ul.linklist > li.rightside, +.rtl p.rightside, +.rtl a.rightside { + text-align: left; float: left; margin-right: 7px; margin-left: 0; - text-align: left; } -.rtl ul.leftside > li, .rtl ul.rightside > li { +.rtl ul.leftside > li, +.rtl ul.rightside > li { float: left; } .rtl ul.leftside { + text-align: right; float: right; - margin-left: 5px; margin-right: 0; - text-align: right; + margin-left: 5px; } .rtl ul.rightside { + text-align: left; float: left; - margin-left: -5px; margin-right: 5px; - text-align: left; + margin-left: -5px; } /* Bulletin icons for list items -----------------------------------------*/ +---------------------------------------- */ .rtl ul.linklist.bulletin > li:before { - padding-left: 4px; padding-right: 0; + padding-left: 4px; } /* Dropdown menu ---------------------------------------- */ -.rtl .dropdown-container.topic-tools, .rtl .dropdown-container-left { +.rtl .dropdown-container.topic-tools, +.rtl .dropdown-container-left { float: right; } @@ -101,8 +108,8 @@ } .rtl .dropdown-contents > li { - padding-left: 15px; padding-right: 0; + padding-left: 15px; } .rtl .dropdown-nonscroll > li { @@ -110,15 +117,16 @@ } .rtl .dropdown li li { - padding-left: 0; padding-right: 18px; + padding-left: 0; } .rtl .dropdown-extended .header { text-align: right; } -.rtl .dropdown-extended .header .header_settings, .rtl .dropdown-container-right { +.rtl .dropdown-extended .header .header-settings, +.rtl .dropdown-container-right { float: left; } @@ -128,42 +136,42 @@ } /* Notifications ------------------------------------------*/ -.rtl .notification_list ul li img { +----------------------------------------- */ +.rtl .notification-avatar { float: right; - margin-left: 5px; margin-right: 0; + margin-left: 5px; } -.rtl .notification_list div.notifications { - margin-left: 0; +.rtl .notification-menu .notifications { margin-right: 50px; + margin-left: 0; } -.rtl .notification_text { - margin-left: 0; +.rtl .notification-text { margin-right: 58px; + margin-left: 0; } -.rtl .notification_list p.notification-time { +.rtl .notification-time { text-align: left; } /* Responsive breadcrumbs -----------------------------------------*/ +---------------------------------------- */ .rtl .breadcrumbs .crumb { float: right; } /* Table styles -----------------------------------------*/ +---------------------------------------- */ .rtl table.table1 thead th { padding: 0 3px 4px 0; } .rtl table.table1 thead th span { - padding-left: 0; padding-right: 7px; + padding-left: 0; } .rtl table.table1 tbody th { @@ -171,11 +179,27 @@ } /* Specific column styles */ -.rtl table.table1 .name { text-align: right; } -.rtl table.table1 .joined { text-align: right; } -.rtl table.table1 .active { text-align: right; } -.rtl table.table1 .info { text-align: right; } -.rtl table.table1 thead .autocol { padding-left: 0; padding-right: 1em; } +.rtl table.table1 .name { + text-align: right; +} + +.rtl table.table1 .joined { + text-align: right; +} + +.rtl table.table1 .active { + text-align: right; +} + +.rtl table.table1 .info { + text-align: right; +} + +/* Not used anywhere maybe deprecated? */ +.rtl table.table1 thead .autocol { + padding-right: 10px; + padding-left: 0; +} .rtl table.table1 span.rank-img { float: left; @@ -191,6 +215,7 @@ /* Misc layout styles ---------------------------------------- */ + /* column[1-2] styles are containers for two column layouts */ .rtl .column1 { float: right; @@ -204,37 +229,27 @@ /* General classes for placing floating blocks */ .rtl .left-box { - float: right; text-align: right; + float: right; } .rtl .right-box { - float: left; text-align: left; + float: left; } .rtl dl.details dt { + text-align: left; float: right; clear: right; - text-align: left; } .rtl dl.details dd { + float: right; margin-right: 0; margin-left: 0; padding-right: 5px; padding-left: 0; - float: right; -} - -*:first-child+html dl.details dd { - margin-right: 30%; - float: none; -} - -* html dl.details dd { - margin-right: 30%; - float: none; } /* Pagination @@ -249,16 +264,16 @@ } .rtl .pagination > ul { - margin-left: 0; margin-right: 5px; + margin-left: 0; } /* Pagination in viewforum for multipage topics */ .rtl .row .pagination { background-position: 100% 50%; float: left; - padding-left: 0; padding-right: 15px; + padding-left: 0; } .rtl .row .pagination > ul { @@ -269,21 +284,26 @@ direction: ltr; } -.pagination li.page-jump { - margin-left: 5px; +.rtl .pagination li.page-jump { margin-right: 0; + margin-left: 5px; +} + +.rtl .topic-poster { + float: right; + padding-left: 6px; } /* Action Bar styles ---------------------------------------- */ .rtl .action-bar .button { - margin-right: 0; float: right; + margin-right: 0; } .rtl .action-bar > .button { - margin-left: 5px; float: right; + margin-left: 5px; } .rtl .action-bar .dropdown-button-control .button { @@ -294,14 +314,14 @@ /* Miscellaneous styles ---------------------------------------- */ .rtl .quick-links { - margin-left: 7px; margin-right: 0; + margin-left: 7px; } .rtl .header-avatar span:after { float: left; - padding-left: 0; padding-right: 2px; + padding-left: 0; } .rtl .member-search { @@ -318,15 +338,15 @@ unicode-bidi: embed; } -li.breadcrumbs span:first-child > a { +.rtl li.breadcrumbs span:first-child > a { padding-left: 0; } /* Notification mark read link */ .rtl .dropdown-extended a.mark_read { border-radius: 0 3px 3px 0; - left: 0; right: auto; + left: 0; } .rtl .back2top .top { @@ -335,9 +355,10 @@ li.breadcrumbs span:first-child > a { } .rtl .skiplink { + right: -999px; + /* invisible skip link, used for accessibility */ left: 0; - right: -999px; } .rtl a.feed-icon-forum { @@ -347,7 +368,8 @@ li.breadcrumbs span:first-child > a { /** * content.css */ -.rtl ul.topiclist dt, .rtl li.header dt { +.rtl ul.topiclist dt, +.rtl li.header dt { float: right; margin-right: 0; margin-left: -440px; @@ -389,21 +411,21 @@ li.breadcrumbs span:first-child > a { } .rtl ul.topiclist dd { - float: right; border-right-width: 1px; border-right-style: solid; border-left: none; + float: right; } .rtl ul.topiclist dfn { - left: auto; right: -999px; + left: auto; } .rtl ul.topiclist li.row dt a.subforum { - padding-right: 12px; background-position: right; position: static; + padding-right: 12px; } .rtl .forum-image { @@ -412,16 +434,17 @@ li.breadcrumbs span:first-child > a { margin-left: 5px; } -.rtl li.header dt, .rtl li.header dd { +.rtl li.header dt, +.rtl li.header dd { border-right-width: 0; } .rtl li.header dd { - padding-left: 0; padding-right: 1px; + padding-left: 0; } -.rtl dl.row-item{ +.rtl dl.row-item { background-position: 99.5% 50%; } @@ -432,34 +455,39 @@ li.breadcrumbs span:first-child > a { } .rtl dl.row-item dt { - background-position: 99.5% 95%; /* Position of topic icon */ + background-position: 99.5% 95%; /* Position of topic icon */ } .rtl dl.row-item dt .list-inner { + padding-right: 45px; /* Space for folder icon */ padding-left: 5px; - padding-right: 45px; /* Space for folder icon */ } -.rtl dl a.row-item-link { /* topic row icon links */ - display: inline-block; - left: auto; +.rtl dl a.row-item-link { /* topic row icon links */ right: 0; - margin-left: 0; + left: auto; + display: inline-block; margin-right: 2px; + margin-left: 0; } -.rtl dd.lastpost > span, .rtl ul.topiclist dd.info > span, .rtl ul.topiclist dd.time > span, .rtl dd.redirect > span, .rtl dd.moderation > span { - padding-left: 0; +.rtl dd.lastpost > span, +.rtl ul.topiclist dd.info > span, +.rtl ul.topiclist dd.time > span, +.rtl dd.redirect > span, +.rtl dd.moderation > span { padding-right: 5px; + padding-left: 0; } /* Post body styles -----------------------------------------*/ +---------------------------------------- */ .rtl .date { float: left; } -.rtl .postbody, .rtl .postbody h3 { +.rtl .postbody, +.rtl .postbody h3 { float: right; } @@ -473,21 +501,22 @@ li.breadcrumbs span:first-child > a { } .rtl p.post-notice:before { - left: auto; right: 0; + left: auto; } /* Topic review panel -----------------------------------------*/ +---------------------------------------- */ .rtl .topicreview { padding-right: 0; padding-left: 5px; } /* Content container styles -----------------------------------------*/ -.rtl .content ul, .rtl .content ol { - margin-right: 3em; +---------------------------------------- */ +.rtl .content ul, +.rtl .content ol { + margin-right: 40px; margin-left: 0; } @@ -505,23 +534,25 @@ li.breadcrumbs span:first-child > a { } /* BB Code styles -----------------------------------------*/ +---------------------------------------- */ + /* Quote block */ .rtl blockquote { - margin: 0.5em 25px 0 1px; + margin: 5px 25px 0 1px; } +/* Nested quotes */ .rtl blockquote blockquote { - /* Nested quotes */ - margin: 0.5em 15px 0 1px; + margin: 5px 15px 0 1px; } +/* Username/source of quoter */ .rtl blockquote cite { - /* Username/source of quoter */ margin-left: 0; } -.rtl blockquote cite:before, .rtl .uncited:before { +.rtl blockquote cite:before, +.rtl .uncited:before { padding-left: 5px; } @@ -534,11 +565,11 @@ li.breadcrumbs span:first-child > a { } /* Attachments -----------------------------------------*/ +---------------------------------------- */ .rtl .attachbox { float: right; - margin: 5px 0 5px 5px; clear: right; + margin: 5px 0 5px 5px; } .rtl .attachbox dd { @@ -554,16 +585,16 @@ li.breadcrumbs span:first-child > a { } /* Post poll styles -----------------------------------------*/ +---------------------------------------- */ .rtl fieldset.polls dt { text-align: right; - float: right; border-left: none; + float: right; } .rtl fieldset.polls dd { - float: right; border-right: none; + float: right; margin-right: 0; } @@ -571,18 +602,23 @@ li.breadcrumbs span:first-child > a { text-align: left; } -.rtl .pollbar1, .rtl .pollbar2, .rtl .pollbar3, .rtl .pollbar4, .rtl .pollbar5 { +.rtl .pollbar1, +.rtl .pollbar2, +.rtl .pollbar3, +.rtl .pollbar4, +.rtl .pollbar5 { + border-right: none; border-left-width: 1px; border-left-style: solid; - border-right: none; } /* Poster profile block -----------------------------------------*/ +---------------------------------------- */ .rtl .postprofile { border-width: 0 1px 0 0; float: left; -/* text-align: right; */ + + /* text-align: right; */ } .rtl .pm .postprofile { @@ -591,19 +627,16 @@ li.breadcrumbs span:first-child > a { border-left: none; } -.rtl .postprofile dd, .rtl .postprofile dt { - margin-left: 0; +.rtl .postprofile dd, +.rtl .postprofile dt { margin-right: 8px; + margin-left: 0; } .rtl .postprofile .avatar { float: right; } -.rtl .online { - background-position: 0 0; -} - .rtl dl.pmlist dd { margin-right: 61% !important; margin-left: 0 !important; @@ -627,8 +660,8 @@ li.breadcrumbs span:first-child > a { } .rtl .has-profile .post-buttons { - left: 0; right: auto; + left: 0; } .rtl .post-buttons li { @@ -636,11 +669,11 @@ li.breadcrumbs span:first-child > a { } /* Poster contact icons - ----------------------------------------*/ + ---------------------------------------- */ .rtl .contact-icons a { + border-right: none; border-left-width: 1px; border-left-style: dotted; - border-right: none; float: right; } @@ -651,12 +684,13 @@ li.breadcrumbs span:first-child > a { /** * cp.css */ + /* Control Panel Styles ---------------------------------------- */ /* Main CP box -----------------------------------------*/ +---------------------------------------- */ .rtl .cp-menu { float: right; } @@ -666,7 +700,7 @@ li.breadcrumbs span:first-child > a { } .rtl .cp-main .panel ol { - margin-right: 2em; + margin-right: 22px; margin-left: 0; } @@ -675,15 +709,15 @@ li.breadcrumbs span:first-child > a { margin-left: 0; } -.tabs-container h2 { +.rtl .tabs-container h2 { float: right; } /* CP tabbed menu -----------------------------------------*/ +---------------------------------------- */ .rtl .tabs { - margin-left: 0; margin-right: 7px; + margin-left: 0; } .rtl .tabs .tab { @@ -691,12 +725,12 @@ li.breadcrumbs span:first-child > a { } .rtl .tabs .tab > a { - margin-left: 1px; margin-right: 0; + margin-left: 1px; } /* Mini tabbed menu used in MCP -----------------------------------------*/ +---------------------------------------- */ .rtl .minitabs { float: left; margin-right: 0; @@ -713,7 +747,7 @@ li.breadcrumbs span:first-child > a { } /* Responsive tabs -----------------------------------------*/ +---------------------------------------- */ .rtl .tabs .dropdown { margin-left: -2px; } @@ -730,23 +764,14 @@ li.breadcrumbs span:first-child > a { text-align: right; } -/* Responsive *CP navigation -----------------------------------------*/ -@media only screen and (max-width: 900px), only screen and (max-device-width: 900px) -{ - .rtl .cp-menu, .rtl .navigation, .rtl .cp-main { - float: none; - } -} - /* UCP navigation menu -----------------------------------------*/ +---------------------------------------- */ /* Preferences pane layout -----------------------------------------*/ +---------------------------------------- */ .rtl .cp-main h2 { - margin-left: 0; margin-right: 10px; + margin-left: 0; } /* Friends list */ @@ -755,7 +780,7 @@ li.breadcrumbs span:first-child > a { } /* PM Styles -----------------------------------------*/ +---------------------------------------- */ /* PM panel adjustments */ .rtl .reply-all a.right { @@ -780,8 +805,8 @@ li.breadcrumbs span:first-child > a { border-right-width: 10px; border-right-style: solid; border-left-width: 0; - padding-left: 0; padding-right: 3px; + padding-left: 0; } /* Avatar gallery */ @@ -789,25 +814,16 @@ li.breadcrumbs span:first-child > a { float: right; } -/* Responsive *CP navigation -----------------------------------------*/ -@media only screen and (max-width: 900px), only screen and (max-device-width: 900px) -{ - .rtl .cp-menu, .rtl .navigation, .rtl .cp-main { - float: none; - } -} - /** * forms.css */ /* General form styles -----------------------------------------*/ +---------------------------------------- */ .rtl option { padding-right: 0; - padding-left: 1em; + padding-left: 11px; } .rtl label { @@ -818,26 +834,26 @@ li.breadcrumbs span:first-child > a { /* Definition list layout for forms ---------------------------------------- */ .rtl fieldset dt { - float: right; text-align: right; + float: right; } .rtl fieldset dd { - margin-left: 0; margin-right: 41%; + margin-left: 0; } /* Specific layout 1 */ .rtl fieldset.fields1 dt { - border-left-width: 0; border-right-width: 1px; + border-left-width: 0; } .rtl fieldset.fields1 dd { - margin-right: 15em; - margin-left: 0; border-right-width: 0; border-left-width: 1px; + margin-right: 165px; + margin-left: 0; } /* Specific layout 2 */ @@ -847,10 +863,10 @@ li.breadcrumbs span:first-child > a { } .rtl fieldset.fields2 dd { - margin-right: 16em; - margin-left: 0; - border-left-width: 1px; border-right-width: 0; + border-left-width: 1px; + margin-right: 176px; + margin-left: 0; } /* Form elements */ @@ -858,26 +874,27 @@ li.breadcrumbs span:first-child > a { text-align: right; } -.rtl dd input, .rtl dd textarea { - margin-left: 3px; +.rtl dd input, +.rtl dd textarea { margin-right: 0; + margin-left: 3px; } /* Quick-login on index page */ .rtl fieldset.quick-login input.inputbox { - margin-left: 5px; margin-right: 0; + margin-left: 5px; } .rtl fieldset.quick-login label { - padding-left: 2px; padding-right: 0; + padding-left: 2px; } /* Display options on viewtopic/viewforum pages */ .rtl fieldset.display-options label { - padding-left: 2px; padding-right: 0; + padding-left: 2px; } .rtl .dropdown fieldset.display-options label { @@ -887,16 +904,16 @@ li.breadcrumbs span:first-child > a { /* Display actions for ucp and mcp pages */ .rtl fieldset.display-actions { text-align: left; - padding-left: 1em; padding-right: 0; + padding-left: 11px; } .rtl fieldset.display-actions label { - padding-left: 2px; padding-right: 0; + padding-left: 2px; } -/* MCP forum selection*/ +/* MCP forum selection */ .rtl fieldset.forum-selection { float: left; } @@ -906,7 +923,7 @@ li.breadcrumbs span:first-child > a { } /* Posting page styles -----------------------------------------*/ +---------------------------------------- */ /* Emoticons panel */ .rtl .smiley-box { @@ -922,22 +939,22 @@ li.breadcrumbs span:first-child > a { } .rtl .search-box .inputbox { - border-left-width: 0; border-right-width: 1px; + border-left-width: 0; border-radius: 0 4px 4px 0; float: right; padding: 3px; } .rtl .button-search, -.button-search-end { +.rtl .button-search-end { float: right; } .rtl .button-search-end { - border-radius: 4px 0 0 4px; - border-left-width: 1px; border-right-width: 0; + border-left-width: 1px; + border-radius: 4px 0 0 4px; } .rtl .search-header .button-search-end { @@ -955,7 +972,10 @@ li.breadcrumbs span:first-child > a { ---------------------------------------- */ /** Reference: Bug #27155 */ -.rtl .wrap, .rtl .headerbar, .rtl .site-description, .rtl .navbar { +.rtl .wrap, +.rtl .headerbar, +.rtl .site-description, +.rtl .navbar { position: relative; } @@ -967,124 +987,4 @@ li.breadcrumbs span:first-child > a { float: left; } -/** -* responsive.css -*/ -@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) -{ - /* .topiclist lists - ----------------------------------------*/ - .rtl ul.topiclist li.header dt, .rtl ul.topiclist li.header dt .list-inner { - margin-left: 0 !important; - padding-left: 0; - } - - .rtl ul.topiclist dt, .rtl ul.topiclist dt .list-inner, - .rtl ul.topiclist.missing-column dt, .rtl ul.topiclist.missing-column dt .list-inner, - .rtl ul.topiclist.two-long-columns dt, .rtl ul.topiclist.two-long-columns dt .list-inner, - .rtl ul.topiclist.two-columns dt, .rtl ul.topiclist.two-columns dt .list-inner { - margin-left: 0; - } - - .rtl ul.topiclist dt .list-inner.with-mark { - padding-left: 34px; - } - - /* Forums and topics lists - ----------------------------------------*/ - .rtl ul.topiclist.forums dt { - margin-left: -250px; - } - .rtl ul.topiclist.forums dt .list-inner { - margin-left: 250px; - } - - .rtl ul.topiclist dd.mark { - left: 5px; - right: auto; - text-align: right; - } - - .rtl table.responsive.show-header thead, .rtl table.responsive.show-header th:first-child { - text-align: right !important; - } - - .rtl table.responsive td { - text-align: right !important; - } - - /* User profile - ----------------------------------------*/ - .rtl .column1, .rtl .column2, .rtl .left-box.profile-details { - float: none; - } - - /* Post - ----------------------------------------*/ - .rtl .postprofile, .rtl .postbody, .rtl .search .postbody { - float: none; - } - - .rtl .post .postprofile { - border-width: 0 0 1px 0; - } - - .rtl .postprofile dt, .rtl .postprofile dd.profile-rank, .rtl .search .postprofile dd { - margin: 0; - } - - .rtl .postprofile .avatar { - margin-left: 5px; - margin-right: 0; - } - - .rtl .has-profile .post-buttons { - left: 20px; - } - - /* Forms - ----------------------------------------*/ - .rtl fieldset dt, .rtl fieldset.fields1 dt, .rtl fieldset.fields2 dt { - float: none; - } - - .rtl fieldset dd, .rtl fieldset.fields1 dd, .rtl fieldset.fields2 dd { - margin-right: 20px; - } -} - -@media only screen and (max-width: 550px), only screen and (max-device-width: 550px) -{ - /* .topiclist lists - ----------------------------------------*/ - .rtl ul.topiclist.forums dt { - margin-left: 0; - } - - .rtl ul.topiclist.forums dt .list-inner { - margin-left: 0; - } -} - -@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) -{ - .rtl dl.details dt, .rtl dl.details dd { - float: none; - text-align: right; - } - - .rtl dl.details dd { - margin-left: 0; - margin-right: 20px; - } - - .captcha-panel dd.captcha { - margin-right: 0; - } - - .rtl p.responsive-center { - float: none; - text-align: center; - margin-bottom: 5px; - } -} +/* stylelint-enable selector-no-qualifying-type */ diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index 575c41aaef7..77325f3d32f 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -1,31 +1,31 @@ -/* Button Styles ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Buttons +/* -------------------------------------------------------------- */ .button { - display: inline-block; - padding: 2px 8px; + font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica; font-size: 13px; font-weight: 600; - font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica; line-height: 1.4; text-align: center; - white-space: nowrap; vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; + white-space: nowrap; border: 1px solid transparent; border-radius: 4px; + display: inline-block; + padding: 2px 8px; + cursor: pointer; + touch-action: manipulation; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } .button:focus, .button:hover { - text-decoration: none; - outline: none; + text-decoration: none; + outline: none; } .caret { @@ -39,11 +39,21 @@ } /* Posting page styles -----------------------------------------*/ +---------------------------------------- */ +.button-form, +.button-form-bold { + font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; + border-radius: 0; +} + +.button-form-bold { + font-weight: 700; +} + .button-search, -.button-search-end { - float: left; +.button-search-end { border-radius: 0; + float: left; margin: 0; padding: 2px 5px; } @@ -65,27 +75,28 @@ } .button-icon-only { - padding-left: 3px; padding-right: 3px; + padding-left: 3px; } /* Poster contact icons -----------------------------------------*/ +---------------------------------------- */ .contact-icons.dropdown-contents { + font-size: 0; min-width: 0; padding: 0; - font-size: 0; } .contact-icon { background-repeat: no-repeat; display: block; - height: 16px; width: 16px; + height: 16px; } + .contact-icons a { - border-bottom: 1px dotted; border-right: 1px dotted; + border-bottom: 1px dotted; display: block; float: left; padding: 8px; @@ -107,16 +118,15 @@ --------------------------------------------- */ .post-buttons { float: right; - list-style: none; margin-top: 2px; + list-style: none; } .has-profile .post-buttons { - float: none; position: absolute; - margin: 0; - right: 0; top: 5px; + right: 0; + margin: 0; } .post-buttons > li { @@ -124,9 +134,10 @@ margin-right: 3px; } -.post-buttons .button, .format-buttons .button { - padding-left: 3px; +.post-buttons .button, +.format-buttons .button { padding-right: 3px; + padding-left: 3px; } .hastouch .post-buttons { @@ -143,9 +154,9 @@ } .post-buttons .dropdown a { - display: block; - font-size: 1.2em; + font-size: 13px; text-align: right; + display: block; } .hasjs .postbody .post-buttons { @@ -154,16 +165,16 @@ /* Browser-specific tweaks */ button::-moz-focus-inner { + border: 0; padding: 0; - border: 0 } /* Deprecated as of version 3.2 --------------------------------------------------*/ +------------------------------------------------- */ .small-icon { - background-position: 0 50%; - background-repeat: no-repeat; background-image: none; + background-repeat: no-repeat; + background-position: 0 50%; } .dropdown .small-icon { @@ -175,9 +186,12 @@ button::-moz-focus-inner { padding: 0 0 0 18px; } + +/* stylelint-disable selector-no-qualifying-type */ ul.linklist.bulletin > li.small-icon:before { display: none; } +/* stylelint-enable selector-no-qualifying-type */ .dropdown .small-icon > a { display: block; @@ -188,6 +202,6 @@ ul.linklist.bulletin > li.small-icon:before { } .rtl .small-icon > a { - padding-left: 0; padding-right: 19px; + padding-left: 0; } diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index ffaa71034f3..2788295b680 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -1,115 +1,121 @@ -/* --------------------------------------------------------------- -Colours and backgrounds for common.css --------------------------------------------------------------- */ +/* -------------------------------------------------------------- /* + $Colours +/* -------------------------------------------------------------- * -html, body { - color: #536482; - background-color: #F5F7FA; +/* stylelint-disable selector-max-compound-selectors */ +/* stylelint-disable selector-no-qualifying-type */ + +/* colours and backgrounds for common.css */ +html, +body { + background-color: #f5f5f5; + color: #47536b; +} + +.wrap { + background-color: #ffffff; + border-color: #ededed; } h1 { - color: #FFFFFF; + color: #ffffff; } h2 { - color: #28313F; + color: #29303d; } h3 { - border-bottom-color: #CCCCCC; - color: #115098; + border-bottom-color: #dedede; + color: #0059b3; } hr { - border-color: #FFFFFF; - border-top-color: #CCCCCC; + border-color: #ffffff; + border-top-color: #dedede; } -/* --------------------------------------------------------------- -Colours and backgrounds for links.css --------------------------------------------------------------- */ - -a { color: #105289; } -a:hover { color: #D31141; } +/* colours and backgrounds for links.css */ +a { + color: #0f4d8a; +} -/* Links on gradient backgrounds */ -.forumbg .header a, .forabg .header a, th a { - color: #FFFFFF; +a:hover { + color: #d41142; } -.forumbg .header a:hover, .forabg .header a:hover, th a:hover { - color: #A8D8FF; +/* links on gradient backgrounds */ +.forumbg .header a, +.forabg .header a, +th a { + color: #ffffff; } -/* Notification mark read link */ -.dropdown-extended a.mark_read { - background-color: #FFFFFF; +.forumbg .header a:hover, +.forabg .header a:hover, +th a:hover { + color: #80bfff; } -/* Post body links */ +/* post body links */ .postlink { - border-bottom-color: #368AD2; - color: #368AD2; + border-bottom-color: #2d80d2; + color: #2d80d2; } .postlink:visited { - border-bottom-color: #5D8FBD; - color: #5D8FBD; + border-bottom-color: #5380ac; + color: #5380ac; } .postlink:hover { - background-color: #D0E4F6; - color: #0D4473; + background-color: #d4e6f7; + color: #164069; } -.signature a, .signature a:hover { +.signature a, +.signature a:hover { background-color: transparent; } -/* Back to top of page */ +/* back to top of page */ .top i { - color: #999999; + color: #9e9e9e; } -/* Arrow links */ -.arrow-left:hover, .arrow-right:hover { - color: #368AD2; -} - -/* Round cornered boxes and backgrounds ----------------------------------------- */ -.wrap { - background-color: #FFF; - border-color: #E6E9ED; +/* arrow links */ +.arrow-left:hover, +.arrow-right:hover { + color: #2d80d2; } +/* round cornered boxes and backgrounds */ .headerbar { - color: #FFFFFF; + color: #ffffff; } -.headerbar, .forumbg { - background-color: #12A3EB; - background-image: -webkit-linear-gradient(top, #6ACEFF 0%, #0076B1 2px, #12A3EB 92px, #12A3EB 100%); - background-image: linear-gradient(to bottom, #6ACEFF 0%,#0076B1 2px,#12A3EB 92px,#12A3EB 100%); +.headerbar, +.forumbg { + background-color: #13a4ec; + background-image: -webkit-gradient(linear, left top, left bottom, from(#80d5ff), color-stop(0.1%, #0077b3), color-stop(30%, #13a4ec), to(#13a4ec)); + background-image: linear-gradient(to bottom, #80d5ff 0%, #0077b3 0.1%, #13a4ec 30%, #13a4ec 100%); background-repeat: repeat-x; } .forabg { - background-color: #0076B1; - background-image: -webkit-linear-gradient(top, #6ACEFF 0%, #12A3EB 2px, #0076B1 92px, #0076B1 100%); - background-image: linear-gradient(to bottom, #6ACEFF 0%,#12A3EB 2px,#0076B1 92px,#0076B1 100%); + background-color: #0077b3; + background-image: -webkit-gradient(linear, left top, left bottom, from(#80d5ff), color-stop(0.1%, #13a4ec), color-stop(30%, #0077b3), to(#0077b3)); + background-image: linear-gradient(to bottom, #80d5ff 0%, #13a4ec 0.1%, #0077b3 30%, #0077b3 100%); background-repeat: repeat-x; } .navbar { - background-color: #CADCEB; + background-color: #c9dee8; } .panel { - background-color: #ECF1F3; - color: #28313F; + background-color: #f0f3f5; + color: #29303d; } .post:target .content { @@ -121,226 +127,216 @@ a:hover { color: #D31141; } } .bg1 { - background-color: #ECF3F7; + background-color: #edf4f7; } -table.zebra-list tr:nth-child(odd) td, ul.zebra-list li:nth-child(odd) { - background-color: #ECF3F7; +table.zebra-list tr:nth-child(odd) td, +ul.zebra-list li:nth-child(odd) { + background-color: #edf4f7; } .bg2 { - background-color: #E1EBF2; -} - -table.zebra-list tr:nth-child(even) td, ul.zebra-list li:nth-child(even) { - background-color: #E1EBF2; -} - -.bg3 { - background-color: #CADCEB; + background-color: #dbe9f0; } -.ucprowbg { - background-color: #DCDEE2; +table.zebra-list tr:nth-child(even) td, +ul.zebra-list li:nth-child(even) { + background-color: #dbe9f0; } -.fieldsbg { - background-color: #E7E8EA; +.bg3 { + background-color: #c9dee8; } -.site_logo { - background-image: url("./images/site_logo.gif"); -} - -/* Horizontal lists -----------------------------------------*/ - +/* horizontal lists */ ul.navlinks { - border-top-color: #FFFFFF; + border-top-color: #ffffff; } -/* Table styles -----------------------------------------*/ +/* table styles */ table.table1 thead th { - color: #FFFFFF; + color: #ffffff; } table.table1 tbody tr { - border-color: #BFC1CF; + border-color: #c9dee8; } -table.table1 tbody tr:hover, table.table1 tbody tr.hover { - background-color: #CFE1F6; - color: #000; +table.table1 tbody tr:hover, +table.table1 tbody tr.hover { + background-color: #d4e6f7; + color: #000000; } table.table1 td { - color: #536482; + color: #47536b; } table.table1 tbody td { - border-top-color: #FAFAFA; + border-top-color: #fafafa; } table.table1 tbody th { + background-color: #ffffff; border-bottom-color: #000000; - color: #333333; - background-color: #FFFFFF; + color: #212121; } table.info tbody th { color: #000000; } -/* Misc layout styles ----------------------------------------- */ +/* misc layout styles */ dl.details dt { color: #000000; } dl.details dd { - color: #536482; + color: #47536b; } -.sep { - color: #1198D9; +/* icon styles */ +.icon.icon-blue, +a:hover .icon.icon-blue { + color: #0059b3; } -/* Icon styles ----------------------------------------- */ -.icon.icon-blue, a:hover .icon.icon-blue { - color: #196db5; +.icon.online { + color: #85de39; } -.icon.icon-green, a:hover .icon.icon-green{ - color: #1b9A1B; +.icon.icon-green, +a:hover .icon.icon-green { + color: #4db355; } -.icon.icon-red, a:hover .icon.icon-red{ - color: #BC2A4D; +.icon.icon-red, +a:hover .icon.icon-red { + color: #d41142; } -.icon.icon-orange, a:hover .icon.icon-orange{ - color: #FF6600; +.icon.icon-orange, +a:hover .icon.icon-orange { + color: #ff9500; } -.icon.icon-bluegray, a:hover .icon.icon-bluegray{ - color: #536482; +.icon.icon-bluegray, +a:hover .icon.icon-bluegray { + color: #47536b; } -.icon.icon-gray, a:hover .icon.icon-gray{ - color: #777777; +.icon.icon-gray, +a:hover .icon.icon-gray { + color: #757575; } -.icon.icon-lightgray, a:hover .icon.icon-lightgray{ - color: #999999; +.icon.icon-lightgray, +a:hover .icon.icon-lightgray { + color: #9e9e9e; } -.icon.icon-black, a:hover .icon.icon-black{ - color: #333333; +.icon.icon-black, +a:hover .icon.icon-black { + color: #212121; } .alert_close .icon:before { - background-color: #FFFFFF; + background-color: #ffffff; } -/* Jumpbox */ +/* jumpbox */ .jumpbox .dropdown li { - border-top-color: #CCCCCC; + border-top-color: #dedede; } .jumpbox-cat-link { - background-color: #0076b1; - border-top-color: #0076B1; - color: #FFFFFF; + background-color: #0077b3; + border-top-color: #0077b3; + color: #ffffff; } -.jumpbox-cat-link:hover { - background-color: #12A3EB; - border-top-color: #12A3EB; - color: #FFFFFF; +.jumpbox-cat-link:hover, +.jumpbox-cat-link:focus { + background-color: #13a4ec; + border-top-color: #13a4ec; + color: #ffffff; } .jumpbox-forum-link { - background-color: #E1EBF2; + background-color: #dbe9f0; } .jumpbox-forum-link:hover { - background-color: #F6F4D0; + background-color: #fffbcc; } .jumpbox .dropdown .pointer-inner { - border-color: #E1EBF2 transparent; + border-color: #dbe9f0 transparent; } .jumpbox-sub-link { - background-color: #E1EBF2; + background-color: #dbe9f0; } .jumpbox-sub-link:hover { - background-color: #F1F8FF; + background-color: #e6f7ff; } -/* Miscellaneous styles ----------------------------------------- */ - +/* miscellaneous styles */ .copyright { - color: #555555; + color: #424242; } .error { - color: #BC2A4D; + color: #d41142; } .reported { - background-color: #F7ECEF; + background-color: #f7edf0; } li.reported:hover { - background-color: #ECD5D8 !important; + background-color: #f0dbe0 !important; } -.sticky, .announce { - /* you can add a background for stickies and announcements*/ + +.sticky, +.announce { + /* you can add a background for stickies and announcements */ } div.rules { - background-color: #ECD5D8; - color: #BC2A4D; + background-color: #f0dbe0; + color: #d41142; } p.post-notice { - background-color: #ECD5D8; + background-color: #f0dbe0; background-image: none; } -/* --------------------------------------------------------------- -Colours and backgrounds for content.css --------------------------------------------------------------- */ - +/* colours and backgrounds for content.css */ ul.forums { - background-color: #EEF5F9; /* Old browsers */ /* FF3.6+ */ - background-image: -webkit-linear-gradient(top, #D2E0EB 0%, #EEF5F9 100%); - background-image: linear-gradient(to bottom, #D2E0EB 0%,#EEF5F9 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#D2E0EB', endColorstr='#EEF5F9',GradientType=0 ); /* IE6-9 */ + background-color: #edf4f7; + background-image: -webkit-gradient(linear, left top, left bottom, from(#b8d3e0), to(#edf4f7)); + background-image: linear-gradient(to bottom, #b8d3e0 0%, #edf4f7 100%); } -ul.topiclist li { - color: #4C5D77; +ul.topiclist > li { + color: #47536b; } ul.topiclist dd { - border-left-color: #FFFFFF; + border-left-color: #ffffff; } .rtl ul.topiclist dd { - border-right-color: #FFFFFF; + border-right-color: #ffffff; border-left-color: transparent; } li.row { - border-top-color: #FFFFFF; - border-bottom-color: #00608F; + border-top-color: #ffffff; + border-bottom-color: #0077b3; } li.row strong { @@ -348,150 +344,143 @@ li.row strong { } li.row:hover { - background-color: #F6F4D0; + background-color: #fffbcc; } li.row:hover dd { - border-left-color: #CCCCCC; + border-left-color: #dedede; } .rtl li.row:hover dd { - border-right-color: #CCCCCC; + border-right-color: #dedede; border-left-color: transparent; } -li.header dt, li.header dd { - color: #FFFFFF; +li.header dt, +li.header dd { + color: #ffffff; } -/* Post body styles -----------------------------------------*/ +/* post body styles */ .postbody { - color: #333333; + color: #212121; } -/* Content container styles -----------------------------------------*/ +/* content container styles */ .content { - color: #333333; + color: #212121; } -.content h2, .panel h2 { - color: #115098; - border-bottom-color: #CCCCCC; +.content h2, +.panel h2 { + border-bottom-color: #dedede; + color: #0059b3; } dl.faq dt { - color: #333333; + color: #212121; } .posthilit { - background-color: #F3BFCC; - color: #BC2A4D; + background-color: #f4becb; + color: #d41142; } -.announce, .unreadpost { - /* Highlight the announcements & unread posts box */ +.announce, +.unreadpost { + /* highlight the announcements & unread posts box */ } -/* Post signature */ +/* post signature */ .signature { - border-top-color: #CCCCCC; + border-top-color: #dedede; } -/* Post noticies */ +/* post noticies */ .notice { - border-top-color: #CCCCCC; + border-top-color: #dedede; } -/* BB Code styles -----------------------------------------*/ -/* Quote block */ +/* bb code styles */ + +/* quote block */ blockquote { - background-color: #EBEADD; - border-color:#DBDBCE; + background-color: #f4f1d7; + border-color: #f1efda; } blockquote blockquote { - /* Nested quotes */ - background-color:#EFEED9; + /* nested quotes */ + background-color: #f7f4d4; } blockquote blockquote blockquote { - /* Nested quotes */ - background-color: #EBEADD; + /* nested quotes */ + background-color: #f4f1d7; } -/* Code block */ +/* code block */ .codebox { - background-color: #FFFFFF; - border-color: #C9D2D8; + background-color: #ffffff; + border-color: #c0d3dd; } .codebox p { - border-bottom-color: #CCCCCC; + border-bottom-color: #dedede; } .codebox code { - color: #2E8B57; + color: #4db355; } -/* Attachments -----------------------------------------*/ +/* attachments */ .attachbox { - background-color: #FFFFFF; - border-color: #C9D2D8; -} - -.pm-message .attachbox { - background-color: #F2F3F3; + background-color: #ffffff; + border-color: #c0d3dd; } .attachbox dd { - border-top-color: #C9D2D8; + border-top-color: #c0d3dd; } .attachbox p { - color: #666666; + color: #616161; } .attachbox p.stats { - color: #666666; + color: #616161; } .attach-image img { - border-color: #999999; + border-color: #9e9e9e; } -/* Inline image thumbnails */ - +/* inline image thumbnails */ dl.file dd { - color: #666666; + color: #616161; } dl.thumbnail img { - border-color: #666666; - background-color: #FFFFFF; + background-color: #ffffff; + border-color: #616161; } dl.thumbnail dd { - color: #666666; + color: #616161; } dl.thumbnail dt a:hover { - background-color: #EEEEEE; + background-color: #ededed; } dl.thumbnail dt a:hover img { - border-color: #368AD2; + border-color: #2d80d2; } -/* Post poll styles -----------------------------------------*/ - +/* post poll styles */ fieldset.polls dl { - border-top-color: #DCDEE2; - color: #666666; + border-top-color: #c9dee8; + color: #616161; } fieldset.polls dl.voted { @@ -499,472 +488,486 @@ fieldset.polls dl.voted { } fieldset.polls dd div { - color: #FFFFFF; + color: #ffffff; } -.rtl .pollbar1, .rtl .pollbar2, .rtl .pollbar3, .rtl .pollbar4, .rtl .pollbar5 { +.rtl .pollbar1, +.rtl .pollbar2, +.rtl .pollbar3, +.rtl .pollbar4, +.rtl .pollbar5 { border-right-color: transparent; } .pollbar1 { - background-color: #AA2346; - border-bottom-color: #74162C; - border-right-color: #74162C; + background-color: #b31a40; + border-right-color: #821732; + border-bottom-color: #821732; } .rtl .pollbar1 { - border-left-color: #74162C; + border-left-color: #821732; } .pollbar2 { - background-color: #BE1E4A; - border-bottom-color: #8C1C38; - border-right-color: #8C1C38; + background-color: #cf1745; + border-right-color: #9c1638; + border-bottom-color: #9c1638; } .rtl .pollbar2 { - border-left-color: #8C1C38; + border-left-color: #9c1638; } .pollbar3 { - background-color: #D11A4E; - border-bottom-color: #AA2346; - border-right-color: #AA2346; + background-color: #ec1349; + border-right-color: #cf1745; + border-bottom-color: #cf1745; } .rtl .pollbar3 { - border-left-color: #AA2346; + border-left-color: #cf1745; } .pollbar4 { - background-color: #E41653; - border-bottom-color: #BE1E4A; - border-right-color: #BE1E4A; + background-color: #f42559; + border-right-color: #ec1349; + border-bottom-color: #ec1349; } .rtl .pollbar4 { - border-left-color: #BE1E4A; + border-left-color: #ec1349; } .pollbar5 { - background-color: #F81157; - border-bottom-color: #D11A4E; - border-right-color: #D11A4E; + background-color: #fa3869; + border-right-color: #f42559; + border-bottom-color: #f42559; } .rtl .pollbar5 { - border-left-color: #D11A4E; + border-left-color: #f42559; } -/* Poster profile block -----------------------------------------*/ +/* poster profile block */ .postprofile { - color: #666666; - border-color: #FFFFFF; + border-color: #ffffff; + color: #616161; } .pm .postprofile { - border-color: #DDDDDD; + border-color: #dedede; } .postprofile strong { color: #000000; } -.online { - background-image: url("./en/icon_user_online.gif"); +dd.profile-warnings { + color: #d41142; } -dd.profile-warnings { - color: #BC2A4D; +/* Show scrollbars for items with overflow on iOS devices */ +.postbody .content::-webkit-scrollbar, +.topicreview::-webkit-scrollbar, +.post_details::-webkit-scrollbar, +.codebox code::-webkit-scrollbar, +.attachbox dd::-webkit-scrollbar, +.attach-image::-webkit-scrollbar, +.dropdown-extended ul::-webkit-scrollbar { + background: rgba(0, 0, 0, 0.1); +} + +.postbody .content::-webkit-scrollbar-thumb, +.topicreview::-webkit-scrollbar-thumb, +.post_details::-webkit-scrollbar-thumb, +.codebox code::-webkit-scrollbar-thumb, +.attachbox dd::-webkit-scrollbar-thumb, +.attach-image::-webkit-scrollbar-thumb, +.dropdown-extended ul::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.3); } -/* --------------------------------------------------------------- -Colours and backgrounds for buttons.css --------------------------------------------------------------- */ +/* colours and backgrounds for buttons.css */ .button { - border-color: #C7C3BF; - background-color: #E9E9E9; /* Old browsers */ /* FF3.6+ */ - background-image: -webkit-linear-gradient(top, #FFFFFF 0%, #E9E9E9 100%); - background-image: linear-gradient(to bottom, #FFFFFF 0%,#E9E9E9 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#E9E9E9',GradientType=0 ); /* IE6-9 */ - box-shadow: 0 0 0 1px #FFFFFF inset; - -webkit-box-shadow: 0 0 0 1px #FFFFFF inset; - color: #D31141; + background-color: #e0e0e0; + background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%); + border-color: #bdbdbd; + -webkit-box-shadow: 0 0 0 1px #ffffff inset; + box-shadow: 0 0 0 1px #ffffff inset; + color: #d41142; } .button:hover, .button:focus { - border-color: #0A8ED0; - background-color: #FFFFFF; /* Old browsers */ /* FF3.6+ */ - background-image: -webkit-linear-gradient(top, #E9E9E9 0%, #FFFFFF 100%); - background-image: linear-gradient(to bottom, #E9E9E9 0%,#FFFFFF 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E9E9E9', endColorstr='#FFFFFF',GradientType=0 ); /* IE6-9 */ - text-shadow: 1px 1px 0 #FFFFFF, -1px -1px 0 #FFFFFF, -1px -1px 0 rgba(188, 42, 77, 0.2); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e0e0e0), to(#ffffff)); + background-image: linear-gradient(to bottom, #e0e0e0 0%, #ffffff 100%); + border-color: #0077b3; + text-shadow: 1px 1px 0 #ffffff, -1px -1px 0 #ffffff, -1px -1px 0 rgba(189, 40, 77, 0.2); + color: #d41142; } - .button .icon, .button-secondary { - color: #8f8f8f; + color: #9e9e9e; +} + +.button-form, +.button-form-bold { + border-color: #757575; + -webkit-box-shadow: none; + box-shadow: none; + color: #212121; +} + +.button-form:hover, +.button-form-bold:hover { + border-color: #d41142; + text-shadow: none; + color: #d41142; +} + +.button-form:focus, +.button-form-bold:focus { + border-color: #0077b3; + text-shadow: none; + color: #0077b3; } .button-secondary:focus, .button-secondary:hover, .button:focus .icon, .button:hover .icon { - color: #0A8ED0; + color: #0077b3; } .button-search:hover, .button-search-end:hover { - border-color: #C7C3BF; + border-color: #bdbdbd; } -.caret { border-color: #DADADA; } -.caret { border-color: #C7C3BF; } +.caret { + border-color: #bdbdbd; +} -.contact-icons a { border-color: #DCDCDC; } -.contact-icons a:hover { background-color: #F2F6F9; } +.contact-icons a { + border-color: #dedede; +} -/* Pagination ----------------------------------------- */ +.contact-icons a:hover { + background-color: #ededed; +} +/* pagination */ .pagination li a { - background: #ECEDEE; + background: #ededed; + -webkit-filter: none; filter: none; - border-color: #B4BAC0; - box-shadow: none; + border-color: #bdbdbd; -webkit-box-shadow: none; - color: #5C758C; + box-shadow: none; + color: #9e9e9e; } .pagination li.ellipsis span { background: transparent; - color: #000000; + color: #000000; } .pagination li.active span { - background: #4692BF; - border-color: #4692BF; - color: #FFFFFF; + background: #2d80d2; + border-color: #2d80d2; + color: #ffffff; } -.pagination li a:hover, .pagination li a:hover .icon, .pagination .dropdown-visible a.dropdown-trigger, .nojs .pagination .dropdown-container:hover a.dropdown-trigger { - background: #368AD2; - border-color: #368AD2; - filter: none; - color: #FFFFFF; +.pagination li a:hover, +.pagination li a:hover .icon, +.pagination .dropdown-visible a.dropdown-trigger, +.nojs .pagination .dropdown-container:hover a.dropdown-trigger { + background: #2d80d2; + border-color: #2d80d2; text-shadow: none; + color: #ffffff; } -/* Search box ---------------------------------------------- */ - +/* search box */ .search-box .inputbox, .search-box .inputbox:hover, .search-box .inputbox:focus { - border-color: #C7C3BF; + border-color: #bdbdbd; } .search-header { - box-shadow: 0 0 10px #0075B0; -} - -/* Icon images ----------------------------------------- */ - -.contact-icon { background-image: url("./images/icons_contact.png"); } - -/* Profile & navigation icons */ -.pm-icon { background-position: 0 0; } -.email-icon { background-position: -21px 0; } -.jabber-icon { background-position: -80px 0; } -.phpbb_icq-icon { background-position: -61px 0 ; } -.phpbb_wlm-icon { background-position: -182px 0; } -.phpbb_aol-icon { background-position: -244px 0; } -.phpbb_website-icon { background-position: -40px 0; } -.phpbb_youtube-icon { background-position: -98px 0; } -.phpbb_facebook-icon { background-position: -119px 0; } -.phpbb_googleplus-icon { background-position: -140px 0; } -.phpbb_skype-icon { background-position: -161px 0; } -.phpbb_twitter-icon { background-position: -203px 0; } -.phpbb_yahoo-icon { background-position: -224px 0; } - -/* Forum icons & Topic icons */ -.global_read { background-image: url("./images/announce_read.gif"); } -.global_read_mine { background-image: url("./images/announce_read_mine.gif"); } -.global_read_locked { background-image: url("./images/announce_read_locked.gif"); } -.global_read_locked_mine { background-image: url("./images/announce_read_locked_mine.gif"); } -.global_unread { background-image: url("./images/announce_unread.gif"); } -.global_unread_mine { background-image: url("./images/announce_unread_mine.gif"); } -.global_unread_locked { background-image: url("./images/announce_unread_locked.gif"); } -.global_unread_locked_mine { background-image: url("./images/announce_unread_locked_mine.gif"); } - -.announce_read { background-image: url("./images/announce_read.gif"); } -.announce_read_mine { background-image: url("./images/announce_read_mine.gif"); } -.announce_read_locked { background-image: url("./images/announce_read_locked.gif"); } -.announce_read_locked_mine { background-image: url("./images/announce_read_locked_mine.gif"); } -.announce_unread { background-image: url("./images/announce_unread.gif"); } -.announce_unread_mine { background-image: url("./images/announce_unread_mine.gif"); } -.announce_unread_locked { background-image: url("./images/announce_unread_locked.gif"); } -.announce_unread_locked_mine { background-image: url("./images/announce_unread_locked_mine.gif"); } - -.forum_link { background-image: url("./images/forum_link.gif"); } -.forum_read { background-image: url("./images/forum_read.gif"); } -.forum_read_locked { background-image: url("./images/forum_read_locked.gif"); } -.forum_read_subforum { background-image: url("./images/forum_read_subforum.gif"); } -.forum_unread { background-image: url("./images/forum_unread.gif"); } -.forum_unread_locked { background-image: url("./images/forum_unread_locked.gif"); } -.forum_unread_subforum { background-image: url("./images/forum_unread_subforum.gif"); } - -.sticky_read { background-image: url("./images/sticky_read.gif"); } -.sticky_read_mine { background-image: url("./images/sticky_read_mine.gif"); } -.sticky_read_locked { background-image: url("./images/sticky_read_locked.gif"); } -.sticky_read_locked_mine { background-image: url("./images/sticky_read_locked_mine.gif"); } -.sticky_unread { background-image: url("./images/sticky_unread.gif"); } -.sticky_unread_mine { background-image: url("./images/sticky_unread_mine.gif"); } -.sticky_unread_locked { background-image: url("./images/sticky_unread_locked.gif"); } -.sticky_unread_locked_mine { background-image: url("./images/sticky_unread_locked_mine.gif"); } - -.topic_moved { background-image: url("./images/topic_moved.gif"); } -.pm_read, -.topic_read { background-image: url("./images/topic_read.gif"); } -.topic_read_mine { background-image: url("./images/topic_read_mine.gif"); } -.topic_read_hot { background-image: url("./images/topic_read_hot.gif"); } -.topic_read_hot_mine { background-image: url("./images/topic_read_hot_mine.gif"); } -.topic_read_locked { background-image: url("./images/topic_read_locked.gif"); } -.topic_read_locked_mine { background-image: url("./images/topic_read_locked_mine.gif"); } -.pm_unread, -.topic_unread { background-image: url("./images/topic_unread.gif"); } -.topic_unread_mine { background-image: url("./images/topic_unread_mine.gif"); } -.topic_unread_hot { background-image: url("./images/topic_unread_hot.gif"); } -.topic_unread_hot_mine { background-image: url("./images/topic_unread_hot_mine.gif"); } -.topic_unread_locked { background-image: url("./images/topic_unread_locked.gif"); } -.topic_unread_locked_mine { background-image: url("./images/topic_unread_locked_mine.gif"); } + -webkit-box-shadow: 0 0 10px #0077b3; + box-shadow: 0 0 10px #0077b3; +} + +/* icon images */ +.site_logo { background-image: url("./images/site_logo.gif"); } +.contact-icon { background-image: url("./images/icons_contact.png"); } + +/* profile icons */ +.pm-icon { background-position: 0 0; } +.email-icon { background-position: -21px 0; } +.jabber-icon { background-position: -80px 0; } +.phpbb_icq-icon { background-position: -61px 0; } +.phpbb_wlm-icon { background-position: -182px 0; } +.phpbb_aol-icon { background-position: -244px 0; } +.phpbb_website-icon { background-position: -40px 0; } +.phpbb_youtube-icon { background-position: -98px 0; } +.phpbb_facebook-icon { background-position: -119px 0; } +.phpbb_googleplus-icon { background-position: -140px 0; } +.phpbb_skype-icon { background-position: -161px 0; } +.phpbb_twitter-icon { background-position: -203px 0; } +.phpbb_yahoo-icon { background-position: -224px 0; } + +/* forum icons & topic icons */ +.global_read { background-image: url("./images/announce_read.gif"); } +.global_read_mine { background-image: url("./images/announce_read_mine.gif"); } +.global_read_locked { background-image: url("./images/announce_read_locked.gif"); } +.global_read_locked_mine { background-image: url("./images/announce_read_locked_mine.gif"); } +.global_unread { background-image: url("./images/announce_unread.gif"); } +.global_unread_mine { background-image: url("./images/announce_unread_mine.gif"); } +.global_unread_locked { background-image: url("./images/announce_unread_locked.gif"); } +.global_unread_locked_mine { background-image: url("./images/announce_unread_locked_mine.gif"); } + +.announce_read { background-image: url("./images/announce_read.gif"); } +.announce_read_mine { background-image: url("./images/announce_read_mine.gif"); } +.announce_read_locked { background-image: url("./images/announce_read_locked.gif"); } +.announce_read_locked_mine { background-image: url("./images/announce_read_locked_mine.gif"); } +.announce_unread { background-image: url("./images/announce_unread.gif"); } +.announce_unread_mine { background-image: url("./images/announce_unread_mine.gif"); } +.announce_unread_locked { background-image: url("./images/announce_unread_locked.gif"); } +.announce_unread_locked_mine { background-image: url("./images/announce_unread_locked_mine.gif"); } + +.forum_link { background-image: url("./images/forum_link.gif"); } +.forum_read { background-image: url("./images/forum_read.gif"); } +.forum_read_locked { background-image: url("./images/forum_read_locked.gif"); } +.forum_read_subforum { background-image: url("./images/forum_read_subforum.gif"); } +.forum_unread { background-image: url("./images/forum_unread.gif"); } +.forum_unread_locked { background-image: url("./images/forum_unread_locked.gif"); } +.forum_unread_subforum { background-image: url("./images/forum_unread_subforum.gif"); } + +.sticky_read { background-image: url("./images/sticky_read.gif"); } +.sticky_read_mine { background-image: url("./images/sticky_read_mine.gif"); } +.sticky_read_locked { background-image: url("./images/sticky_read_locked.gif"); } +.sticky_read_locked_mine { background-image: url("./images/sticky_read_locked_mine.gif"); } +.sticky_unread { background-image: url("./images/sticky_unread.gif"); } +.sticky_unread_mine { background-image: url("./images/sticky_unread_mine.gif"); } +.sticky_unread_locked { background-image: url("./images/sticky_unread_locked.gif"); } +.sticky_unread_locked_mine { background-image: url("./images/sticky_unread_locked_mine.gif"); } +.pm_read, +.topic_read { background-image: url("./images/topic_read.gif"); } +.topic_moved { background-image: url("./images/topic_moved.gif"); } +.topic_read_mine { background-image: url("./images/topic_read_mine.gif"); } +.topic_read_hot { background-image: url("./images/topic_read_hot.gif"); } +.topic_read_hot_mine { background-image: url("./images/topic_read_hot_mine.gif"); } +.topic_read_locked { background-image: url("./images/topic_read_locked.gif"); } +.topic_read_locked_mine { background-image: url("./images/topic_read_locked_mine.gif"); } -/* --------------------------------------------------------------- -Colours and backgrounds for cp.css --------------------------------------------------------------- */ +.pm_unread, +.topic_unread { background-image: url("./images/topic_unread.gif"); } +.topic_unread_mine { background-image: url("./images/topic_unread_mine.gif"); } +.topic_unread_hot { background-image: url("./images/topic_unread_hot.gif"); } +.topic_unread_hot_mine { background-image: url("./images/topic_unread_hot_mine.gif"); } +.topic_unread_locked { background-image: url("./images/topic_unread_locked.gif"); } +.topic_unread_locked_mine { background-image: url("./images/topic_unread_locked_mine.gif"); } -/* Main CP box -----------------------------------------*/ +/* colours and backgrounds for cp.css */ -.panel-container h3, .panel-container hr, .cp-menu hr { - border-color: #A4B3BF; +/* main cp box */ +.panel-container h3, +.panel-container hr, +.cp-menu hr { + border-color: #c9dee8; } .panel-container .panel li.row { - border-bottom-color: #B5C1CB; - border-top-color: #F9F9F9; + border-top-color: #fafafa; + border-bottom-color: #c9dee8; } ul.cplist { - border-top-color: #B5C1CB; + border-top-color: #c9dee8; } -.panel-container .panel li.header dd, .panel-container .panel li.header dt { +.panel-container .panel li.header dd, +.panel-container .panel li.header dt { color: #000000; } .panel-container table.table1 thead th { - color: #333333; - border-bottom-color: #333333; + border-bottom-color: #212121; + color: #212121; } -.cp-main .pm-message { - border-color: #DBDEE2; - background-color: #FFFFFF; -} - -/* CP tabbed menu -----------------------------------------*/ +/* cp tabbed menu */ .tabs .tab > a { - background: #BACCD9; - color: #536482; + background: #c0d3dd; + color: #47536b; } .tabs .tab > a:hover { - background: #DDEDFB; - color: #D31141; + background: #e6f7ff; + color: #d41142; } -.tabs .activetab > a, -.tabs .activetab > a:hover { - background-color: #CADCEB; /* Old browsers */ /* FF3.6+ */ - background-image: -webkit-linear-gradient(top, #E2F2FF 0%, #CADCEB 100%); - background-image: linear-gradient(to bottom, #E2F2FF 0%,#CADCEB 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E2F2FF', endColorstr='#CADCEB',GradientType=0 ); /* IE6-9 */ - border-color: #CADCEB; - box-shadow: 0 1px 1px #F2F9FF inset; - color: #333333; +/* responsive tabs */ +.responsive-tab .responsive-tab-link:before { + border-color: #47536b; } +.responsive-tab .responsive-tab-link:hover:before { + border-color: #d41142; +} + +.tabs .activetab > a, .tabs .activetab > a:hover { - color: #000000; + background-color: #c9dee8; + background-image: -webkit-gradient(linear, left top, left bottom, from(#e6f7ff), to(#c9dee8)); + background-image: linear-gradient(to bottom, #e6f7ff 0%, #c9dee8 100%); + border-color: #c9dee8; + -webkit-box-shadow: 0 1px 1px #e6f7ff inset; + box-shadow: 0 1px 1px #e6f7ff inset; + color: #212121; } -/* Mini tabbed menu used in MCP -----------------------------------------*/ +/* mini tabbed menu used in mcp */ .minitabs .tab > a { - background-color: #E1EBF2; + background-color: #dbe9f0; } .minitabs .activetab > a, .minitabs .activetab > a:hover { - background-color: #F9F9F9; - color: #333333; + background-color: #fafafa; + color: #212121; } -/* Responsive tabs -----------------------------------------*/ -.responsive-tab .responsive-tab-link:before { - border-color: #536482; -} +/* ucp navigation menu */ -.responsive-tab .responsive-tab-link:hover:before { - border-color: #D31141; -} - -/* UCP navigation menu -----------------------------------------*/ - -/* Link styles for the sub-section links */ +/* link styles for the sub-section links */ .navigation a { - color: #333; - background: #CADCEB; /* Old browsers */ /* FF3.6+ */ - background: -webkit-linear-gradient(left, #B4C4D1 50%, #CADCEB 100%); - background: linear-gradient(to right, #B4C4D1 50%,#CADCEB 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#B4C4D1', endColorstr='#CADCEB',GradientType=1 ); /* IE6-9 */ + background: #c0d3dd; + background-image: -webkit-gradient(linear, left top, right top, color-stop(50%, #aab9c0), to(#c0d3dd)); + background-image: linear-gradient(to right, #aab9c0 50%, #c0d3dd 100%); + color: #212121; } .rtl .navigation a { - background: #B4C4D1; /* Old browsers */ /* FF3.6+ */ - background: -webkit-linear-gradient(left, #CADCEB 50%, #B4C4D1 100%); - background: linear-gradient(to right, #CADCEB 50%,#B4C4D1 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#CADCEB', endColorstr='#B4C4D1',GradientType=1 ); /* IE6-9 */ + background: #afc5cf; + background-image: -webkit-gradient(linear, left top, right top, color-stop(50%, #c0d3dd), to(#aab9c0)); + background-image: linear-gradient(to right, #c0d3dd 50%, #aab9c0 100%); } .navigation a:hover { - background: #AABAC6; - color: #BC2A4D; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background: #aab9c0; + color: #d41142; } .navigation .active-subsection a { - background: #F9F9F9; - color: #D31141; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background: #fafafa; + color: #d41142; } .navigation .active-subsection a:hover { - color: #D31141; -} - -@media only screen and (max-width: 900px), only screen and (max-device-width: 900px) -{ - #navigation a, .rtl #navigation a { - background: #B2C2CF; - } + color: #d41142; } -/* Preferences pane layout -----------------------------------------*/ +/* preferences pane layout */ .panel-container h2 { - color: #333333; + color: #212121; } .panel-container .panel { - background-color: #F9F9F9; + background-color: #fafafa; } .cp-main .pm { - background-color: #FFFFFF; + background-color: #ffffff; } -/* Friends list */ +/* friends list */ .cp-mini { - background-color: #EEF5F9; + background-color: #edf4f7; } dl.mini dt { - color: #425067; + color: #47536b; } -/* PM Styles -----------------------------------------*/ -/* PM Message history */ +/* pm styles */ + +/* pm message history */ .current { color: #000000 !important; } -/* PM marking colours */ -.pmlist li.pm_message_reported_colour, .pm_message_reported_colour { - border-left-color: #BC2A4D; - border-right-color: #BC2A4D; +/* pm marking colours */ +.pmlist li.pm_message_reported_colour, +.pm_message_reported_colour { + border-right-color: #ec1349; + border-left-color: #ec1349; } -.pmlist li.pm_marked_colour, .pm_marked_colour { - border-color: #FF6600; +.pmlist li.pm_marked_colour, +.pm_marked_colour { + border-color: #ff9500; } -.pmlist li.pm_replied_colour, .pm_replied_colour { - border-color: #A9B8C2; +.pmlist li.pm_replied_colour, +.pm_replied_colour { + border-color: #a3b8c2; } -.pmlist li.pm_friend_colour, .pm_friend_colour { - border-color: #5D8FBD; +.pmlist li.pm_friend_colour, +.pm_friend_colour { + border-color: #4582a1; } -.pmlist li.pm_foe_colour, .pm_foe_colour { +.pmlist li.pm_foe_colour, +.pm_foe_colour { border-color: #000000; } -/* Avatar gallery */ +/* avatar gallery */ .gallery label { - background: #FFFFFF; - border-color: #CCC; + background: #ffffff; + border-color: #dedede; } .gallery label:hover { - background-color: #EEE; + background-color: #ededed; } -/* --------------------------------------------------------------- -Colours and backgrounds for forms.css --------------------------------------------------------------- */ +/* colours and backgrounds for forms.css */ -/* General form styles -----------------------------------------*/ +/* general form styles */ select { - border-color: #666666; - background-color: #FAFAFA; - color: #000; + background-color: #fafafa; + border-color: #616161; + color: #000000; } label { - color: #425067; + color: #47536b; } option.disabled-option { - color: graytext; + color: #7f7f7f; } -/* Definition list layout for forms ----------------------------------------- */ +/* definition list layout for forms */ dd label { - color: #333; + color: #212121; } fieldset.fields1 { background-color: transparent; } -/* Hover effects */ +/* hover effects */ fieldset dl:hover dt label { color: #000000; } @@ -973,191 +976,178 @@ fieldset.fields2 dl:hover dt label { color: inherit; } -/* Quick-login on index page */ -fieldset.quick-login input.inputbox { - background-color: #F2F3F3; -} - -/* Posting page styles -----------------------------------------*/ - +/* posting page styles */ .message-box textarea { - color: #333333; + color: #212121; } .message-box textarea.drag-n-drop { - outline-color: rgba(102, 102, 102, 0.5); + outline-color: rgba(97, 97, 97, 0.5); } .message-box textarea.drag-n-drop-highlight { - outline-color: rgba(17, 163, 234, 0.5); + outline-color: rgba(19, 164, 236, 0.5); } -/* Input field styles ----------------------------------------- */ +/* input field styles */ .inputbox { - background-color: #FFFFFF; - border-color: #B4BAC0; - color: #333333; + background-color: #ffffff; + border-color: #bdbdbd; + color: #212121; } -.inputbox:-moz-placeholder { - color: #333333; +.inputbox:-moz-placeholder, +.inputbox::-webkit-input-placeholder { + color: #212121; } -.inputbox::-webkit-input-placeholder { - color: #333333; +.inputbox:hover, +.inputbox:focus { + border-color: #13a4ec; } -.inputbox:hover { - border-color: #11A3EA; +.inputbox:focus:-moz-placeholder, +.inputbox:focus::-webkit-input-placeholder { + color: transparent; } -.inputbox:focus { - border-color: #11A3EA; +input.disabled { + color: #616161; } -.inputbox:focus:-moz-placeholder { - color: transparent; +/* jquery popups */ +.phpbb_alert { + background-color: #ffffff; + border-color: #9e9e9e; } -.inputbox:focus::-webkit-input-placeholder { - color: transparent; +.darken { + background-color: #000000; } +/* stylelint-disable at-rule-no-vendor-prefix */ -/* Form button styles ----------------------------------------- */ +@-webkit-keyframes colors { + 0% { + stroke: #4285f4; + } -a.button1, input.button1, input.button3, a.button2, input.button2 { - color: #000; - background-color: #EFEFEF; /* Old browsers */ /* FF3.6+ */ - background-image: -webkit-linear-gradient(top, #D2D2D2 0%, #EFEFEF 100%); - background-image: linear-gradient(to bottom, #D2D2D2 0%,#EFEFEF 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#D2D2D2', endColorstr='#EFEFEF',GradientType=0 ); /* IE6-9 */ -} + 25% { + stroke: #de3e35; + } -a.button1, input.button1 { - border-color: #666666; -} + 50% { + stroke: #f7c223; + } -input.button3 { - background-image: none; -} + 75% { + stroke: #1b9a59; + } -/* Alternative button */ -a.button2, input.button2, input.button3 { - border-color: #666666; + 100% { + stroke: #4285f4; + } } -/* button in the style of the form buttons */ -a.button1, a.button2 { - color: #000000; -} +/* stylelint-enable at-rule-no-vendor-prefix */ -/* Hover states */ -a.button1:hover, input.button1:hover, a.button2:hover, input.button2:hover, input.button3:hover { - border-color: #D31141; - color: #D31141; - background-color: #D2D2D2; /* Old browsers */ /* FF3.6+ */ - background-image: -webkit-linear-gradient(top, #EFEFEF 0%, #D2D2D2 100%); - background-image: linear-gradient(to bottom, #EFEFEF 0%,#D2D2D2 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#EFEFEF', endColorstr='#D2D2D2',GradientType=0 ); /* IE6-9 */ -} -/* Focus states */ -input.button1:focus, input.button2:focus, input.button3:focus { - border-color: #11A3EA; - color: #0F4987; -} +@keyframes colors { + 0% { + stroke: #4285f4; + } -input.disabled { - color: #666666; -} + 25% { + stroke: #de3e35; + } -/* jQuery popups ----------------------------------------- */ -.phpbb_alert { - background-color: #FFFFFF; - border-color: #999999; -} -.darken { - background-color: #000000; -} + 50% { + stroke: #f7c223; + } -.loading_indicator { - background-color: #000000; - background-image: url("./images/loading.gif"); + 75% { + stroke: #1b9a59; + } + + 100% { + stroke: #4285f4; + } } -.dropdown-extended ul li { - border-top-color: #B9B9B9; +.dropdown-extended .dropdown-extended-item { + border-top-color: #bdbdbd; } -.dropdown-extended ul li:hover { - background-color: #CFE1F6; +.dropdown-extended .dropdown-extended-item:hover { + background-color: #d4e6f7; color: #000000; } -.dropdown-extended .header, .dropdown-extended .footer { - border-color: #B9B9B9; +.dropdown-extended a.mark_read { + background-color: #ffffff; +} + +.dropdown-extended .header, +.dropdown-extended .footer { + border-color: #bdbdbd; color: #000000; } .dropdown-extended .footer { - border-top-style: solid; border-top-width: 1px; + border-top-style: solid; } .dropdown-extended .header { - background-color: #F1F8FF; /* Old browsers */ /* FF3.6+ */ - background-image: -webkit-linear-gradient(top, #F1F8FF 0%, #CADCEB 100%); - background-image: linear-gradient(to bottom, #F1F8FF 0%,#CADCEB 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F1F8FF', endColorstr='#CADCEB',GradientType=0 ); /* IE6-9 */ + background-color: #e6f7ff; + background-image: -webkit-gradient(linear, left top, left bottom, from(#e6f7ff), to(#c9dee8)); + background-image: linear-gradient(to bottom, #e6f7ff 0%, #c9dee8 100%); } .dropdown .pointer { - border-color: #B9B9B9 transparent; + border-color: #bdbdbd transparent; } .dropdown .pointer-inner { - border-color: #FFF transparent; + border-color: #ffffff transparent; } -.dropdown-extended .pointer-inner { - border-color: #F1F8FF transparent; +.dropdown-extended-pointer .pointer-inner { + border-color: #e6f7ff transparent; } .dropdown .dropdown-contents { - background: #fff; - border-color: #B9B9B9; + background: #ffffff; + border-color: #bdbdbd; + -webkit-box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2); box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2); } .dropdown-up .dropdown-contents { + -webkit-box-shadow: 1px 0 5px rgba(0, 0, 0, 0.2); box-shadow: 1px 0 5px rgba(0, 0, 0, 0.2); } -.dropdown li, .dropdown li li { - border-color: #DCDCDC; +.dropdown li, +.dropdown li li { + border-color: #dedede; } .dropdown li.separator { - border-color: #DCDCDC; + border-color: #dedede; } -/* Notifications ----------------------------------------- */ - -.notification_list p.notification-time { - color: #4C5D77; +/* notifications */ +.notification-time { + color: #47536b; } -li.notification-reported strong, li.notification-disapproved strong { - color: #D31141; +.notification-reported strong, +.notification-disapproved strong { + color: #d41142; } .badge { - background-color: #D31141; + background-color: #d41142; color: #ffffff; } diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 348355e8c4b..f5c6f848099 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -1,64 +1,69 @@ -/* General Markup Styles ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Common +/* -------------------------------------------------------------- */ +/* stylelint-disable selector-max-compound-selectors */ +/* stylelint-disable selector-no-qualifying-type */ + html { font-size: 100%; + /* Always show a scrollbar for short pages - stops the jump when the scrollbar appears. non-IE browsers */ height: 101%; } body { font-family: Verdana, Helvetica, Arial, sans-serif; - font-size: 10px; + font-size: 16px; line-height: normal; + word-wrap: break-word; margin: 0; padding: 12px 0; - word-wrap: break-word; -webkit-print-color-adjust: exact; } h1 { /* Forum name */ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - margin-right: 200px; - margin-top: 15px; + font-size: 20px; font-weight: bold; - font-size: 2em; + margin-top: 15px; + margin-right: 200px; } h2 { /* Forum header titles */ font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; + font-size: 20px; font-weight: normal; - font-size: 2em; - margin: 0.8em 0 0.2em 0; + margin: 0.8em 0 0.2em; } h2.solo { - margin-bottom: 1em; + margin-bottom: 20px; } h3 { /* Sub-headers (also used as post headers, but defined later) */ font-family: Arial, Helvetica, sans-serif; + font-size: 12px; font-weight: bold; text-transform: uppercase; border-bottom: 1px solid transparent; + margin-top: 20px; margin-bottom: 3px; padding-bottom: 2px; - font-size: 1.05em; - margin-top: 20px; } h4 { /* Forum and topic list titles */ - font-family: "Trebuchet MS", Verdana, Helvetica, Arial, Sans-serif; - font-size: 1.3em; + font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; + font-size: 13px; } p { - line-height: 1.3em; - font-size: 1.1em; - margin-bottom: 1.5em; + font-size: 11px; + line-height: 14px; + margin-bottom: 16px; } img { @@ -68,10 +73,10 @@ img { hr { border: 0 solid transparent; border-top-width: 1px; - height: 1px; - margin: 5px 0; display: block; clear: both; + height: 1px; + margin: 5px 0; } hr.dashed { @@ -88,12 +93,13 @@ p.right { } p.jumpbox-return { + float: left; margin-top: 10px; margin-bottom: 0; - float: left; } -b, strong { +b, +strong { font-weight: bold; } @@ -101,7 +107,8 @@ b, strong { font-weight: bold; } -i, em { +i, +em { font-style: italic; } @@ -125,36 +132,36 @@ li { display: list-item; } -ul ul, ol ul { +ul ul, +ol ul { list-style-type: circle; } -ol ol ul, ol ul ul, ul ol ul, ul ul ul { +ol ol ul, +ol ul ul, +ul ol ul, +ul ul ul { list-style-type: square; } -a:hover { text-decoration: underline; } +a:hover { + text-decoration: underline; +} /* Main blocks ---------------------------------------- */ .wrap { border: 1px solid transparent; border-radius: 8px; - margin: 0 auto; - max-width: 1152px; min-width: 625px; + max-width: 1152px; + margin: 0 auto; padding: 15px; } -@media only screen and (max-width: 1220px), only screen and (max-device-width: 1220px) { - .wrap { - margin: 0 12px; - } -} - .page-body { - margin: 4px 0; clear: both; + margin: 4px 0; } .page-footer { @@ -194,51 +201,51 @@ a:hover { text-decoration: underline; } /* Round cornered boxes and backgrounds ---------------------------------------- */ .headerbar { + border-radius: 7px; margin-bottom: 4px; padding: 5px; - border-radius: 7px; } .navbar { - padding: 3px 10px; border-radius: 7px; + padding: 3px 10px; } .forabg { + border-radius: 7px; + clear: both; margin-bottom: 4px; padding: 5px; - clear: both; - border-radius: 7px; } .forumbg { + border-radius: 7px; + clear: both; margin-bottom: 4px; padding: 5px; - clear: both; - border-radius: 7px; } .panel { + border-radius: 7px; margin-bottom: 4px; padding: 5px 10px; - border-radius: 7px; } .post { - padding: 5px 10px; - margin-bottom: 4px; background-repeat: no-repeat; background-position: 100% 0; border-radius: 7px; position: relative; + margin-bottom: 4px; + padding: 5px 10px; } .rowbg { - margin: 5px 5px 2px 5px; + margin: 5px 5px 2px; } /* Horizontal lists -----------------------------------------*/ +---------------------------------------- */ .navbar ul.linklist { padding: 2px 0; list-style-type: none; @@ -254,20 +261,22 @@ ul.linklist { } ul.linklist > li { + font-size: 11px; + line-height: 24px; float: left; - font-size: 1.1em; - line-height: 2.2em; - list-style-type: none; + width: auto; margin-right: 7px; padding-top: 1px; - width: auto; + list-style-type: none; } -ul.linklist > li.rightside, p.rightside, a.rightside { +ul.linklist > li.rightside, +p.rightside, +a.rightside { + text-align: right; float: right; margin-right: 0; margin-left: 7px; - text-align: right; } ul.navlinks { @@ -275,17 +284,17 @@ ul.navlinks { } ul.leftside { + text-align: left; float: left; - margin-left: 0; margin-right: 5px; - text-align: left; + margin-left: 0; } ul.rightside { + text-align: right; float: right; - margin-left: 5px; margin-right: -5px; - text-align: right; + margin-left: 5px; } ul.linklist li.responsive-menu { @@ -293,7 +302,8 @@ ul.linklist li.responsive-menu { margin: 0 5px 0 0; } -.hasjs ul.linklist.leftside, .hasjs ul.linklist.rightside { +.hasjs ul.linklist.leftside, +.hasjs ul.linklist.rightside { max-width: 48%; } @@ -314,18 +324,18 @@ ul.linklist .dropdown { } ul.linklist .dropdown-up .dropdown { - bottom: 18px; top: auto; + bottom: 18px; } /* Bulletin icons for list items -----------------------------------------*/ +---------------------------------------- */ ul.linklist.bulletin > li:before { - display: inline-block; - content: "\2022"; font-size: inherit; line-height: inherit; + display: inline-block; padding-right: 4px; + content: "\2022"; } ul.linklist.bulletin > li:first-child:before, @@ -343,8 +353,8 @@ ul.linklist.bulletin > li.no-bulletin:before { /* Profile in overall_header.html */ .header-profile { - display: inline-block; vertical-align: top; + display: inline-block; } a.header-avatar, @@ -353,23 +363,23 @@ a.header-avatar:hover { } a.header-avatar img { - margin-bottom: 2px; - max-height: 20px; vertical-align: middle; width: auto; + max-height: 20px; + margin-bottom: 2px; } a.header-avatar span:after { - content: '\f0dd'; - display: inline-block; font: normal normal normal 14px/1 FontAwesome; - padding-left: 6px; - padding-top: 2px; vertical-align: top; + display: inline-block; + padding-top: 2px; + padding-left: 6px; + content: "\f0dd"; } /* Dropdown menu -----------------------------------------*/ +---------------------------------------- */ .dropdown-container { position: relative; } @@ -387,15 +397,15 @@ a.header-avatar span:after { } .dropdown { - display: none; - position: absolute; - left: 0; - top: 1.2em; - z-index: 2; border: 1px solid transparent; border-radius: 5px; - padding: 9px 0 0; + position: absolute; + z-index: 2; + top: 1.2em; + left: 0; + display: none; margin-right: -500px; + padding: 9px 0 0; } .dropdown.live-search { @@ -412,11 +422,12 @@ a.header-avatar span:after { padding: 0 0 9px; } -.dropdown-left .dropdown, .nojs .rightside .dropdown { - left: auto; +.dropdown-left .dropdown, +.nojs .rightside .dropdown { right: 0; - margin-left: -500px; + left: auto; margin-right: 0; + margin-left: -500px; } .dropdown-button-control .dropdown { @@ -428,38 +439,42 @@ a.header-avatar span:after { bottom: 24px; } -.dropdown .pointer, .dropdown .pointer-inner { - position: absolute; - width: 0; - height: 0; +.dropdown .pointer, +.dropdown .pointer-inner { border-top-width: 0; + border-right: 10px dashed transparent; border-bottom: 10px solid transparent; border-left: 10px dashed transparent; - border-right: 10px dashed transparent; - -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */ + position: absolute; display: block; + width: 0; + height: 0; + -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */ + transform: rotate(360deg); } -.dropdown-up .pointer, .dropdown-up .pointer-inner { - border-bottom-width: 0; +.dropdown-up .pointer, +.dropdown-up .pointer-inner { border-top: 10px solid transparent; + border-bottom-width: 0; } .dropdown .pointer { + z-index: 3; + top: -1px; right: auto; left: 10px; - top: -1px; - z-index: 3; } .dropdown-up .pointer { - bottom: -1px; top: auto; + bottom: -1px; } -.dropdown-left .dropdown .pointer, .nojs .rightside .dropdown .pointer { - left: auto; +.dropdown-left .dropdown .pointer, +.nojs .rightside .dropdown .pointer { right: 10px; + left: auto; } .dropdown .pointer-inner { @@ -469,19 +484,19 @@ a.header-avatar span:after { } .dropdown-up .pointer-inner { - bottom: auto; top: -11px; + bottom: auto; } .dropdown .dropdown-contents { - z-index: 2; - overflow: hidden; - overflow-y: auto; border: 1px solid transparent; border-radius: 5px; - padding: 5px; position: relative; + z-index: 2; + overflow: hidden; + overflow-y: auto; max-height: 300px; + padding: 5px; } .dropdown-contents a { @@ -497,13 +512,9 @@ a.header-avatar span:after { border-top: 1px solid transparent; } -.jumpbox .dropdown-select { - margin: 0; -} - .jumpbox .dropdown-contents { - padding: 0; text-decoration: none; + padding: 0; } .jumpbox .dropdown-contents li { @@ -511,44 +522,35 @@ a.header-avatar span:after { } .jumpbox .dropdown-contents a { - margin-right: 20px; - padding: 5px 10px; text-decoration: none; width: 100%; + margin-right: 20px; + padding: 5px 10px; } .jumpbox .spacer { display: inline-block; - width: 0px; + width: 0; } .jumpbox .spacer + .spacer { width: 20px; } -.dropdown-contents a { - display: block; - padding: 5px; -} - .jumpbox .dropdown-select { margin: 0; } -.jumpbox .dropdown-contents a { - text-decoration: none; -} - .dropdown li { - display: list-item; + font-size: 11px !important; + line-height: normal !important; + text-align: left; + white-space: nowrap; border-top: 1px dotted transparent; + display: list-item; float: none !important; - line-height: normal !important; - font-size: 1em !important; - list-style: none; margin: 0; - white-space: nowrap; - text-align: left; + list-style: none; } .dropdown-contents > li { @@ -559,7 +561,9 @@ a.header-avatar span:after { padding-right: 0; } -.dropdown li:first-child, .dropdown li.separator + li, .dropdown li li { +.dropdown li:first-child, +.dropdown li.separator + li, +.dropdown li li { border-top: 0; } @@ -576,7 +580,9 @@ a.header-avatar span:after { padding-left: 18px; } -.wrap .dropdown li, .dropdown.wrap li, .dropdown-extended li { +.wrap .dropdown li, +.dropdown.wrap li, +.dropdown-extended li { white-space: normal; } @@ -585,22 +591,23 @@ a.header-avatar span:after { padding: 0; } -.dropdown li.separator:first-child, .dropdown li.separator:last-child { +.dropdown li.separator:first-child, +.dropdown li.separator:last-child { display: none !important; } /* Responsive breadcrumbs -----------------------------------------*/ +---------------------------------------- */ .breadcrumbs .crumb { - float: left; font-weight: bold; word-wrap: normal; + float: left; } .breadcrumbs .crumb:before { - content: '\2039'; font-weight: bold; padding: 0 0.5em; + content: "\2039"; } .breadcrumbs .crumb:first-child:before { @@ -608,24 +615,46 @@ a.header-avatar span:after { } .breadcrumbs .crumb a { + vertical-align: bottom; white-space: nowrap; text-overflow: ellipsis; - vertical-align: bottom; overflow: hidden; } -.breadcrumbs.wrapped .crumb a { letter-spacing: -.3px; } -.breadcrumbs.wrapped .crumb.wrapped-medium a { letter-spacing: -.4px; } -.breadcrumbs.wrapped .crumb.wrapped-tiny a { letter-spacing: -.5px; } +.breadcrumbs.wrapped .crumb a { + letter-spacing: -0.019em; +} + +.breadcrumbs.wrapped .crumb.wrapped-medium a { + letter-spacing: -0.025em; +} -.breadcrumbs .crumb.wrapped-max a { max-width: 120px; } -.breadcrumbs .crumb.wrapped-wide a { max-width: 100px; } -.breadcrumbs .crumb.wrapped-medium a { max-width: 80px; } -.breadcrumbs .crumb.wrapped-small a { max-width: 60px; } -.breadcrumbs .crumb.wrapped-tiny a { max-width: 40px; } +.breadcrumbs.wrapped .crumb.wrapped-tiny a { + letter-spacing: -0.031em; +} + +.breadcrumbs .crumb.wrapped-max a { + max-width: 120px; +} + +.breadcrumbs .crumb.wrapped-wide a { + max-width: 100px; +} + +.breadcrumbs .crumb.wrapped-medium a { + max-width: 80px; +} + +.breadcrumbs .crumb.wrapped-small a { + max-width: 60px; +} + +.breadcrumbs .crumb.wrapped-tiny a { + max-width: 40px; +} /* Table styles -----------------------------------------*/ +---------------------------------------- */ table.table1 { width: 100%; } @@ -635,10 +664,10 @@ table.table1 { } table.table1 thead th { + font-size: 10px; font-weight: normal; + line-height: 13px; text-transform: uppercase; - line-height: 1.3em; - font-size: 1em; padding: 0 0 4px 3px; } @@ -651,32 +680,72 @@ table.table1 tbody tr { } table.table1 td { - font-size: 1.1em; + font-size: 11px; } table.table1 tbody td { - padding: 5px; border-top: 1px solid transparent; + padding: 5px; } table.table1 tbody th { - padding: 5px; - border-bottom: 1px solid transparent; text-align: left; + border-bottom: 1px solid transparent; + padding: 5px; } /* Specific column styles */ -table.table1 .name { text-align: left; } -table.table1 .center { text-align: center; } -table.table1 .reportby { width: 15%; } -table.table1 .posts { text-align: center; width: 7%; } -table.table1 .joined { text-align: left; width: 15%; } -table.table1 .active { text-align: left; width: 15%; } -table.table1 .mark { text-align: center; width: 7%; } -table.table1 .info { text-align: left; width: 30%; } -table.table1 .info div { width: 100%; white-space: normal; overflow: hidden; } -table.table1 .autocol { line-height: 2em; white-space: nowrap; } -table.table1 thead .autocol { padding-left: 1em; } +table.table1 .name { + text-align: left; +} + +table.table1 .center { + text-align: center; +} + +table.table1 .reportby { + width: 15%; +} + +table.table1 .posts { + text-align: center; + width: 7%; +} + +table.table1 .joined { + text-align: left; + width: 15%; +} + +table.table1 .active { + text-align: left; + width: 15%; +} + +table.table1 .mark { + text-align: center; + width: 7%; +} + +table.table1 .info { + text-align: left; + width: 30%; +} + +table.table1 .info div { + white-space: normal; + overflow: hidden; + width: 100%; +} + +table.table1 .autocol { + line-height: 22px; + white-space: nowrap; +} + +table.table1 thead .autocol { + padding-left: 10px; +} table.table1 span.rank-img { float: right; @@ -688,10 +757,10 @@ table.info td { } table.info tbody th { - padding: 3px; + font-weight: normal; text-align: right; vertical-align: top; - font-weight: normal; + padding: 3px; } .forumbg table.table1 { @@ -703,12 +772,13 @@ table.info tbody th { } .color_palette_placeholder table { - border-collapse: separate; border-spacing: 1px; + border-collapse: separate; } /* Misc layout styles ---------------------------------------- */ + /* column[1-2] styles are containers for two column layouts */ .column1 { float: left; @@ -724,9 +794,9 @@ table.info tbody th { /* General classes for placing floating blocks */ .left-box { + text-align: left; float: left; width: auto; - text-align: left; max-width: 100%; } @@ -735,53 +805,56 @@ table.info tbody th { } .right-box { + text-align: right; float: right; width: auto; - text-align: right; max-width: 100%; } dl.details { - /*font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;*/ - font-size: 1.1em; + font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; + font-size: 11px; } dl.details dt { + text-align: right; + display: block; float: left; clear: left; width: 30%; - text-align: right; - display: block; } dl.details dd { - margin-left: 0; - padding-left: 5px; - margin-bottom: 5px; + text-overflow: ellipsis; float: left; - width: 65%; overflow: hidden; - text-overflow: ellipsis; + width: 65%; + margin-bottom: 5px; + margin-left: 0; + padding-left: 5px; } -.clearfix, fieldset dl, ul.topiclist dl, dl.polls { +.clearfix, +fieldset dl, +ul.topiclist dl, +dl.polls { overflow: hidden; } fieldset.fields1 ul.recipients { - list-style-type: none; line-height: 1.8; - max-height: 150px; overflow-y: auto; + max-height: 150px; + list-style-type: none; } fieldset.fields1 dd.recipients { clear: left; - margin-left: 1em; + margin-left: 11px; } -fieldset.fields1 ul.recipients input.button2{ - font-size: 0.8em; +fieldset.fields1 ul.recipients input.button2 { + font-size: 12px; margin-right: 0; padding: 0; } @@ -802,12 +875,12 @@ fieldset.fields1 dl.pmlist dd.recipients { } .forabg + .action-bar { - margin-top: 2em; + margin-top: 12px; } .action-bar .button { - margin-right: 5px; float: left; + margin-right: 5px; } .action-bar .button-search { @@ -817,8 +890,8 @@ fieldset.fields1 dl.pmlist dd.recipients { /* Pagination ---------------------------------------- */ .pagination { - float: right; text-align: right; + float: right; width: auto; } @@ -827,39 +900,40 @@ fieldset.fields1 dl.pmlist dd.recipients { } .action-bar .pagination .button { - margin-right: 0; float: none; + margin-right: 0; } .pagination > ul { display: inline-block; - list-style: none !important; margin-left: 5px; + list-style: none; } .pagination > ul > li { - display: inline-block !important; - padding: 0; font-size: 100%; line-height: normal; vertical-align: middle; + display: inline-block; + padding: 0; } -.pagination li a, .pagination li span { +.pagination li a, +.pagination li span { border-radius: 2px; padding: 2px 5px; } .pagination li.active span { - display: inline-block; + font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica; font-size: 13px; font-weight: normal; - font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica; line-height: 1.4; text-align: center; - white-space: nowrap; vertical-align: middle; + white-space: nowrap; border: 1px solid transparent; + display: inline-block; } .pagination li.ellipsis span { @@ -877,6 +951,7 @@ fieldset.fields1 dl.pmlist dd.recipients { .pagination li.page-jump a i { font-size: 21px; + line-height: 21px; } .pagination .arrow a { @@ -894,38 +969,32 @@ fieldset.fields1 dl.pmlist dd.recipients { margin: 0; } -.row .pagination li a, .row .pagination li span { +.row .pagination li a, +.row .pagination li span { + font-size: 9px; border-radius: 2px; padding: 1px 3px; - font-size: 9px; } /* jQuery popups ---------------------------------------- */ .phpbb_alert { border: 1px solid transparent; - display: none; - left: 0; - padding: 0 25px 20px 25px; position: fixed; - right: 0; - top: 150px; z-index: 50; + top: 150px; + right: 0; + left: 0; + display: none; width: 620px; margin: 0 auto; -} - -@media only screen and (max-height: 500px), only screen and (max-device-width: 500px) -{ - .phpbb_alert { - top: 25px; - } + padding: 0 25px 20px; } .phpbb_alert .alert_close { float: right; - margin-right: -36px; margin-top: -8px; + margin-right: -36px; } .phpbb_alert p { @@ -944,49 +1013,128 @@ fieldset.fields1 dl.pmlist dd.recipients { .phpbb_alert div.alert_text > select, .phpbb_alert div.alert_text > textarea, .phpbb_alert div.alert_text > input { - font-size: 1.1em; + font-size: 11px; } .darkenwrapper { - display: none; position: relative; z-index: 44; + display: none; } .darken { + opacity: 0.5; position: fixed; - left: 0; + z-index: 45; top: 0; + left: 0; width: 100%; height: 100%; - opacity: 0.5; - z-index: 45; } .loading_indicator { - background: center center no-repeat; - border-radius: 5px; - display: none; - opacity: 0.8; - margin-top: -50px; - margin-left: -50px; - height: 50px; - width: 50px; position: fixed; - left: 50%; - top: 50%; z-index: 51; + top: 50%; + left: 50%; + display: none; +} + +.loader { + width: 48px; + height: 48px; + padding: 12px; +} + +.spinner { + -webkit-animation: rotator 1s linear infinite; + animation: rotator 1s linear infinite; +} + +/* stylelint-disable no-unknown-animations */ +.spinner-path { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-animation: dash 1s ease-in-out infinite, colors 4s ease-in-out infinite; + animation: dash 1s ease-in-out infinite, colors 4s ease-in-out infinite; + stroke-dasharray: 187; + stroke-dashoffset: 0; } +/* stylelint-enable no-unknown-animations */ + +/* stylelint-disable at-rule-no-vendor-prefix */ +@-webkit-keyframes rotator { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -webkit-transform: rotate(270deg); + transform: rotate(270deg); + } +} + +@keyframes rotator { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -webkit-transform: rotate(270deg); + transform: rotate(270deg); + } +} + +@-webkit-keyframes dash { + 0% { + stroke-dashoffset: 187; + } + + 50% { + -webkit-transform: rotate(135deg); + transform: rotate(135deg); + stroke-dashoffset: 46.75; + } + + 100% { + -webkit-transform: rotate(450deg); + transform: rotate(450deg); + stroke-dashoffset: 187; + } +} + +@keyframes dash { + 0% { + stroke-dashoffset: 187; + } + + 50% { + -webkit-transform: rotate(135deg); + transform: rotate(135deg); + stroke-dashoffset: 46.75; + } + + 100% { + -webkit-transform: rotate(450deg); + transform: rotate(450deg); + stroke-dashoffset: 187; + } +} +/* stylelint-enable at-rule-no-vendor-prefix */ + /* Miscellaneous styles ---------------------------------------- */ .copyright { - padding: 5px; + font-size: 10px; text-align: center; + padding: 5px; } .small { - font-size: 0.9em !important; + font-size: 90% !important; } .titlespace { @@ -998,26 +1146,27 @@ fieldset.fields1 dl.pmlist dd.recipients { } .error { + font-size: 10px; font-weight: bold; - font-size: 1em; } div.rules { + font-size: 11px; + border-radius: 7px; margin: 10px 0; - font-size: 1.1em; padding: 5px 10px; - border-radius: 7px; } -div.rules ul, div.rules ol { +div.rules ul, +div.rules ol { margin-left: 20px; } p.post-notice { position: relative; - padding: 5px; min-height: 14px; - margin-bottom: 1em; + margin-bottom: 11px; + padding: 5px; } form > p.post-notice strong { @@ -1029,39 +1178,41 @@ form > p.post-notice strong { } .top-anchor { - display: block; position: absolute; top: -20px; + display: block; } .clear { - display: block; - clear: both; font-size: 1px; line-height: 1px; background: transparent; + display: block; + clear: both; } /* Inner box-model clearing */ .inner:after, ul.linklist:after, .action-bar:after, -.notification_text:after, +.notification-text:after, .tabs-container:after, .tabs > ul:after, .minitabs > ul:after, .postprofile .avatar-container:after { - clear: both; - content: ''; display: block; + clear: both; + content: ""; } +/* stylelint-disable declaration-property-unit-whitelist */ .emoji { - min-height: 18px; + width: 1em; min-width: 18px; height: 1em; - width: 1em; + min-height: 18px; } +/* stylelint-enable declaration-property-unit-whitelist */ .smilies { vertical-align: text-bottom; @@ -1078,45 +1229,44 @@ ul.linklist:after, } .member-search strong { - font-size: 0.95em; + font-size: 11px; } .dropdown-extended { - display: none; z-index: 1; + display: none; } -.dropdown-extended ul { - max-height: 350px; - overflow-y: auto; - overflow-x: hidden; +.dropdown-extended .dropdown-extended-list { clear: both; + overflow-x: hidden; + overflow-y: auto; + max-height: 350px; } -.dropdown-extended ul li { - padding: 0; - margin: 0 !important; - float: none; +.dropdown-extended .dropdown-extended-item { border-top: 1px solid; - list-style-type: none; - font-size: 0.95em; - clear: both; position: relative; + float: none; + clear: both; + margin: 0 !important; + padding: 0; + list-style-type: none; } -.dropdown-extended ul li:first-child { +.dropdown-extended .dropdown-extended-item:first-child { border-top: none; } -.dropdown-extended ul li.no_notifications { +.dropdown-extended .dropdown-extended-item.no-notifications { padding: 10px; } .dropdown-extended .dropdown-contents { - max-height: none; - padding: 0; position: absolute; width: 340px; + max-height: none; + padding: 0; } .nojs .dropdown-extended .dropdown-contents { @@ -1124,40 +1274,43 @@ ul.linklist:after, } .dropdown-extended .header { - padding: 0 10px; font-family: Arial, "Helvetica Neue", Helvetica, Arial, sans-serif; font-weight: bold; + line-height: 33px; text-align: left; - text-shadow: 1px 1px 1px white; text-transform: uppercase; - line-height: 3em; border-bottom: 1px solid; border-radius: 5px 5px 0 0; + + /* needs moved to colurs.css */ + text-shadow: 1px 1px 1px #ffffff; + padding: 0 10px; } -.dropdown-extended .header .header_settings { - float: right; +.dropdown-extended .header .header-settings { font-weight: normal; text-transform: none; + float: right; } -.dropdown-extended .header .header_settings a { +.dropdown-extended .header .header-settings a { display: inline-block; padding: 0 5px; } .dropdown-extended .header:after { - content: ''; display: table; clear: both; + content: ""; } .dropdown-extended .footer { + font-size: 12px; text-align: center; - font-size: 1.1em; } -.dropdown-extended ul li a, .dropdown-extended ul li.no-url { +.dropdown-extended .notification-block, +.dropdown-extended .dropdown-extended-item.no-url { padding: 8px; } @@ -1165,78 +1318,79 @@ ul.linklist:after, padding: 5px 0; } -.dropdown-extended ul li a, .notification_list dt > a, .dropdown-extended .footer > a { - display: block; +.dropdown-extended .dropdown-extended-item a, +.notification-menu dt > a, +.dropdown-extended .footer > a { text-decoration: none; + display: block; } -.notification_list ul li img { +.notification-avatar, +.notification-menu .notification-list .notification-item .avatar, +.notification-menu .notification-list .notification-item .gravatar { float: left; - max-height: 50px; - max-width: 50px; width: auto !important; + max-width: 50px; height: auto !important; + max-height: 50px; margin-right: 5px; } -.notification_list ul li p { +.notification-item p { margin-bottom: 4px; - font-size: 1em; } -.notification_list p.notification-reference, -.notification_list p.notification-location, -.notification_list li a p.notification-reason { - overflow: hidden; - text-overflow: ellipsis; +.notification-reference, +.notification-location, +.notification-reason { white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; } -.notification_list p.notification-time { - font-size: 0.9em; - margin: 0; +.notification-time { + font-size: 10px; text-align: right; + margin: 0; } -.notification_list div.notifications { +.notification-menu .notifications { margin-left: 50px; padding: 5px; } -.notification_list div.notifications a { +.notification-menu .notifications a { display: block; } -.notification_list p.notifications_title { +.notifications-title { font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 1.2em !important; + font-size: 13px !important; } -.notification_list p.notifications_title strong { +.notifications-title strong { font-weight: bold; } -.notification_list p.notifications_time { - font-size: 0.9em !important; +.notifications-time { + font-size: 10px !important; } -.notification_text { +.notification-text { margin-left: 58px; } .badge { - border-radius: 10px; - opacity: 0.8; - text-align: center; - white-space: nowrap; font-size: 10px; line-height: 1; - float: right; - display: inline-block; - margin-left: 3px; - vertical-align: baseline; + text-align: center; + white-space: nowrap; + border-radius: 10px; + opacity: 0.8; position: relative; top: 3px; + float: right; + margin-left: 3px; padding: 4px 6px; } @@ -1245,7 +1399,7 @@ ul.linklist:after, } /* Navbar specific list items -----------------------------------------*/ +---------------------------------------- */ .linklist .quick-links { margin: 0 7px 0 0; @@ -1274,3 +1428,6 @@ ul.linklist:after, .dropdown .clone.hidden + li { border-top: none; } + +/* stylelint-enable selector-max-compound-selectors */ +/* stylelint-enable selector-no-qualifying-type */ diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index 807633864ce..98a4a36c085 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -1,16 +1,20 @@ -/* Content Styles ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Content +/* -------------------------------------------------------------- */ + +/* stylelint-disable selector-max-compound-selectors */ +/* stylelint-disable selector-no-qualifying-type */ ul.topiclist { display: block; - list-style-type: none; margin: 0; + list-style-type: none; } -ul.topiclist li { +ul.topiclist > li { display: block; - list-style-type: none; margin: 0; + list-style-type: none; } ul.topiclist dl { @@ -21,15 +25,16 @@ ul.topiclist li.row dl { margin: 2px 0; } -ul.topiclist dt, ul.topiclist dd { +ul.topiclist dt, +ul.topiclist dd { display: block; float: left; } ul.topiclist dt { + font-size: 11px; width: 100%; margin-right: -440px; - font-size: 1.1em; } ul.topiclist.missing-column dt { @@ -46,8 +51,8 @@ ul.topiclist.two-columns dt { ul.topiclist dt .list-inner { margin-right: 440px; - padding-left: 5px; padding-right: 5px; + padding-left: 5px; } ul.topiclist.missing-column dt .list-inner { @@ -64,15 +69,14 @@ ul.topiclist.two-columns dt .list-inner { ul.topiclist dd { border-left: 1px solid transparent; - padding: 4px 0; -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; + padding: 4px 0; } ul.topiclist li.row dd { - padding: 4px 0 999px 0; margin-bottom: -995px; + padding: 4px 0 999px; } ul.topiclist dfn { @@ -84,8 +88,20 @@ ul.topiclist dfn { .forum-image { float: left; - padding-top: 5px; margin-right: 5px; + padding-top: 5px; +} + +.forum-desc { + display: block; +} + +.forum-mods { + display: block; +} + +.forum-subs { + display: block; } li.row { @@ -97,15 +113,16 @@ li.row strong { font-weight: normal; } -li.header dt, li.header dd { - line-height: 1em; +li.header dt, +li.header dd { + font-family: Arial, Helvetica, sans-serif; + font-size: 10px; + line-height: 10px; + text-transform: uppercase; border-left-width: 0; - margin: 2px 0 4px 0; + margin: 2px 0 4px; padding-top: 2px; padding-bottom: 2px; - font-size: 1em; - font-family: Arial, Helvetica, sans-serif; - text-transform: uppercase; } li.header dt { @@ -119,28 +136,29 @@ li.header dt .list-inner { } li.header dd { - padding-left: 1px; -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; + padding-left: 1px; } -li.header dl.row-item dt, li.header dl.row-item dd { +li.header dl.row-item dt, +li.header dl.row-item dd { min-height: 0; } li.header dl.row-item dt .list-inner { + padding-right: 50px; + /* Tweak for headers alignment when folder icon used */ padding-left: 0; - padding-right: 50px; } /* Forum list column styles */ .row .list-inner { padding: 4px 0; } dl.row-item { - background-position: 10px 50%; /* Position of folder icon */ background-repeat: no-repeat; + background-position: 10px 50%; /* Position of folder icon */ background-size: 32px; } @@ -154,7 +172,8 @@ dl.row-item dt .list-inner { padding-left: 52px; /* Space for folder icon */ } -dl.row-item dt, dl.row-item dd { +dl.row-item dt, +dl.row-item dd { min-height: 35px; } @@ -162,100 +181,117 @@ dl.row-item dt a { display: inline; } -dl a.row-item-link { /* topic row icon links */ - display: block; - width: 30px; - height: 30px; - padding: 0; +/* topic row icon links */ +dl a.row-item-link { position: absolute; top: 50%; left: 0; + display: block; + width: 30px; + height: 30px; margin-top: -15px; margin-left: 9px; + padding: 0; } -dd.posts, dd.topics, dd.views, dd.extra, dd.mark { - width: 80px; +dd.posts, +dd.topics, +dd.views, +dd.extra, +dd.mark { + font-size: 12px; + line-height: 26px; text-align: center; - line-height: 2.2em; - font-size: 1.2em; + width: 80px; } -dd.posts, dd.topics, dd.views { +dd.posts, +dd.topics, +dd.views { width: 95px; } /* List in forum description */ dl.row-item dt ol, dl.row-item dt ul { + margin-left: 10px; list-style-position: inside; - margin-left: 1em; } -dl.row-item dt li { +dl.row-item dt > ul li { display: list-item; list-style-type: inherit; } -dd.lastpost, dd.redirect, dd.moderation, dd.time, dd.info { +dd.lastpost, +dd.redirect, +dd.moderation, +dd.time, +dd.info { + font-size: 11px; width: 250px; - font-size: 1.1em; } dd.redirect { - line-height: 2.5em; + line-height: 26px; } dd.time { - line-height: 200%; + line-height: 22px; } -dd.lastpost > span, ul.topiclist dd.info > span, ul.topiclist dd.time > span, dd.redirect > span, dd.moderation > span { +dd.lastpost > span, +ul.topiclist dd.info > span, +ul.topiclist dd.time > span, +dd.redirect > span, +dd.moderation > span { display: block; padding-left: 5px; } -dd.extra, dd.mark { - line-height: 200%; +dd.extra, +dd.mark { + line-height: 24px; } dd.option { - width: 125px; - line-height: 200%; + font-size: 11px; + line-height: 22px; text-align: center; - font-size: 1.1em; + width: 125px; } /* Post body styles -----------------------------------------*/ +---------------------------------------- */ .postbody { - padding: 0; - line-height: 1.48em; - width: 76%; - float: left; + line-height: 16px; position: relative; + float: left; + width: 76%; + padding: 0; } .postbody .ignore { - font-size: 1.1em; + font-size: 11px; } .postbody h3.first { /* The first post on the page uses this */ - font-size: 1.7em; + font-size: 17px; } .postbody h3 { + font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; + font-size: 15px; + line-height: 19px; + text-transform: none; + border: none; + /* Postbody requires a different h3 format - so change it here */ float: left; - font-size: 1.5em; - padding: 2px 0 0 0; margin-top: 0 !important; - margin-bottom: 0.3em !important; - text-transform: none; - border: none; - font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; - line-height: 125%; + margin-bottom: 4px !important; + padding: 2px 0 0; } .postbody h3 img { @@ -269,38 +305,37 @@ dd.option { } .postbody .content { - font-size: 1.3em; + font-size: 13px; overflow-x: auto; } .postbody img.postimage { - max-width: 100%; -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; + max-width: 100%; } .search .postbody { - width: 68% + width: 68%; } /* Topic review panel -----------------------------------------*/ +---------------------------------------- */ .panel .review { - margin-top: 2em; + margin-top: 20px; } .topicreview { - padding-right: 5px; overflow: auto; height: 300px; + padding-right: 5px; } .topicreview .postbody { - width: auto; float: none; - margin: 0; + width: auto; height: auto; + margin: 0; } .topicreview .post { @@ -316,7 +351,7 @@ dd.option { } /* MCP Post details -----------------------------------------*/ +---------------------------------------- */ .post_details { /* This will only work in IE7+, plus the others */ overflow: auto; @@ -324,24 +359,25 @@ dd.option { } /* Content container styles -----------------------------------------*/ +---------------------------------------- */ .content { + font-family: "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; + font-size: 10px; + line-height: 14px; clear: both; - min-height: 3em; overflow: hidden; - line-height: 1.4em; - font-family: "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; - font-size: 1em; + min-height: 30px; padding-bottom: 1px; } -.content h2, .panel h2 { +.content h2, +.panel h2 { + font-size: 16px; font-weight: normal; border-bottom: 1px solid transparent; - font-size: 1.6em; - margin-top: 0.5em; - margin-bottom: 0.5em; - padding-bottom: 0.5em; + margin-top: 8px; + margin-bottom: 8px; + padding-bottom: 8px; } .panel h3 { @@ -349,24 +385,21 @@ dd.option { } .panel p { - font-size: 1.2em; - margin-bottom: 1em; - line-height: 1.4em; + font-size: 12px; + line-height: 16px; + margin-bottom: 12px; } .content p { font-family: "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; - font-size: 1.2em; - margin-bottom: 1em; - line-height: 1.4em; } dl.faq { font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; - font-size: 1.1em; - margin-top: 1em; - margin-bottom: 2em; - line-height: 1.4em; + font-size: 11px; + line-height: 15px; + margin-top: 11px; + margin-bottom: 22px; } dl.faq dt { @@ -374,42 +407,43 @@ dl.faq dt { } .content dl.faq { - font-size: 1.2em; - margin-bottom: 0.5em; + font-size: 12px; + margin-bottom: 6px; } .content li { list-style-type: inherit; } -.content ul, .content ol { +.content ul, +.content ol { margin: 0.8em 0 0.9em 3em; } .posthilit { - padding: 0 2px 1px 2px; + padding: 0 2px 1px; } /* Post author */ p.author { - margin-bottom: 0.6em; - padding: 0 0 5px 0; font-family: Verdana, Helvetica, Arial, sans-serif; - font-size: 1em; - line-height: 1.2em; + font-size: 10px; + line-height: 12px; clear: both; + margin-bottom: 8px; + padding: 0 0 5px; } /* Post signature */ .signature { - margin-top: 1.5em; - padding-top: 0.2em; - font-size: 1.1em; + font-size: 11px; + line-height: 16px; border-top: 1px solid transparent; clear: left; - line-height: 140%; overflow: hidden; width: 100%; + margin-top: 16px; + padding-top: 2px; } .signature.standalone { @@ -418,75 +452,72 @@ p.author { } dd .signature { + border: none; + clear: none; margin: 0; padding: 0; - clear: none; - border: none; } .signature li { list-style-type: inherit; } -.signature ul, .signature ol { - margin: 0.8em 0 0.9em 3em; +.signature ul, +.signature ol { + margin: 10px 0 10px 33px; } /* Post noticies */ .notice { font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; - width: auto; - margin-top: 1.5em; - padding-top: 0.2em; - font-size: 1em; + font-size: 10px; + line-height: 13px; border-top: 1px dashed transparent; clear: left; - line-height: 130%; + width: auto; + margin-top: 15px; + padding-top: 2px; } /* Jump to post link for now */ ul.searchresults { - list-style: none; text-align: right; clear: both; + list-style: none; } /* BB Code styles -----------------------------------------*/ +---------------------------------------- */ + /* Quote block */ blockquote { border: 1px solid transparent; - font-size: 0.95em; - margin: 1em 1px 1em 25px; overflow: hidden; + margin: 10px 1px 10px 25px; padding: 5px; } blockquote blockquote { /* Nested quotes */ - font-size: 1em; - margin: 1em 1px 1em 15px; + margin: 10px 1px 10px 15px; } blockquote cite { + font-weight: bold; + /* Username/source of quoter */ font-style: normal; - font-weight: bold; display: block; - font-size: 0.9em; -} - -blockquote cite cite { - font-size: 1em; } -blockquote cite:before, .uncited:before { +blockquote cite:before, +.uncited:before { padding-right: 5px; } blockquote cite > div { - float: right; font-weight: normal; + float: right; } .postbody .content li blockquote { @@ -496,20 +527,20 @@ blockquote cite > div { /* Code block */ .codebox { - border: 1px solid transparent; - font-size: 1em; - margin: 1em 0 1.2em 0; + font-size: 13px; word-wrap: normal; + border: 1px solid transparent; + margin: 13px 0 16px; } .codebox p { + font-size: 10px !important; + font-weight: bold; text-transform: uppercase; border-bottom: 1px solid transparent; + display: block; margin-bottom: 0; padding: 3px; - font-size: 0.8em !important; - font-weight: bold; - display: block; } blockquote .codebox { @@ -517,29 +548,28 @@ blockquote .codebox { } .codebox code { - overflow: auto; + font: 12px Monaco, "Andale Mono", "Courier New", Courier, monospace; + line-height: 15px; display: block; + overflow: auto; height: auto; max-height: 200px; padding: 5px 3px; - font: 0.9em Monaco, "Andale Mono","Courier New", Courier, monospace; - line-height: 1.3em; } /* Attachments -----------------------------------------*/ +---------------------------------------- */ .attachbox { font-size: 13px; + border: 1px dashed transparent; float: left; + clear: left; + -webkit-box-sizing: border-box; + box-sizing: border-box; width: auto; max-width: 100%; margin: 5px 5px 5px 0; padding: 6px; - border: 1px dashed transparent; - clear: left; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; } .attachbox dt { @@ -548,11 +578,11 @@ blockquote .codebox { } .attachbox dd { - margin-top: 4px; - padding-top: 4px; - clear: left; border-top: 1px solid transparent; + clear: left; overflow-x: auto; + margin-top: 4px; + padding-top: 4px; } .attachbox dd dd { @@ -560,31 +590,32 @@ blockquote .codebox { } .attachbox p { - line-height: 110%; font-weight: normal; + line-height: 12px; clear: left; } -.attachbox p.stats -{ - line-height: 110%; +.attachbox p.stats { font-weight: normal; + line-height: 12px; clear: left; } .attach-image { - margin: 3px 0; max-width: 100%; + margin: 3px 0; } .attach-image img { border: 1px solid transparent; -/* cursor: move; */ + + /* cursor: move; */ cursor: default; } /* Inline image thumbnails */ -div.inline-attachment dl.thumbnail, div.inline-attachment dl.file { +div.inline-attachment dl.thumbnail, +div.inline-attachment dl.file { display: block; margin-bottom: 4px; } @@ -599,11 +630,11 @@ dl.file { } dl.file dt { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-weight: bold; text-transform: none; margin: 0; padding: 0; - font-weight: bold; - font-family: Verdana, Arial, Helvetica, sans-serif; } dl.file dd { @@ -612,14 +643,15 @@ dl.file dd { } dl.thumbnail img { - padding: 3px; border: 1px solid transparent; + -webkit-box-sizing: border-box; box-sizing: border-box; + padding: 3px; } dl.thumbnail dd { - font-style: italic; font-family: Verdana, Arial, Helvetica, sans-serif; + font-style: italic; } .attachbox dl.thumbnail dd { @@ -631,16 +663,16 @@ dl.thumbnail dt a:hover img { } /* Post poll styles -----------------------------------------*/ +---------------------------------------- */ fieldset.polls { font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; } fieldset.polls dl { - margin-top: 5px; + line-height: 13px; border-top: 1px solid transparent; - padding: 5px 0 0 0; - line-height: 120%; + margin-top: 5px; + padding: 5px 0 0; } fieldset.polls dl.voted { @@ -648,23 +680,23 @@ fieldset.polls dl.voted { } fieldset.polls dt { + font-size: 11px; text-align: left; - float: left; + border-right: none; display: block; + float: left; width: 30%; - border-right: none; - padding: 0; margin: 0; - font-size: 1.1em; + padding: 0; } fieldset.polls dd { + font-size: 11px; + border-left: none; float: left; width: 10%; - border-left: none; - padding: 0 5px; margin-left: 0; - font-size: 1.1em; + padding: 0 5px; } fieldset.polls dd.resultbar { @@ -676,59 +708,66 @@ fieldset.polls dd input { } fieldset.polls dd div { - text-align: right; font-family: Arial, Helvetica, sans-serif; font-weight: bold; - padding: 2px 2px 0 2px; + text-align: right; overflow: visible; min-width: 8px; + padding: 2px 2px 0; } -.pollbar1, .pollbar2, .pollbar3, .pollbar4, .pollbar5 { - border-bottom: 1px solid transparent; +.pollbar1, +.pollbar2, +.pollbar3, +.pollbar4, +.pollbar5 { border-right: 1px solid transparent; + border-bottom: 1px solid transparent; } .vote-submitted { - font-size: 1.2em; + font-size: 12px; font-weight: bold; text-align: center; } /* Poster profile block -----------------------------------------*/ +---------------------------------------- */ .postprofile { - margin: 5px 0 10px 0; - min-height: 80px; border: 1px solid transparent; border-width: 0 0 0 1px; - width: 22%; float: right; - display: inline; + width: 22%; + min-height: 80px; + margin: 5px 0 10px; } -.postprofile dd, .postprofile dt { - line-height: 1.2em; +.postprofile dd, +.postprofile dt { + font-size: 10px; + line-height: 12px; margin-left: 8px; } .postprofile dd { - overflow: hidden; text-overflow: ellipsis; + overflow: hidden; } .postprofile strong { font-weight: normal; } -.postprofile dt.no-profile-rank, .postprofile dd.profile-rank, .postprofile .search-result-date { +.postprofile dt.no-profile-rank, +.postprofile dd.profile-rank, +.postprofile .search-result-date { margin-bottom: 10px; } /* Post-profile avatars */ .postprofile .has-avatar .avatar-container { - margin-bottom: 3px; overflow: hidden; + margin-bottom: 3px; } .postprofile .avatar { @@ -739,8 +778,8 @@ fieldset.polls dd div { .postprofile .avatar img { display: block; - height: auto !important; max-width: 100%; + height: auto !important; } .postprofile .profile-posts a { @@ -767,13 +806,7 @@ dd.profile-contact { margin-right: -14px; } -.online { - background-image: none; - background-position: 100% 0; - background-repeat: no-repeat; -} - -/* Poster profile used by search*/ +/* Poster profile used by search */ .search .postprofile { width: 30%; } @@ -793,8 +826,8 @@ dl.pmlist dt textarea { } dl.pmlist dd { - margin-left: 61% !important; margin-bottom: 2px; + margin-left: 61% !important; } .action-bar div.dl_links { @@ -802,8 +835,8 @@ dl.pmlist dd { } div.dl_links { - display: inline-block; text-transform: none; + display: inline-block; } .dl_links strong { @@ -811,9 +844,9 @@ div.dl_links { } .dl_links ul { - list-style-type: none; - margin: 0; display: inline-block; + margin: 0; + list-style-type: none; } .dl_links li { @@ -825,10 +858,10 @@ div.dl_links { } .ellipsis-text { + white-space: nowrap; + text-overflow: ellipsis; display: inline-block; overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; } table.fixed-width-table { @@ -836,20 +869,37 @@ table.fixed-width-table { } /* Show scrollbars for items with overflow on iOS devices -----------------------------------------*/ -.postbody .content::-webkit-scrollbar, .topicreview::-webkit-scrollbar, .post_details::-webkit-scrollbar, .codebox code::-webkit-scrollbar, .attachbox dd::-webkit-scrollbar, .attach-image::-webkit-scrollbar, .dropdown-extended ul::-webkit-scrollbar { +---------------------------------------- */ +.postbody .content::-webkit-scrollbar, +.topicreview::-webkit-scrollbar, +.post_details::-webkit-scrollbar, +.codebox code::-webkit-scrollbar, +.attachbox dd::-webkit-scrollbar, +.attach-image::-webkit-scrollbar, +.dropdown-extended ul::-webkit-scrollbar { + border-radius: 3px; width: 8px; height: 8px; -webkit-appearance: none; - background: rgba(0, 0, 0, .1); - border-radius: 3px; } -.postbody .content::-webkit-scrollbar-thumb, .topicreview::-webkit-scrollbar-thumb, .post_details::-webkit-scrollbar-thumb, .codebox code::-webkit-scrollbar-thumb, .attachbox dd::-webkit-scrollbar-thumb, .attach-image::-webkit-scrollbar-thumb, .dropdown-extended ul::-webkit-scrollbar-thumb { - background: rgba(0, 0, 0, .3); +.postbody .content::-webkit-scrollbar-thumb, +.topicreview::-webkit-scrollbar-thumb, +.post_details::-webkit-scrollbar-thumb, +.codebox code::-webkit-scrollbar-thumb, +.attachbox dd::-webkit-scrollbar-thumb, +.attach-image::-webkit-scrollbar-thumb, +.dropdown-extended ul::-webkit-scrollbar-thumb { border-radius: 3px; } -#memberlist tr.inactive, #team tr.inactive { +/* Factor out this ID */ +/* stylelint-disable selector-no-id */ +.memberlist tr.inactive, +.team tr.inactive { font-style: italic; } +/* stylelint-enable selector-no-id */ + +/* stylelint-enable selector-max-compound-selectors */ +/* stylelint-enable selector-no-qualifying-type */ diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css index d54c9483430..11ca6dd10c1 100644 --- a/phpBB/styles/prosilver/theme/cp.css +++ b/phpBB/styles/prosilver/theme/cp.css @@ -1,13 +1,16 @@ -/* Control Panel Styles ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Contorl Panel +/* -------------------------------------------------------------- */ +/* stylelint-disable selector-max-compound-selectors */ +/* stylelint-disable selector-no-qualifying-type */ /* Main CP box -----------------------------------------*/ +---------------------------------------- */ .cp-menu { - float:left; + float: left; width: 19%; - margin-top: 1em; + margin-top: 10px; margin-bottom: 5px; } @@ -21,30 +24,31 @@ } .panel-container .panel p { - font-size: 1.1em; + font-size: 11px; } .panel-container .panel ol { - margin-left: 2em; - font-size: 1.1em; + font-size: 11px; + margin-left: 22px; } .panel-container .panel li.row { - border-bottom: 1px solid transparent; border-top: 1px solid transparent; + border-bottom: 1px solid transparent; } ul.cplist { - margin-bottom: 5px; border-top: 1px solid transparent; + margin-bottom: 5px; } -.panel-container .panel li.header dd, .panel-container .panel li.header dt { +.panel-container .panel li.header dd, +.panel-container .panel li.header dt { margin-bottom: 2px; } .panel-container table.table1 { - margin-bottom: 1em; + margin-bottom: 10px; } .panel-container table.table1 thead th { @@ -61,21 +65,22 @@ ul.cplist { .cp-main .pm-message { border: 1px solid transparent; - margin: 10px 0; - width: auto; float: none; + width: auto; + margin: 10px 0; } .pm-message h2 { padding-bottom: 5px; } -.cp-main .postbody h3, .cp-main .box2 h3 { +.cp-main .postbody h3, +.cp-main .box2 h3 { margin-top: 0; } .panel-container .postbody p.author { - font-size: 1.1em; + font-size: 11px; } .cp-main .buttons { @@ -93,41 +98,45 @@ ul.cplist { .tabs-container h2 { float: left; - margin-bottom: 0px; + margin-bottom: 0; } /* CP tabs shared -----------------------------------------*/ -.tabs, .minitabs { +---------------------------------------- */ +.tabs, +.minitabs { line-height: normal; } -.tabs > ul, .minitabs > ul { - list-style: none; +.tabs > ul, +.minitabs > ul { + position: relative; margin: 0; padding: 0; - position: relative; + list-style: none; } -.tabs .tab, .minitabs .tab { +.tabs .tab, +.minitabs .tab { + font-size: 10px; + font-weight: bold; + line-height: 14px; display: block; float: left; - font-size: 1em; - font-weight: bold; - line-height: 1.4em; } -.tabs .tab > a, .minitabs .tab > a { +.tabs .tab > a, +.minitabs .tab > a { + white-space: nowrap; + text-decoration: none; + position: relative; display: block; padding: 5px 9px; - position: relative; - text-decoration: none; - white-space: nowrap; cursor: pointer; } /* CP tabbed menu -----------------------------------------*/ +---------------------------------------- */ .tabs { margin: 20px 0 0 7px; } @@ -144,11 +153,11 @@ ul.cplist { } /* Mini tabbed menu used in MCP -----------------------------------------*/ +---------------------------------------- */ .minitabs { float: right; - margin: 15px 7px 0 0; max-width: 50%; + margin: 15px 7px 0 0; } .minitabs .tab { @@ -165,45 +174,47 @@ ul.cplist { } /* Responsive tabs -----------------------------------------*/ +---------------------------------------- */ .responsive-tab { position: relative; } .responsive-tab > a.responsive-tab-link { - display: block; - font-size: 1.6em; + font-size: 16px; + line-height: 14px; + text-decoration: none; position: relative; + display: block; width: 16px; - line-height: 0.9em; - text-decoration: none; } .responsive-tab .responsive-tab-link:before { - content: ''; + border-top: 6px double rgba(0, 0, 0, 0); + border-bottom: 2px solid rgba(0, 0, 0, 0); position: absolute; - left: 10px; top: 7px; - height: .125em; + left: 10px; width: 14px; - border-bottom: 0.125em solid transparent; - border-top: 0.375em double transparent; + height: 2px; + content: ""; } -.tabs .dropdown, .minitabs .dropdown { +.tabs .dropdown, +.minitabs .dropdown { + font-size: 11px; + font-weight: normal; top: 20px; margin-right: -2px; - font-size: 1.1em; - font-weight: normal; } .minitabs .dropdown { margin-right: -4px; } -.tabs .dropdown-up .dropdown, .minitabs .dropdown-up .dropdown { - bottom: 20px; +.tabs .dropdown-up .dropdown, +.minitabs .dropdown-up .dropdown { top: auto; + bottom: 20px; } .tabs .dropdown li { @@ -215,7 +226,8 @@ ul.cplist { } /* UCP navigation menu -----------------------------------------*/ +---------------------------------------- */ + /* Container for sub-navigation list */ .navigation { width: 100%; @@ -228,18 +240,19 @@ ul.cplist { /* Default list state */ .navigation li { - display: inline; font-weight: bold; + display: inline; margin: 1px 0; padding: 0; } /* Link styles for the sub-section links */ .navigation a { + font-size: 10px; + text-decoration: none; display: block; - padding: 5px; margin: 1px 0; - text-decoration: none; + padding: 5px; } .navigation a:hover { @@ -247,20 +260,21 @@ ul.cplist { } /* Preferences pane layout -----------------------------------------*/ +---------------------------------------- */ .cp-main h2 { border-bottom: none; - padding: 0; margin-left: 10px; + padding: 0; } /* Friends list */ .cp-mini { - margin: 10px 15px 10px 5px; - max-height: 200px; + font-size: 10px; + border-radius: 7px; overflow-y: auto; + max-height: 200px; + margin: 10px 15px 10px 5px; padding: 5px 10px; - border-radius: 7px; } dl.mini dt { @@ -280,14 +294,15 @@ dl.mini dd { } /* PM Styles -----------------------------------------*/ +---------------------------------------- */ + /* Defined rules list for PM options */ ol.def-rules { padding-left: 0; } ol.def-rules li { - line-height: 180%; + line-height: 18px; padding: 1px; } @@ -300,73 +315,47 @@ ol.def-rules li { padding: 0 3px; } -.pmlist li.pm_message_reported_colour, .pm_message_reported_colour { - border-left-color: transparent; +.pmlist li.pm_message_reported_colour, +.pm_message_reported_colour { border-right-color: transparent; + border-left-color: transparent; } -.pmlist li.pm_marked_colour, .pm_marked_colour, -.pmlist li.pm_replied_colour, .pm_replied_colour, -.pmlist li.pm_friend_colour, .pm_friend_colour, -.pmlist li.pm_foe_colour, .pm_foe_colour { - padding: 0; +.pmlist li.pm_marked_colour, +.pm_marked_colour, +.pmlist li.pm_replied_colour, +.pm_replied_colour, +.pmlist li.pm_friend_colour, +.pm_friend_colour, +.pmlist li.pm_foe_colour, +.pm_foe_colour { border: solid 3px transparent; border-width: 0 3px; + padding: 0; } .pm-legend { + border-right-width: 0; border-left-width: 10px; border-left-style: solid; - border-right-width: 0; margin-bottom: 3px; padding-left: 3px; } /* Avatar gallery */ .gallery label { + text-align: center; + border: 1px solid transparent; position: relative; float: left; + width: auto; margin: 10px; padding: 5px; - width: auto; - border: 1px solid transparent; - text-align: center; } -/* Responsive *CP navigation -----------------------------------------*/ -@media only screen and (max-width: 900px), only screen and (max-device-width: 900px) -{ - .nojs .tabs a span, .nojs .minitabs a span { - max-width: 40px; - overflow: hidden; - text-overflow: ellipsis; - letter-spacing: -.5px; - } - - .cp-menu, .navigation, .cp-main { - float: none; - width: auto; - margin: 0; - } - - .navigation { - padding: 0; - margin: 0 auto; - max-width: 320px; - } - - .navigation a { - background-image: none; - } - - .navigation li:first-child a { - border-top-left-radius: 5px; - border-top-right-radius: 5px; - } - - .navigation li:last-child a { - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; - } +.cplist .topictitle { + line-height: 30px; } + +/* stylelint-enable selector-max-compound-selectors */ +/* stylelint-enable selector-no-qualifying-type */ diff --git a/phpBB/styles/prosilver/theme/en/icon_user_online.gif b/phpBB/styles/prosilver/theme/en/icon_user_online.gif deleted file mode 100644 index 6b571ffce0d..00000000000 Binary files a/phpBB/styles/prosilver/theme/en/icon_user_online.gif and /dev/null differ diff --git a/phpBB/styles/prosilver/theme/en/stylesheet.css b/phpBB/styles/prosilver/theme/en/stylesheet.css index 604b2994882..ae0d2f152d1 100644 --- a/phpBB/styles/prosilver/theme/en/stylesheet.css +++ b/phpBB/styles/prosilver/theme/en/stylesheet.css @@ -1,2 +1 @@ -/* Online image */ -.online { background-image: url("./icon_user_online.gif"); } +/* language specific styles go here */ diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css index 5646a7d6c7a..1257c2c56de 100644 --- a/phpBB/styles/prosilver/theme/forms.css +++ b/phpBB/styles/prosilver/theme/forms.css @@ -1,30 +1,34 @@ -/* Form Styles ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Forms +/* -------------------------------------------------------------- */ + +/* stylelint-disable selector-max-compound-selectors */ +/* stylelint-disable selector-no-qualifying-type */ /* General form styles -----------------------------------------*/ +---------------------------------------- */ fieldset { - border-width: 0; font-family: Verdana, Helvetica, Arial, sans-serif; - font-size: 1.1em; + font-size: 11px; + border-width: 0; } input { + font-family: Verdana, Helvetica, Arial, sans-serif; + font-size: 11px; font-weight: normal; vertical-align: middle; padding: 0 3px; - font-size: 1em; - font-family: Verdana, Helvetica, Arial, sans-serif; } select { font-family: Verdana, Helvetica, Arial, sans-serif; + font-size: 11px; font-weight: normal; - cursor: pointer; vertical-align: middle; border: 1px solid transparent; padding: 1px; - font-size: 1em; + cursor: pointer; } select:focus { @@ -32,25 +36,25 @@ select:focus { } option { - padding-right: 1em; + padding-right: 11px; } select optgroup option { - padding-right: 1em; font-family: Verdana, Helvetica, Arial, sans-serif; + padding-right: 11px; } textarea { font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; + font-size: 11px; + line-height: 18px; width: 60%; padding: 2px; - font-size: 1em; - line-height: 1.4em; } label { - cursor: default; padding-right: 5px; + cursor: default; } label input { @@ -68,27 +72,16 @@ fieldset dl { } fieldset dt { - float: left; - width: 40%; text-align: left; display: block; + float: left; + width: 40%; } fieldset dd { - margin-left: 41%; vertical-align: top; margin-bottom: 3px; -} - -/* Specific layout 1 */ -fieldset.fields1 dt { - width: 15em; - border-right-width: 0; -} - -fieldset.fields1 dd { - margin-left: 15em; - border-left-width: 0; + margin-left: 41%; } fieldset.fields1 div { @@ -100,15 +93,21 @@ fieldset.fields1 .live-search div { margin-bottom: 0; } -/* Specific layout 2 */ -fieldset.fields2 dt { - width: 15em; +/* Specific layouts */ +fieldset.fields2 dt, +fieldset.fields1 dt { border-right-width: 0; + width: 165px; } fieldset.fields2 dd { - margin-left: 16em; border-left-width: 0; + margin-left: 176px; +} + +fieldset.fields1 dd { + border-left-width: 0; + margin-left: 165px; } /* Form elements */ @@ -121,7 +120,8 @@ dd label { white-space: nowrap; } -dd input, dd textarea { +dd input, +dd textarea { margin-right: 3px; } @@ -144,8 +144,8 @@ dd textarea { /* Browser-specific tweaks */ button::-moz-focus-inner { + border: 0; padding: 0; - border: 0 } /* Quick-login on index page */ @@ -158,8 +158,8 @@ fieldset.quick-login input { } fieldset.quick-login input.inputbox { - width: 15%; vertical-align: middle; + width: 15%; margin-right: 5px; } @@ -171,7 +171,7 @@ fieldset.quick-login label { /* Display options on viewtopic/viewforum pages */ fieldset.display-options { text-align: center; - margin: 3px 0 5px 0; + margin: 3px 0 5px; } fieldset.display-options label { @@ -184,17 +184,17 @@ fieldset.display-options a { } .dropdown fieldset.display-options { - font-size: 1em; + font-size: 11px; margin: 0; padding: 0; } .dropdown fieldset.display-options label { + text-align: right; + white-space: nowrap; display: block; margin: 4px; padding: 0; - text-align: right; - white-space: nowrap; } .dropdown fieldset.display-options select { @@ -203,10 +203,10 @@ fieldset.display-options a { /* Display actions for ucp and mcp pages */ fieldset.display-actions { + line-height: 22px; text-align: right; - line-height: 2em; white-space: nowrap; - padding-right: 1em; + padding-right: 11px; } fieldset.display-actions label { @@ -214,19 +214,20 @@ fieldset.display-actions label { padding-right: 2px; } +/* Not used anywhere */ fieldset.sort-options { - line-height: 2em; + line-height: 22px; } -/* MCP forum selection*/ +/* MCP forum selection */ fieldset.forum-selection { - margin: 5px 0 3px 0; float: right; + margin: 5px 0 3px; } fieldset.forum-selection2 { - margin: 13px 0 3px 0; float: right; + margin: 13px 0 3px; } /* Submit button fieldset */ @@ -241,14 +242,15 @@ fieldset.submit-buttons input { } /* Posting page styles -----------------------------------------*/ +---------------------------------------- */ /* Buttons used in the editor */ .format-buttons { - margin: 15px 0 2px 0; + margin: 15px 0 2px; } -.format-buttons input, .format-buttons select { +.format-buttons input, +.format-buttons select { vertical-align: middle; } @@ -259,25 +261,22 @@ fieldset.submit-buttons input { .message-box textarea { font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; + font-size: 13px; + outline: 3px dashed transparent; + outline-offset: -4px; width: 450px; - height: 270px; min-width: 100%; max-width: 100%; - font-size: 1.2em; + height: 270px; resize: vertical; - outline: 3px dashed transparent; - outline-offset: -4px; - -webkit-transition: all .5s ease, height 1ms linear; - -moz-transition: all .5s ease, height 1ms linear; - -ms-transition: all .5s ease, height 1ms linear; - -o-transition: all .5s ease, height 1ms linear; - transition: all .5s ease, height 1ms linear; + -webkit-transition: all 0.5s ease, height 1ms linear; + transition: all 0.5s ease, height 1ms linear; } /* Emoticons panel */ .smiley-box { - width: 18%; float: right; + width: 18%; } .smiley-box img { @@ -291,15 +290,27 @@ fieldset.submit-buttons input { padding: 2px; } -.inputbox:hover, .inputbox:focus { +.inputbox:hover, +.inputbox:focus { border: 1px solid transparent; outline-style: none; } -input.inputbox { width: 85%; } -input.medium { width: 50%; } -input.narrow { width: 25%; } -input.tiny { width: 150px; } +input.inputbox { + width: 85%; +} + +input.medium { + width: 50%; +} + +input.narrow { + width: 25%; +} + +input.tiny { + width: 150px; +} textarea.inputbox { width: 85%; @@ -314,11 +325,14 @@ input[type="number"] { } input[type="search"] { - -webkit-appearance: textfield; -webkit-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; } -input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-results-button, input[type="search"]::-webkit-search-results-decoration { +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-results-button, +input[type="search"]::-webkit-search-results-decoration { display: none; } @@ -326,65 +340,18 @@ input[type="search"]::-webkit-search-cancel-button { cursor: pointer; } -/* Form button styles ----------------------------------------- */ -input.button1, input.button2 { - font-size: 1em; -} - -a.button1, input.button1, input.button3, a.button2, input.button2 { - width: auto !important; - padding-top: 1px; - padding-bottom: 1px; - font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; - background: transparent none repeat-x top left; - line-height: 1.5; -} - -a.button1, input.button1 { - font-weight: bold; - border: 1px solid transparent; -} - -input.button3 { - padding: 0; - margin: 0; - line-height: 5px; - height: 12px; - background-image: none; - font-variant: small-caps; -} - -input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"] { +input[type="button"], +input[type="submit"], +input[type="reset"], +input[type="checkbox"], +input[type="radio"] { cursor: pointer; } -/* Alternative button */ -a.button2, input.button2, input.button3 { - border: 1px solid transparent; -} - -/* button in the style of the form buttons */ -a.button1, a.button2 { - text-decoration: none; - padding: 0 3px; - vertical-align: text-bottom; -} - -/* Hover states */ -a.button1:hover, input.button1:hover, a.button2:hover, input.button2:hover, input.button3:hover { - border: 1px solid transparent; -} - input.disabled { font-weight: normal; } -/* Focus states */ -input.button1:focus, input.button2:focus, input.button3:focus { - outline-style: none; -} - /* Topic and forum Search */ .search-box { float: left; @@ -395,11 +362,10 @@ input.button1:focus, input.button2:focus, input.button3:focus { border-right-width: 0; border-radius: 4px 0 0 4px; float: left; - height: 24px; - padding: 3px; -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; + height: 24px; + padding: 3px; } /* Search box (header) @@ -408,13 +374,17 @@ input.button1:focus, input.button2:focus, input.button3:focus { border-radius: 4px; display: block; float: right; - margin-right: 5px; margin-top: 30px; + margin-right: 5px; } -.search-header .inputbox { border: 0; } +.search-header .inputbox { + border: 0; +} -.navbar .linklist > li.responsive-search { display: none; } +.navbar .linklist > li.responsive-search { + display: none; +} input.search { background-image: none; @@ -423,7 +393,21 @@ input.search { padding-left: 17px; } -.full { width: 95%; } -.medium { width: 50%;} -.narrow { width: 25%;} -.tiny { width: 10%;} +.full { + width: 95%; +} + +.medium { + width: 50%; +} + +.narrow { + width: 25%; +} + +.tiny { + width: 10%; +} + +/* stylelint-enable selector-max-compound-selectors */ +/* stylelint-enable selector-no-qualifying-type */ diff --git a/phpBB/styles/prosilver/theme/icons.css b/phpBB/styles/prosilver/theme/icons.css index 6643f12d066..0d6a3a52f71 100644 --- a/phpBB/styles/prosilver/theme/icons.css +++ b/phpBB/styles/prosilver/theme/icons.css @@ -1,28 +1,35 @@ -/* -------------------------------------------------------------- +/* -------------------------------------------------------------- /* $Icons --------------------------------------------------------------- */ +/* -------------------------------------------------------------- */ /* Global module setup ---------------------------------*/ +---------------------------------------- */ -/* Renamed version of .fa class for agnostic useage of icon fonts. +/* Renamed version of .fa class for agnostic usage of icon fonts. * Just change the name of the font after the 14/1 to the name of * the font you wish to use. */ -.icon, .button .icon, blockquote cite:before, .uncited:before { +.icon, +.button .icon, +blockquote cite:before, +.uncited:before { + font-family: FontAwesome; + font-size: 14px; + font-weight: normal; + font-style: normal; + font-variant: normal; + line-height: 1; display: inline-block; - font-weight: normal; - font-style: normal; - font-variant: normal; - font-family: FontAwesome; - font-size: 14px; - line-height: 1; - text-rendering: auto; /* optimizelegibility throws things off #1094 */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + /* stylelint-disable order/declaration-block-properties-specified-order */ + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + /* stylelint-enable order/declaration-block-properties-specified-order */ + text-rendering: auto; /* optimizelegibility throws things off #1094 */ } -.icon:before { padding-right: 2px; } +.icon:before { + padding-right: 2px; +} .button .icon:before { padding-right: 0; @@ -48,49 +55,50 @@ /* icon modifiers */ .icon-tiny { + font-size: 16px; + vertical-align: text-bottom; width: 12px; + -webkit-transform: scale(0.65, 0.75); transform: scale(0.65, 0.75); - vertical-align: text-bottom; - font-size: 16px; } -.arrow-left .icon { - float: left; +.arrow-right .icon { + float: right; } .arrow-left:hover .icon { - margin-left: -5px; margin-right: 5px; + margin-left: -5px; } -.arrow-right .icon { - float: right; +.arrow-left .icon { + float: left; } .arrow-right:hover .icon { - margin-left: 5px; margin-right: -5px; + margin-left: 5px; } .post-buttons .dropdown-contents .icon { - float: right; - margin-left: 5px; + float: right; + margin-left: 5px; } .alert_close .icon:before { + border-radius: 50%; + display: block; + width: 11px; + height: 12px; padding: 0; - border-radius: 50%; - width: 11px; - display: block; - line-height: .9; - height: 12px; } -blockquote cite:before, .uncited:before { - content: '\f10d'; /* Font Awesome quote-left */ +blockquote cite:before, +.uncited:before { + content: "\f10d"; /* Font Awesome quote-left */ } -.rtl blockquote cite:before, .rtl .uncited:before { - content: '\f10e'; /* Font Awesome quote-right */ +.rtl blockquote cite:before, +.rtl .uncited:before { + content: "\f10e"; /* Font Awesome quote-right */ } - diff --git a/phpBB/styles/prosilver/theme/images/loading.gif b/phpBB/styles/prosilver/theme/images/loading.gif deleted file mode 100644 index e1ed0883e07..00000000000 Binary files a/phpBB/styles/prosilver/theme/images/loading.gif and /dev/null differ diff --git a/phpBB/styles/prosilver/theme/links.css b/phpBB/styles/prosilver/theme/links.css index 6a61e9a262f..3a8407e2a64 100644 --- a/phpBB/styles/prosilver/theme/links.css +++ b/phpBB/styles/prosilver/theme/links.css @@ -1,15 +1,16 @@ -/* Link Styles ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Links +/* -------------------------------------------------------------- */ /* Links adjustment to correctly display an order of rtl/ltr mixed content */ a { - direction: ltr; - unicode-bidi: embed; text-decoration: none; + /* we use links inline more often then not so to address several bugs with IE and some other browsers we render all links as inlineblock by default */ display: inline-block; - + direction: ltr; + unicode-bidi: embed; } /* Coloured usernames */ @@ -20,28 +21,33 @@ a { } /* Links on gradient backgrounds */ -.forumbg .header a, .forabg .header a, th a { +.forumbg .header a, +.forabg .header a, +th a { text-decoration: none; } -.forumbg .header a:hover, .forabg .header a:hover, th a:hover { +.forumbg .header a:hover, +.forabg .header a:hover, +th a:hover { text-decoration: underline; } +/* stylelint-disable selector-no-qualifying-type */ + /* Notification mark read link */ .dropdown-extended a.mark_read { - background-position: center center; background-repeat: no-repeat; + background-position: center center; border-radius: 3px 0 0 3px; - display: none; - margin-top: -20px; position: absolute; z-index: 2; - right: 0; top: 50%; + right: 0; + display: none; -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; + margin-top: -20px; } .dropdown-extended li:hover a.mark_read { @@ -53,13 +59,16 @@ a { } .jumpbox-cat-link, -.jumpbox-forum-link { font-weight: bold; } +.jumpbox-forum-link { + font-weight: bold; +} /* Links for forum/topic lists */ -a.forumtitle { - font-family: "Trebuchet MS", Helvetica, Arial, Sans-serif; - font-size: 1.2em; +a.forumtitle, +a.topictitle { + font-family: "Trebuchet MS", Helvetica, Arial, sans-serif; + font-size: 13px; font-weight: bold; text-decoration: none; } @@ -69,10 +78,6 @@ a.forumtitle:hover { } a.topictitle { - font-family: "Trebuchet MS", Helvetica, Arial, Sans-serif; - font-size: 1.2em; - font-weight: bold; - text-decoration: none; display: inline; } @@ -90,7 +95,7 @@ a.lastsubject:hover { } .row-item a:hover { - text-decoration: none + text-decoration: none; } .row-item .topictitle:hover, @@ -111,25 +116,28 @@ a.lastsubject:hover { text-decoration: none; } -.signature a, .signature a:hover { - border: none; +.signature a, +.signature a:hover { text-decoration: underline; + border: none; } /* Profile links */ -.postprofile a, .postprofile dt.author a { +.postprofile a, +.postprofile dt.author a { font-weight: bold; text-decoration: none; } -.postprofile a:hover, .postprofile dt.author a:hover { +.postprofile a:hover, +.postprofile dt.author a:hover { text-decoration: underline; } /* Profile searchresults */ .search .postprofile a { - text-decoration: none; font-weight: normal; + text-decoration: none; } .search .postprofile a:hover { @@ -149,20 +157,20 @@ a.lastsubject:hover { .back2top .top { float: right; - margin-right: -10px; margin-top: 0; + margin-right: -10px; } /* Arrow links */ .arrow-up { - padding-left: 10px; text-decoration: none; border-bottom-width: 0; + padding-left: 10px; } .arrow-up:hover { - + /* add hover styles here */ } .arrow-down { @@ -170,7 +178,7 @@ a.lastsubject:hover { } .arrow-down:hover { - + /* add hover styles here */ } .arrow-left:hover { diff --git a/phpBB/styles/prosilver/theme/normalize.css b/phpBB/styles/prosilver/theme/normalize.css index 23d84492c8e..16857d54996 100644 --- a/phpBB/styles/prosilver/theme/normalize.css +++ b/phpBB/styles/prosilver/theme/normalize.css @@ -1,424 +1,465 @@ -/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +/* stylelint-disable */ + +/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */ /** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS and IE text size adjust after device orientation change, - * without disabling user zoom. + * 1. Change the default font family in all browsers (opinionated). + * 2. Correct the line height in all browsers. + * 3. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. */ +/* Document + ========================================================================== */ + html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ + font-family: sans-serif; /* 1 */ + line-height: 1.15; /* 2 */ + -ms-text-size-adjust: 100%; /* 3 */ + -webkit-text-size-adjust: 100%; /* 3 */ } +/* Sections + ========================================================================== */ + /** - * Remove default margin. + * Remove the margin in all browsers (opinionated). */ body { - margin: 0; + margin: 0; } -/* HTML5 display definitions - ========================================================================== */ - /** - * Correct `block` display not defined for any HTML5 element in IE 8/9. - * Correct `block` display not defined for `details` or `summary` in IE 10/11 - * and Firefox. - * Correct `block` display not defined for `main` in IE 11. + * Add the correct display in IE 9-. */ article, aside, -details, -figcaption, -figure, footer, header, -hgroup, -main, -menu, nav, -section, -summary { - display: block; +section { + display: block; } /** - * 1. Correct `inline-block` display not defined in IE 8/9. - * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. */ -audio, -canvas, -progress, -video { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ +h1 { + font-size: 2em; + margin: 0.67em 0; } +/* Grouping content + ========================================================================== */ + /** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. + * Add the correct display in IE 9-. + * 1. Add the correct display in IE. */ -audio:not([controls]) { - display: none; - height: 0; +figcaption, +figure, +main { /* 1 */ + display: block; } /** - * Address `[hidden]` styling not present in IE 8/9/10. - * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + * Add the correct margin in IE 8. */ -[hidden], -template { - display: none; +figure { + margin: 1em 40px; } -/* Links - ========================================================================== */ +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} /** - * Remove the gray background color from active links in IE 10. + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * 1. Remove the gray background on active links in IE 10. + * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. */ a { - background-color: transparent; + background-color: transparent; /* 1 */ + -webkit-text-decoration-skip: objects; /* 2 */ } /** - * Improve readability of focused elements when they are also in an - * active/hover state. + * Remove the outline on focused links when they are also active or hovered + * in all browsers (opinionated). */ a:active, a:hover { - outline: 0; + outline-width: 0; } -/* Text-level semantics - ========================================================================== */ - /** - * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + * 1. Remove the bottom border in Firefox 39-. + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. */ abbr[title] { - border-bottom: 1px dotted; + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ } /** - * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + * Prevent the duplicate application of `bolder` by the next rule in Safari 6. */ b, strong { - font-weight: bold; + font-weight: inherit; } /** - * Address styling not present in Safari and Chrome. + * Add the correct font weight in Chrome, Edge, and Safari. */ -dfn { - font-style: italic; +b, +strong { + font-weight: bolder; } /** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari, and Chrome. + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. */ -h1 { - font-size: 2em; - margin: 0.67em 0; +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ } /** - * Address styling not present in IE 8/9. + * Add the correct font style in Android 4.3-. + */ + +dfn { + font-style: italic; +} + +/** + * Add the correct background and color in IE 9-. */ mark { - background: #ff0; - color: #000; + background-color: #ff0; + color: #000; } /** - * Address inconsistent and variable font size in all browsers. + * Add the correct font size in all browsers. */ small { - font-size: 80%; + font-size: 80%; } /** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. */ sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } -sup { - top: -0.5em; +sub { + bottom: -0.25em; } -sub { - bottom: -0.25em; +sup { + top: -0.5em; } /* Embedded content - ========================================================================== */ + ========================================================================== */ /** - * Remove border when inside `a` element in IE 8/9/10. + * Add the correct display in IE 9-. */ -img { - border: 0; +audio, +video { + display: inline-block; } /** - * Correct overflow not hidden in IE 9/10/11. + * Add the correct display in iOS 4-7. */ -svg:not(:root) { - overflow: hidden; +audio:not([controls]) { + display: none; + height: 0; } -/* Grouping content - ========================================================================== */ - /** - * Address margin not present in IE 8/9 and Safari. + * Remove the border on images inside links in IE 10-. */ -figure { - margin: 1em 40px; +img { + border-style: none; } /** - * Address differences between Firefox and other browsers. + * Hide the overflow in IE. */ -hr { - box-sizing: content-box; - height: 0; +svg:not(:root) { + overflow: hidden; } +/* Forms + ========================================================================== */ + /** - * Contain overflow in all browsers. + * 1. Change the font styles in all browsers (opinionated). + * 2. Remove the margin in Firefox and Safari. */ -pre { - overflow: auto; +button, +input, +optgroup, +select, +textarea { + font-family: sans-serif; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ } /** - * Address odd `em`-unit font size rendering in all browsers. + * Show the overflow in IE. + * 1. Show the overflow in Edge. */ -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; +button, +input { /* 1 */ + overflow: visible; } -/* Forms - ========================================================================== */ - /** - * Known limitation: by default, Chrome and Safari on OS X allow very limited - * styling of `select`, unless a `border` property is set. + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. */ +button, +select { /* 1 */ + text-transform: none; +} + /** - * 1. Correct color not being inherited. - * Known issue: affects color of disabled elements. - * 2. Correct font properties not being inherited. - * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` + * controls in Android 4. + * 2. Correct the inability to style clickable types in iOS and Safari. */ button, -input, -optgroup, -select, -textarea { - color: inherit; /* 1 */ - font: inherit; /* 2 */ - margin: 0; /* 3 */ +html [type="button"], /* 1 */ +[type="reset"], +[type="submit"] { + -webkit-appearance: button; /* 2 */ } /** - * Address `overflow` set to `hidden` in IE 8/9/10/11. + * Remove the inner border and padding in Firefox. */ -button { - overflow: visible; +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } /** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. - * Correct `select` style inheritance in Firefox. + * Restore the focus styles unset by the previous rule. */ -button, -select { - text-transform: none; +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; } /** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. + * Change the border, margin, and padding in all browsers (opinionated). */ -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } /** - * Re-set default cursor for disabled elements. + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. */ -button[disabled], -html input[disabled] { - cursor: default; +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ } /** - * Remove inner padding and border in Firefox 4+. + * 1. Add the correct display in IE 9-. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. */ -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; +progress { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } /** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. + * Remove the default vertical scrollbar in IE. */ -input { - line-height: normal; +textarea { + overflow: auto; } /** - * It's recommended that you don't attempt to style these elements. - * Firefox's implementation doesn't respect box-sizing, padding, or width. - * - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. + * 1. Add the correct box sizing in IE 10-. + * 2. Remove the padding in IE 10-. */ -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ } /** - * Fix the cursor style for Chrome's increment/decrement buttons. For certain - * `font-size` values of the `input`, it causes the cursor style of the - * decrement button to change from `default` to `text`. + * Correct the cursor style of increment and decrement buttons in Chrome. */ -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; } /** - * 1. Address `appearance` set to `searchfield` in Safari and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. */ -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ - box-sizing: content-box; /* 2 */ +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ } /** - * Remove inner padding and search cancel button in Safari and Chrome on OS X. - * Safari (but not Chrome) clips the cancel button when the search input has - * padding (and `textfield` appearance). + * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. */ -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } /** - * Define consistent border, margin, and padding. + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. */ -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ } -/** - * 1. Correct `color` not being inherited in IE 8/9/10/11. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in IE 9-. + * 1. Add the correct display in Edge, IE, and Firefox. */ -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ +details, /* 1 */ +menu { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; } +/* Scripting + ========================================================================== */ + /** - * Remove default vertical scrollbar in IE 8/9/10/11. + * Add the correct display in IE 9-. */ -textarea { - overflow: auto; +canvas { + display: inline-block; } /** - * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + * Add the correct display in IE. */ -optgroup { - font-weight: bold; +template { + display: none; } -/* Tables - ========================================================================== */ +/* Hidden + ========================================================================== */ /** - * Remove most spacing between table cells. + * Add the correct display in IE 10-. */ -table { - border-collapse: collapse; - border-spacing: 0; +[hidden] { + display: none; } -td, -th { - padding: 0; -} +/* stylelint-enable */ diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css index f466803964f..bddb5da834d 100644 --- a/phpBB/styles/prosilver/theme/plupload.css +++ b/phpBB/styles/prosilver/theme/plupload.css @@ -1,6 +1,10 @@ +/* -------------------------------------------------------------- /* + $Plupload +/* -------------------------------------------------------------- */ + .attach-panel-multi { display: none; - margin-bottom: 1em; + margin-bottom: 10px; } .file-list td { @@ -16,8 +20,8 @@ } .attach-comment .inputbox { - resize: vertical; width: 100%; + resize: vertical; } .attach-filesize { @@ -28,12 +32,12 @@ width: 5%; } -.attach-filesize, .attach-status { +.attach-filesize, +.attach-status { text-align: center; } .attach-controls { - display: inline-block; float: right; } @@ -42,45 +46,46 @@ } .file-total-progress { - height: 2px; - display: block; position: relative; + display: block; + height: 2px; margin: 4px -10px -6px -10px; } .file-progress { - background-color: #CCCCCC; - display:inline-block; - height: 8px; + background-color: #cccccc; + display: inline-block; width: 50px; + height: 8px; } -.file-progress-bar, .file-total-progress-bar { - background-color: green; +.file-progress-bar, +.file-total-progress-bar { + background-color: #008000; display: block; - height: 100%; width: 0; + height: 100%; } .file-status.file-working { - background: url('./images/plupload/throbber.gif'); + background: url("./images/plupload/throbber.gif"); } .file-status.file-uploaded { - background: url('./images/plupload/done.gif'); + background: url("./images/plupload/done.gif"); } .file-status.file-error { - background: url('./images/plupload/error.gif'); + background: url("./images/plupload/error.gif"); } .file-status { display: inline-block; - height: 16px; width: 16px; + height: 16px; } .file-name { - max-width: 65%; vertical-align: bottom; + max-width: 65%; } diff --git a/phpBB/styles/prosilver/theme/print.css b/phpBB/styles/prosilver/theme/print.css index 9445279773a..a846ed34de3 100644 --- a/phpBB/styles/prosilver/theme/print.css +++ b/phpBB/styles/prosilver/theme/print.css @@ -1,25 +1,47 @@ -/* Print Style Sheet ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Print +/* -------------------------------------------------------------- */ +/* stylelint-disable selector-max-compound-selectors */ /* Lots still TODO here! */ /* General markup styles */ * { - padding: 0; margin: 0; + padding: 0; } body { - font: 11pt Verdana, Arial, Helvetica, sans-serif; - color:#000000; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 14px; + color: #000000; } -a:link { color: #000000; text-decoration: none; } -a:visited { color: #000000; text-decoration: none; } -a:active { color: #000000; text-decoration: none; } +a:link { + text-decoration: none; + color: #000000; +} + +a:visited { + text-decoration: none; + color: #000000; +} + +a:active { + text-decoration: none; + color: #000000; +} + +img, +.noprint, +.navbar, +.box1, +.divider, +.signature { + display: none; +} -img, .noprint, .navbar, .box1, .divider, .signature { display: none; } /* Display smilies (Bug #47265) */ .content img { display: inline; @@ -27,124 +49,184 @@ img, .noprint, .navbar, .box1, .divider, .signature { display: none; } /* Container for the main body */ .wrap { - margin: 0 2em; + margin: 0 30px; } -p { font-size: 85%; } -.copyright { font-size: 75%; } -.page-number { float:right; width: auto; text-align: right; font-size: 75%; } +p { + font-size: 85%; +} -h1, h2, h3, h1 a, h2 a, h3 a { - font-family: "Trebuchet MS",georgia,Verdana,Sans-serif; - color: #000000; - background: none; - text-decoration: none; +.copyright { + font-size: 75%; +} + +.page-number { + font-size: 75%; + text-align: right; + float: right; + width: auto; +} + +h1, +h2, +h3, +h1 a, +h2 a, +h3 a { + font-family: "Trebuchet MS", georgia, Verdana, sans-serif; font-weight: bold; + text-decoration: none; + background: none; + color: #000000; } -h1 { font-size: 20pt; } -h2 { font-size: 16pt; margin-top: 1em; } -h3 { font-size: 14pt; margin-top: 1em; } +h1 { + font-size: 26px; +} + +h2 { + font-size: 21px; + margin-top: 20px; +} + +h3 { + font-size: 18px; + margin-top: 20px; +} .content { - font-size: 11pt; - line-height: 14pt; - margin-bottom: 1em; font-family: "Lucida Grande", "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; + font-size: 14px; + line-height: 18px; overflow: hidden; + margin-bottom: 14px; +} + +.postbody .content { + font-size: 14px; } /* CSS2 Print tip from: http://www.alistapart.com/articles/goingtoprint/ */ -.postbody a:link, .postbody a:visited, .postbody a:hover, .postbody a:active { - text-decoration: underline; - padding: 0.1em 0.2em; - margin: -0.1em -0.2em; - color: #666; - background: none; +.postbody a:link, +.postbody a:visited, +.postbody a:hover, +.postbody a:active { font-size: 100%; + background: none; + color: #666666; + padding: 2px 4px; } -html>body .postbody a:link:after, html>body .postbody a:visited:after { - content: " (" attr(href) ") "; +html > body .postbody a:link:after, +html > body .postbody a:visited:after { font-size: 90%; text-decoration: none; + content: " (" attr(href) ") "; } hr { - height: 1px; background-color: #999999; border-width: 0; + height: 1px; } .author { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 75%; - margin-bottom: 0.6em; } .date { font-family: Verdana, Arial, Helvetica, sans-serif; - float: right; - position: relative; - text-align: right; font-size: 75%; + text-align: right; + position: relative; + float: right; } -/* Dont want to print url for names or titles in content area */ -.postbody .author a:link, .postbody .author a:visited, -html>body .postbody .author a:link:after, -html>body .postbody .author a:visited:after, -.postquote .quote-by a:link, .postquote .quote-by a:visited, -html>body .postquote .quote-by a:link:after, -html>body .postquote .quote-by a:visited:after, -html>body .postbody h1 a:link:after, html>body .postbody h2 a:link:after { +/* Don't want to print url for names or titles in content area */ +.postbody .author a:link, +.postbody .author a:visited, +html > body .postbody .author a:link:after, +html > body .postbody .author a:visited:after, +.postquote .quote-by a:link, +.postquote .quote-by a:visited, +html > body .postquote .quote-by a:link:after, +html > body .postquote .quote-by a:visited:after, +html > body .postbody h1 a:link:after, +html > body .postbody h2 a:link:after, +.post-buttons a:after { text-decoration: none; - content: ""; + content: "" !important; } /* Poster profile */ -.postprofile { display: none; } -.grip-show { display:none; } +.postprofile { + display: none; +} + +.grip-show { + display: none; +} /* Quote */ -.postquote, blockquote { +.postquote, +blockquote { font-size: 85%; - margin: 1em 18% 1em 4%; - padding: 0.5em; - position: relative; - line-height: 1.5em; + line-height: 18px; border: 1px #999999 solid; + position: relative; + margin: 12px 154px 12px 34px; + padding: 6px; +} + +.postquote img { + display: none; +} + +.postquote span { + display: block; +} + +.postquote span .postquote { + font-size: 100%; } -.postquote img { display: none; } -.postquote span { display: block; } -.postquote span .postquote { font-size: 100%; } -.quote-by, blockquote cite { - color: black; - display : block; +.quote-by, +blockquote cite { font-weight: bold; + color: #000000; + display: block; } /* List */ -ol, ul { - margin-left: 15pt +ol, +ul { + margin-left: 20px; } /* Misc page elements */ -div.spacer { clear: both; } +.spacer { + clear: both; +} code { display: block; } /* Accessibility tweaks: Mozilla.org */ -.skip_link { display: none; } +.skip_link { + display: none; +} -.codebox p { display: none; } +.codebox p { + display: none; +} /* stylelint-disable declaration-property-unit-whitelist */ .emoji { - min-height: 18px; + width: 1em; min-width: 18px; height: 1em; - width: 1em; + min-height: 18px; } /* stylelint-enable declaration-property-unit-whitelist */ + +/* stylelint-enable selector-max-compound-selectors */ diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css index fcc11f1fc20..07cdd1cff95 100644 --- a/phpBB/styles/prosilver/theme/responsive.css +++ b/phpBB/styles/prosilver/theme/responsive.css @@ -1,14 +1,19 @@ -/* Responsive Design ----------------------------------------- */ +/* -------------------------------------------------------------- /* + $Responsive +/* -------------------------------------------------------------- */ +/* stylelint-disable selector-max-compound-selectors */ +/* stylelint-disable selector-no-qualifying-type */ @media (max-width: 320px) { - select, .inputbox { + select, + .inputbox { max-width: 240px; } } /* Notifications list -----------------------------------------*/ +---------------------------------------------------------------- */ + @media (max-width: 350px) { .dropdown-extended .dropdown-contents { width: auto; @@ -25,16 +30,16 @@ } .action-bar .search-box .inputbox ::-moz-placeholder { - content: "Search..."; - } + content: "Search..."; + } - .action-bar .search-box .inputbox :-ms-input-placeholder { - content: "Search..."; - } + .action-bar .search-box .inputbox :-ms-input-placeholder { + content: "Search..."; + } - .action-bar .search-box .inputbox ::-webkit-input-placeholder { - content: "Search..."; - } + .action-bar .search-box .inputbox ::-webkit-input-placeholder { + content: "Search..."; + } } @media (max-width: 500px) { @@ -42,7 +47,8 @@ white-space: normal; } - select, .inputbox { + select, + .inputbox { max-width: 260px; } @@ -54,10 +60,11 @@ width: 100%; } - dl.details dt, dl.details dd { - width: auto; - float: none; + dl.details dt, + dl.details dd { text-align: left; + float: none; + width: auto; } dl.details dd { @@ -65,20 +72,24 @@ } p.responsive-center { - float: none; text-align: center; + float: none; margin-bottom: 5px; } + .phpbb_alert { + top: 25px; + } + .action-bar > div { margin-bottom: 5px; - } + } .action-bar > .pagination { + text-align: center; float: none; clear: both; padding-bottom: 1px; - text-align: center; } .action-bar > .pagination li.page-jump { @@ -95,13 +106,28 @@ } .attach-controls { - margin-top: 5px; width: 100%; + margin-top: 5px; } .quick-links .dropdown-trigger span { display: none; } + + .rtl dl.details dt, + .rtl dl.details dd { + text-align: right; + float: none; + } + + .rtl dl.details dd { + margin-right: 20px; + margin-left: 0; + } + + .rtl .captcha-panel dd.captcha { + margin-right: 0; + } } @media (max-width: 550px) { @@ -116,16 +142,39 @@ ul.topiclist.forums dd.lastpost { display: none; } + + /* RTL */ + + /* .topiclist lists + ---------------------------------------- */ + .rtl ul.topiclist.forums dt { + margin-left: 0; + } + + .rtl ul.topiclist.forums dt .list-inner { + margin-left: 0; + } } @media (max-width: 700px) { - .responsive-hide { display: none !important; } - .responsive-show { display: block !important; } - .responsive-show-inline { display: inline !important; } - .responsive-show-inline-block { display: inline-block !important; } + .responsive-hide { + display: none !important; + } + + .responsive-show { + display: block !important; + } + + .responsive-show-inline { + display: inline !important; + } + + .responsive-show-inline-block { + display: inline-block !important; + } /* Content wrappers - ----------------------------------------*/ + ---------------------------------------------------------------- */ html { height: auto; } @@ -137,29 +186,37 @@ .wrap { border: none; border-radius: 0; - margin: 0; min-width: 290px; + margin: 0; padding: 0 5px; } /* Common block wrappers - ----------------------------------------*/ - .headerbar, .navbar, .forabg, .forumbg, .post, .panel { + ---------------------------------------------------------------- */ + .headerbar, + .navbar, + .forabg, + .forumbg, + .post, + .panel { border-radius: 0; - margin-left: -5px; margin-right: -5px; + margin-left: -5px; } - .cp-main .forabg, .cp-main .forumdb, .cp-main .post, .cp-main .panel { + .cp-main .forabg, + .cp-main .forumdb, + .cp-main .post, + .cp-main .panel { border-radius: 7px; } /* Logo block - ----------------------------------------*/ + ---------------------------------------------------------------- */ .site-description { + text-align: center; float: none; width: auto; - text-align: center; } .logo { @@ -169,40 +226,45 @@ padding: 10px; } - .site-description h1, .site-description p { + .site-description h1, + .site-description p { + line-height: 24px; text-align: inherit; + text-overflow: ellipsis; float: none; - margin: 5px; - line-height: 1.2em; overflow: hidden; - text-overflow: ellipsis; + margin: 5px; } - .site-description p, .search-header { + .site-description p, + .search-header { display: none; } /* Navigation - ----------------------------------------*/ + ---------------------------------------------------------------- */ .headerbar + .navbar { margin-top: -5px; } /* Search - ----------------------------------------*/ - .responsive-search { display: block !important; } + ---------------------------------------------------------------- */ + .responsive-search { + display: block !important; + } - /* .topiclist lists - ----------------------------------------*/ + /* Forums and topicslists + ---------------------------------------------------------------- */ li.header dt { + font-size: 12px; + line-height: 12px; text-align: center; text-transform: none; - line-height: 1em; - font-size: 1.2em; padding-bottom: 4px; } - ul.topiclist li.header dt, ul.topiclist li.header dt .list-inner { + ul.topiclist li.header dt, + ul.topiclist li.header dt .list-inner { margin-right: 0 !important; padding-right: 0; } @@ -211,10 +273,14 @@ display: none !important; } - ul.topiclist dt, ul.topiclist dt .list-inner, - ul.topiclist.missing-column dt, ul.topiclist.missing-column dt .list-inner, - ul.topiclist.two-long-columns dt, ul.topiclist.two-long-columns dt .list-inner, - ul.topiclist.two-columns dt, ul.topiclist.two-columns dt .list-inner { + ul.topiclist dt, + ul.topiclist dt .list-inner, + ul.topiclist.missing-column dt, + ul.topiclist.missing-column dt .list-inner, + ul.topiclist.two-long-columns dt, + ul.topiclist.two-long-columns dt .list-inner, + ul.topiclist.two-columns dt, + ul.topiclist.two-columns dt .list-inner { margin-right: 0; } @@ -233,33 +299,28 @@ ul.topiclist dd { display: none; } - ul.topiclist dd.mark { - display: block; - } - /* Forums and topics lists - ----------------------------------------*/ ul.topiclist.forums dt { margin-right: -250px; } ul.topiclist dd.mark { - display: block; + text-align: left; position: absolute; - right: 5px; top: 0; - margin: 0; + right: 5px; + display: block; width: auto; min-width: 0; - text-align: left; + margin: 0; } - ul.topiclist.forums dd.topics dfn, ul.topiclist.topics dd.posts dfn { + ul.topiclist.forums dd.topics dfn, + ul.topiclist.topics dd.posts dfn { + font-weight: normal; position: relative; left: 0; - width: auto; display: inline; - font-weight: normal; } li.row .responsive-show strong { @@ -269,13 +330,13 @@ ul.topiclist li.row dt a.subforum { vertical-align: bottom; - overflow: hidden; text-overflow: ellipsis; + overflow: hidden; max-width: 100px; } /* Pagination - ----------------------------------------*/ + ---------------------------------------------------------------- */ .pagination > ul { margin: 5px 0 0; } @@ -285,19 +346,24 @@ } /* Responsive tables - ----------------------------------------*/ - table.responsive, table.responsive tbody, table.responsive tr, table.responsive td { + ---------------------------------------------------------------- */ + table.responsive, + table.responsive tbody, + table.responsive tr, + table.responsive td { display: block; } - table.responsive thead, table.responsive th { + table.responsive thead, + table.responsive th { display: none; } - table.responsive.show-header thead, table.responsive.show-header th:first-child { + table.responsive.show-header thead, + table.responsive.show-header th:first-child { + text-align: left !important; display: block; width: auto !important; - text-align: left !important; } table.responsive.show-header th:first-child span.rank-img { @@ -309,8 +375,8 @@ } table.responsive td { - width: auto !important; text-align: left !important; + width: auto !important; padding: 4px; } @@ -323,8 +389,8 @@ } table.responsive td > dfn:after { - content: ':'; padding-right: 5px; + content: ":"; } table.responsive span.rank-img { @@ -337,20 +403,26 @@ } /* Forms - ----------------------------------------*/ - fieldset dt, fieldset.fields1 dt, fieldset.fields2 dt { - width: auto; + ---------------------------------------------------------------- */ + fieldset dt, + fieldset.fields1 dt, + fieldset.fields2 dt { float: none; + width: auto; } - fieldset dd, fieldset.fields1 dd, fieldset.fields2 dd { - margin-left: 0px; + fieldset dd, + fieldset.fields1 dd, + fieldset.fields2 dd { + margin-left: 0; } - textarea, dd textarea, .message-box textarea { - width: 100%; - -moz-box-sizing: border-box; + textarea, + dd textarea, + .message-box textarea { + -webkit-box-sizing: border-box; box-sizing: border-box; + width: 100%; } dl.pmlist dt { @@ -367,7 +439,8 @@ padding-left: 20px; } - .smiley-box, .message-box { + .smiley-box, + .message-box { float: none; width: auto; } @@ -380,7 +453,9 @@ display: none; } - .colour-palette, .colour-palette tbody, .colour-palette tr { + .colour-palette, + .colour-palette tbody, + .colour-palette tr { display: block; } @@ -389,14 +464,15 @@ margin-right: 2px; } - .horizontal-palette td:nth-child(2n), .vertical-palette tr:nth-child(2n) { + .horizontal-palette td:nth-child(2n), + .vertical-palette tr:nth-child(2n) { display: none; } fieldset.quick-login label { + white-space: normal; display: block; margin-bottom: 5px; - white-space: normal; } fieldset.quick-login label > span { @@ -411,20 +487,22 @@ } fieldset.quick-login label[for="autologin"] { - display: inline-block; text-align: right; + display: inline-block; min-width: 50%; } /* User profile - ----------------------------------------*/ - .column1, .column2, .left-box.profile-details { + ---------------------------------------------------------------- */ + .column1, + .column2, + .left-box.profile-details { float: none; width: auto; } /* Polls - ----------------------------------------*/ + ---------------------------------------------------------------- */ fieldset.polls dt { width: 90%; } @@ -437,46 +515,51 @@ width: 20%; } - fieldset.polls dd.resultbar, fieldset.polls dd.poll_option_percent { + fieldset.polls dd.resultbar, + fieldset.polls dd.poll_option_percent { margin-top: 5px; } /* Post - ----------------------------------------*/ + ---------------------------------------------------------------- */ .postbody { position: inherit; } - .postprofile, .postbody, .search .postbody { + .postprofile, + .postbody, + .search .postbody { display: block; - width: auto; float: none; - padding: 0; + width: auto; min-height: 0; + padding: 0; } .post .postprofile { + border-width: 0 0 1px; + overflow: hidden; width: auto; - border-width: 0 0 1px 0; - padding-bottom: 5px; + min-height: 40px; margin: 0; margin-bottom: 5px; - min-height: 40px; - overflow: hidden; + padding-bottom: 5px; } .postprofile dd { display: none; } - .postprofile dt, .postprofile dd.profile-rank, .search .postprofile dd { + .postprofile dt, + .postprofile dd.profile-rank, + .search .postprofile dd { display: block; margin: 0; } .postprofile .has-avatar .avatar-container { - margin: 0; overflow: inherit; + margin: 0; } .postprofile .avatar-container:after { @@ -494,28 +577,24 @@ } .has-profile .postbody h3 { - margin-left: 0 !important; margin-right: 0 !important; + margin-left: 0 !important; } .has-profile .post-buttons { - right: 30px; top: 15px; - } - - .online { - background-size: 40px; + right: 30px; } /* Misc stuff - ----------------------------------------*/ + ---------------------------------------------------------------- */ h2 { - margin-top: .5em; + margin-top: 12px; } p { - margin-bottom: .5em; overflow: hidden; + margin-bottom: 8px; } p.rightside { @@ -550,33 +629,206 @@ .attach-comment dfn { width: 100%; } + + /* RTL */ + + /* .topiclist lists + ---------------------------------------- */ + .rtl ul.topiclist li.header dt, + .rtl ul.topiclist li.header dt .list-inner { + margin-left: 0 !important; + padding-left: 0; + } + + .rtl ul.topiclist dt, + .rtl ul.topiclist dt .list-inner, + .rtl ul.topiclist.missing-column dt, + .rtl ul.topiclist.missing-column dt .list-inner, + .rtl ul.topiclist.two-long-columns dt, + .rtl ul.topiclist.two-long-columns dt .list-inner, + .rtl ul.topiclist.two-columns dt, + .rtl ul.topiclist.two-columns dt .list-inner { + margin-left: 0; + } + + .rtl ul.topiclist dt .list-inner.with-mark { + padding-left: 34px; + } + + /* Forums and topics lists + ---------------------------------------- */ + .rtl ul.topiclist.forums dt { + margin-left: -250px; + } + + .rtl ul.topiclist.forums dt .list-inner { + margin-left: 250px; + } + + .rtl ul.topiclist dd.mark { + text-align: right; + right: auto; + left: 5px; + } + + .rtl table.responsive.show-header thead, + .rtl table.responsive.show-header th:first-child { + text-align: right !important; + } + + .rtl table.responsive td { + text-align: right !important; + } + + /* User profile + ---------------------------------------- */ + .rtl .column1, + .rtl .column2, + .rtl .left-box.profile-details { + float: none; + } + + /* Post + ---------------------------------------- */ + .rtl .postprofile, + .rtl .postbody, + .rtl .search .postbody { + float: none; + } + + .rtl .post .postprofile { + border-width: 0 0 1px; + } + + .rtl .postprofile dt, + .rtl .postprofile dd.profile-rank, + .rtl .search .postprofile dd { + margin: 0; + } + + .rtl .postprofile .avatar { + margin-right: 0; + margin-left: 5px; + } + + .rtl .has-profile .post-buttons { + left: 20px; + } + + /* Forms + ---------------------------------------- */ + .rtl fieldset dt, + .rtl fieldset.fields1 dt, + .rtl fieldset.fields2 dt { + float: none; + } + + .rtl fieldset dd, + .rtl fieldset.fields1 dd, + .rtl fieldset.fields2 dd { + margin-right: 20px; + } } @media (min-width: 700px) { - .postbody { width: 70%; } + .postbody { + width: 70%; + } } @media (min-width: 850px) { - .postbody { width: 76%; } + .postbody { + width: 76%; + } } @media (max-width: 850px) { - .postprofile { width: 28%; } - - + .postprofile { + width: 28%; + } } @media (min-width: 701px) and (max-width: 950px) { - ul.topiclist dt { - margin-right: -410px; + margin-right: -410px; } ul.topiclist dt .list-inner { - margin-right: 410px; + margin-right: 410px; } - dd.posts, dd.topics, dd.views { - width: 80px; + dd.posts, + dd.topics, + dd.views { + width: 80px; } } + +/* Responsive *CP navigation +---------------------------------------- */ +@media (max-width: 900px) { + .nojs .tabs a span, + .nojs .minitabs a span { + letter-spacing: -0.03em; + text-overflow: ellipsis; + overflow: hidden; + max-width: 40px; + } + + .cp-menu, + .navigation, + .cp-main { + float: none; + width: auto; + margin: 0; + } + + .navigation { + max-width: 320px; + margin: 0 auto; + padding: 0; + } + + .navigation a { + background-image: none; + } + + .navigation li:first-child a { + border-top-left-radius: 5px; + border-top-right-radius: 5px; + } + + .navigation li:last-child a { + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; + } + + .rtl .cp-menu, + .rtl .navigation, + .rtl .cp-main { + float: none; + } + + .navigation a, + .rtl .navigation a { + background: #b2c2cf; + } +} + +@media (max-width: 992px) { + .row .pagination { + text-align: left; + float: left; + margin-top: 4px; + margin-bottom: 4px; + } +} + +@media (max-width: 1220px) { + .wrap { + margin: 0 12px; + } +} + +/* stylelint-enable selector-max-compound-selectors */ +/* stylelint-enable selector-no-qualifying-type */ diff --git a/phpBB/styles/prosilver/theme/stylesheet.css b/phpBB/styles/prosilver/theme/stylesheet.css index 45eb5b6fc96..0da29846db6 100644 --- a/phpBB/styles/prosilver/theme/stylesheet.css +++ b/phpBB/styles/prosilver/theme/stylesheet.css @@ -7,15 +7,16 @@ -------------------------------------------------------------- */ -@import url("normalize.css?v=3.2"); -@import url("base.css?v=3.2"); -@import url("utilities.css?v=3.2"); -@import url("common.css?v=3.2"); -@import url("links.css?v=3.2"); -@import url("content.css?v=3.2"); -@import url("buttons.css?v=3.2"); -@import url("cp.css?v=3.2"); -@import url("forms.css?v=3.2"); -@import url("icons.css?v=3.2"); -@import url("colours.css?v=3.2"); -@import url("responsive.css?v=3.2"); +@import url("normalize.css?v=3.3"); +@import url("base.css?v=3.3"); +@import url("utilities.css?v=3.3"); +@import url("common.css?v=3.3"); +@import url("links.css?v=3.3"); +@import url("content.css?v=3.3"); +@import url("buttons.css?v=3.3"); +@import url("cp.css?v=3.3"); +@import url("forms.css?v=3.3"); +@import url("icons.css?v=3.3"); +@import url("colours.css?v=3.3"); +@import url("responsive.css?v=3.3"); +@import url("tweaks.css?v=3.3"); diff --git a/phpBB/styles/prosilver/theme/tweaks.css b/phpBB/styles/prosilver/theme/tweaks.css index ba82551f851..4b3b7afd24f 100644 --- a/phpBB/styles/prosilver/theme/tweaks.css +++ b/phpBB/styles/prosilver/theme/tweaks.css @@ -1,41 +1,4 @@ -/* Style Sheet Tweaks - -These style definitions are IE 8 & 9 only. -They are required due to the poor CSS support in IE browsers. -------------------------------------------------------------------------------*/ - -/* IE 8 Tweaks (value)\9 equates to IE <= 8 -------------------------------------------------------------------------------*/ - -/* Clear float fix */ -.inner, ul.linklist { zoom: 1\9; } - -/* Align checkboxes/radio buttons nicely */ -dd label input { vertical-align: text-bottom\9; } - -/* Fixes header-avatar aspect-ratio */ -.header-avatar img { height: 20px\9; } - -/* IE8 often can't handle max-width in %, so we use px instead */ -.postprofile .avatar img { max-width: 150px\9; } - - -/* IE 9 Tweaks -------------------------------------------------------------------------------*/ - -/* Border-radius bleed fix in IE9 */ -.search-header, .search-header .inputbox, .search-header a.button { - border-radius: 0; -} - -.headerbar, .forumbg { - background-image: url("./images/bg_header.gif"); -} - -.forabg { - background-image: url("./images/bg_list.gif"); -} - -.tabs .tab > a { - border-radius: 0; -} +/* -------------------------------------------------------------- /* + $Tweaks +/* -------------------------------------------------------------- /* +/* -------------------------------------------------------------- */ diff --git a/phpBB/styles/prosilver/theme/utilities.css b/phpBB/styles/prosilver/theme/utilities.css index cbb8127d1c2..ab47754d5d9 100644 --- a/phpBB/styles/prosilver/theme/utilities.css +++ b/phpBB/styles/prosilver/theme/utilities.css @@ -1,26 +1,26 @@ -/* -------------------------------------------------------------- +/* -------------------------------------------------------------- /* $Utilities --------------------------------------------------------------- */ +/* -------------------------------------------------------------- */ .sr-only { + border: 0; position: absolute; + overflow: hidden; + clip: rect(0, 0, 0, 0); width: 1px; height: 1px; margin: -1px; padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; } .sr-only-focusable:active, .sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - margin: 0; - overflow: visible; - clip: auto; + position: static; + overflow: visible; + clip: auto; + width: auto; + height: auto; + margin: 0; } .clearfix:before, @@ -31,36 +31,55 @@ .container-fluid:after, .row:before, .row:after { - content: " "; display: table; + content: " "; } + .clearfix:after, .container:after, .container-fluid:after, -.row:after { clear: both } +.row:after { + clear: both; +} .center-block { display: block; - margin-left: auto; margin-right: auto; + margin-left: auto; } -.pull-right { float: right !important } -.pull-left { float: left !important } -.hide { display: none !important } -.show { display: block !important } -.invisible { visibility: hidden } +.pull-right { + float: right !important; +} + +.pull-left { + float: left !important; +} + +.hide { + display: none !important; +} + +.show { + display: block !important; +} + +.invisible { + visibility: hidden; +} .text-hide { font: 0/0 a; - color: transparent; - text-shadow: none; background-color: transparent; border: 0; + text-shadow: none; + color: transparent; } .hidden { - display: none ; + display: none; } -.affix { position: fixed } +.affix { + position: fixed; +} diff --git a/phpBB/ucp.php b/phpBB/ucp.php index 7eca5ede62a..03b123d7ef4 100644 --- a/phpBB/ucp.php +++ b/phpBB/ucp.php @@ -387,6 +387,11 @@ $vars = array('module', 'id', 'mode'); extract($phpbb_dispatcher->trigger_event('core.ucp_display_module_before', compact($vars))); +$template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $user->lang('UCP'), + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}ucp.$phpEx"), +)); + // Select the active module $module->set_active($id, $mode); diff --git a/phpBB/vendor-ext/.git-keep b/phpBB/vendor-ext/.git-keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index d5ddb0ba131..f1d4527c191 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -487,6 +487,11 @@ $base_url = append_sid("{$phpbb_root_path}viewonline.$phpEx", "sg=$show_guests&sk=$sort_key&sd=$sort_dir"); $pagination->generate_template_pagination($base_url, 'pagination', 'start', $counter, $config['topics_per_page'], $start); +$template->assign_block_vars('navlinks', array( + 'FORUM_NAME' => $user->lang('WHO_IS_ONLINE'), + 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewonline.$phpEx"), +)); + // Send data to template $template->assign_vars(array( 'TOTAL_REGISTERED_USERS_ONLINE' => $user->lang('REG_USERS_ONLINE', (int) $logged_visible_online, $user->lang('HIDDEN_USERS_ONLINE', (int) $logged_hidden_online)), diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c6e539b7ba8..71a94da89fb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ db = $this->new_dbal(); $db = $this->db; $this->resync = new \phpbb\attachment\resync($this->db); - $this->filesystem = $this->getMock('\phpbb\filesystem\filesystem', array('remove', 'exists')); + $this->filesystem = $this->createMock('\phpbb\filesystem\filesystem', array('remove', 'exists')); $this->filesystem->expects($this->any()) ->method('remove') ->willReturn(false); @@ -103,7 +103,7 @@ public function data_attachment_unlink() */ public function test_attachment_delete_success($remove_success, $exists_success, $expected, $throw_exception = false) { - $this->filesystem = $this->getMock('\phpbb\filesystem\filesystem', array('remove', 'exists')); + $this->filesystem = $this->createMock('\phpbb\filesystem\filesystem', array('remove', 'exists')); if ($throw_exception) { $this->filesystem->expects($this->any()) diff --git a/tests/attachment/upload_test.php b/tests/attachment/upload_test.php index 235ecd082a0..6aaae6ad61e 100644 --- a/tests/attachment/upload_test.php +++ b/tests/attachment/upload_test.php @@ -81,7 +81,7 @@ public function setUp() $config = $this->config; $this->db = $this->new_dbal(); $this->cache = new \phpbb\cache\service(new \phpbb\cache\driver\dummy(), $this->config, $this->db, $phpbb_root_path, $phpEx); - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->filesystem = new \phpbb\filesystem\filesystem(); $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); @@ -336,14 +336,14 @@ public function data_image_upload() */ public function test_image_upload($is_image, $plupload_active, $config_data, $expected) { - $filespec = $this->getMock('\phpbb\files\filespec', - array( + $filespec = $this->getMockBuilder('\phpbb\files\filespec') + ->setMethods(array( 'init_error', 'is_image', 'move_file', 'is_uploaded', - ), - array( + )) + ->setConstructorArgs(array( $this->filesystem, $this->language, $this->php_ini, @@ -351,7 +351,8 @@ public function test_image_upload($is_image, $plupload_active, $config_data, $ex $this->phpbb_root_path, $this->mimetype_guesser, $this->plupload - )); + )) + ->getMock(); foreach ($config_data as $key => $value) { $this->config[$key] = $value; diff --git a/tests/auth/provider_apache_test.php b/tests/auth/provider_apache_test.php index 7d77d763fba..f30d19ef9d2 100644 --- a/tests/auth/provider_apache_test.php +++ b/tests/auth/provider_apache_test.php @@ -27,7 +27,7 @@ protected function setup() $config = new \phpbb\config\config(array()); $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->user = new \phpbb\user($lang, '\phpbb\datetime'); $driver_helper = new \phpbb\passwords\driver\helper($config); $passwords_drivers = array( diff --git a/tests/auth/provider_db_test.php b/tests/auth/provider_db_test.php index 6ff77da5646..b7d94ed046c 100644 --- a/tests/auth/provider_db_test.php +++ b/tests/auth/provider_db_test.php @@ -37,7 +37,7 @@ public function test_login() )); $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); - $request = $this->getMock('\phpbb\request\request'); + $request = $this->createMock('\phpbb\request\request'); $user = new \phpbb\user($lang, '\phpbb\datetime'); $driver_helper = new \phpbb\passwords\driver\helper($config); $passwords_drivers = array( diff --git a/tests/avatar/manager_test.php b/tests/avatar/manager_test.php index 9e826a3a593..2866a1673d1 100644 --- a/tests/avatar/manager_test.php +++ b/tests/avatar/manager_test.php @@ -30,22 +30,28 @@ public function setUp() global $phpbb_root_path, $phpEx; // Mock phpbb_container - $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $phpbb_container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface'); $phpbb_container->expects($this->any()) ->method('get') ->will($this->returnArgument(0)); $filesystem = new \phpbb\filesystem\filesystem(); + $adapter = new \phpbb\storage\adapter\local($filesystem, new \FastImageSize\FastImageSize(), new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\extension_guesser)), $phpbb_root_path); + $adapter->configure(['path' => 'images/avatars/upload']); + $adapter_factory_mock = $this->createMock('\phpbb\storage\adapter_factory'); + $adapter_factory_mock->expects($this->any()) + ->method('get') + ->willReturn($adapter); + $storage = new \phpbb\storage\storage($adapter_factory_mock, ''); // Prepare dependencies for avatar manager and driver $this->config = new \phpbb\config\config(array()); - $cache = $this->getMock('\phpbb\cache\driver\driver_interface'); + $cache = $this->createMock('\phpbb\cache\driver\driver_interface'); $path_helper = new \phpbb\path_helper( new \phpbb\symfony_request( new phpbb_mock_request() ), - $filesystem, - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, $phpEx ); @@ -62,12 +68,17 @@ public function setUp() $dispatcher = new phpbb_mock_event_dispatcher(); // $this->avatar_foobar will be needed later on - $this->avatar_foobar = $this->getMock('\phpbb\avatar\driver\foobar', array('get_name'), array($this->config, $imagesize, $phpbb_root_path, $phpEx, $path_helper, $cache)); + $this->avatar_foobar = $this->getMockBuilder('\phpbb\avatar\driver\foobar') + ->setMethods(array('get_name')) + ->setConstructorArgs(array($this->config, $imagesize, $phpbb_root_path, $phpEx, $path_helper, $cache)) + ->getMock(); $this->avatar_foobar->expects($this->any()) ->method('get_name') ->will($this->returnValue('avatar.driver.foobar')); // barfoo driver can't be mocked with constructor arguments - $this->avatar_barfoo = $this->getMock('\phpbb\avatar\driver\barfoo', array('get_name', 'get_config_name')); + $this->avatar_barfoo = $this->getMockBuilder('\phpbb\avatar\driver\barfoo') + ->setMethods(array('get_name', 'get_config_name')) + ->getMock(); $this->avatar_barfoo->expects($this->any()) ->method('get_name') ->will($this->returnValue('avatar.driver.barfoo')); @@ -78,15 +89,23 @@ public function setUp() $files_factory = new \phpbb\files\factory($phpbb_container); + $php_ini = new \bantu\IniGetWrapper\IniGetWrapper; + foreach ($this->avatar_drivers() as $driver) { if ($driver !== 'upload') { - $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($this->config, $imagesize, $phpbb_root_path, $phpEx, $path_helper, $cache)); + $cur_avatar = $this->getMockBuilder('\phpbb\avatar\driver\\' . $driver) + ->setMethods(array('get_name')) + ->setConstructorArgs(array($this->config, $imagesize, $phpbb_root_path, $phpEx, $path_helper, $cache)) + ->getMock(); } else { - $cur_avatar = $this->getMock('\phpbb\avatar\driver\\' . $driver, array('get_name'), array($this->config, $phpbb_root_path, $phpEx, $filesystem, $path_helper, $dispatcher, $files_factory, $cache)); + $cur_avatar = $this->getMockBuilder('\phpbb\avatar\driver\\' . $driver) + ->setMethods(array('get_name')) + ->setConstructorArgs(array($this->config, $phpbb_root_path, $phpEx, $storage, $path_helper, $dispatcher, $files_factory, $php_ini)) + ->getMock(); } $cur_avatar->expects($this->any()) ->method('get_name') @@ -288,10 +307,10 @@ public function test_localize_errors() { global $phpbb_root_path, $phpEx; - $user = $this->getMock('\phpbb\user', array(), array( - new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), - '\phpbb\datetime') - ); + $user = $this->getMockBuilder('\phpbb\user') + ->setMethods(array()) + ->setConstructorArgs(array(new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime')) + ->getMock(); $lang_array = array( array('FOOBAR_OFF', 'foobar_off'), array('FOOBAR_EXPLAIN', 'FOOBAR_EXPLAIN %s'), diff --git a/tests/console/cache/purge_test.php b/tests/console/cache/purge_test.php index 6c92660580e..7a7e1dee5ce 100644 --- a/tests/console/cache/purge_test.php +++ b/tests/console/cache/purge_test.php @@ -44,10 +44,10 @@ protected function setUp() $this->cache = new \phpbb\cache\driver\file($this->cache_dir); - $this->db = $this->getMock('\phpbb\db\driver\driver_interface'); + $this->db = $this->createMock('\phpbb\db\driver\driver_interface'); $this->config = new \phpbb\config\config(array('assets_version' => 1)); - $this->user = $this->getMock('\phpbb\user', array(), array( + $this->user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime') ); @@ -91,7 +91,7 @@ private function remove_cache_dir() public function get_command_tester() { $application = new Application(); - $application->add(new purge($this->user, $this->cache, $this->db, $this->getMock('\phpbb\auth\auth'), new \phpbb\log\dummy(), $this->config)); + $application->add(new purge($this->user, $this->cache, $this->db, $this->createMock('\phpbb\auth\auth'), new \phpbb\log\dummy(), $this->config)); $command = $application->find('cache:purge'); $this->command_name = $command->getName(); diff --git a/tests/console/config/config_test.php b/tests/console/config/config_test.php index 076316217d4..7f8b2efce24 100644 --- a/tests/console/config/config_test.php +++ b/tests/console/config/config_test.php @@ -26,7 +26,7 @@ public function setUp() $this->config = new \phpbb\config\config(array()); - $this->user = $this->getMock('\phpbb\user', array(), array( + $this->user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime') ); diff --git a/tests/console/cron/cron_list_test.php b/tests/console/cron/cron_list_test.php index fdc9a05cb23..931713cd3c0 100644 --- a/tests/console/cron/cron_list_test.php +++ b/tests/console/cron/cron_list_test.php @@ -34,7 +34,7 @@ protected function setUp() { global $phpbb_root_path, $phpEx; - $this->user = $this->getMock('\phpbb\user', array(), array( + $this->user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); @@ -74,7 +74,34 @@ public function get_cron_manager(array $tasks) $task->set_name('command' . $i); $i++; } - $this->cron_manager = new \phpbb\cron\manager($tasks, $phpbb_root_path, $pathEx); + + $mock_config = new \phpbb\config\config(array( + 'force_server_vars' => false, + 'enable_mod_rewrite' => '', + )); + + $mock_router = $this->getMockBuilder('\phpbb\routing\router') + ->setMethods(array('setContext', 'generate')) + ->disableOriginalConstructor() + ->getMock(); + $mock_router->method('setContext') + ->willReturn(true); + $mock_router->method('generate') + ->willReturn('foobar'); + + $request = new \phpbb\request\request(); + $request->enable_super_globals(); + + $routing_helper = new \phpbb\routing\helper( + $mock_config, + $mock_router, + new \phpbb\symfony_request($request), + $request, + $phpbb_root_path, + $pathEx + ); + + $this->cron_manager = new \phpbb\cron\manager($tasks, $routing_helper, $phpbb_root_path, $pathEx); } public function get_command_tester() diff --git a/tests/console/cron/run_test.php b/tests/console/cron/run_test.php index b4a0203325d..81e4e69f396 100644 --- a/tests/console/cron/run_test.php +++ b/tests/console/cron/run_test.php @@ -40,7 +40,7 @@ public function setUp() $config = $this->config = new \phpbb\config\config(array('cron_lock' => '0')); $this->lock = new \phpbb\lock\db('cron_lock', $this->config, $this->db); - $this->user = $this->getMock('\phpbb\user', array(), array( + $this->user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); @@ -50,7 +50,34 @@ public function setUp() $tasks = array( $this->task, ); - $this->cron_manager = new \phpbb\cron\manager($tasks, $phpbb_root_path, $phbEx); + + $mock_config = new \phpbb\config\config(array( + 'force_server_vars' => false, + 'enable_mod_rewrite' => '', + )); + + $mock_router = $this->getMockBuilder('\phpbb\routing\router') + ->setMethods(array('setContext', 'generate')) + ->disableOriginalConstructor() + ->getMock(); + $mock_router->method('setContext') + ->willReturn(true); + $mock_router->method('generate') + ->willReturn('foobar'); + + $request = new \phpbb\request\request(); + $request->enable_super_globals(); + + $routing_helper = new \phpbb\routing\helper( + $mock_config, + $mock_router, + new \phpbb\symfony_request($request), + $request, + $phpbb_root_path, + $phpEx + ); + + $this->cron_manager = new \phpbb\cron\manager($tasks, $routing_helper, $phpbb_root_path, $phpEx); $this->assertSame('0', $config['cron_lock']); } @@ -96,7 +123,34 @@ public function test_no_task() { $tasks = array( ); - $this->cron_manager = new \phpbb\cron\manager($tasks, $phpbb_root_path, $phpEx); + + $mock_config = new \phpbb\config\config(array( + 'force_server_vars' => false, + 'enable_mod_rewrite' => '', + )); + + $mock_router = $this->getMockBuilder('\phpbb\routing\router') + ->setMethods(array('setContext', 'generate')) + ->disableOriginalConstructor() + ->getMock(); + $mock_router->method('setContext') + ->willReturn(true); + $mock_router->method('generate') + ->willReturn('foobar'); + + $request = new \phpbb\request\request(); + $request->enable_super_globals(); + + $routing_helper = new \phpbb\routing\helper( + $mock_config, + $mock_router, + new \phpbb\symfony_request($request), + $request, + $phpbb_root_path, + $phpEx + ); + + $this->cron_manager = new \phpbb\cron\manager($tasks, $routing_helper, $phpbb_root_path, $phpEx); $command_tester = $this->get_command_tester(); $exit_status = $command_tester->execute(array('command' => $this->command_name)); @@ -109,7 +163,34 @@ public function test_no_task_verbose() { $tasks = array( ); - $this->cron_manager = new \phpbb\cron\manager($tasks, $phpbb_root_path, $phpEx); + + $mock_config = new \phpbb\config\config(array( + 'force_server_vars' => false, + 'enable_mod_rewrite' => '', + )); + + $mock_router = $this->getMockBuilder('\phpbb\routing\router') + ->setMethods(array('setContext', 'generate')) + ->disableOriginalConstructor() + ->getMock(); + $mock_router->method('setContext') + ->willReturn(true); + $mock_router->method('generate') + ->willReturn('foobar'); + + $request = new \phpbb\request\request(); + $request->enable_super_globals(); + + $routing_helper = new \phpbb\routing\helper( + $mock_config, + $mock_router, + new \phpbb\symfony_request($request), + $request, + $phpbb_root_path, + $phpEx + ); + + $this->cron_manager = new \phpbb\cron\manager($tasks, $routing_helper, $phpbb_root_path, $phpEx); $command_tester = $this->get_command_tester(); $exit_status = $command_tester->execute(array('command' => $this->command_name, '--verbose' => true)); diff --git a/tests/console/thumbnail_test.php b/tests/console/thumbnail_test.php index 439e3623fa0..ecce6f157c1 100644 --- a/tests/console/thumbnail_test.php +++ b/tests/console/thumbnail_test.php @@ -50,14 +50,14 @@ public function setUp() )); $this->db = $this->db = $this->new_dbal(); - $this->user = $this->getMock('\phpbb\user', array(), array( + $this->user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime') ); $this->phpbb_root_path = $phpbb_root_path; $this->phpEx = $phpEx; - $this->cache = $this->getMock('\phpbb\cache\service', array(), array(new phpbb_mock_cache(), $this->config, $this->db, $this->phpbb_root_path, $this->phpEx)); + $this->cache = $this->createMock('\phpbb\cache\service', array(), array(new phpbb_mock_cache(), $this->config, $this->db, $this->phpbb_root_path, $this->phpEx)); $this->cache->expects(self::any())->method('obtain_attach_extensions')->will(self::returnValue(array( 'png' => array('display_cat' => ATTACHMENT_CATEGORY_IMAGE), 'txt' => array('display_cat' => ATTACHMENT_CATEGORY_NONE), diff --git a/tests/console/update/check_test.php b/tests/console/update/check_test.php index 5cadc5cc97f..6812ea61b8d 100644 --- a/tests/console/update/check_test.php +++ b/tests/console/update/check_test.php @@ -84,7 +84,7 @@ public function get_command_tester($current_version) $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); - $user = $this->getMock('\phpbb\user', array(), array( + $user = $this->createMock('\phpbb\user', array(), array( $this->language, '\phpbb\datetime' )); diff --git a/tests/console/user/base.php b/tests/console/user/base.php index b84c0bb267d..5382b9d8963 100644 --- a/tests/console/user/base.php +++ b/tests/console/user/base.php @@ -39,7 +39,7 @@ public function setUp() $phpbb_container->set('cache.driver', new phpbb_mock_cache()); $phpbb_container->set('notification_manager', new phpbb_mock_notification_manager()); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $cache = $phpbb_container->get('cache.driver'); @@ -62,7 +62,7 @@ public function setUp() $this->language->expects($this->any()) ->method('lang') ->will($this->returnArgument(0)); - $user = $this->user = $this->getMock('\phpbb\user', array(), array( + $user = $this->user = $this->createMock('\phpbb\user', array(), array( $this->language, '\phpbb\datetime' )); diff --git a/tests/content_visibility/delete_post_test.php b/tests/content_visibility/delete_post_test.php index 4ea95b0a966..4f978219c25 100644 --- a/tests/content_visibility/delete_post_test.php +++ b/tests/content_visibility/delete_post_test.php @@ -299,7 +299,7 @@ public function test_delete_post($forum_id, $topic_id, $post_id, $data, $is_soft $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); // Create auth mock - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $auth->expects($this->any()) ->method('acl_get') ->with($this->stringContains('_'), $this->anything()) diff --git a/tests/content_visibility/get_forums_visibility_sql_test.php b/tests/content_visibility/get_forums_visibility_sql_test.php index 6c5066119e2..fde2b621310 100644 --- a/tests/content_visibility/get_forums_visibility_sql_test.php +++ b/tests/content_visibility/get_forums_visibility_sql_test.php @@ -129,7 +129,7 @@ public function test_get_forums_visibility_sql($table, $mode, $forum_ids, $table $db = $this->new_dbal(); // Create auth mock - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $auth->expects($this->any()) ->method('acl_getf') ->with($this->stringContains('_'), $this->anything()) diff --git a/tests/content_visibility/get_global_visibility_sql_test.php b/tests/content_visibility/get_global_visibility_sql_test.php index 9ae4182673a..eced3aa680d 100644 --- a/tests/content_visibility/get_global_visibility_sql_test.php +++ b/tests/content_visibility/get_global_visibility_sql_test.php @@ -129,7 +129,7 @@ public function test_get_global_visibility_sql($table, $mode, $forum_ids, $table $db = $this->new_dbal(); // Create auth mock - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $auth->expects($this->any()) ->method('acl_getf') ->with($this->stringContains('_'), $this->anything()) diff --git a/tests/content_visibility/get_visibility_sql_test.php b/tests/content_visibility/get_visibility_sql_test.php index aaaf64330e0..18802fadbc0 100644 --- a/tests/content_visibility/get_visibility_sql_test.php +++ b/tests/content_visibility/get_visibility_sql_test.php @@ -76,7 +76,7 @@ public function test_get_visibility_sql($table, $mode, $forum_id, $table_alias, $db = $this->new_dbal(); // Create auth mock - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $auth->expects($this->any()) ->method('acl_get') ->with($this->stringContains('_'), $this->anything()) diff --git a/tests/content_visibility/set_post_visibility_test.php b/tests/content_visibility/set_post_visibility_test.php index e33a1f30d50..8f629dca627 100644 --- a/tests/content_visibility/set_post_visibility_test.php +++ b/tests/content_visibility/set_post_visibility_test.php @@ -120,7 +120,7 @@ public function test_set_post_visibility($visibility, $post_id, $topic_id, $foru $cache = new phpbb_mock_cache; $db = $this->new_dbal(); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); $user = new \phpbb\user($lang, '\phpbb\datetime'); @@ -173,7 +173,7 @@ public function test_set_post_soft_deleted($post_id, $topic_id, $forum_id, $user $cache = new phpbb_mock_cache; $db = $this->new_dbal(); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); $user = new \phpbb\user($lang, '\phpbb\datetime'); diff --git a/tests/content_visibility/set_topic_visibility_test.php b/tests/content_visibility/set_topic_visibility_test.php index 78431396c3a..3db79c0fe0c 100644 --- a/tests/content_visibility/set_topic_visibility_test.php +++ b/tests/content_visibility/set_topic_visibility_test.php @@ -84,7 +84,7 @@ public function test_set_topic_visibility($visibility, $topic_id, $forum_id, $us $cache = new phpbb_mock_cache; $db = $this->new_dbal(); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); $user = new \phpbb\user($lang, '\phpbb\datetime'); diff --git a/tests/controller/common_helper_route.php b/tests/controller/common_helper_route.php index ea2bc042b14..3c732ff49b8 100644 --- a/tests/controller/common_helper_route.php +++ b/tests/controller/common_helper_route.php @@ -91,7 +91,6 @@ protected function generate_route_objects() $this->filesystem = new \phpbb\filesystem\filesystem(); $this->phpbb_path_helper = new \phpbb\path_helper( $this->symfony_request, - $this->filesystem, $this->request, $phpbb_root_path, $phpEx @@ -106,7 +105,7 @@ protected function generate_route_objects() $container->setParameter('core.environment', PHPBB_ENVIRONMENT); $cache_path = $phpbb_root_path . 'cache/twig'; $context = new \phpbb\template\context(); - $loader = new \phpbb\template\twig\loader($this->filesystem, ''); + $loader = new \phpbb\template\twig\loader(''); $twig = new \phpbb\template\twig\environment( $this->config, $this->filesystem, @@ -137,7 +136,7 @@ protected function generate_route_objects() ); $loader = new \Symfony\Component\Routing\Loader\YamlFileLoader( - new \phpbb\routing\file_locator($this->filesystem, dirname(__FILE__) . '/') + new \phpbb\routing\file_locator(dirname(__FILE__) . '/') ); $resources_locator = new \phpbb\routing\resources_locator\default_resources_locator(dirname(__FILE__) . '/', PHPBB_ENVIRONMENT, $this->extension_manager); $this->router = new phpbb_mock_router($container, $resources_locator, $loader, dirname(__FILE__) . '/', 'php'); @@ -185,7 +184,7 @@ public function helper_url_data_no_rewrite() public function test_helper_url_no_rewrite($route, $params, $is_amp, $session_id, $expected, $description) { $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id), $description); } @@ -229,7 +228,7 @@ public function helper_url_data_with_rewrite() public function test_helper_url_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) { $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id), $description); } @@ -273,7 +272,7 @@ public function helper_url_data_absolute() public function test_helper_url_absolute($route, $params, $is_amp, $session_id, $expected, $description) { $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::ABSOLUTE_URL), $description); } @@ -317,7 +316,7 @@ public function helper_url_data_relative_path() public function test_helper_url_relative_path($route, $params, $is_amp, $session_id, $expected, $description) { $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::RELATIVE_PATH), $description); } @@ -361,7 +360,7 @@ public function helper_url_data_network() public function test_helper_url_network($route, $params, $is_amp, $session_id, $expected, $description) { $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::NETWORK_PATH), $description); } @@ -405,7 +404,7 @@ public function helper_url_data_absolute_with_rewrite() public function test_helper_url_absolute_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) { $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::ABSOLUTE_URL), $description); } @@ -446,7 +445,7 @@ public function helper_url_data_relative_path_with_rewrite() public function test_helper_url_relative_path_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) { $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::RELATIVE_PATH), $description); } @@ -490,7 +489,7 @@ public function helper_url_data_network_with_rewrite() public function test_helper_url_network_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) { $this->config = new \phpbb\config\config(['enable_mod_rewrite' => '1']); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::NETWORK_PATH), $description); } @@ -522,7 +521,7 @@ public function test_helper_url_force_server_vars($enable_mod_rewrite, $force_se 'server_protocol' => $server_protocol, )); - $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper); static::assertEquals($expected, $this->helper->route('controller1', array(), false, false, $type)); } diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php index d921d0eade4..3bab158ac8a 100644 --- a/tests/controller/controller_test.php +++ b/tests/controller/controller_test.php @@ -45,7 +45,7 @@ public function test_router_default_loader() $container->setParameter('core.environment', PHPBB_ENVIRONMENT); $loader = new \Symfony\Component\Routing\Loader\YamlFileLoader( - new \phpbb\routing\file_locator(new \phpbb\filesystem\filesystem(), dirname(__FILE__) . '/') + new \phpbb\routing\file_locator(dirname(__FILE__) . '/') ); $resources_locator = new \phpbb\routing\resources_locator\default_resources_locator(dirname(__FILE__) . '/', PHPBB_ENVIRONMENT, $this->extension_manager); $router = new phpbb_mock_router($container, $resources_locator, $loader, dirname(__FILE__) . '/', 'php'); diff --git a/tests/cron/manager_test.php b/tests/cron/manager_test.php index 76f8c753bf2..e1699e64868 100644 --- a/tests/cron/manager_test.php +++ b/tests/cron/manager_test.php @@ -75,6 +75,32 @@ private function create_cron_manager($tasks) { global $phpbb_root_path, $phpEx; - return new \phpbb\cron\manager($tasks, $phpbb_root_path, $phpEx); + $mock_config = new \phpbb\config\config(array( + 'force_server_vars' => false, + 'enable_mod_rewrite' => '', + )); + + $mock_router = $this->getMockBuilder('\phpbb\routing\router') + ->setMethods(array('setContext', 'generate')) + ->disableOriginalConstructor() + ->getMock(); + $mock_router->method('setContext') + ->willReturn(true); + $mock_router->method('generate') + ->willReturn('foobar'); + + $request = new \phpbb\request\request(); + $request->enable_super_globals(); + + $routing_helper = new \phpbb\routing\helper( + $mock_config, + $mock_router, + new \phpbb\symfony_request($request), + $request, + $phpbb_root_path, + $phpEx + ); + + return new \phpbb\cron\manager($tasks, $routing_helper, $phpbb_root_path, $phpEx); } } diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index 0365463a48c..818d8d8e171 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -346,10 +346,10 @@ public function test_table_drop() public function test_perform_schema_changes_drop_tables() { - $db_tools = $this->getMock('\phpbb\db\tools\tools', array( - 'sql_table_exists', - 'sql_table_drop', - ), array(&$this->db)); + $db_tools = $this->getMockBuilder('\phpbb\db\tools\tools') + ->setMethods(array('sql_table_exists', 'sql_table_drop')) + ->setConstructorArgs(array(&$this->db)) + ->getMock(); // pretend all tables exist $db_tools->expects($this->any())->method('sql_table_exists') @@ -372,10 +372,10 @@ public function test_perform_schema_changes_drop_tables() public function test_perform_schema_changes_drop_columns() { - $db_tools = $this->getMock('\phpbb\db\tools\tools', array( - 'sql_column_exists', - 'sql_column_remove', - ), array(&$this->db)); + $db_tools = $this->getMockBuilder('\phpbb\db\tools\tools') + ->setMethods(array('sql_column_exists', 'sql_column_remove')) + ->setConstructorArgs(array(&$this->db)) + ->getMock(); // pretend all columns exist $db_tools->expects($this->any())->method('sql_column_exists') diff --git a/tests/dbal/migration/if.php b/tests/dbal/migration/if.php index 481250ea77c..83fba1cbd49 100644 --- a/tests/dbal/migration/if.php +++ b/tests/dbal/migration/if.php @@ -23,11 +23,11 @@ function update_data() return array( array('if', array( true, - array('custom', array(array(&$this, 'test_true'))), + array('custom', array(array($this, 'test_true'))), )), array('if', array( false, - array('custom', array(array(&$this, 'test_false'))), + array('custom', array(array($this, 'test_false'))), )), ); } diff --git a/tests/dbal/migration/if_params.php b/tests/dbal/migration/if_params.php new file mode 100644 index 00000000000..7280088ddc5 --- /dev/null +++ b/tests/dbal/migration/if_params.php @@ -0,0 +1,44 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +class phpbb_dbal_migration_if_params extends \phpbb\db\migration\migration +{ + function update_schema() + { + return array(); + } + + function update_data() + { + return array( + array('if', array( + true, + array('custom', array(array($this, 'test'), array('true'))), + )), + array('if', array( + false, + array('custom', array(array($this, 'test'), array('false'))), + )), + ); + } + + function test($param) + { + global $migrator_test_if_true_failed, $migrator_test_if_false_failed; + + $var = 'migrator_test_if_' . $param . '_failed'; + + ${$var} = !${$var}; + } + +} diff --git a/tests/dbal/migration/recall.php b/tests/dbal/migration/recall.php index c0333b084d4..e065b5c4d8c 100644 --- a/tests/dbal/migration/recall.php +++ b/tests/dbal/migration/recall.php @@ -21,7 +21,7 @@ function update_schema() function update_data() { return array( - array('custom', array(array(&$this, 'test_call'))), + array('custom', array(array($this, 'test_call'))), ); } diff --git a/tests/dbal/migration/recall_params.php b/tests/dbal/migration/recall_params.php new file mode 100644 index 00000000000..ee0f04c09db --- /dev/null +++ b/tests/dbal/migration/recall_params.php @@ -0,0 +1,42 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +class phpbb_dbal_migration_recall_params extends \phpbb\db\migration\migration +{ + function update_schema() + { + return array(); + } + + function update_data() + { + return array( + array('custom', array(array($this, 'test_call'), array(5))), + ); + } + + // This function should be called 5 times + function test_call($times, $input) + { + global $migrator_test_call_input; + + $migrator_test_call_input = (int) $input; + + if ($migrator_test_call_input < $times) + { + return ($migrator_test_call_input + 1); + } + + return; + } +} diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index 372b2dbe1eb..a5f587fc710 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -15,6 +15,8 @@ require_once dirname(__FILE__) . '/migration/unfulfillable.php'; require_once dirname(__FILE__) . '/migration/if.php'; require_once dirname(__FILE__) . '/migration/recall.php'; +require_once dirname(__FILE__) . '/migration/if_params.php'; +require_once dirname(__FILE__) . '/migration/recall_params.php'; require_once dirname(__FILE__) . '/migration/revert.php'; require_once dirname(__FILE__) . '/migration/revert_with_dependency.php'; require_once dirname(__FILE__) . '/migration/revert_table.php'; @@ -77,7 +79,6 @@ public function setUp() $container, $this->db, $this->config, - new phpbb\filesystem\filesystem(), 'phpbb_ext', dirname(__FILE__) . '/../../phpBB/', 'php', @@ -196,6 +197,54 @@ public function test_recall() $this->assertSame(10, $migrator_test_call_input); } + public function test_if_params() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_if_params')); + + // Don't like this, but I'm not sure there is any other way to do this + global $migrator_test_if_true_failed, $migrator_test_if_false_failed; + $migrator_test_if_true_failed = true; + $migrator_test_if_false_failed = false; + + while (!$this->migrator->finished()) + { + $this->migrator->update(); + } + + $this->assertFalse($migrator_test_if_true_failed, 'True test failed'); + $this->assertFalse($migrator_test_if_false_failed, 'False test failed'); + + while ($this->migrator->migration_state('phpbb_dbal_migration_if_params') !== false) + { + $this->migrator->revert('phpbb_dbal_migration_if_params'); + } + + $this->assertFalse($migrator_test_if_true_failed, 'True test after revert failed'); + $this->assertFalse($migrator_test_if_false_failed, 'False test after revert failed'); + } + + public function test_recall_params() + { + $this->migrator->set_migrations(array('phpbb_dbal_migration_recall_params')); + + global $migrator_test_call_input; + + // Run the schema first + $this->migrator->update(); + + $i = 0; + while (!$this->migrator->finished()) + { + $this->migrator->update(); + + $this->assertSame($i, $migrator_test_call_input); + + $i++; + } + + $this->assertSame(5, $migrator_test_call_input); + } + public function test_revert() { global $migrator_test_revert_counter; diff --git a/tests/dbal/migrator_tool_module_test.php b/tests/dbal/migrator_tool_module_test.php index c625b93ded3..12fb09d21a0 100644 --- a/tests/dbal/migrator_tool_module_test.php +++ b/tests/dbal/migrator_tool_module_test.php @@ -36,7 +36,7 @@ public function setup() $cache = new phpbb_mock_cache; $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); $phpbb_extension_manager = new phpbb_mock_extension_manager($phpbb_root_path); diff --git a/tests/di/fixtures/config/production/container/environment.yml b/tests/di/fixtures/config/production/container/environment.yml index 8281d9e941d..ba6b6797955 100644 --- a/tests/di/fixtures/config/production/container/environment.yml +++ b/tests/di/fixtures/config/production/container/environment.yml @@ -19,6 +19,11 @@ services: ext.manager: class: phpbb\extension\manager_mock + config: + class: phpbb\config\config + arguments: + - [] + template.twig.environment: class: Exception arguments: diff --git a/tests/di/fixtures/config/test/container/environment.yml b/tests/di/fixtures/config/test/container/environment.yml index 252117dd327..97ebe4aee1f 100644 --- a/tests/di/fixtures/config/test/container/environment.yml +++ b/tests/di/fixtures/config/test/container/environment.yml @@ -16,6 +16,11 @@ services: dispatcher: class: phpbb\db\driver\container_mock + config: + class: phpbb\config\config + arguments: + - [] + template.twig.environment: class: Exception arguments: diff --git a/tests/di/fixtures/ext/vendor/enabled_4/di/extension.php b/tests/di/fixtures/ext/vendor/enabled_4/di/extension.php index 8e5ed6c52c9..2164077d8eb 100644 --- a/tests/di/fixtures/ext/vendor/enabled_4/di/extension.php +++ b/tests/di/fixtures/ext/vendor/enabled_4/di/extension.php @@ -17,6 +17,7 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use phpbb\filesystem\helper as filesystem_helper; /** * Container core extension @@ -25,8 +26,7 @@ class extension extends extension_base { protected function load_services(ContainerBuilder $container) { - $filesystem = new \phpbb\filesystem\filesystem(); - $loader = new YamlFileLoader($container, new FileLocator($filesystem->realpath($this->ext_path))); + $loader = new YamlFileLoader($container, new FileLocator(filesystem_helper::realpath($this->ext_path))); $loader->load('environment.yml'); } } diff --git a/tests/di/fixtures/other_config/production/container/environment.yml b/tests/di/fixtures/other_config/production/container/environment.yml index c0d2f87babc..aeb552eeb73 100644 --- a/tests/di/fixtures/other_config/production/container/environment.yml +++ b/tests/di/fixtures/other_config/production/container/environment.yml @@ -19,6 +19,11 @@ services: ext.manager: class: phpbb\extension\manager_mock + config: + class: phpbb\config\config + arguments: + - [] + template.twig.environment: class: Exception arguments: diff --git a/tests/di/service_collection_test.php b/tests/di/service_collection_test.php index 5b51254a4a7..5815b4367d6 100644 --- a/tests/di/service_collection_test.php +++ b/tests/di/service_collection_test.php @@ -23,10 +23,14 @@ public function setUp() $container = new phpbb_mock_container_builder(); $container->set('foo', new StdClass); $container->set('bar', new StdClass); + $container->set('baz', new StdClass); $this->service_collection = new \phpbb\di\service_collection($container); $this->service_collection->add('foo'); $this->service_collection->add('bar'); + $this->service_collection->add_service_class('foo', 'foo_class'); + $this->service_collection->add_service_class('bar', 'bar_class'); + $this->service_collection->add_service_class('baz', 'bar_class'); parent::setUp(); } @@ -44,4 +48,23 @@ public function test_service_collection() $this->assertSame(array('foo', 'bar'), $service_names); } + + public function test_get_by_class() + { + $this->assertSame($this->service_collection['foo'], $this->service_collection->get_by_class('foo_class')); + } + + public function test_get_by_class_many_services_exception() + { + $this->setExpectedException('RuntimeException', 'More than one service definitions found for class "bar_class" in collection.'); + + $this->service_collection->get_by_class('bar_class'); + } + + public function test_get_by_class_no_service_exception() + { + $this->setExpectedException('RuntimeException', 'No service found for class "baz_class" in collection.'); + + $this->service_collection->get_by_class('baz_class'); + } } diff --git a/tests/email/email_parsing_test.php b/tests/email/email_parsing_test.php index 8fdfe3035e3..245c2c3a588 100644 --- a/tests/email/email_parsing_test.php +++ b/tests/email/email_parsing_test.php @@ -39,7 +39,6 @@ public function setUp() $filesystem = new \phpbb\filesystem\filesystem(); $phpbb_path_helper = new \phpbb\path_helper( $symfony_request, - $filesystem, $request, $phpbb_root_path, $phpEx @@ -80,7 +79,7 @@ public function setUp() $phpbb_path_helper, $cache_path, null, - new \phpbb\template\twig\loader($filesystem, ''), + new \phpbb\template\twig\loader(''), new \phpbb\event\dispatcher($phpbb_container), array( 'cache' => false, diff --git a/tests/event/exception_listener_test.php b/tests/event/exception_listener_test.php index 08679a3ed85..fbae9e25b7f 100644 --- a/tests/event/exception_listener_test.php +++ b/tests/event/exception_listener_test.php @@ -84,7 +84,7 @@ public function test_phpbb_exception($is_ajax, $exception, $expected) $exception_listener = new \phpbb\event\kernel_exception_subscriber($template, $lang); - $event = new \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent($this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, \Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST, $exception); + $event = new \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent($this->createMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, \Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST, $exception); $exception_listener->on_kernel_exception($event); $response = $event->getResponse(); diff --git a/tests/event/php_exporter_test.php b/tests/event/php_exporter_test.php index 21dbb1e1d43..07929065c3a 100644 --- a/tests/event/php_exporter_test.php +++ b/tests/event/php_exporter_test.php @@ -122,7 +122,7 @@ public function test_crawl_php_file($file, $expected) static public function crawl_php_file_throws_data() { return array( - array('missing_var.test', null), + array('missing_var.test', 2), array('duplicate_event.test', 10), ); } @@ -132,7 +132,8 @@ static public function crawl_php_file_throws_data() */ public function test_crawl_php_file_throws($file, $exception_code) { - $this->setExpectedException('LogicException', '', $exception_code); + $this->expectException('LogicException'); + $this->expectExceptionCode($exception_code); $this->exporter->crawl_php_file($file); } @@ -206,7 +207,8 @@ static public function validate_event_throws_data() */ public function test_validate_event_throws($event_name, $event, $exception_code) { - $this->setExpectedException('LogicException', '', $exception_code); + $this->expectException('LogicException'); + $this->expectExceptionCode($exception_code); $this->exporter->validate_event($event_name, $event); } @@ -461,7 +463,8 @@ static public function get_vars_from_array_throws_data() */ public function test_get_vars_from_array_throws($lines, $event_line, $exception_code) { - $this->setExpectedException('LogicException', '', $exception_code); + $this->expectException('LogicException'); + $this->expectExceptionCode($exception_code); $this->exporter->set_current_event('', $event_line); $this->exporter->set_content($lines); @@ -546,7 +549,8 @@ static public function get_vars_from_docblock_throws_data() */ public function test_get_vars_from_docblock_throws($lines, $event_line, $exception_code) { - $this->setExpectedException('LogicException', '', $exception_code); + $this->expectException('LogicException'); + $this->expectExceptionCode($exception_code); $this->exporter->set_current_event('', $event_line); $this->exporter->set_content($lines); @@ -649,7 +653,8 @@ static public function find_since_throws_data() */ public function test_find_since_throws($lines, $event_line, $exception_code) { - $this->setExpectedException('LogicException', '', $exception_code); + $this->expectException('LogicException'); + $this->expectExceptionCode($exception_code); $this->exporter->set_current_event('', $event_line); $this->exporter->set_content($lines); @@ -750,7 +755,8 @@ static public function find_description_throws_data() */ public function test_find_description_throws($lines, $event_line, $exception_code) { - $this->setExpectedException('LogicException', '', $exception_code); + $this->expectException('LogicException'); + $this->expectExceptionCode($exception_code); $this->exporter->set_current_event('', $event_line); $this->exporter->set_content($lines); diff --git a/tests/extension/finder_test.php b/tests/extension/finder_test.php index 71de2c2fc5a..02c70fd503d 100644 --- a/tests/extension/finder_test.php +++ b/tests/extension/finder_test.php @@ -239,11 +239,11 @@ public function test_find_from_extension() /** * These do not work because of changes with PHPBB3-11386 - * They do not seem neccessary to me, so I am commenting them out for now + * They do not seem necessary to me, so I am commenting them out for now public function test_get_classes_create_cache() { $cache = new phpbb_mock_cache; - $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), dirname(__FILE__) . '/', $cache, 'php', '_custom_cache_name'); + $finder = new \phpbb\finder(dirname(__FILE__) . '/', $cache, 'php', '_custom_cache_name'); $finder->set_extensions(array_keys($this->extension_manager->all_enabled())); $files = $finder->suffix('_class.php')->get_files(); @@ -283,7 +283,6 @@ public function test_cached_get_files() ); $finder = new \phpbb\finder( - new \phpbb\filesystem\filesystem(), dirname(__FILE__) . '/', new phpbb_mock_cache(array( '_ext_finder' => array( diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php index f619d4c19df..a1765775d82 100644 --- a/tests/extension/manager_test.php +++ b/tests/extension/manager_test.php @@ -176,7 +176,6 @@ protected function create_extension_manager($with_cache = true) $container, $db, $config, - new \phpbb\filesystem\filesystem(), 'phpbb_ext', dirname(__FILE__) . '/', $php_ext, diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index 533da68c57f..5887fd974d7 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -52,14 +52,13 @@ protected function setUp() $container = new phpbb_mock_container_builder(); $cache_path = $this->phpbb_root_path . 'cache/twig'; $context = new \phpbb\template\context(); - $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), ''); + $loader = new \phpbb\template\twig\loader(''); $filesystem = new \phpbb\filesystem\filesystem(); $phpbb_path_helper = new \phpbb\path_helper( new \phpbb\symfony_request( new phpbb_mock_request() ), - $filesystem, - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $this->phpbb_root_path, $this->phpEx ); @@ -97,7 +96,6 @@ protected function setUp() $container, $this->db, $this->config, - new \phpbb\filesystem\filesystem(), 'phpbb_ext', $this->phpbb_root_path, $this->phpEx, diff --git a/tests/extension/modules_test.php b/tests/extension/modules_test.php index 88634bc6ba7..20b71e28128 100644 --- a/tests/extension/modules_test.php +++ b/tests/extension/modules_test.php @@ -46,7 +46,7 @@ public function setUp() $this->module_manager = new \phpbb\module\module_manager( new \phpbb\cache\driver\dummy(), - $this->getMock('\phpbb\db\driver\driver_interface'), + $this->createMock('\phpbb\db\driver\driver_interface'), $this->extension_manager, MODULES_TABLE, dirname(__FILE__) . '/', diff --git a/tests/feed/attachments_base_test.php b/tests/feed/attachments_base_test.php index 573218be420..3d66c906ada 100644 --- a/tests/feed/attachments_base_test.php +++ b/tests/feed/attachments_base_test.php @@ -35,8 +35,7 @@ public function setUp() new \phpbb\symfony_request( new phpbb_mock_request() ), - $this->filesystem, - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, 'php' ); diff --git a/tests/files/types_base_test.php b/tests/files/types_base_test.php index e630bf8c483..3b1cf68d509 100644 --- a/tests/files/types_base_test.php +++ b/tests/files/types_base_test.php @@ -39,7 +39,7 @@ protected function setUp() { global $phpbb_root_path, $phpEx; - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->filesystem = new \phpbb\filesystem\filesystem(); $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); @@ -75,7 +75,7 @@ public function data_check_upload_size() */ public function test_check_upload_size($filename, $max_filesize, $expected) { - $php_ini = $this->getMock('\bantu\IniGetWrapper\IniGetWrapper'); + $php_ini = $this->createMock('\bantu\IniGetWrapper\IniGetWrapper'); $php_ini->expects($this->any()) ->method('getString') ->willReturn($max_filesize); diff --git a/tests/files/types_form_test.php b/tests/files/types_form_test.php index 925babb47fd..25d79f61175 100644 --- a/tests/files/types_form_test.php +++ b/tests/files/types_form_test.php @@ -42,7 +42,7 @@ protected function setUp() { global $phpbb_root_path, $phpEx; - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->request->expects($this->any()) ->method('file') ->willReturn(array()); @@ -137,7 +137,7 @@ public function data_upload_form() */ public function test_upload_form($upload, $expected, $plupload = array()) { - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->request->expects($this->any()) ->method('file') ->willReturn($upload); diff --git a/tests/files/types_local_test.php b/tests/files/types_local_test.php index 31070de107b..67e4c571f52 100644 --- a/tests/files/types_local_test.php +++ b/tests/files/types_local_test.php @@ -42,7 +42,7 @@ protected function setUp() { global $phpbb_root_path, $phpEx; - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->request->expects($this->any()) ->method('file') ->willReturn(array()); diff --git a/tests/files/types_remote_test.php b/tests/files/types_remote_test.php index 1a7d63d7905..85ec2a528b2 100644 --- a/tests/files/types_remote_test.php +++ b/tests/files/types_remote_test.php @@ -47,7 +47,7 @@ protected function setUp() $config = new \phpbb\config\config(array()); $this->config = $config; $this->config->set('remote_upload_verify', 0); - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->filesystem = new \phpbb\filesystem\filesystem(); $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); @@ -102,7 +102,7 @@ public function data_get_max_file_size() */ public function test_get_max_file_size($max_file_size, $link, $expected = array('URL_NOT_FOUND')) { - $php_ini = $this->getMock('\bantu\IniGetWrapper\IniGetWrapper', array('getString')); + $php_ini = $this->createMock('\bantu\IniGetWrapper\IniGetWrapper', array('getString')); $php_ini->expects($this->any()) ->method('getString') ->willReturn($max_file_size); diff --git a/tests/files/upload_test.php b/tests/files/upload_test.php index c41204a0d5b..a9c2dca9d99 100644 --- a/tests/files/upload_test.php +++ b/tests/files/upload_test.php @@ -48,7 +48,7 @@ protected function setUp() $config['rand_seed'] = ''; $config['rand_seed_last_update'] = time() + 600; - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->filesystem = new \phpbb\filesystem\filesystem(); $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); diff --git a/tests/filesystem/helper_clean_path_test.php b/tests/filesystem/helper_clean_path_test.php new file mode 100644 index 00000000000..fd9ed605c89 --- /dev/null +++ b/tests/filesystem/helper_clean_path_test.php @@ -0,0 +1,52 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +use phpbb\filesystem\helper as filesystem_helper; + +class phpbb_filesystem_helper_clean_path_test extends phpbb_test_case +{ + + public function setUp() + { + parent::setUp(); + } + + public function clean_path_data() + { + yield ['foo', 'foo']; + yield ['foo/bar', 'foo/bar']; + yield ['foo/bar/', 'foo/bar/']; + yield ['foo/./bar', 'foo/bar']; + yield ['foo/./././bar', 'foo/bar']; + yield ['foo/bar/.', 'foo/bar']; + yield ['./foo/bar', './foo/bar']; + yield ['../foo/bar', '../foo/bar']; + yield ['./../foo/bar', './../foo/bar']; + yield ['././../foo/bar', './../foo/bar']; + yield ['one/two/three', 'one/two/three']; + yield ['one/two/../three', 'one/three']; + yield ['one/../two/three', 'two/three']; + yield ['one/two/..', 'one']; + yield ['one/two/../', 'one/']; + yield ['one/two/../three/../four', 'one/four']; + yield ['one/two/three/../../four', 'one/four']; + } + + /** + * @dataProvider clean_path_data + */ + public function test_clean_path($input, $expected) + { + $this->assertEquals($expected, filesystem_helper::clean_path($input)); + } +} diff --git a/tests/filesystem/helper_is_absolute_test.php b/tests/filesystem/helper_is_absolute_test.php new file mode 100644 index 00000000000..e7562bfaee6 --- /dev/null +++ b/tests/filesystem/helper_is_absolute_test.php @@ -0,0 +1,64 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +use phpbb\filesystem\helper as filesystem_helper; + +class phpbb_filesystem_helper_is_absolute_test extends phpbb_test_case +{ + + public function setUp() + { + parent::setUp(); + } + + static public function is_absolute_data() + { + // Empty + yield ['', false]; + + // Absolute unix style + yield ['/etc/phpbb', true]; + // Unix does not support \ so that is not an absolute path + yield ['\etc\phpbb', false]; + + // Absolute windows style + yield ['c:\windows', true]; + yield ['C:\Windows', true]; + yield ['c:/windows', true]; + yield ['C:/Windows', true]; + + // Executable + yield ['etc/phpbb', false]; + yield ['explorer.exe', false]; + + // Relative subdir + yield ['Windows\System32', false]; + yield ['Windows\System32\explorer.exe', false]; + yield ['Windows/System32', false]; + yield ['Windows/System32/explorer.exe', false]; + + // Relative updir + yield ['..\Windows\System32', false]; + yield ['..\Windows\System32\explorer.exe', false]; + yield ['../Windows/System32', false]; + yield ['../Windows/System32/explorer.exe', false]; + } + + /** + * @dataProvider is_absolute_data + */ + public function test_is_absolute($path, $expected) + { + $this->assertEquals($expected, filesystem_helper::is_absolute_path($path)); + } +} diff --git a/tests/filesystem/helper_realpath_test.php b/tests/filesystem/helper_realpath_test.php new file mode 100644 index 00000000000..ce85439504b --- /dev/null +++ b/tests/filesystem/helper_realpath_test.php @@ -0,0 +1,83 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +use phpbb\filesystem\helper as filesystem_helper; + +class phpbb_filesystem_helper_realpath_test extends phpbb_test_case +{ + protected static $filesystem_helper_phpbb_own_realpath; + + static public function setUpBeforeClass() + { + parent::setUpBeforeClass(); + + self::$filesystem_helper_phpbb_own_realpath = new ReflectionMethod('\phpbb\filesystem\helper', 'phpbb_own_realpath'); + self::$filesystem_helper_phpbb_own_realpath->setAccessible(true); + } + + public function setUp() + { + parent::setUp(); + } + + public function realpath_resolve_absolute_without_symlinks_data() + { + // Constant data + yield [__DIR__, __DIR__]; + yield [__DIR__ . '/../filesystem/../filesystem', __DIR__]; + yield [__DIR__ . '/././', __DIR__]; + yield [__DIR__ . '/non_existent', false]; + + yield [__FILE__, __FILE__]; + yield [__FILE__ . '../', false]; + } + + public function realpath_resolve_relative_without_symlinks_data() + { + if (!function_exists('getcwd')) + { + yield []; + } + else + { + $relative_path = filesystem_helper::make_path_relative(__DIR__, getcwd()); + + yield [$relative_path, __DIR__]; + yield [$relative_path . '../filesystem/../filesystem', __DIR__]; + yield [$relative_path . '././', __DIR__]; + + yield [$relative_path . 'helper_realpath_test.php', __FILE__]; + } + } + + /** + * @dataProvider realpath_resolve_absolute_without_symlinks_data + */ + public function test_realpath_absolute_without_links($path, $expected) + { + $this->assertEquals($expected, self::$filesystem_helper_phpbb_own_realpath->invoke(null, $path)); + } + + /** + * @dataProvider realpath_resolve_relative_without_symlinks_data + */ + public function test_realpath_relative_without_links($path, $expected) + { + if (!function_exists('getcwd')) + { + $this->markTestSkipped('phpbb_own_realpath() cannot be tested with relative paths: getcwd is not available.'); + } + + $this->assertEquals($expected, self::$filesystem_helper_phpbb_own_realpath->invoke(null, $path)); + } +} diff --git a/tests/functional/controllers_compatibility_test.php b/tests/functional/controllers_compatibility_test.php index 9499888a1a6..36a34aa7c8a 100644 --- a/tests/functional/controllers_compatibility_test.php +++ b/tests/functional/controllers_compatibility_test.php @@ -37,6 +37,13 @@ public function test_feed_compatibility() $this->assert301('feed.php?t=1', 'app.php/feed/topic/1'); } + public function test_cron_compatibility() + { + $this->assert301('cron.php?cron_type=foo', 'app.php/cron/foo'); + $this->assert301('cron.php?cron_type=foo&bar=foobar', 'app.php/cron/foo?bar=foobar'); + $this->assert301('cron.php?cron_type=foo&bar=foobar&who=me', 'app.php/cron/foo?bar=foobar&who=me'); + } + protected function assert301($from, $to) { self::$client->followRedirects(false); @@ -44,6 +51,7 @@ protected function assert301($from, $to) // Fix sid issues $location = self::$client->getResponse()->getHeader('Location'); + $location = str_replace('&', '&', $location); $location = preg_replace('#sid=[^&]+(&(amp;)?)?#', '', $location); if (substr($location, -1) === '?') { diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php index 58c3878b8bb..2957749e89f 100644 --- a/tests/functional/extension_controller_test.php +++ b/tests/functional/extension_controller_test.php @@ -89,6 +89,15 @@ public function test_controller_with_template() $this->phpbb_extension_manager->purge('foo/bar'); } + /** + * Check includejs/includecss when the request_uri is a subdirectory + */ + public function test_controller_template_include_js_css() + { + $crawler = self::request('GET', 'app.php/help/faq'); + $this->assertContains("./../../assets/javascript/core.js", $crawler->filter('body')->html()); + } + /** * Check the error produced by calling a controller without a required * argument. diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php index 426ebcee530..4fced5700ac 100644 --- a/tests/functional/fileupload_remote_test.php +++ b/tests/functional/fileupload_remote_test.php @@ -54,7 +54,7 @@ public function setUp() $this->filesystem = new \phpbb\filesystem\filesystem(); $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper; $container = new phpbb_mock_container_builder(); diff --git a/tests/functional/notification_test.php b/tests/functional/notification_test.php index 91fc9628469..4ca1d4b6373 100644 --- a/tests/functional/notification_test.php +++ b/tests/functional/notification_test.php @@ -77,12 +77,12 @@ public function test_mark_notifications_read() $crawler = self::request('GET', 'ucp.php?i=ucp_notifications'); // At least one notification should exist - $this->assertGreaterThan(0, $crawler->filter('#notification_list_button strong')->text()); + $this->assertGreaterThan(0, $crawler->filter('#notification-button strong')->text()); // Get form token $link = $crawler->selectLink($this->lang('NOTIFICATIONS_MARK_ALL_READ'))->link()->getUri(); $crawler = self::request('GET', substr($link, strpos($link, 'ucp.'))); - $this->assertCount(1, $crawler->filter('#notification_list_button strong.badge.hidden')); - $this->assertEquals("0", $crawler->filter('#notification_list_button strong.badge.hidden')->text()); + $this->assertCount(1, $crawler->filter('#notification-button strong.badge.hidden')); + $this->assertEquals("0", $crawler->filter('#notification-button strong.badge.hidden')->text()); } } diff --git a/tests/functional/prune_shadow_topic_test.php b/tests/functional/prune_shadow_topic_test.php index c014119b98e..39bf223f930 100644 --- a/tests/functional/prune_shadow_topic_test.php +++ b/tests/functional/prune_shadow_topic_test.php @@ -130,7 +130,16 @@ public function test_move_topic() $crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}"); $this->assertNotEmpty($crawler->filter('img')->last()->attr('src')); - self::request('GET', "cron.php?cron_type=cron.task.core.prune_shadow_topics&f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}", array(), false); + self::request('GET', "app.php/cron/cron.task.core.prune_shadow_topics?f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}", array(), false); + + // Try to ensure that the cron can actually run before we start to wait for it + sleep(1); + $cron_lock = new \phpbb\lock\db('cron_lock', new \phpbb\config\db($this->db, new \phpbb\cache\driver\dummy(), 'phpbb_config'), $this->db); + while (!$cron_lock->acquire()) + { + // do nothing + } + $cron_lock->release(); $this->assert_forum_details($this->data['forums']['Prune Shadow'], array( 'forum_posts_approved' => 0, diff --git a/tests/functions/build_url_test.php b/tests/functions/build_url_test.php index 91a4a9ec665..95b20050d73 100644 --- a/tests/functions/build_url_test.php +++ b/tests/functions/build_url_test.php @@ -27,8 +27,7 @@ protected function setUp() new \phpbb\symfony_request( new phpbb_mock_request() ), - new \phpbb\filesystem\filesystem(), - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, 'php' ); diff --git a/tests/functions/obtain_online_test.php b/tests/functions/obtain_online_test.php index 778753e5d23..77b10798024 100644 --- a/tests/functions/obtain_online_test.php +++ b/tests/functions/obtain_online_test.php @@ -162,7 +162,7 @@ public function test_obtain_users_online_string($forum_id, $display_guests, $exp $config['load_online_guests'] = $display_guests; $user = new phpbb_mock_lang(); $user->lang = $this->load_language(); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $acl_get_map = array( array('u_viewonline', true), array('u_viewprofile', true), diff --git a/tests/functions_content/get_username_string_test.php b/tests/functions_content/get_username_string_test.php index e79342d05d9..ac36e37e933 100644 --- a/tests/functions_content/get_username_string_test.php +++ b/tests/functions_content/get_username_string_test.php @@ -18,7 +18,7 @@ public function setUp() parent::setUp(); global $auth, $phpbb_dispatcher, $user; - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $auth->expects($this->any()) ->method('acl_get') ->with($this->stringContains('_'), $this->anything()) diff --git a/tests/functions_user/group_user_attributes_test.php b/tests/functions_user/group_user_attributes_test.php index 3124d57ba09..6968b1cd3a4 100644 --- a/tests/functions_user/group_user_attributes_test.php +++ b/tests/functions_user/group_user_attributes_test.php @@ -134,11 +134,11 @@ public function test_group_user_attributes($description, $user_id, $group_id, $g $cache = new phpbb_mock_cache; $db = $this->new_dbal(); $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $auth->expects($this->any()) ->method('acl_clear_prefetch'); $cache_driver = new \phpbb\cache\driver\dummy(); - $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $phpbb_container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface'); $phpbb_container ->expects($this->any()) ->method('get') diff --git a/tests/installer/installer_config_test.php b/tests/installer/installer_config_test.php index 13ac325a790..1193d7aee45 100644 --- a/tests/installer/installer_config_test.php +++ b/tests/installer/installer_config_test.php @@ -23,8 +23,9 @@ class phpbb_installer_config_test extends phpbb_test_case public function setUp() { $phpbb_root_path = __DIR__ . './../../phpBB/'; - $filesystem = $this->getMock('\phpbb\filesystem\filesystem'); + $filesystem = $this->createMock('\phpbb\filesystem\filesystem'); $php_ini = $this->getMockBuilder('\bantu\IniGetWrapper\IniGetWrapper') + ->setMethods(array('getInt', 'getBytes')) ->getMock(); $php_ini->method('getInt') ->willReturn(-1); diff --git a/tests/installer/module_base_test.php b/tests/installer/module_base_test.php index 95780100477..71ec2b8db24 100644 --- a/tests/installer/module_base_test.php +++ b/tests/installer/module_base_test.php @@ -42,7 +42,7 @@ public function setUp() $this->module = new test_installer_module($module_collection, true, false); - $iohandler = $this->getMock('\phpbb\install\helper\iohandler\iohandler_interface'); + $iohandler = $this->createMock('\phpbb\install\helper\iohandler\iohandler_interface'); $config = new \phpbb\install\helper\config(new \phpbb\filesystem\filesystem(), new \bantu\IniGetWrapper\IniGetWrapper(), '', 'php'); $this->module->setup($config, $iohandler); } diff --git a/tests/log/add_test.php b/tests/log/add_test.php index 604c8364dc3..469d4ebd691 100644 --- a/tests/log/add_test.php +++ b/tests/log/add_test.php @@ -28,7 +28,7 @@ public function test_log_enabled() $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); $user = new \phpbb\user($lang, '\phpbb\datetime'); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); @@ -59,7 +59,7 @@ public function test_log_add() $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); $user = new \phpbb\user($lang, '\phpbb\datetime'); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); diff --git a/tests/log/delete_test.php b/tests/log/delete_test.php index e8b75d01d96..04aa20d9ce5 100644 --- a/tests/log/delete_test.php +++ b/tests/log/delete_test.php @@ -30,7 +30,7 @@ protected function setUp() $lang = new \phpbb\language\language($lang_loader); $user = new \phpbb\user($lang, '\phpbb\datetime'); $user->data['user_id'] = 1; - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $this->log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); diff --git a/tests/log/function_add_log_test.php b/tests/log/function_add_log_test.php index 3b5537fc133..c3f1a0bebad 100644 --- a/tests/log/function_add_log_test.php +++ b/tests/log/function_add_log_test.php @@ -159,11 +159,11 @@ public function test_add_log_function($expected, $user_id, $mode, $required1, $a $db = $this->new_dbal(); $cache = new phpbb_mock_cache; $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $user = $this->getMock('\phpbb\user', array(), array( + $user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); diff --git a/tests/log/function_view_log_test.php b/tests/log/function_view_log_test.php index ee9c3e58930..c26644088e3 100644 --- a/tests/log/function_view_log_test.php +++ b/tests/log/function_view_log_test.php @@ -274,7 +274,7 @@ public static function view_log_function_data() // Offset that will be returned from the function 'expected_returned' => 0, // view_log parameters (see includes/functions_admin.php for docblock) - // $log is ommited! + // $log is omitted! 'mod', 5, 0, 12, 45, ), */ @@ -378,7 +378,7 @@ public function test_view_log_function($expected, $expected_returned, $mode, $lo $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); // Create auth mock - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $acl_get_map = array( array('f_read', 23, true), array('m_', 23, true), diff --git a/tests/mock/container_builder.php b/tests/mock/container_builder.php index 134589b0b87..edf0d58a281 100644 --- a/tests/mock/container_builder.php +++ b/tests/mock/container_builder.php @@ -23,11 +23,11 @@ class phpbb_mock_container_builder implements ContainerInterface * * @param string $id The service identifier * @param object $service The service instance - * @param string $scope The scope of the service + * @param bool $shared Whether service is shared * * @api */ - public function set($id, $service, $scope = self::SCOPE_CONTAINER) + public function set($id, $service, $shared = false) { $this->services[$id] = $service; } @@ -193,4 +193,9 @@ public function isFrozen() { return false; } + + public function initialized($id) + { + return true; + } } diff --git a/tests/mock/session_testable.php b/tests/mock/session_testable.php index 2f24978ba8b..5a57eecf61b 100644 --- a/tests/mock/session_testable.php +++ b/tests/mock/session_testable.php @@ -33,7 +33,7 @@ public function set_cookie($name, $data, $time, $httponly = true) * @param PHPUnit_Framework_Assert test The test from which this is called * @param array(string => mixed) cookies The cookie data to check against. * The keys are cookie names, the values can either be null to - * check only the existance of the cookie, or an array(d, t), + * check only the existence of the cookie, or an array(d, t), * where d is the cookie data to check, or null to skip the * check and t is the cookie time to check, or null to skip. */ diff --git a/tests/notification/fixtures/services_notification.yml b/tests/notification/fixtures/services_notification.yml index 6e68cccff67..c83d8bd3235 100644 --- a/tests/notification/fixtures/services_notification.yml +++ b/tests/notification/fixtures/services_notification.yml @@ -70,7 +70,7 @@ services: test: class: phpbb\notification\type\test - scope: prototype + shared: false parent: notification.type.base tags: - { name: notification.type } diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index 21559c42a52..baa90f29b1a 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -58,7 +58,7 @@ public function setUp() $db = $this->db; // Auth - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $auth->expects($this->any()) ->method('acl_get') ->with($this->stringContains('_'), @@ -92,7 +92,7 @@ public function setUp() $lang = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); // User - $user = $this->getMock('\phpbb\user', array(), array( + $user = $this->createMock('\phpbb\user', array(), array( $lang, '\phpbb\datetime' )); @@ -105,8 +105,8 @@ public function setUp() ); // Request - $type_cast_helper = $this->getMock('\phpbb\request\type_cast_helper_interface'); - $request = $this->getMock('\phpbb\request\request'); + $type_cast_helper = $this->createMock('\phpbb\request\type_cast_helper_interface'); + $request = $this->createMock('\phpbb\request\request'); $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); $user_loader = new \phpbb\user_loader($db, $phpbb_root_path, $phpEx, USERS_TABLE); diff --git a/tests/notification/submit_post_type_topic_test.php b/tests/notification/submit_post_type_topic_test.php index f14f3055173..a51f0780b1b 100644 --- a/tests/notification/submit_post_type_topic_test.php +++ b/tests/notification/submit_post_type_topic_test.php @@ -42,7 +42,7 @@ public function setUp() ), ))); - $phpbb_log = $this->getMock('\phpbb\log\dummy'); + $phpbb_log = $this->createMock('\phpbb\log\dummy'); } /** diff --git a/tests/notification/user_list_trim_test.php b/tests/notification/user_list_trim_test.php index 7d4dff6024a..0de62944910 100644 --- a/tests/notification/user_list_trim_test.php +++ b/tests/notification/user_list_trim_test.php @@ -39,7 +39,7 @@ public function setUp() $phpEx ); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $auth->expects($this->any()) ->method('acl_get') ->with($this->stringContains('_'), diff --git a/tests/pagination/pagination_test.php b/tests/pagination/pagination_test.php index 2d7d1671a82..a9c78059a58 100644 --- a/tests/pagination/pagination_test.php +++ b/tests/pagination/pagination_test.php @@ -29,7 +29,7 @@ public function setUp() global $phpbb_dispatcher, $phpbb_root_path, $phpEx; $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $this->user = $this->getMock('\phpbb\user', array(), array( + $this->user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); @@ -39,12 +39,11 @@ public function setUp() $this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); - $filesystem = new \phpbb\filesystem\filesystem(); $manager = new phpbb_mock_extension_manager(dirname(__FILE__) . '/', array()); $loader = new \Symfony\Component\Routing\Loader\YamlFileLoader( - new \phpbb\routing\file_locator($filesystem, dirname(__FILE__) . '/') + new \phpbb\routing\file_locator(dirname(__FILE__) . '/') ); $resources_locator = new \phpbb\routing\resources_locator\default_resources_locator(dirname(__FILE__) . '/', PHPBB_ENVIRONMENT, $manager); $router = new phpbb_mock_router(new phpbb_mock_container_builder(), $resources_locator, $loader, dirname(__FILE__) . '/', 'php'); @@ -58,7 +57,7 @@ public function setUp() $request ); - $this->routing_helper = new \phpbb\routing\helper($this->config, $router, $symfony_request, $request, $filesystem, '', 'php'); + $this->routing_helper = new \phpbb\routing\helper($this->config, $router, $symfony_request, $request, '', 'php'); $this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $symfony_request, $request, $this->routing_helper); $this->pagination = new \phpbb\pagination($this->template, $this->user, $this->helper, $phpbb_dispatcher); } diff --git a/tests/passwords/manager_test.php b/tests/passwords/manager_test.php index 0410d7035fa..40e2849f9c4 100644 --- a/tests/passwords/manager_test.php +++ b/tests/passwords/manager_test.php @@ -361,13 +361,13 @@ public function test_driver_interface_driver($use_new_interface, $needs_rehash, { if ($use_new_interface) { - $test_driver = $this->getMock('\phpbb\passwords\driver\rehashable_driver_interface', array('needs_rehash', 'get_prefix', 'check', 'is_supported', 'is_legacy', 'hash', 'get_settings_only')); + $test_driver = $this->createMock('\phpbb\passwords\driver\rehashable_driver_interface', array('needs_rehash', 'get_prefix', 'check', 'is_supported', 'is_legacy', 'hash', 'get_settings_only')); $test_driver->method('needs_rehash') ->willReturn($needs_rehash); } else { - $test_driver = $this->getMock('\phpbb\passwords\driver\driver_interface', array('get_prefix', 'check', 'is_supported', 'is_legacy', 'hash', 'get_settings_only')); + $test_driver = $this->createMock('\phpbb\passwords\driver\driver_interface', array('get_prefix', 'check', 'is_supported', 'is_legacy', 'hash', 'get_settings_only')); } $config = new \phpbb\config\config(array()); diff --git a/tests/path_helper/path_helper_test.php b/tests/path_helper/path_helper_test.php index 49dd40fbec9..f22606843cd 100644 --- a/tests/path_helper/path_helper_test.php +++ b/tests/path_helper/path_helper_test.php @@ -11,6 +11,8 @@ * */ +use phpbb\filesystem\helper as filesystem_helper; + class phpbb_path_helper_test extends phpbb_test_case { /** @var \phpbb\path_helper */ @@ -21,15 +23,13 @@ public function setUp() { parent::setUp(); - $filesystem = new \phpbb\filesystem\filesystem(); - $this->set_phpbb_root_path($filesystem); + $this->set_phpbb_root_path(); $this->path_helper = new \phpbb\path_helper( new \phpbb\symfony_request( new phpbb_mock_request() ), - new \phpbb\filesystem\filesystem(), - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $this->phpbb_root_path, 'php' ); @@ -43,9 +43,9 @@ public function setUp() * any time we wish to use it in one of these functions (and * also in general for everything else) */ - public function set_phpbb_root_path($filesystem) + public function set_phpbb_root_path() { - $this->phpbb_root_path = $filesystem->clean_path(dirname(__FILE__) . '/../../phpBB/'); + $this->phpbb_root_path = filesystem_helper::clean_path(dirname(__FILE__) . '/../../phpBB/'); } public function test_get_web_root_path() @@ -56,8 +56,7 @@ public function test_get_web_root_path() public function basic_update_web_root_path_data() { - $filesystem = new \phpbb\filesystem\filesystem(); - $this->set_phpbb_root_path($filesystem); + $this->set_phpbb_root_path(); return array( array( @@ -75,7 +74,7 @@ public function basic_update_web_root_path_data() ), array( $this->phpbb_root_path . $this->phpbb_root_path . 'test.php', - $filesystem->clean_path($this->phpbb_root_path . $this->phpbb_root_path . 'test.php'), + filesystem_helper::clean_path($this->phpbb_root_path . $this->phpbb_root_path . 'test.php'), ), ); } @@ -90,7 +89,7 @@ public function test_basic_update_web_root_path($input, $expected) public function update_web_root_path_data() { - $this->set_phpbb_root_path(new \phpbb\filesystem\filesystem()); + $this->set_phpbb_root_path(); return array( array( @@ -180,7 +179,7 @@ public function update_web_root_path_data() */ public function test_update_web_root_path($input, $getPathInfo, $getRequestUri, $getScriptName, $correction) { - $symfony_request = $this->getMock('\phpbb\symfony_request', array(), array( + $symfony_request = $this->createMock('\phpbb\symfony_request', array(), array( new phpbb_mock_request(), )); $symfony_request->expects($this->any()) @@ -195,8 +194,7 @@ public function test_update_web_root_path($input, $getPathInfo, $getRequestUri, $path_helper = new \phpbb\path_helper( $symfony_request, - new \phpbb\filesystem\filesystem(), - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $this->phpbb_root_path, 'php' ); diff --git a/tests/profilefields/type_bool_test.php b/tests/profilefields/type_bool_test.php index 10239172c34..66e1578e8a6 100644 --- a/tests/profilefields/type_bool_test.php +++ b/tests/profilefields/type_bool_test.php @@ -27,15 +27,17 @@ public function setUp() { global $phpbb_root_path, $phpEx; - $user = $this->getMock('\phpbb\user', array(), array( - new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), - '\phpbb\datetime' - )); + $db = $this->createMock('phpbb\\db\\driver\\driver'); + + $user = $this->createMock('\phpbb\user'); $user->expects($this->any()) ->method('lang') ->will($this->returnCallback(array($this, 'return_callback_implode'))); - $lang = $this->getMock('\phpbb\profilefields\lang_helper', array(), array(null, null)); + $lang = $this->getMockBuilder('\phpbb\profilefields\lang_helper') + ->setMethods(array('get_options_lang', 'is_set', 'get')) + ->setConstructorArgs(array($db, LANG_TABLE)) + ->getMock(); $lang->expects($this->any()) ->method('get_options_lang'); @@ -48,8 +50,8 @@ public function setUp() ->method('get') ->will($this->returnCallback(array($this, 'get'))); - $request = $this->getMock('\phpbb\request\request'); - $template = $this->getMock('\phpbb\template\template'); + $request = $this->createMock('\phpbb\request\request'); + $template = $this->createMock('\phpbb\template\template'); $this->cp = new \phpbb\profilefields\type\type_bool( $lang, diff --git a/tests/profilefields/type_date_test.php b/tests/profilefields/type_date_test.php index e0807b2f9bd..dc547c2d104 100644 --- a/tests/profilefields/type_date_test.php +++ b/tests/profilefields/type_date_test.php @@ -27,7 +27,7 @@ public function setUp() { global $phpbb_root_path, $phpEx; - $this->user = $this->getMock('\phpbb\user', array(), array( + $this->user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); @@ -45,8 +45,8 @@ public function setUp() 'DATE_FORMAT' => 'm/d/Y', ); - $request = $this->getMock('\phpbb\request\request'); - $template = $this->getMock('\phpbb\template\template'); + $request = $this->createMock('\phpbb\request\request'); + $template = $this->createMock('\phpbb\template\template'); $this->cp = new \phpbb\profilefields\type\type_date( $request, diff --git a/tests/profilefields/type_dropdown_test.php b/tests/profilefields/type_dropdown_test.php index ab02353fb9b..96b2ad31beb 100644 --- a/tests/profilefields/type_dropdown_test.php +++ b/tests/profilefields/type_dropdown_test.php @@ -27,18 +27,20 @@ public function setUp() { global $phpbb_root_path, $phpEx; - $user = $this->getMock('\phpbb\user', array(), array( - new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), - '\phpbb\datetime' - )); + $db = $this->createMock('phpbb\\db\\driver\\driver'); + + $user = $this->createMock('\phpbb\user'); $user->expects($this->any()) ->method('lang') ->will($this->returnCallback(array($this, 'return_callback_implode'))); - $request = $this->getMock('\phpbb\request\request'); - $template = $this->getMock('\phpbb\template\template'); + $request = $this->createMock('\phpbb\request\request'); + $template = $this->createMock('\phpbb\template\template'); - $lang = $this->getMock('\phpbb\profilefields\lang_helper', array(), array(null, null)); + $lang = $this->getMockBuilder('\phpbb\profilefields\lang_helper') + ->setMethods(array('get_options_lang', 'is_set', 'get')) + ->setConstructorArgs(array($db, LANG_TABLE)) + ->getMock(); $lang->expects($this->any()) ->method('get_options_lang'); diff --git a/tests/profilefields/type_googleplus_test.php b/tests/profilefields/type_googleplus_test.php index 92223622140..06ba231e68f 100644 --- a/tests/profilefields/type_googleplus_test.php +++ b/tests/profilefields/type_googleplus_test.php @@ -25,8 +25,8 @@ public function setUp() $lang = new \phpbb\language\language($lang_loader); $user = new \phpbb\user($lang, '\phpbb\datetime'); $user->add_lang('ucp'); - $request = $this->getMock('\phpbb\request\request'); - $template = $this->getMock('\phpbb\template\template'); + $request = $this->createMock('\phpbb\request\request'); + $template = $this->createMock('\phpbb\template\template'); $this->field = new \phpbb\profilefields\type\type_googleplus( $request, diff --git a/tests/profilefields/type_int_test.php b/tests/profilefields/type_int_test.php index 33f3f575c8b..326c6051b31 100644 --- a/tests/profilefields/type_int_test.php +++ b/tests/profilefields/type_int_test.php @@ -26,7 +26,7 @@ public function setUp() { global $phpbb_root_path, $phpEx; - $user = $this->getMock('\phpbb\user', array(), array( + $user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); @@ -34,8 +34,8 @@ public function setUp() ->method('lang') ->will($this->returnCallback(array($this, 'return_callback_implode'))); - $request = $this->getMock('\phpbb\request\request'); - $template = $this->getMock('\phpbb\template\template'); + $request = $this->createMock('\phpbb\request\request'); + $template = $this->createMock('\phpbb\template\template'); $this->cp = new \phpbb\profilefields\type\type_int( $request, diff --git a/tests/profilefields/type_string_test.php b/tests/profilefields/type_string_test.php index 54bb4068382..946e513e96b 100644 --- a/tests/profilefields/type_string_test.php +++ b/tests/profilefields/type_string_test.php @@ -26,7 +26,7 @@ public function setUp() { global $config, $request, $user, $cache, $phpbb_root_path, $phpEx; - $user = $this->getMock('\phpbb\user', array(), array( + $user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); @@ -36,8 +36,8 @@ public function setUp() ->will($this->returnCallback(array($this, 'return_callback_implode'))); $config = new \phpbb\config\config([]); - $request = $this->getMock('\phpbb\request\request'); - $template = $this->getMock('\phpbb\template\template'); + $request = $this->createMock('\phpbb\request\request'); + $template = $this->createMock('\phpbb\template\template'); $this->cp = new \phpbb\profilefields\type\type_string( $request, diff --git a/tests/profilefields/type_url_test.php b/tests/profilefields/type_url_test.php index 3bb5d528994..18aa214e3d6 100644 --- a/tests/profilefields/type_url_test.php +++ b/tests/profilefields/type_url_test.php @@ -32,7 +32,7 @@ public function setUp() $config = new \phpbb\config\config([]); $cache = new phpbb_mock_cache; - $user = $this->getMock('\phpbb\user', array(), array( + $user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); @@ -40,8 +40,8 @@ public function setUp() ->method('lang') ->will($this->returnCallback(array($this, 'return_callback_implode'))); - $request = $this->getMock('\phpbb\request\request'); - $template = $this->getMock('\phpbb\template\template'); + $request = $this->createMock('\phpbb\request\request'); + $template = $this->createMock('\phpbb\template\template'); $this->cp = new \phpbb\profilefields\type\type_url( $request, diff --git a/tests/request/deactivated_super_global_test.php b/tests/request/deactivated_super_global_test.php index d45f9ca6662..eabc79ed960 100644 --- a/tests/request/deactivated_super_global_test.php +++ b/tests/request/deactivated_super_global_test.php @@ -19,7 +19,7 @@ class phpbb_deactivated_super_global_test extends phpbb_test_case public function test_write_triggers_error() { $this->setExpectedTriggerError(E_USER_ERROR); - $obj = new \phpbb\request\deactivated_super_global($this->getMock('\phpbb\request\request_interface'), 'obj', \phpbb\request\request_interface::POST); + $obj = new \phpbb\request\deactivated_super_global($this->createMock('\phpbb\request\request_interface'), 'obj', \phpbb\request\request_interface::POST); $obj->offsetSet(0, 0); } } diff --git a/tests/request/request_test.php b/tests/request/request_test.php index ebaea1f9ef6..47798177e19 100644 --- a/tests/request/request_test.php +++ b/tests/request/request_test.php @@ -39,7 +39,7 @@ protected function setUp() $_SERVER['HTTP_ACCEPT'] = 'application/json'; $_SERVER['HTTP_SOMEVAR'] = ''; - $this->type_cast_helper = $this->getMock('\phpbb\request\type_cast_helper_interface'); + $this->type_cast_helper = $this->createMock('\phpbb\request\type_cast_helper_interface'); $this->request = new \phpbb\request\request($this->type_cast_helper); } diff --git a/tests/security/hash_test.php b/tests/security/hash_test.php index 84d4fcf479d..113c32bf7fe 100644 --- a/tests/security/hash_test.php +++ b/tests/security/hash_test.php @@ -18,7 +18,7 @@ public function setUp() global $phpbb_container; $config = new \phpbb\config\config(array()); - $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $phpbb_container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface'); $driver_helper = new \phpbb\passwords\driver\helper($config); $passwords_drivers = array( 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $driver_helper), diff --git a/tests/security/redirect_test.php b/tests/security/redirect_test.php index 40cb7d2f04d..b71f487e4fa 100644 --- a/tests/security/redirect_test.php +++ b/tests/security/redirect_test.php @@ -66,8 +66,7 @@ protected function get_path_helper() new \phpbb\symfony_request( new phpbb_mock_request() ), - new \phpbb\filesystem\filesystem(), - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $this->phpbb_root_path, 'php' ); diff --git a/tests/storage/adapter/local_test.php b/tests/storage/adapter/local_test.php new file mode 100644 index 00000000000..b478ce4009f --- /dev/null +++ b/tests/storage/adapter/local_test.php @@ -0,0 +1,125 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + + class phpbb_storage_adapter_local_test extends phpbb_test_case + { + protected $adapter; + + protected $path; + + public function setUp() + { + parent::setUp(); + + $filesystem = new \phpbb\filesystem\filesystem(); + $phpbb_root_path = getcwd() . DIRECTORY_SEPARATOR; + + $this->adapter = new \phpbb\storage\adapter\local($filesystem, new \FastImageSize\FastImageSize(), new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\extension_guesser)), $phpbb_root_path); + $this->adapter->configure(['path' => 'test_path']); + + $this->path = $phpbb_root_path . 'test_path/'; + mkdir($this->path); + } + + public function data_test_exists() + { + yield [$this->path . '../README.md', true]; + yield [$this->path . 'nonexistent_file.php', false]; + yield [$this->path . '../phpBB/phpbb', true]; + yield [$this->path . 'nonexistent/folder', false]; + } + + public function tearDown() + { + $this->adapter = null; + rmdir($this->path); + } + + public function test_put_contents() + { + $this->adapter->put_contents('file.txt', 'abc'); + $this->assertTrue(file_exists($this->path . 'file.txt')); + $this->assertEquals(file_get_contents($this->path . 'file.txt'), 'abc'); + unlink($this->path . 'file.txt'); + } + + public function test_get_contents() + { + file_put_contents($this->path . 'file.txt', 'abc'); + $this->assertEquals($this->adapter->get_contents('file.txt'), 'abc'); + unlink($this->path . 'file.txt'); + } + + /** + * @dataProvider data_test_exists + */ + public function test_exists($path, $expected) + { + $this->assertSame($expected, $this->adapter->exists($path)); + } + + public function test_delete_file() + { + file_put_contents($this->path . 'file.txt', ''); + $this->assertTrue(file_exists($this->path . 'file.txt')); + $this->adapter->delete('file.txt'); + $this->assertFalse(file_exists($this->path . 'file.txt')); + } + + public function test_delete_folder() + { + mkdir($this->path . 'path/to/dir', 0777, true); + $this->assertTrue(file_exists($this->path . 'path/to/dir')); + $this->adapter->delete('path'); + $this->assertFalse(file_exists($this->path . 'path/to/dir')); + } + + public function test_rename() + { + file_put_contents($this->path . 'file.txt', ''); + $this->adapter->rename('file.txt', 'file2.txt'); + $this->assertFalse(file_exists($this->path . 'file.txt')); + $this->assertTrue(file_exists($this->path . 'file2.txt')); + unlink($this->path . 'file2.txt'); + } + + public function test_copy() + { + file_put_contents($this->path . 'file.txt', 'abc'); + $this->adapter->copy('file.txt', 'file2.txt'); + $this->assertEquals(file_get_contents($this->path . 'file.txt'), 'abc'); + $this->assertEquals(file_get_contents($this->path . 'file.txt'), 'abc'); + unlink($this->path . 'file.txt'); + unlink($this->path . 'file2.txt'); + } + + public function test_read_stream() + { + file_put_contents($this->path . 'file.txt', ''); + $stream = $this->adapter->read_stream('file.txt'); + $this->assertTrue(is_resource($stream)); + fclose($stream); + unlink($this->path . 'file.txt'); + } + + public function test_write_stream() + { + file_put_contents($this->path . 'file.txt', 'abc'); + $stream = fopen($this->path . 'file.txt', 'rb'); + $this->adapter->write_stream('file2.txt', $stream); + fclose($stream); + $this->assertEquals(file_get_contents($this->path . 'file2.txt'), 'abc'); + unlink($this->path . 'file.txt'); + unlink($this->path . 'file2.txt'); + } + } diff --git a/tests/template/includephp_test.php b/tests/template/includephp_test.php index 722e10e42d8..baf2eed11b5 100644 --- a/tests/template/includephp_test.php +++ b/tests/template/includephp_test.php @@ -11,6 +11,8 @@ * */ +use phpbb\filesystem\helper as filesystem_helper; + require_once dirname(__FILE__) . '/template_test_case.php'; class phpbb_template_includephp_test extends phpbb_template_template_test_case @@ -39,9 +41,8 @@ public function test_includephp_absolute() { global $phpbb_root_path; - $filesystem = new \phpbb\filesystem\filesystem(); $path_to_php = str_replace('\\', '/', dirname(__FILE__)) . '/templates/_dummy_include.php.inc'; - $this->assertTrue($filesystem->is_absolute_path($path_to_php)); + $this->assertTrue(filesystem_helper::is_absolute_path($path_to_php)); $template_text = "Path is absolute.\n"; $cache_dir = $phpbb_root_path . 'cache/'; diff --git a/tests/template/template_allfolder_test.php b/tests/template/template_allfolder_test.php index 63a6ef08ea9..17a57fba353 100644 --- a/tests/template/template_allfolder_test.php +++ b/tests/template/template_allfolder_test.php @@ -39,8 +39,7 @@ protected function setup_engine_for_allfolder(array $new_config = array()) new \phpbb\symfony_request( new phpbb_mock_request() ), - $filesystem, - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, $phpEx ); @@ -59,7 +58,7 @@ protected function setup_engine_for_allfolder(array $new_config = array()) $container = new phpbb_mock_container_builder(); $cache_path = $phpbb_root_path . 'cache/twig'; $context = new \phpbb\template\context(); - $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), ''); + $loader = new \phpbb\template\twig\loader(''); $twig = new \phpbb\template\twig\environment( $config, $filesystem, diff --git a/tests/template/template_events_test.php b/tests/template/template_events_test.php index 3a93c91e116..024bdc57ce4 100644 --- a/tests/template/template_events_test.php +++ b/tests/template/template_events_test.php @@ -144,8 +144,7 @@ protected function setup_engine_for_events($dataset, $style_names, array $new_co new \phpbb\symfony_request( new phpbb_mock_request() ), - new \phpbb\filesystem\filesystem(), - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, $phpEx ); @@ -153,7 +152,7 @@ protected function setup_engine_for_events($dataset, $style_names, array $new_co $container = new phpbb_mock_container_builder(); $cache_path = $phpbb_root_path . 'cache/twig'; $context = new \phpbb\template\context(); - $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), ''); + $loader = new \phpbb\template\twig\loader(''); $twig = new \phpbb\template\twig\environment( $config, $filesystem, diff --git a/tests/template/template_includecss_test.php b/tests/template/template_includecss_test.php index 4eb30eda1e2..f195742dc68 100644 --- a/tests/template/template_includecss_test.php +++ b/tests/template/template_includecss_test.php @@ -34,8 +34,7 @@ protected function setup_engine(array $new_config = array()) new \phpbb\symfony_request( new phpbb_mock_request() ), - $filesystem, - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, $phpEx ); @@ -45,7 +44,7 @@ protected function setup_engine(array $new_config = array()) $container = new phpbb_mock_container_builder(); $cache_path = $phpbb_root_path . 'cache/twig'; $context = new \phpbb\template\context(); - $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), ''); + $loader = new \phpbb\template\twig\loader(''); $twig = new \phpbb\template\twig\environment( $config, $filesystem, diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index 8adbafb1b26..bcb6f4cde74 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -86,8 +86,7 @@ protected function setup_engine(array $new_config = array()) new \phpbb\symfony_request( new phpbb_mock_request() ), - $filesystem, - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, $phpEx ); @@ -97,7 +96,7 @@ protected function setup_engine(array $new_config = array()) $container = new phpbb_mock_container_builder(); $cache_path = $phpbb_root_path . 'cache/twig'; $context = new \phpbb\template\context(); - $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), ''); + $loader = new \phpbb\template\twig\loader(''); $twig = new \phpbb\template\twig\environment( $config, $filesystem, diff --git a/tests/template/template_test_case_with_tree.php b/tests/template/template_test_case_with_tree.php index 75e3918f446..aa71bf6ed6d 100644 --- a/tests/template/template_test_case_with_tree.php +++ b/tests/template/template_test_case_with_tree.php @@ -28,8 +28,7 @@ protected function setup_engine(array $new_config = array()) new \phpbb\symfony_request( new phpbb_mock_request() ), - $filesystem, - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, $phpEx ); @@ -40,7 +39,7 @@ protected function setup_engine(array $new_config = array()) $container = new phpbb_mock_container_builder(); $cache_path = $phpbb_root_path . 'cache/twig'; $context = new \phpbb\template\context(); - $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), ''); + $loader = new \phpbb\template\twig\loader(''); $twig = new \phpbb\template\twig\environment( $config, $filesystem, diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index 606c40a6233..abfdf399409 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -58,7 +58,7 @@ static public function setUpBeforeClass() $setup_extensions = static::setup_extensions(); - $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path, null, $phpEx); + $finder = new \phpbb\finder($phpbb_root_path, null, $phpEx); $finder->core_path('phpbb/db/migration/data/'); if (!empty($setup_extensions)) { diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index f3adbefc1ba..f7ba3ba21b9 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -374,7 +374,7 @@ protected function load_schema_from_file($directory, \phpbb\db\driver\driver_int { global $phpbb_root_path, $phpEx, $table_prefix; - $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path, null, $phpEx); + $finder = new \phpbb\finder($phpbb_root_path, null, $phpEx); $classes = $finder->core_path('phpbb/db/migration/data/') ->get_classes(); diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index e1daa4558a0..f068ab8c199 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -259,7 +259,6 @@ protected function get_extension_manager() $container, $db, $config, - new phpbb\filesystem\filesystem(), self::$config['table_prefix'] . 'ext', dirname(__FILE__) . '/', $phpEx, @@ -623,11 +622,11 @@ protected function remove_user_group($group_name, $usernames) $db = $this->get_db(); $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $user = $this->getMock('\phpbb\user', array(), array( + $user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); $cache = new phpbb_mock_null_cache; @@ -665,17 +664,17 @@ protected function add_user_group($group_name, $usernames, $default = false, $le $db = $this->get_db(); $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $user = $this->getMock('\phpbb\user', array(), array( + $user = $this->createMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' )); - $auth = $this->getMock('\phpbb\auth\auth'); + $auth = $this->createMock('\phpbb\auth\auth'); $phpbb_log = new \phpbb\log\log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); $cache = new phpbb_mock_null_cache; $cache_driver = new \phpbb\cache\driver\dummy(); - $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $phpbb_container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface'); $phpbb_container ->expects($this->any()) ->method('get') diff --git a/tests/test_framework/phpbb_session_test_case.php b/tests/test_framework/phpbb_session_test_case.php index b3d7780d143..207659b3bd5 100644 --- a/tests/test_framework/phpbb_session_test_case.php +++ b/tests/test_framework/phpbb_session_test_case.php @@ -29,15 +29,13 @@ function setUp() { parent::setUp(); - global $symfony_request, $phpbb_filesystem, $phpbb_path_helper, $request, $phpbb_root_path, $phpEx; + global $symfony_request, $phpbb_path_helper, $request, $phpbb_root_path, $phpEx; $symfony_request = new \phpbb\symfony_request( new phpbb_mock_request() ); - $phpbb_filesystem = new \phpbb\filesystem\filesystem(); $phpbb_path_helper = new \phpbb\path_helper( $symfony_request, - $phpbb_filesystem, - $this->getMock('\phpbb\request\request'), + $this->createMock('\phpbb\request\request'), $phpbb_root_path, $phpEx ); diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index c792976b1ea..367b5f14d26 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -95,7 +95,12 @@ public function setExpectedTriggerError($errno, $message = '') break; } $this->expectedTriggerError = true; - $this->test_case->setExpectedException($exceptionName, (string) $message, $errno); + $this->test_case->expectException($exceptionName); + $this->test_case->expectExceptionCode($errno); + if ($message) + { + $this->test_case->expectExceptionMessage((string) $message); + } } public function makedirs($path) @@ -382,10 +387,16 @@ public function set_s9e_services(ContainerInterface $container = null, $fixture } // Mock the DAL, make it return data from the fixture + $db_driver = $this->test_case->getMockBuilder('phpbb\\db\\driver\\driver') + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->disallowMockingUnknownTypes() + ->getMock(); $mb = $this->test_case->getMockBuilder('phpbb\\textformatter\\data_access'); $mb->setMethods(array('get_bbcodes', 'get_censored_words', 'get_smilies', 'get_styles')); $mb->setConstructorArgs(array( - $this->test_case->getMockBuilder('phpbb\\db\\driver\\driver')->getMock(), + $db_driver, 'phpbb_bbcodes', 'phpbb_smilies', 'phpbb_styles', diff --git a/tests/test_framework/phpbb_ui_test_case.php b/tests/test_framework/phpbb_ui_test_case.php index d38d14f45c2..f8a35c75a53 100644 --- a/tests/test_framework/phpbb_ui_test_case.php +++ b/tests/test_framework/phpbb_ui_test_case.php @@ -382,7 +382,6 @@ protected function get_extension_manager() $container, $db, $config, - new phpbb\filesystem(), $user, self::$config['table_prefix'] . 'ext', dirname(__FILE__) . '/', diff --git a/tests/text_formatter/s9e/factory_test.php b/tests/text_formatter/s9e/factory_test.php index 0d780a19a94..1505609684e 100644 --- a/tests/text_formatter/s9e/factory_test.php +++ b/tests/text_formatter/s9e/factory_test.php @@ -286,7 +286,7 @@ public function test_malformed_bbcodes() */ public function test_configure_events() { - $this->dispatcher = $this->getMock('phpbb\\event\\dispatcher_interface'); + $this->dispatcher = $this->createMock('phpbb\\event\\dispatcher_interface'); $this->dispatcher ->expects($this->at(0)) ->method('trigger_event') diff --git a/tests/text_formatter/s9e/parser_test.php b/tests/text_formatter/s9e/parser_test.php index 4b9bbf9bb2f..e10ebd29ee9 100644 --- a/tests/text_formatter/s9e/parser_test.php +++ b/tests/text_formatter/s9e/parser_test.php @@ -19,7 +19,7 @@ public function test_load_from_cache() ->disableOriginalConstructor() ->getMock(); - $cache = $this->getMock('phpbb_mock_cache'); + $cache = $this->createMock('phpbb_mock_cache'); $cache->expects($this->once()) ->method('get') ->with('_foo_parser') @@ -172,7 +172,7 @@ public function get_options_tests() public function test_setup_event() { $container = $this->get_test_case_helpers()->set_s9e_services(); - $dispatcher = $this->getMock('phpbb\\event\\dispatcher_interface'); + $dispatcher = $this->createMock('phpbb\\event\\dispatcher_interface'); $dispatcher ->expects($this->once()) ->method('trigger_event') @@ -202,7 +202,7 @@ public function setup_event_callback($vars) public function test_parse_event() { $container = $this->get_test_case_helpers()->set_s9e_services(); - $dispatcher = $this->getMock('phpbb\\event\\dispatcher_interface'); + $dispatcher = $this->createMock('phpbb\\event\\dispatcher_interface'); $dispatcher ->expects($this->any()) ->method('trigger_event') diff --git a/tests/text_formatter/s9e/renderer_test.php b/tests/text_formatter/s9e/renderer_test.php index 175b90fdc79..672069590a0 100644 --- a/tests/text_formatter/s9e/renderer_test.php +++ b/tests/text_formatter/s9e/renderer_test.php @@ -26,7 +26,7 @@ public function test_load_from_cache() 'getMock('phpbb_mock_cache'); + $cache = $this->createMock('phpbb_mock_cache'); $cache->expects($this->once()) ->method('get') ->with('_foo_renderer') @@ -50,7 +50,7 @@ public function test_regenerate_on_cache_miss() { $mock = $this->getMockForAbstractClass('s9e\\TextFormatter\\Renderer'); - $cache = $this->getMock('phpbb_mock_cache'); + $cache = $this->createMock('phpbb_mock_cache'); $cache->expects($this->once()) ->method('get') ->with('_foo_renderer') @@ -197,7 +197,7 @@ function ($phpbb_container, $test) $config = new \phpbb\config\config(array('allow_nocensors' => true)); - $auth = $test->getMock('phpbb\\auth\\auth'); + $auth = $test->createMock('phpbb\\auth\\auth'); $auth->expects($test->any()) ->method('acl_get') ->with('u_chgcensors') @@ -393,7 +393,7 @@ public function test_style_inheritance2() public function test_setup_event() { $container = $this->get_test_case_helpers()->set_s9e_services(); - $dispatcher = $this->getMock('phpbb\\event\\dispatcher_interface'); + $dispatcher = $this->createMock('phpbb\\event\\dispatcher_interface'); $dispatcher ->expects($this->once()) ->method('trigger_event') @@ -424,7 +424,7 @@ public function setup_event_callback($vars) public function test_render_event() { $container = $this->get_test_case_helpers()->set_s9e_services(); - $dispatcher = $this->getMock('phpbb\\event\\dispatcher_interface'); + $dispatcher = $this->createMock('phpbb\\event\\dispatcher_interface'); $dispatcher ->expects($this->any()) ->method('trigger_event') diff --git a/tests/text_processing/generate_text_for_display_test.php b/tests/text_processing/generate_text_for_display_test.php index 86bc803c981..22d6d26c75c 100644 --- a/tests/text_processing/generate_text_for_display_test.php +++ b/tests/text_processing/generate_text_for_display_test.php @@ -77,7 +77,7 @@ public function test_censor_is_restored() $config = new \phpbb\config\config(array('allow_nocensors' => true)); - $auth = $this->getMock('phpbb\\auth\\auth'); + $auth = $this->createMock('phpbb\\auth\\auth'); $auth->expects($this->any()) ->method('acl_get') ->with('u_chgcensors') diff --git a/tests/upload/fileupload_test.php b/tests/upload/fileupload_test.php index 5b3357237d4..84fc00bf985 100644 --- a/tests/upload/fileupload_test.php +++ b/tests/upload/fileupload_test.php @@ -50,7 +50,7 @@ protected function setUp() $config['rand_seed'] = ''; $config['rand_seed_last_update'] = time() + 600; - $this->request = $this->getMock('\phpbb\request\request'); + $this->request = $this->createMock('\phpbb\request\request'); $this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper; $this->filesystem = new \phpbb\filesystem\filesystem(); @@ -83,13 +83,13 @@ protected function setUp() $this->php_ini, $plupload, $this->request - ), phpbb_mock_container_builder::SCOPE_PROTOTYPE); + )); $this->container->set('files.types.local', new \phpbb\files\types\local( $this->factory, $this->language, $this->php_ini, $this->request - ), phpbb_mock_container_builder::SCOPE_PROTOTYPE); + )); $this->path = __DIR__ . '/fixture/'; $this->phpbb_root_path = $phpbb_root_path; diff --git a/tests/version/version_helper_remote_test.php b/tests/version/version_helper_remote_test.php index 35c3d92a3a3..7b8d71181f3 100644 --- a/tests/version/version_helper_remote_test.php +++ b/tests/version/version_helper_remote_test.php @@ -30,7 +30,11 @@ public function setUp() )); $container = new \phpbb_mock_container_builder(); $db = new \phpbb\db\driver\factory($container); - $this->cache = $this->getMock('\phpbb\cache\service', array('get'), array(new \phpbb\cache\driver\dummy(), $config, $db, '../../', 'php')); + $this->cache = $this->getMockBuilder('\phpbb\cache\service') + ->setMethods(array('get')) + ->setConstructorArgs(array(new \phpbb\cache\driver\dummy(), $config, $db, '../../', 'php')) + ->getMock(); + $this->cache->expects($this->any()) ->method('get') ->with($this->anything()) diff --git a/travis/check-stylesheet.sh b/travis/check-stylesheet.sh new file mode 100755 index 00000000000..331f3f0c30a --- /dev/null +++ b/travis/check-stylesheet.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# +# This file is part of the phpBB Forum Software package. +# +# @copyright (c) phpBB Limited +# @license GNU General Public License, version 2 (GPL-2.0) +# +# For full copyright and license information, please see +# the docs/CREDITS.txt file. +# +set -e +set +x + +NOTESTS=$1 + +if [ "$NOTESTS" == '1' ] +then + # Define a node version. + TRAVIS_NODE_VERSION="4" + + # Clear out whatever version of NVM Travis has. + # Their version of NVM is probably old. + rm -rf ~/.nvm + # Grab NVM. + git clone https://github.com/creationix/nvm.git ~/.nvm > /dev/null + # Checkout the latest stable tag. + # Note that you can just hardcode a preferred version here. + (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) + # Install the desired version of Node + source ~/.nvm/nvm.sh + nvm install $TRAVIS_NODE_VERSION > /dev/null + npm install -g > /dev/null + npm install > /dev/null + set -x + stylelint "phpBB/styles/prosilver/theme/*.css" + # Disable admin stylelint for now + stylelint "phpBB/adm/style/*.css" +fi diff --git a/travis/phpunit-mariadb-travis.xml b/travis/phpunit-mariadb-travis.xml index 53a206b9b00..4b85124783e 100644 --- a/travis/phpunit-mariadb-travis.xml +++ b/travis/phpunit-mariadb-travis.xml @@ -1,6 +1,6 @@ > ${PHPBB_CONFIG} + +# Change environment to development +sed -i '/^.*PHPBB_ENVIRONMENT.*$/s/production/development/' ${PHPBB_CONFIG} + +# Display load time +sed -i '/^.*PHPBB_DISPLAY_LOAD_TIME.*$/s/^\/\/[[:blank:]]*//' ${PHPBB_CONFIG} # Update the PHP memory limits (enough to allow phpunit tests to run) -sed -i "s/memory_limit = .*/memory_limit = 1024M/" /etc/php5/fpm/php.ini +sed -i "s/memory_limit = .*/memory_limit = 1024M/" /etc/php/7.1/fpm/php.ini + +# Make routes work in vagrant (https://tracker.phpbb.com/browse/PHPBB3-15400) +sed -i '/^.*try_files.*$/s/index/app/' /etc/nginx/sites-enabled/phpbb.app +nginx -s reload echo "Your board is ready at http://192.168.10.10/"

    {L_RANK} {group.GROUP_NAME}{group.GROUP_NAME}
    -   - +   +